From 2b45b7ae56568ad63fc98cc48054bb765e718d40 Mon Sep 17 00:00:00 2001 From: GenZmeY Date: Sun, 8 Oct 2023 20:20:17 +0300 Subject: [PATCH] speed up item sync --- LTI/Classes/LTI.uc | 15 +- LTI/Classes/LTI_LocalMessage.uc | 10 +- LTI/Classes/LTI_RepInfo.uc | 274 ++++++++++++++++++-------------- LTI/Classes/Trader.uc | 24 ++- Localization/INT/LTI.int | Bin 426 -> 476 bytes Localization/RUS/LTI.rus | Bin 438 -> 484 bytes 6 files changed, 192 insertions(+), 131 deletions(-) diff --git a/LTI/Classes/LTI.uc b/LTI/Classes/LTI.uc index c707136..d356296 100644 --- a/LTI/Classes/LTI.uc +++ b/LTI/Classes/LTI.uc @@ -14,6 +14,7 @@ var private config bool bOfficialWeaponsList; var private KFGameInfo KFGI; var private KFGameReplicationInfo KFGRI; +var private Array > WeapDefs; var private Array > RemoveItems; var private Array RepInfos; var private bool ReadyToSync; @@ -149,13 +150,15 @@ private function PostInit() CfgRemoveItems.default.bDLC, LogLevel); + WeapDefs = Trader.static.GetTraderWeapDefs(KFGRI, LogLevel); + ReadyToSync = true; foreach RepInfos(RepInfo) { if (RepInfo.PendingSync) { - RepInfo.ServerSync(); + RepInfo.Replicate(WeapDefs); } } } @@ -189,19 +192,13 @@ public function bool CreateRepInfo(Controller C) if (RepInfo == None) return false; - RepInfo.PrepareSync( - Self, - LogLevel, - RemoveItems, - CfgRemoveItems.default.bAll, - CfgRemoveItems.default.bHRG, - CfgRemoveItems.default.bDLC); + RepInfo.PrepareSync(Self, LogLevel); RepInfos.AddItem(RepInfo); if (ReadyToSync) { - RepInfo.ServerSync(); + RepInfo.Replicate(WeapDefs); } else { diff --git a/LTI/Classes/LTI_LocalMessage.uc b/LTI/Classes/LTI_LocalMessage.uc index 9936065..f361b57 100644 --- a/LTI/Classes/LTI_LocalMessage.uc +++ b/LTI/Classes/LTI_LocalMessage.uc @@ -16,13 +16,17 @@ var private localized String IncompatibleGRIWarning; var const String SecondsShortDefault; var private localized String SecondsShort; +var const String PleaseWaitDefault; +var private localized String PleaseWait; + enum E_LTI_LocalMessageType { LTI_SyncItems, LTI_WaitingGRI, LTI_IncompatibleGRI, LTI_IncompatibleGRIWarning, - LTI_SecondsShort + LTI_SecondsShort, + LTI_PleaseWait }; public static function String GetLocalizedString( @@ -50,6 +54,9 @@ public static function String GetLocalizedString( case LTI_SecondsShort: return (default.SecondsShort != "" ? default.SecondsShort : default.SecondsShortDefault); + + case LTI_PleaseWait: + return (default.PleaseWait != "" ? default.PleaseWait : default.PleaseWaitDefault); } return ""; @@ -62,4 +69,5 @@ defaultproperties IncompatibleGRIDefault = "Incompatible GRI:" IncompatibleGRIWarningDefault = "You can enter the game, but the trader may not work correctly."; SecondsShortDefault = "s" + PleaseWaitDefault = "Please wait" } \ No newline at end of file diff --git a/LTI/Classes/LTI_RepInfo.uc b/LTI/Classes/LTI_RepInfo.uc index 60e356c..7e0d0c0 100644 --- a/LTI/Classes/LTI_RepInfo.uc +++ b/LTI/Classes/LTI_RepInfo.uc @@ -1,19 +1,23 @@ class LTI_RepInfo extends ReplicationInfo; +const CAPACITY = 64; // max: 128 + const Trader = class'Trader'; const LocalMessage = class'LTI_LocalMessage'; +struct ReplicationStruct +{ + var int Size; + var int Transfered; + + var class Items[CAPACITY]; + var int Length; +}; + var public bool PendingSync; var private LTI LTI; var private E_LogLevel LogLevel; -var private Array > RemoveItems; -var private bool ReplaceMode; -var private bool RemoveHRG; -var private bool RemoveDLC; - -var private int Recieved; -var private int SyncSize; var private KFPlayerController KFPC; var private KFGFxWidget_PartyInGame PartyInGameWidget; @@ -27,10 +31,13 @@ var private int NotificationPercent; var private int WaitingGRI; var private int WaitingGRILimit; +var private ReplicationStruct RepData; +var private Array > RepArray; + replication { if (bNetInitial && Role == ROLE_Authority) - LogLevel, ReplaceMode, RemoveHRG, RemoveDLC, SyncSize; + LogLevel; } public simulated function bool SafeDestroy() @@ -40,23 +47,113 @@ public simulated function bool SafeDestroy() return (bPendingDelete || bDeleteMe || Destroy()); } -public function PrepareSync( - LTI _LTI, - E_LogLevel _LogLevel, - Array > _RemoveItems, - bool _ReplaceMode, - bool _RemoveHRG, - bool _RemoveDLC) +public function PrepareSync(LTI _LTI, E_LogLevel _LogLevel) { `Log_Trace(); LTI = _LTI; LogLevel = _LogLevel; - RemoveItems = _RemoveItems; - ReplaceMode = _ReplaceMode; - RemoveHRG = _RemoveHRG; - RemoveDLC = _RemoveDLC; - SyncSize = RemoveItems.Length; +} + +public function Replicate(const out Array > WeapDefs) +{ + `Log_Trace(); + + RepArray = WeapDefs; + RepData.Size = RepArray.Length; + + if (WorldInfo.NetMode == NM_StandAlone) + { + Progress(RepArray.Length, RepArray.Length); + return; + } + + Sync(); +} + +private reliable server function Sync() +{ + local int LocalIndex; + local int GlobalIndex; + + `Log_Trace(); + + LocalIndex = 0; + GlobalIndex = RepData.Transfered; + + while (LocalIndex < CAPACITY && GlobalIndex < RepData.Size) + { + RepData.Items[LocalIndex++] = RepArray[GlobalIndex++]; + } + + if (RepData.Transfered == GlobalIndex) return; // Finished + + RepData.Transfered = GlobalIndex; + RepData.Length = LocalIndex; + + Send(RepData); + + Progress(RepData.Transfered, RepData.Size); +} + +private reliable client function Send(ReplicationStruct RD) +{ + local int LocalIndex; + + `Log_Trace(); + + for (LocalIndex = 0; LocalIndex < RD.Length; LocalIndex++) + { + RepArray.AddItem(RD.Items[LocalIndex]); + } + + Progress(RD.Transfered, RD.Size); + + Sync(); +} + +private simulated function Progress(int Value, int Size) +{ + `Log_Trace(); + + `Log_Debug("Replicated:" @ Value @ "/" @ Size); + + if (ROLE < ROLE_Authority) + { + NotifyProgress(Value, Size); + if (Value >= Size) Finished(); + } +} + +private simulated function Finished() +{ + local KFGameReplicationInfo KFGRI; + + `Log_Trace(); + + if (WorldInfo.GRI == None && WaitingGRI++ < WaitingGRILimit) + { + `Log_Debug("Finished: Waiting GRI" @ WaitingGRI); + NotifyWaitingGRI(); + SetTimer(1.0f, false, nameof(Finished)); + return; + } + + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + if (KFGRI != None) + { + `Log_Debug("Finished: Trader.static.OverwriteTraderItems"); + Trader.static.OverwriteTraderItems(KFGRI, RepArray, LogLevel); + `Log_Info("Trader items successfully synchronized!"); + } + else + { + `Log_Error("Incompatible Replication info:" @ String(WorldInfo.GRI)); + NotifyIncompatibleGRI(); + } + + ShowReadyButton(); + ClientCleanup(); } private simulated function KFPlayerController GetKFPC() @@ -147,6 +244,8 @@ private simulated function ShowReadyButton() { `Log_Trace(); + ClearTimer(nameof(KeepNotification)); + if (CheckPartyInGameWidget()) { Notification.SetVisible(false); @@ -172,41 +271,6 @@ private simulated function UpdateNotification(String Title, String Left, String } } -private reliable client function ClientSync(class WeapDef) -{ - `Log_Trace(); - - if (WeapDef == None) - { - `Log_Fatal("WeapDef is:" @ WeapDef); - Cleanup(); - ConsoleCommand("Disconnect"); - SafeDestroy(); - return; - } - - if (!IsTimerActive(nameof(KeepNotification))) - { - SetTimer(0.1f, true, nameof(KeepNotification)); - } - - RemoveItems.AddItem(WeapDef); - - Recieved = RemoveItems.Length; - - NotificationHeaderText = "-" @ WeapDef.static.GetItemName(); - NotificationLeftText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_SyncItems); - NotificationRightText = Recieved @ "/" @ SyncSize; - if (SyncSize != 0) - { - NotificationPercent = (float(Recieved) / float(SyncSize)) * 100; - } - - `Log_Debug("ClientSync: -" @ String(WeapDef) @ NotificationRightText); - - ServerSync(); -} - private simulated function KeepNotification() { HideReadyButton(); @@ -217,86 +281,61 @@ private simulated function KeepNotification() NotificationPercent); } -private simulated reliable client function ClientSyncFinished() +private simulated function ClientCleanup() { - local KFGameReplicationInfo KFGRI; - - `Log_Trace(); - - if (WorldInfo.GRI == None && WaitingGRI++ < WaitingGRILimit) - { - `Log_Debug("ClientSyncFinished: Waiting GRI" @ WaitingGRI); - NotificationHeaderText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_WaitingGRI); - NotificationLeftText = String(WaitingGRI) $ LocalMessage.static.GetLocalizedString(LogLevel, LTI_SecondsShort); - NotificationRightText = ""; - NotificationPercent = 0; - SetTimer(1.0f, false, nameof(ClientSyncFinished)); - return; - } - - NotificationHeaderText = ""; - NotificationLeftText = ""; - NotificationRightText = ""; - NotificationPercent = 0; - - KFGRI = KFGameReplicationInfo(WorldInfo.GRI); - if (KFGRI != None) - { - `Log_Debug("ClientSyncFinished: Trader.static.ModifyTrader"); - Trader.static.ModifyTrader(KFGRI, RemoveItems, ReplaceMode, RemoveHRG, RemoveDLC, LogLevel); - } - else - { - `Log_Error("Incompatible Replication info:" @ String(WorldInfo.GRI)); - WriteToChatLocalized( - LTI_IncompatibleGRI, - class'KFLocalMessage'.default.InteractionColor, - WorldInfo.GRI == None ? "None" : String(WorldInfo.GRI.class)); - WriteToChatLocalized( - LTI_IncompatibleGRIWarning, - class'KFLocalMessage'.default.InteractionColor); - } - - ClearTimer(nameof(KeepNotification)); - ShowReadyButton(); - - Cleanup(); + ServerCleanup(); SafeDestroy(); } -private reliable server function Cleanup() +private reliable server function ServerCleanup() { `Log_Trace(); `Log_Debug("Cleanup"); - if (!LTI.DestroyRepInfo(Controller(Owner))) + if (!LTI.DestroyRepInfo(GetKFPC())) { `Log_Debug("Cleanup (forced)"); SafeDestroy(); } } -public reliable server function ServerSync() +private simulated function NotifyWaitingGRI() { - `Log_Trace(); - - PendingSync = false; - - if (bPendingDelete || bDeleteMe) return; - - if (SyncSize <= Recieved || WorldInfo.NetMode == NM_StandAlone) + if (!IsTimerActive(nameof(KeepNotification))) { - `Log_Debug("ServerSync: Finished"); - ClientSyncFinished(); + SetTimer(0.1f, true, nameof(KeepNotification)); } - else + + NotificationHeaderText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_WaitingGRI); + NotificationLeftText = String(WaitingGRI) $ LocalMessage.static.GetLocalizedString(LogLevel, LTI_SecondsShort); + NotificationRightText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_PleaseWait); + NotificationPercent = 0; + KeepNotification(); +} + +private simulated function NotifyProgress(int Value, int Size) +{ + if (!IsTimerActive(nameof(KeepNotification))) { - if (Recieved < RemoveItems.Length) - { - `Log_Debug("ServerSync[-]:" @ (Recieved + 1) @ "/" @ SyncSize @ RemoveItems[Recieved]); - ClientSync(RemoveItems[Recieved++]); - } + SetTimer(0.1f, true, nameof(KeepNotification)); } + + NotificationHeaderText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_SyncItems); + NotificationLeftText = Value @ "/" @ Size; + NotificationRightText = LocalMessage.static.GetLocalizedString(LogLevel, LTI_PleaseWait); + NotificationPercent = (float(Value) / float(Size)) * 100; + KeepNotification(); +} + +private simulated function NotifyIncompatibleGRI() +{ + WriteToChatLocalized( + LTI_IncompatibleGRI, + class'KFLocalMessage'.default.InteractionColor, + String(WorldInfo.GRI.class)); + WriteToChatLocalized( + LTI_IncompatibleGRIWarning, + class'KFLocalMessage'.default.InteractionColor); } defaultproperties @@ -306,9 +345,8 @@ defaultproperties bSkipActorPropertyReplication = false PendingSync = false - Recieved = 0 NotificationPercent = 0 WaitingGRI = 0 - WaitingGRILimit = 15 + WaitingGRILimit = 30 } diff --git a/LTI/Classes/Trader.uc b/LTI/Classes/Trader.uc index 5f17e8a..09b9535 100644 --- a/LTI/Classes/Trader.uc +++ b/LTI/Classes/Trader.uc @@ -75,9 +75,7 @@ public static simulated function ModifyTrader( { local KFGFxObject_TraderItems TraderItems; local STraderItem Item; - local class WeapDef; local Array > WeapDefs; - local int MaxItemID; `Log_TraceStatic(); @@ -99,13 +97,33 @@ public static simulated function ModifyTrader( WeapDefs.Sort(ByPrice); + OverwriteTraderItems(KFGRI, WeapDefs, LogLevel); +} + +public static simulated function OverwriteTraderItems( + KFGameReplicationInfo KFGRI, + const out Array > WeapDefs, + E_LogLevel LogLevel) +{ + local KFGFxObject_TraderItems TraderItems; + local STraderItem Item; + local class WeapDef; + local int MaxItemID; + + `Log_TraceStatic(); + + TraderItems = GetTraderItems(KFGRI, LogLevel); + TraderItems.SaleItems.Length = 0; MaxItemID = 0; + + `Log_Debug("Trader Items:"); foreach WeapDefs(WeapDef) { Item.WeaponDef = WeapDef; - Item.ItemID = ++MaxItemID; + Item.ItemID = MaxItemID++; TraderItems.SaleItems.AddItem(Item); + `Log_Debug("[" $ MaxItemID $ "]" @ String(WeapDef)); } TraderItems.SetItemsInfo(TraderItems.SaleItems); diff --git a/Localization/INT/LTI.int b/Localization/INT/LTI.int index 4c2e36bb44b60928f0add1dfcc86ebec93f2ea40..9d7ea835162dc3176a944ad645e4d31f508f0233 100644 GIT binary patch delta 58 vcmZ3*e200%Dn_FKh8%`ehD3&9AQ=v%GZ{)4Y#Edoki``k%Aqn!3|tHVn2`&^ delta 7 Ocmcb^yo!0lDno;e E09s=SyZ`_I delta 7 OcmaFDyp4IoHbwvqYy$`Y