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"
Line 10: | Line 10: | ||
/* | /* | ||
* 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 | ||
* | * - Struct Member Alignment = 4 Bytes | ||
* | * - 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/ | #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 | ||
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; | |||
Warn | FFeedbackContextCmd Warn; | ||
GIsStarted = 1; | GIsStarted = 1; | ||
Line 52: | Line 49: | ||
FString CmdLine; | FString CmdLine; | ||
for(int i = 1; i < argc; | 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(); | for(int i = 0; i < List.Num(); ++i){ // Looking Token up in list and autocompleting class name if found | ||
FString | 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; | 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 = | UCommandlet* Default = Cast<UCommandlet>(Class->GetDefaultObject()); | ||
if(Default->ShowBanner) | if(Default->ShowBanner) | ||
ShowBanner(); | ShowBanner(Warn); | ||
Warn.Logf("Executing %s | 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; | 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 | ExitCode = CommandletMain(Commandlet, CommandletCmdLine); | ||
if(Default->ShowErrorCount) | if(Default->ShowErrorCount){ | ||
Warn.Logf(" | 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 | 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 | ||
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; | |||
} | } | ||
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 */
- include "../../Core/Inc/Core.h"
- include "../../Core/Inc/FOutputDeviceFile.h"
- include "../../Core/Inc/FOutputDeviceWindowsError.h"
- include "../../Core/Inc/FFeedbackContextCmd.h"
- 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; }