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)
This commit is contained in:
Robert Paciorek 2024-03-08 22:05:24 +00:00
parent 13248e70c3
commit 6a34677ab2
4 changed files with 111 additions and 93 deletions

View File

@ -16,7 +16,7 @@ class SetUserVariablesHandler : ICommandHandler {
uid = suvData.Get<string>("UID"); uid = suvData.Get<string>("UID");
// TODO // TODO
if (uid != null && client.PlayerData.Uid != uid) if (uid != null && (client.PlayerData.Uid != uid || !client.PlayerData.IsValid))
ProcessPlayerData(); ProcessPlayerData();
else else
UpdateVars(); UpdateVars();
@ -45,8 +45,9 @@ class SetUserVariablesHandler : ICommandHandler {
client.PlayerData.J = suvData.Get<string>("J"); client.PlayerData.J = suvData.Get<string>("J");
client.PlayerData.Bu = suvData.Get<string>("BU"); client.PlayerData.Bu = suvData.Get<string>("BU");
client.PlayerData.Fp = suvData.Get<string>("FP"); client.PlayerData.Fp = suvData.Get<string>("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(); UpdatePlayersInRoom();
SendSUVToPlayerInRoom(); SendSUVToPlayerInRoom();
@ -55,8 +56,9 @@ class SetUserVariablesHandler : ICommandHandler {
private void UpdateVars() { private void UpdateVars() {
string? FP = suvData.Get<string>("FP"); string? FP = suvData.Get<string>("FP");
string? PU = suvData.Get<string>("PU"); string? PU = suvData.Get<string>("PU");
string? A = suvData.Get<string>("A");
string? L = suvData.Get<string>("L"); string? L = suvData.Get<string>("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 return; // TODO
} }
NetworkObject data = new(); NetworkObject data = new();
@ -74,6 +76,11 @@ class SetUserVariablesHandler : ICommandHandler {
data2.Add("PU", client.PlayerData.Pu); data2.Add("PU", client.PlayerData.Pu);
vl.Add(NetworkArray.Param("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) { if (L != null) {
client.PlayerData.L = L; client.PlayerData.L = L;
data2.Add("L", client.PlayerData.L); data2.Add("L", client.PlayerData.L);

View File

@ -80,7 +80,7 @@ public class Client {
} }
public void InvalidatePlayerData() { public void InvalidatePlayerData() {
PlayerData = new(); PlayerData.IsValid = false;
} }
public void Disconnect() { public void Disconnect() {

View File

@ -100,7 +100,8 @@ public class Room {
NetworkArray userList = new(); NetworkArray userList = new();
foreach (Client player in Clients) { 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); obj.Add("r", roomInfo);

View File

@ -3,6 +3,27 @@ using sodoffmmo.Core;
namespace sodoffmmo.Data; namespace sodoffmmo.Data;
public class PlayerData { 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) // rotation (eulerAngles.y)
public double R { get; set; } public double R { get; set; }
// velocity x // velocity x
@ -11,90 +32,33 @@ public class PlayerData {
public double R2 { get; set; } public double R2 { get; set; }
// velocity z // velocity z
public double R3 { get; set; } public double R3 { get; set; }
// max speed
public double Mx { get; set; } = 6;
// UDT points
public string Udt { get; set; } = "";
// position x // position x
public double P1 { get; set; } public double P1 { get; set; }
// position y // position y
public double P2 { get; set; } public double P2 { get; set; }
// position z // position z
public double P3 { get; set; } 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, ...) // animation bitfield (animations used by avatar, e.g. mounted, swim, ...)
public int Mbf { get; set; } 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 (?) // busy (?)
public string Bu { get; set; } = "False"; public string Bu { get; set; } = "False";
// viking uid // UDT points
public string Uid { get; set; } = ""; public string Udt { get; set; } = "";
// (not raised) pet data
public string Pu { get; set; } = "";
// avatar data
public string A { get; set; } = "";
// XP rank (points and level) // XP rank (points and level)
public string Ra { get; set; } = ""; public string Ra { get; set; } = "";
// country info (for flag?) // country info (for flag?)
public string Cu { get; set; } = "-1"; public string Cu { get; set; } = "-1";
// membership status // membership status
public string M { get; set; } = "False"; public string M { get; set; } = "True";
// 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<string, string> 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 NetworkArray GetNetworkData(int clientID, out NetworkArray paramArr) { public NetworkArray GetNetworkData(int clientID, out NetworkArray paramArr) {
NetworkArray arr = new(); NetworkArray arr = new();
@ -104,33 +68,79 @@ public class PlayerData {
arr.Add((short)clientID); arr.Add((short)clientID);
paramArr = new(); 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("NT", (double)(Runtime.CurrentRuntime))); // network time
paramArr.Add(NetworkArray.Param("t", (int)(Runtime.CurrentRuntime / 1000))); // timestamp 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("UID", Uid));
paramArr.Add(NetworkArray.Param("R3", R3));
paramArr.Add(NetworkArray.Param("PU", Pu));
paramArr.Add(NetworkArray.Param("A", A)); paramArr.Add(NetworkArray.Param("A", A));
paramArr.Add(NetworkArray.Param("RA", Ra)); paramArr.Add(NetworkArray.Param("PU", Pu));
paramArr.Add(NetworkArray.Param("P3", P3)); paramArr.Add(NetworkArray.Param("FP", Fp));
paramArr.Add(NetworkArray.Param("CU", Cu));
paramArr.Add(NetworkArray.Param("M", M)); if (IsValid) {
paramArr.Add(NetworkArray.Param("L", L)); 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); arr.Add(paramArr);
return arr; 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<string, string> 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 { public enum PetGeometryType {