If you want to help us maintaining this wiki, check out our discord server: https://discord.gg/3u69jMa 

Difference between revisions of "Republic Commando UCC"

From SWRC Wiki
Jump to navigation Jump to search
Line 10: Line 10:




==UCC.cpp==
<source lang="cpp" line">
/*
/*
* This is a custom UCC.exe for Star Wars Republic Commando since the game shipped without one.
* This is a custom UCC.exe for Star Wars Republic Commando since the game shipped without one.
* Everything compiles fine with Visual Studio .NET 2003 which is being used to achieve maximum compatibility
* Everything compiles fine with Visual Studio .NET 2003 which is being used to achieve maximum compatibility
* since it was also used to compile RC
* since it was also used to compile RC
* The following settings are required in order to compile everything without errors:
* The following settings are required in order to compile everything without errors:
* - Character Set = Not Set //Important as RC does not use unicode
* - Character Set = Not Set
* - Struct Member Alignment = 4 Bytes //Probably not necessary, but just in case...
* - Struct Member Alignment = 4 Bytes
* - Calling Convention = __fastcall //RC uses __fastcall as default calling convention
* - Calling Convention = __fastcall
*/
*/


#include "../../Core/Inc/Core.h"
#include "../../Core/Inc/Core.h"
#include "../../Core/Inc/FOutputDeviceFile.h"
#include "../../Core/Inc/FOutputDeviceFile.h"
#include "../../Core/Inc/FOutputDeviceWindowsError.h"
#include "../../Core/Inc/FOutputDeviceWindowsError.h"
#include "../../Core/Inc/FFeedbackContextAnsi.h"
#include "../../Core/Inc/FFeedbackContextCmd.h"
#include "../../Core/Inc/FConfigCacheIni.h"
#include "../../Core/Inc/FConfigCacheIni.h"


void UServerCommandletMain(); //Defined in ServerCommandlet.cpp
void UServerCommandletMain(); // Defined in ServerCommandlet.cpp


//Output devices
void ShowBanner(FOutputDevice& Out){
 
Out.Log("=======================================");
FOutputDeviceFile Log;
Out.Log("ucc.exe for Star Wars Republic Commando");
FOutputDeviceWindowsError Error;
Out.Log("made by Leon0628");
FFeedbackContextAnsi Warn;
Out.Log("=======================================");
Out.Log("");
}


void ShowBanner(){
int __cdecl main(int argc, char** argv){
Warn.Log("=======================================");
int ExitCode = EXIT_SUCCESS;
Warn.Log("ucc.exe for Star Wars Republic Commando");
FOutputDeviceFile Log;
Warn.Log("made by Leon0628");
FOutputDeviceWindowsError Error;
Warn.Log("=======================================\n");
FFeedbackContextCmd Warn;
}


int main(int argc, char** argv){
GIsStarted = 1;
GIsStarted = 1;


Line 52: Line 49:
FString CmdLine;
FString CmdLine;


for(int i = 1; i < argc; i++)
for(int i = 1; i < argc; ++i)
CmdLine += FString(argv[i]) + " ";
CmdLine += FString(argv[i]) + " ";


Line 59: Line 56:


if(argc > 1){
if(argc > 1){
//Initializing global state
// Initializing global state
GIsUCC = GIsClient = GIsServer = GIsEditor = GIsScriptable = GLazyLoad = 1;
GIsUCC = GIsClient = GIsServer = GIsEditor = GIsScriptable = GLazyLoad = 1;


Line 65: Line 62:
TArray<FRegistryObjectInfo> List;
TArray<FRegistryObjectInfo> List;


UObject::GetRegistryObjects(List, UClass::StaticClass(), UCommandlet::StaticClass(), 0); //Loading list of commandlets declared in .int files
UObject::GetRegistryObjects(List, UClass::StaticClass(), UCommandlet::StaticClass(), 0); // Loading list of commandlets declared in .int files


for(int i = 0; i < List.Num(); i++){ //Looking Token up in list and autocompleting class name if found
for(int i = 0; i < List.Num(); ++i){ // Looking Token up in list and autocompleting class name if found
FString Str = List[i].Object;
FString FullName = List[i].Object;
FString ShortName = FullName;


if(ClassName == Str || ClassName + "Commandlet" == Str){ //Checking against "PackageName.ClassName (+ Commandlet)"
while(ShortName.InStr(".") >= 0) // Removing package name so that only class name remains
ClassName = List[i].Object;
ShortName = ShortName.Mid(ShortName.InStr(".") + 1);


break;
if(ClassName == FullName || ClassName + "Commandlet" == FullName ||  // Checking against "PackageName.ClassName (+ Commandlet)"
}
  ClassName == ShortName || ClassName + "Commandlet" == ShortName){ // Checking against "ClassName (+ Commandlet)"
 
while(Str.InStr(".") >= 0) //Removing package name so that only class name remains
Str = Str.Mid(Str.InStr(".") + 1);
 
if(ClassName == Str || ClassName + "Commandlet" == Str){ //Checking against "ClassName (+ Commandlet)" and adding "PackageName"
ClassName = List[i].Object;
ClassName = List[i].Object;


Line 88: Line 81:
DWORD LoadFlags = LOAD_NoWarn | LOAD_Quiet;
DWORD LoadFlags = LOAD_NoWarn | LOAD_Quiet;


if(ClassName == "Editor.MakeCommandlet")
if(ClassName == "Editor.MakeCommandlet"){
// Loading default packages to avoid 'Superclass not found' errors
UObject::LoadPackage(NULL, "Core", LOAD_NoFail);
UObject::LoadPackage(NULL, "Engine", LOAD_NoFail);
LoadFlags |= LOAD_DisallowFiles;
LoadFlags |= LOAD_DisallowFiles;
}


UClass* Class = LoadClass<UCommandlet>(NULL, *ClassName, NULL, LoadFlags, NULL);
UClass* Class = LoadClass<UCommandlet>(NULL, *ClassName, NULL, LoadFlags, NULL);


if(!Class) //If class failed to load appending "Commandlet" and trying again
if(!Class) // If class failed to load appending "Commandlet" and trying again
Class = LoadClass<UCommandlet>(NULL, *(ClassName + "Commandlet"), NULL, LoadFlags, NULL);
Class = LoadClass<UCommandlet>(NULL, *(ClassName + "Commandlet"), NULL, LoadFlags, NULL);


if(Class){
if(Class){
UCommandlet* Commandlet = ConstructObject<UCommandlet>(Class);
UCommandlet* Commandlet = ConstructObject<UCommandlet>(Class);
UCommandlet* Default = static_cast<UCommandlet*>(Class->GetDefaultObject());
UCommandlet* Default = Cast<UCommandlet>(Class->GetDefaultObject());


if(Default->ShowBanner)
if(Default->ShowBanner)
ShowBanner();
ShowBanner(Warn);


Warn.Logf("Executing %s\n", Class->GetFullName());
Warn.Logf("Executing %s", Class->GetFullName());
Warn.Log("");


GIsClient = Default->IsClient;
GIsClient = Default->IsClient;
Line 110: Line 108:
GLazyLoad = Default->LazyLoad;
GLazyLoad = Default->LazyLoad;


//Contains only the command-line options that are passed to the commandlet
// Contains only the command-line options that are passed to the commandlet
FString CommandletCmdLine;
FString CommandletCmdLine;


for(int i = 2; i < argc; i++)
for(int i = 2; i < argc; ++i)
CommandletCmdLine += FString(argv[i]) + " ";
CommandletCmdLine += FString(argv[i]) + " ";


Line 119: Line 117:
Commandlet->ParseParms(*CommandletCmdLine);
Commandlet->ParseParms(*CommandletCmdLine);


if(Default->LogToStdout){ //Redirecting commandlet output to console
if(Default->LogToStdout){ // Redirecting commandlet output to console
Warn.AuxOut = GLog;
Warn.AuxOut = GLog;
GLog = &Warn;
GLog = &Warn;
}
}
 
if(ClassName == "Engine.ServerCommandlet")
if(ClassName == "Engine.Server" || ClassName == "Engine.ServerCommandlet")
UServerCommandletMain(); //The ServerCommandlet has a special Main function
UServerCommandletMain(); // The ServerCommandlet has a special Main function
else
else
Commandlet->Main(CommandletCmdLine);
ExitCode = CommandletMain(Commandlet, CommandletCmdLine);


if(Default->ShowErrorCount)
if(Default->ShowErrorCount){
Warn.Logf("\n%s - %i error(s), %i warning(s)", Warn.ErrorCount == 0 ? "Success" : "Failure", Warn.ErrorCount, Warn.WarningCount);
Warn.Log("");
Warn.Logf("%s - %i error(s), %i warning(s)", Warn.ErrorCount == 0 ? "Success" : "Failure", Warn.ErrorCount, Warn.WarningCount);
}


if(Default->LogToStdout){
if(Default->LogToStdout){
Line 137: Line 137:
}
}
}else{
}else{
ShowBanner();
ShowBanner(Warn);
Warn.Logf("Commandlet %s not found", argv[1]);
Warn.Logf("Commandlet %s not found", argv[1]);
}
}
}else{
}else{
ShowBanner();
ShowBanner(Warn);
Warn.Log("Usage:");
Warn.Log("Usage:");
Warn.Log("    ucc CommandletName <parameters>");
Warn.Log("    ucc <command> <parameters>");
}
}


//This prevents an infinite loop during garbage collection when there are compile errors with ucc make
// This prevents an infinite loop during garbage collection when there are compile errors with ucc make
//Hopefully only a temporary fix...
if(Warn.ErrorCount == 0)
if(Warn.ErrorCount == 0)
appPreExit();
appPreExit();
else
ExitCode = EXIT_FAILURE;


GIsGuarded = 0;
GIsGuarded = 0;
Line 155: Line 156:
GIsGuarded = 0;
GIsGuarded = 0;
GLog = &Log;
GLog = &Log;
ExitCode = EXIT_FAILURE;
Error.HandleError();
Error.HandleError();
}
}


appExit();
appExit();
return ExitCode;
}
}
</source>

Revision as of 23:31, 8 September 2020

Author: Leon

Used Tools: MS Visual Studio 2003

Description: A self written UCC for Republic Commando. Used for executing Unreal Commandlets.

Github: here

Latest Build: here


/*

* This is a custom UCC.exe for Star Wars Republic Commando since the game shipped without one.
* Everything compiles fine with Visual Studio .NET 2003 which is being used to achieve maximum compatibility
* since it was also used to compile RC
* The following settings are required in order to compile everything without errors:
* - Character Set = Not Set
* - Struct Member Alignment = 4 Bytes
* - Calling Convention = __fastcall
*/
  1. include "../../Core/Inc/Core.h"
  2. include "../../Core/Inc/FOutputDeviceFile.h"
  3. include "../../Core/Inc/FOutputDeviceWindowsError.h"
  4. include "../../Core/Inc/FFeedbackContextCmd.h"
  5. include "../../Core/Inc/FConfigCacheIni.h"

void UServerCommandletMain(); // Defined in ServerCommandlet.cpp

void ShowBanner(FOutputDevice& Out){ Out.Log("======================================="); Out.Log("ucc.exe for Star Wars Republic Commando"); Out.Log("made by Leon0628"); Out.Log("======================================="); Out.Log(""); }

int __cdecl main(int argc, char** argv){ int ExitCode = EXIT_SUCCESS; FOutputDeviceFile Log; FOutputDeviceWindowsError Error; FFeedbackContextCmd Warn;

GIsStarted = 1;

try{ GIsGuarded = 1;

FString CmdLine;

for(int i = 1; i < argc; ++i) CmdLine += FString(argv[i]) + " ";

appInit("SWRepublicCommando", *CmdLine, &Log, &Error, &Warn, FConfigCacheIni::Factory, 1); UObject::SetLanguage("int");

if(argc > 1){ // Initializing global state GIsUCC = GIsClient = GIsServer = GIsEditor = GIsScriptable = GLazyLoad = 1;

FString ClassName = argv[1]; TArray<FRegistryObjectInfo> List;

UObject::GetRegistryObjects(List, UClass::StaticClass(), UCommandlet::StaticClass(), 0); // Loading list of commandlets declared in .int files

for(int i = 0; i < List.Num(); ++i){ // Looking Token up in list and autocompleting class name if found FString FullName = List[i].Object; FString ShortName = FullName;

while(ShortName.InStr(".") >= 0) // Removing package name so that only class name remains ShortName = ShortName.Mid(ShortName.InStr(".") + 1);

if(ClassName == FullName || ClassName + "Commandlet" == FullName || // Checking against "PackageName.ClassName (+ Commandlet)" ClassName == ShortName || ClassName + "Commandlet" == ShortName){ // Checking against "ClassName (+ Commandlet)" ClassName = List[i].Object;

break; } }

DWORD LoadFlags = LOAD_NoWarn | LOAD_Quiet;

if(ClassName == "Editor.MakeCommandlet"){ // Loading default packages to avoid 'Superclass not found' errors UObject::LoadPackage(NULL, "Core", LOAD_NoFail); UObject::LoadPackage(NULL, "Engine", LOAD_NoFail); LoadFlags |= LOAD_DisallowFiles; }

UClass* Class = LoadClass<UCommandlet>(NULL, *ClassName, NULL, LoadFlags, NULL);

if(!Class) // If class failed to load appending "Commandlet" and trying again Class = LoadClass<UCommandlet>(NULL, *(ClassName + "Commandlet"), NULL, LoadFlags, NULL);

if(Class){ UCommandlet* Commandlet = ConstructObject<UCommandlet>(Class); UCommandlet* Default = Cast<UCommandlet>(Class->GetDefaultObject());

if(Default->ShowBanner) ShowBanner(Warn);

Warn.Logf("Executing %s", Class->GetFullName()); Warn.Log("");

GIsClient = Default->IsClient; GIsEditor = Default->IsEditor; GIsServer = Default->IsServer; GLazyLoad = Default->LazyLoad;

// Contains only the command-line options that are passed to the commandlet FString CommandletCmdLine;

for(int i = 2; i < argc; ++i) CommandletCmdLine += FString(argv[i]) + " ";

Commandlet->InitExecution(); Commandlet->ParseParms(*CommandletCmdLine);

if(Default->LogToStdout){ // Redirecting commandlet output to console Warn.AuxOut = GLog; GLog = &Warn; }

if(ClassName == "Engine.Server" || ClassName == "Engine.ServerCommandlet") UServerCommandletMain(); // The ServerCommandlet has a special Main function else ExitCode = CommandletMain(Commandlet, CommandletCmdLine);

if(Default->ShowErrorCount){ Warn.Log(""); Warn.Logf("%s - %i error(s), %i warning(s)", Warn.ErrorCount == 0 ? "Success" : "Failure", Warn.ErrorCount, Warn.WarningCount); }

if(Default->LogToStdout){ Warn.AuxOut = NULL; GLog = &Log; } }else{ ShowBanner(Warn); Warn.Logf("Commandlet %s not found", argv[1]); } }else{ ShowBanner(Warn); Warn.Log("Usage:"); Warn.Log(" ucc <command> <parameters>"); }

// This prevents an infinite loop during garbage collection when there are compile errors with ucc make if(Warn.ErrorCount == 0) appPreExit(); else ExitCode = EXIT_FAILURE;

GIsGuarded = 0; }catch(...){ GIsGuarded = 0; GLog = &Log; ExitCode = EXIT_FAILURE; Error.HandleError(); }

appExit();

return ExitCode; }