prototype

This commit is contained in:
2022-09-02 15:54:10 +03:00
parent 5ba33cee19
commit a0fd4870fe
15 changed files with 379 additions and 0 deletions

110
SML/Classes/Mut.uc Normal file
View File

@ -0,0 +1,110 @@
class Mut extends KFMutator;
const SML = class'SafeMutLoader';
const OptAC = "AccessControl";
const OptMut = "Mutator";
var private E_LogLevel LogLevel;
public function PreBeginPlay()
{
Super.PreBeginPlay();
LogLevel = SML.default.LogLevel;
if (LogLevel == LL_WrongLevel)
{
LogLevel = LL_Info;
}
`Log_Trace();
if (CorrectLoadOrder())
{
ModifyLoad();
}
else
{
`Log_Fatal(SML.static.GetName(Self) @ "must be loaded first.");
}
}
public function AddMutator(Mutator Mut)
{
`Log_Trace();
if (CorrectLoadOrder() || Mut == Self) return;
if (Mut.Class == Class)
Mut.Destroy();
else
Super.AddMutator(Mut);
}
private function bool CorrectLoadOrder()
{
`Log_Trace();
return (
WorldInfo.Game.BaseMutator == None ||
WorldInfo.Game.BaseMutator == Self);
}
private function ModifyLoad()
{
local String LoadURL;
local String LoadParams;
local String MutatorsRaw;
local String AccessControlRaw;
local Array<String> Mutators;
local int Index;
`Log_Trace();
LoadURL = WorldInfo.GetLocalURL();
LoadParams = Mid(LoadURL, InStr(LoadURL, "?"));
MutatorsRaw = WorldInfo.Game.ParseOption(LoadParams, OptMut);
AccessControlRaw = WorldInfo.Game.ParseOption(LoadParams, OptAC);
LoadURL = Repl(LoadURL, Subst(OptMut) $ MutatorsRaw, "");
LoadURL = Repl(LoadURL, Subst(OptAC) $ AccessControlRaw, "");
SML.static.ClearMutators();
ParseStringIntoArray(MutatorsRaw, Mutators, ",", true);
Index = 0;
while (Index < Mutators.Length)
{
if (SML.static.AddMutator(Mutators[Index]) ||
Mutators[Index] ~= SML.static.GetName(Self))
{
Mutators.Remove(Index, 1);
}
else
{
++Index;
}
}
JoinArray(Mutators, MutatorsRaw);
LoadURL $= (Subst(OptMut) $ MutatorsRaw);
if (SML.static.WantsToSpawn())
{
SML.static.StaticSaveConfig();
LoadURL $= (Subst(OptAC) $ SML.static.GetName());
}
`Log_Info("Loader modified, do server travel...");
WorldInfo.ServerTravel(LoadURL, true);
}
private static function String Subst(String Option)
{
return ("?" $ Option $ "=");
}
defaultproperties
{
}

View File

@ -0,0 +1,148 @@
class SafeMutLoader extends KFAccessControl
config(SML);
var private Array<Actor> ServerActors;
var public config E_LogLevel LogLevel;
var private config Array<String> Mutators;
public function PreBeginPlay()
{
`Log_Trace();
if (LogLevel == LL_WrongLevel)
{
LogLevel = LL_Info;
StaticSaveConfig();
}
LoadActors();
Super.PreBeginPlay();
}
private function LoadActors()
{
local String MutString;
local class<Mutator> MutClass;
local class<Actor> ActClass;
local Actor ServerActor;
`Log_Trace();
foreach Mutators(MutString)
{
MutClass = class<Mutator>(DynamicLoadObject(MutString, class'Class'));
if (MutClass == None)
{
`Log_Error("Can't load mutator:" @ MutString);
continue;
}
ActClass = GetMutReplacement(MutClass);
if (ActClass == None)
{
`Log_Warn("Incompatible:" @ MutString @ "(skip)");
continue;
}
ServerActor = WorldInfo.Spawn(ActClass);
if (ServerActor == None)
{
`Log_Error("Can't spawn:" @ MutString);
continue;
}
ServerActors.AddItem(ServerActor);
`Log_Info("Loaded:" @ MutString);
}
}
public static function bool AddMutator(String MutString)
{
if (GetMutStringReplacement(MutString) != None)
{
if (default.Mutators.Find(MutString) == INDEX_NONE)
{
default.Mutators.AddItem(MutString);
}
return true;
}
return false;
}
public static function ClearMutators()
{
default.Mutators.Length = 0;
}
public static function bool WantsToSpawn()
{
return (default.Mutators.Length > 0);
}
public static function String GetName(optional Object O)
{
if (O == None)
{
return (default.class.GetPackageName() $ "." $ String(default.class));
}
else
{
return (O.class.GetPackageName() $ "." $ String(O.class));
}
}
public function PostLogin(PlayerController C)
{
local Actor A;
`Log_Trace();
if (C != None)
{
foreach ServerActors(A)
{
A.GetTargetLocation(C, false);
}
}
Super.PostLogin(C);
}
public function OnClientConnectionClose(Player ClientConnection)
{
local Controller C;
local Actor A;
`Log_Trace();
C = ClientConnection.Actor;
if (C != None)
{
foreach ServerActors(A)
{
A.GetTargetLocation(C, true);
}
}
Super.OnClientConnectionClose(ClientConnection);
}
private static function class<Actor> GetMutReplacement(class<Mutator> MutClass)
{
if (MutClass == None || MutClass.static.GetLocalString() == "") return None;
return class<Actor>(DynamicLoadObject(
MutClass.GetPackageName() $ "." $
MutClass.static.GetLocalString(), class'Class'));
}
private static function class<Actor> GetMutStringReplacement(String MutString)
{
return GetMutReplacement(class<Mutator>(DynamicLoadObject(MutString, class'Class')));
}
defaultproperties
{
}

View File

@ -0,0 +1,4 @@
[Flags]
AllowDownload=False
ClientOptional=False
ServerSideOnly=True

20
SML/Classes/_Logger.uc Normal file
View File

@ -0,0 +1,20 @@
class _Logger extends Object
abstract;
enum E_LogLevel
{
LL_WrongLevel,
LL_None,
LL_Fatal,
LL_Error,
LL_Warning,
LL_Info,
LL_Debug,
LL_Trace,
LL_All
};
defaultproperties
{
}

2
SML/Constants.uci Normal file
View File

@ -0,0 +1,2 @@
// Constants
`define NO_CONFIG 0

3
SML/Globals.uci Normal file
View File

@ -0,0 +1,3 @@
// Imports
`include(Logger.uci)
`include(Constants.uci)

15
SML/Logger.uci Normal file
View File

@ -0,0 +1,15 @@
// Logger
`define Log_Tag 'SML'
`define LocationStatic "`{ClassName}::" $ GetFuncName()
`define Log_Base(msg, cond) `log(`msg `if(`cond), `cond`{endif}, `Log_Tag)
`define Log_Fatal(msg) `log("FATAL:" @ `msg, (LogLevel >= LL_Fatal), `Log_Tag)
`define Log_Error(msg) `log("ERROR:" @ `msg, (LogLevel >= LL_Error), `Log_Tag)
`define Log_Warn(msg) `log("WARN:" @ `msg, (LogLevel >= LL_Warning), `Log_Tag)
`define Log_Info(msg) `log("INFO:" @ `msg, (LogLevel >= LL_Info), `Log_Tag)
`define Log_Debug(msg) `log("DEBUG:" @ `msg, (LogLevel >= LL_Debug), `Log_Tag)
`define Log_Trace(msg) `log("TRACE:" @ `Location `if(`msg) @ `msg`{endif}, (LogLevel >= LL_Trace), `Log_Tag)
`define Log_TraceStatic(msg) `log("TRACE:" @ `LocationStatic `if(`msg) @ `msg`{endif}, (LogLevel >= LL_Trace), `Log_Tag)