From 3fd6bcf7d8922b463002f4d49f4d71f0a399fecf Mon Sep 17 00:00:00 2001 From: GenZmeY Date: Thu, 5 Oct 2023 22:10:47 +0300 Subject: [PATCH] upload --- Classes/SkinReplicator.uc | 120 +++++++++++++++++++++++++++++++ Classes/SkinReplicator.upkg | 4 ++ Classes/SkinReplicatorMut.uc | 60 ++++++++++++++++ Classes/SkinReplicatorRepInfo.uc | 106 +++++++++++++++++++++++++++ Classes/WeaponReplacements.uc | 32 +++++++++ Classes/_Logger.uc | 20 ++++++ Constants.uci | 2 + Globals.uci | 3 + Logger.uci | 15 ++++ 9 files changed, 362 insertions(+) create mode 100644 Classes/SkinReplicator.uc create mode 100644 Classes/SkinReplicator.upkg create mode 100644 Classes/SkinReplicatorMut.uc create mode 100644 Classes/SkinReplicatorRepInfo.uc create mode 100644 Classes/WeaponReplacements.uc create mode 100644 Classes/_Logger.uc create mode 100644 Constants.uci create mode 100644 Globals.uci create mode 100644 Logger.uci diff --git a/Classes/SkinReplicator.uc b/Classes/SkinReplicator.uc new file mode 100644 index 0000000..94ba157 --- /dev/null +++ b/Classes/SkinReplicator.uc @@ -0,0 +1,120 @@ +class SkinReplicator extends Info; + +var private Array RepInfos; + +var private E_LogLevel LogLevel; + +public simulated function bool SafeDestroy() +{ + `Log_Trace(); + + return (bPendingDelete || bDeleteMe || Destroy()); +} + +public event PreBeginPlay() +{ + `Log_Trace(); + + if (WorldInfo.NetMode == NM_Client) + { + `Log_Fatal("NetMode == NM_Client, Destroy..."); + SafeDestroy(); + return; + } + + Super.PreBeginPlay(); + + PreInit(); +} + +public event PostBeginPlay() +{ + `Log_Trace(); + + if (bPendingDelete || bDeleteMe) return; + + Super.PostBeginPlay(); + + PostInit(); +} + +private function PreInit() +{ + `Log_Trace(); + + if (LogLevel == LL_WrongLevel) + { + LogLevel = LL_Info; + `Log_Warn("Wrong 'LogLevel', return to default value"); + SaveConfig(); + } + `Log_Base("LogLevel:" @ LogLevel); +} + +private function PostInit() +{ + `Log_Trace(); +} + +public function NotifyLogin(Controller C) +{ + `Log_Trace(); + + if (!CreateRepInfo(C)) + { + `Log_Error("Can't create RepInfo for:" @ C); + } +} + +public function NotifyLogout(Controller C) +{ + `Log_Trace(); + + DestroyRepInfo(C); +} + +public function bool CreateRepInfo(Controller C) +{ + local SkinReplicatorRepInfo RepInfo; + + `Log_Trace(); + + if (C == None || KFPlayerController(C) == None) return false; + + RepInfo = Spawn(class'SkinReplicatorRepInfo', C); + + if (RepInfo == None) return false; + + RepInfo.LogLevel = LogLevel; + RepInfo.SkinReplicator = Self; + + RepInfos.AddItem(RepInfo); + + return true; +} + +public function bool DestroyRepInfo(Controller C) +{ + local SkinReplicatorRepInfo RepInfo; + + `Log_Trace(); + + if (C == None) return false; + + foreach RepInfos(RepInfo) + { + if (RepInfo.Owner == C) + { + RepInfos.RemoveItem(RepInfo); + RepInfo.SafeDestroy(); + return true; + } + } + + return false; +} + +DefaultProperties +{ + LogLevel = LL_Info +} \ No newline at end of file diff --git a/Classes/SkinReplicator.upkg b/Classes/SkinReplicator.upkg new file mode 100644 index 0000000..09febdf --- /dev/null +++ b/Classes/SkinReplicator.upkg @@ -0,0 +1,4 @@ +[Flags] +AllowDownload=True +ClientOptional=False +ServerSideOnly=False diff --git a/Classes/SkinReplicatorMut.uc b/Classes/SkinReplicatorMut.uc new file mode 100644 index 0000000..7b3ff5c --- /dev/null +++ b/Classes/SkinReplicatorMut.uc @@ -0,0 +1,60 @@ +class SkinReplicatorMut extends KFMutator; + +var private SkinReplicator SkinReplicator; + +public simulated function bool SafeDestroy() +{ + return (bPendingDelete || bDeleteMe || Destroy()); +} + +public event PreBeginPlay() +{ + Super.PreBeginPlay(); + + if (WorldInfo.NetMode == NM_Client) return; + + foreach WorldInfo.DynamicActors(class'SkinReplicator', SkinReplicator) + { + break; + } + + if (SkinReplicator == None) + { + SkinReplicator = WorldInfo.Spawn(class'SkinReplicator'); + } + + if (SkinReplicator == None) + { + `Log_Base("FATAL: Can't Spawn 'SkinReplicator'"); + SafeDestroy(); + } +} + +public function AddMutator(Mutator Mut) +{ + if (Mut == Self) return; + + if (Mut.Class == Class) + SkinReplicatorMut(Mut).SafeDestroy(); + else + Super.AddMutator(Mut); +} + +public function NotifyLogin(Controller C) +{ + SkinReplicator.NotifyLogin(C); + + Super.NotifyLogin(C); +} + +public function NotifyLogout(Controller C) +{ + SkinReplicator.NotifyLogout(C); + + Super.NotifyLogout(C); +} + +DefaultProperties +{ + +} \ No newline at end of file diff --git a/Classes/SkinReplicatorRepInfo.uc b/Classes/SkinReplicatorRepInfo.uc new file mode 100644 index 0000000..5d37d92 --- /dev/null +++ b/Classes/SkinReplicatorRepInfo.uc @@ -0,0 +1,106 @@ +class SkinReplicatorRepInfo extends ReplicationInfo + dependson(WeaponReplacements); + +const Replacements = class'WeaponReplacements'; + +var public E_LogLevel LogLevel; +var public SkinReplicator SkinReplicator; + +var private KFPlayerController KFPC; +var private KFPlayerReplicationInfo KFPRI; + +replication +{ + if (bNetInitial && Role == ROLE_Authority) + LogLevel; +} + +public simulated function bool SafeDestroy() +{ + `Log_Trace(); + + return (bPendingDelete || bDeleteMe || Destroy()); +} + +public simulated event PostBeginPlay() +{ + if (WorldInfo.NetMode == NM_StandAlone || Role <= ROLE_Authority) + { + SetTimer(1.0f, true, nameof(UpdateSkinsDLC)); + } +} + +private simulated function UpdateSkinsDLC() +{ + local SWeapReplace WeapReplace; + + `Log_Debug("Wait for spawn"); + if (GetKFPRI() != None && KFPRI.bHasSpawnedIn) + { + foreach Replacements.default.List(WeapReplace) + { + if (WeapReplace.WeapParent.default.SkinItemId > 0 && WeapReplace.Weap.default.SkinItemId != WeapReplace.WeapParent.default.SkinItemId) + { + `Log_Debug("Update skin for:" @ String(WeapReplace.WeapDef) @ "SkinId:" @ WeapReplace.WeapParent.default.SkinItemId); + class'KFWeaponSkinList'.static.SaveWeaponSkin(WeapReplace.WeapDef, WeapReplace.WeapParent.default.SkinItemId); + } + } + + ClearTimer(nameof(UpdateSkinsDLC)); + ClientCleanup(); + } +} + +private simulated function KFPlayerController GetKFPC() +{ + `Log_Trace(); + + if (KFPC != None) return KFPC; + + KFPC = KFPlayerController(Owner); + + if (KFPC == None && ROLE < ROLE_Authority) + { + KFPC = KFPlayerController(GetALocalPlayerController()); + } + + return KFPC; +} + +private simulated function KFPlayerReplicationInfo GetKFPRI() +{ + `Log_Trace(); + + if (KFPRI != None) return KFPRI; + + if (GetKFPC() == None) return None; + + KFPRI = KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo); + + return KFPRI; +} + +private simulated function ClientCleanup() +{ + ServerCleanup(); + SafeDestroy(); +} + +private reliable server function ServerCleanup() +{ + `Log_Trace(); + + `Log_Debug("Cleanup"); + if (!SkinReplicator.DestroyRepInfo(GetKFPC())) + { + `Log_Debug("Cleanup (forced)"); + SafeDestroy(); + } +} + +defaultproperties +{ + bAlwaysRelevant = false + bOnlyRelevantToOwner = true + bSkipActorPropertyReplication = false +} diff --git a/Classes/WeaponReplacements.uc b/Classes/WeaponReplacements.uc new file mode 100644 index 0000000..926b23d --- /dev/null +++ b/Classes/WeaponReplacements.uc @@ -0,0 +1,32 @@ +class WeaponReplacements extends Object; + +struct SWeapReplace +{ + var const class WeapDef; + var const class WeapDefParent; + var const class Weap; + var const class WeapParent; +}; + +var public const Array List; + +// Example defaultproperties: +/* +List.Add({( + WeapDef=class'CTI_WeapDef_AutoTurret', + WeapDefParent=class'KFWeapDef_AutoTurret', + Weap=class'CTI_Weap_AutoTurret', + WeapParent=class'KFWeap_AutoTurret' +)}) +List.Add({( + WeapDef=class'CTI_WeapDef_BladedPistol', + WeapDefParent=class'KFWeapDef_BladedPistol', + Weap=class'CTI_Weap_Pistol_Bladed', + WeapParent=class'KFWeap_Pistol_Bladed' +)}) +*/ + +defaultproperties +{ + +} diff --git a/Classes/_Logger.uc b/Classes/_Logger.uc new file mode 100644 index 0000000..d9cfb52 --- /dev/null +++ b/Classes/_Logger.uc @@ -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 +{ + +} diff --git a/Constants.uci b/Constants.uci new file mode 100644 index 0000000..432fa68 --- /dev/null +++ b/Constants.uci @@ -0,0 +1,2 @@ +// Constants +`define NO_CONFIG 0 diff --git a/Globals.uci b/Globals.uci new file mode 100644 index 0000000..4dcd4fb --- /dev/null +++ b/Globals.uci @@ -0,0 +1,3 @@ +// Imports +`include(Logger.uci) +`include(Constants.uci) diff --git a/Logger.uci b/Logger.uci new file mode 100644 index 0000000..1009b5c --- /dev/null +++ b/Logger.uci @@ -0,0 +1,15 @@ +// Logger +`define Log_Tag 'SkinReplicator' + +`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)