From 6a34677ab2595b25014e1689b0bf20e8353dc5e4 Mon Sep 17 00:00:00 2001 From: Robert Paciorek Date: Fri, 8 Mar 2024 22:05:24 +0000 Subject: [PATCH] keep some PlayerData while changing room this is needed when several players are joined in a short time to fix race condition (to fix missing players in race lobby room) --- .../SetUserVariablesHandler.cs | 13 +- src/Core/Client.cs | 2 +- src/Core/Room.cs | 3 +- src/Data/PlayerData.cs | 186 +++++++++--------- 4 files changed, 111 insertions(+), 93 deletions(-) diff --git a/src/CommandHandlers/SetUserVariablesHandler.cs b/src/CommandHandlers/SetUserVariablesHandler.cs index b21c15e..c745c99 100644 --- a/src/CommandHandlers/SetUserVariablesHandler.cs +++ b/src/CommandHandlers/SetUserVariablesHandler.cs @@ -16,7 +16,7 @@ class SetUserVariablesHandler : ICommandHandler { uid = suvData.Get("UID"); // TODO - if (uid != null && client.PlayerData.Uid != uid) + if (uid != null && (client.PlayerData.Uid != uid || !client.PlayerData.IsValid)) ProcessPlayerData(); else UpdateVars(); @@ -45,8 +45,9 @@ class SetUserVariablesHandler : ICommandHandler { client.PlayerData.J = suvData.Get("J"); client.PlayerData.Bu = suvData.Get("BU"); client.PlayerData.Fp = suvData.Get("FP"); + client.PlayerData.IsValid = true; - Console.WriteLine($"SUV {client.Room.Name} IID: {client.ClientID}"); + Console.WriteLine($"SUV {client.Room.Name} ({client.Room.ClientsCount}) IID: {client.ClientID} UID: {uid}"); UpdatePlayersInRoom(); SendSUVToPlayerInRoom(); @@ -55,8 +56,9 @@ class SetUserVariablesHandler : ICommandHandler { private void UpdateVars() { string? FP = suvData.Get("FP"); string? PU = suvData.Get("PU"); + string? A = suvData.Get("A"); string? L = suvData.Get("L"); - if (FP is null && PU is null && L is null) { + if (FP is null && PU is null && A is null && L is null) { return; // TODO } NetworkObject data = new(); @@ -74,6 +76,11 @@ class SetUserVariablesHandler : ICommandHandler { data2.Add("PU", client.PlayerData.Pu); vl.Add(NetworkArray.Param("PU", client.PlayerData.Pu)); } + if (A != null) { + client.PlayerData.A = A; + data2.Add("A", client.PlayerData.A); + vl.Add(NetworkArray.Param("A", client.PlayerData.A)); + } if (L != null) { client.PlayerData.L = L; data2.Add("L", client.PlayerData.L); diff --git a/src/Core/Client.cs b/src/Core/Client.cs index f4b36d7..087025d 100644 --- a/src/Core/Client.cs +++ b/src/Core/Client.cs @@ -80,7 +80,7 @@ public class Client { } public void InvalidatePlayerData() { - PlayerData = new(); + PlayerData.IsValid = false; } public void Disconnect() { diff --git a/src/Core/Room.cs b/src/Core/Room.cs index 6bc5956..39748eb 100644 --- a/src/Core/Room.cs +++ b/src/Core/Room.cs @@ -100,7 +100,8 @@ public class Room { NetworkArray userList = new(); foreach (Client player in Clients) { - userList.Add(player.PlayerData.GetNetworkData(player.ClientID, out _)); + if (player.PlayerData.Uid != "") + userList.Add(player.PlayerData.GetNetworkData(player.ClientID, out _)); } obj.Add("r", roomInfo); diff --git a/src/Data/PlayerData.cs b/src/Data/PlayerData.cs index 0e3f234..58e9aef 100644 --- a/src/Data/PlayerData.cs +++ b/src/Data/PlayerData.cs @@ -3,6 +3,27 @@ using sodoffmmo.Core; namespace sodoffmmo.Data; public class PlayerData { + public bool IsValid { get; set; } = false; + + // viking uid + public string Uid { get; set; } = ""; + // client token + public string UNToken { get; set; } = ""; + // avatar data + public string A { get; set; } = ""; + // (not raised) pet data + public string Pu { get; set; } = ""; + // raised pet data + public string Fp { + get { + return fp; + } + set { + fp = FixMountState(value); + } + } + private string fp = ""; + // rotation (eulerAngles.y) public double R { get; set; } // velocity x @@ -11,90 +32,33 @@ public class PlayerData { public double R2 { get; set; } // velocity z public double R3 { get; set; } - // max speed - public double Mx { get; set; } = 6; - // UDT points - public string Udt { get; set; } = ""; // position x public double P1 { get; set; } // position y public double P2 { get; set; } // position z public double P3 { get; set; } - - - // join (?) - public string J { get; set; } = "2"; - // flags (?) - public int F { get; set; } // animation bitfield (animations used by avatar, e.g. mounted, swim, ...) public int Mbf { get; set; } + // max speed + public double Mx { get; set; } = 6; + // flags (?) + public int F { get; set; } + // location (level) + public string L { get; set; } = ""; + + // join allowed + public string J { get; set; } = "2"; // busy (?) public string Bu { get; set; } = "False"; - // viking uid - public string Uid { get; set; } = ""; - // (not raised) pet data - public string Pu { get; set; } = ""; - // avatar data - public string A { get; set; } = ""; + // UDT points + public string Udt { get; set; } = ""; // XP rank (points and level) public string Ra { get; set; } = ""; // country info (for flag?) public string Cu { get; set; } = "-1"; // membership status - public string M { get; set; } = "False"; - // location (level) - public string L { get; set; } = ""; - // client token - public string UNToken { get; set; } = ""; - // raised pet geometry - set from Fp - public PetGeometryType GeometryType { get; set; } = PetGeometryType.Default; - // raised pet age - set from Fp - public PetAge PetAge { get; set; } = PetAge.Adult; - // raised pet mounted - set from Fp - public bool PetMounted { get; set; } = false; - // raised pet data - public string Fp { - get { - return fp; - } - set { - string[] array = value.Split('*'); - Dictionary keyValPairs = new(); - foreach (string str in array) { - string[] keyValPair = str.Split('$'); - if (keyValPair.Length == 2) - keyValPairs[keyValPair[0]] = keyValPair[1]; - } - GeometryType = PetGeometryType.Default; - PetAge = PetAge.Adult; - if (keyValPairs.TryGetValue("G", out string geometry)) - if (geometry.ToLower().Contains("terribleterror")) - GeometryType = PetGeometryType.Terror; - if (keyValPairs.TryGetValue("A", out string age)) { - switch (age) { - case "E": PetAge = PetAge.EggInHand; break; - case "B": PetAge = PetAge.Baby; break; - case "C": PetAge = PetAge.Child; break; - case "T": PetAge = PetAge.Teen; break; - case "A": PetAge = PetAge.Adult; break; - case "Ti": PetAge = PetAge.Titan; break; - } - } - if (keyValPairs.TryGetValue("U", out string userdata)) { - PetMounted = (userdata == "0" || userdata == "1"); - } - if (PetMounted && !Configuration.ServerConfiguration.AllowChaos && - (GeometryType == PetGeometryType.Default && PetAge < PetAge.Teen - || GeometryType == PetGeometryType.Terror && PetAge < PetAge.Titan) - ) { - fp = Regex.Replace(value, "^U\\$[01]\\*", "U$-1*"); - } else { - fp = value; - } - } - } - private string fp = ""; + public string M { get; set; } = "True"; public NetworkArray GetNetworkData(int clientID, out NetworkArray paramArr) { NetworkArray arr = new(); @@ -104,33 +68,79 @@ public class PlayerData { arr.Add((short)clientID); paramArr = new(); - paramArr.Add(NetworkArray.Param("R1", R1)); - paramArr.Add(NetworkArray.Param("FP", Fp)); - paramArr.Add(NetworkArray.Param("MX", Mx)); - paramArr.Add(NetworkArray.Param("UDT", Udt)); - paramArr.Add(NetworkArray.Param("P2", P2)); paramArr.Add(NetworkArray.Param("NT", (double)(Runtime.CurrentRuntime))); // network time paramArr.Add(NetworkArray.Param("t", (int)(Runtime.CurrentRuntime / 1000))); // timestamp - paramArr.Add(NetworkArray.Param("J", J)); - paramArr.Add(NetworkArray.Param("F", F)); - paramArr.Add(NetworkArray.Param("MBF", Mbf)); - paramArr.Add(NetworkArray.Param("R2", R2)); - paramArr.Add(NetworkArray.Param("R", R)); - paramArr.Add(NetworkArray.Param("BU", Bu)); - paramArr.Add(NetworkArray.Param("P1", P1)); + paramArr.Add(NetworkArray.Param("UID", Uid)); - paramArr.Add(NetworkArray.Param("R3", R3)); - paramArr.Add(NetworkArray.Param("PU", Pu)); paramArr.Add(NetworkArray.Param("A", A)); - paramArr.Add(NetworkArray.Param("RA", Ra)); - paramArr.Add(NetworkArray.Param("P3", P3)); - paramArr.Add(NetworkArray.Param("CU", Cu)); - paramArr.Add(NetworkArray.Param("M", M)); - paramArr.Add(NetworkArray.Param("L", L)); + paramArr.Add(NetworkArray.Param("PU", Pu)); + paramArr.Add(NetworkArray.Param("FP", Fp)); + + if (IsValid) { + paramArr.Add(NetworkArray.Param("R", R)); + paramArr.Add(NetworkArray.Param("R1", R1)); + paramArr.Add(NetworkArray.Param("R2", R2)); + paramArr.Add(NetworkArray.Param("R3", R3)); + paramArr.Add(NetworkArray.Param("P1", P1)); + paramArr.Add(NetworkArray.Param("P2", P2)); + paramArr.Add(NetworkArray.Param("P3", P3)); + paramArr.Add(NetworkArray.Param("MX", Mx)); + paramArr.Add(NetworkArray.Param("F", F)); + paramArr.Add(NetworkArray.Param("MBF", Mbf)); + paramArr.Add(NetworkArray.Param("L", L)); + + paramArr.Add(NetworkArray.Param("J", J)); + paramArr.Add(NetworkArray.Param("BU", Bu)); + paramArr.Add(NetworkArray.Param("UDT", Udt)); + paramArr.Add(NetworkArray.Param("RA", Ra)); + paramArr.Add(NetworkArray.Param("CU", Cu)); + paramArr.Add(NetworkArray.Param("M", M)); + } arr.Add(paramArr); return arr; } + + private string FixMountState(string value) { + // raised pet geometry - set from Fp + PetGeometryType GeometryType = PetGeometryType.Default; + // raised pet age - set from Fp + PetAge PetAge = PetAge.Adult; + // raised pet mounted - set from Fp + bool PetMounted = false; + + string[] array = value.Split('*'); + Dictionary keyValPairs = new(); + foreach (string str in array) { + string[] keyValPair = str.Split('$'); + if (keyValPair.Length == 2) + keyValPairs[keyValPair[0]] = keyValPair[1]; + } + if (keyValPairs.TryGetValue("G", out string geometry)) + if (geometry.ToLower().Contains("terribleterror")) + GeometryType = PetGeometryType.Terror; + if (keyValPairs.TryGetValue("A", out string age)) { + switch (age) { + case "E": PetAge = PetAge.EggInHand; break; + case "B": PetAge = PetAge.Baby; break; + case "C": PetAge = PetAge.Child; break; + case "T": PetAge = PetAge.Teen; break; + case "A": PetAge = PetAge.Adult; break; + case "Ti": PetAge = PetAge.Titan; break; + } + } + if (keyValPairs.TryGetValue("U", out string userdata)) { + PetMounted = (userdata == "0" || userdata == "1"); + } + if (PetMounted && !Configuration.ServerConfiguration.AllowChaos && + (GeometryType == PetGeometryType.Default && PetAge < PetAge.Teen + || GeometryType == PetGeometryType.Terror && PetAge < PetAge.Titan) + ) { + return Regex.Replace(value, "^U\\$[01]\\*", "U$-1*"); + } else { + return value; + } + } } public enum PetGeometryType {