From d65b21b80b34138f63d64378b44c3eadcce0ecf9 Mon Sep 17 00:00:00 2001 From: ripercheto Date: Mon, 23 Feb 2026 20:12:44 +0100 Subject: [PATCH 1/6] Added lobby code encoders --- Assets/PurrLobby/Editor/LobbyManagerEditor.cs | 30 +++++++++++- .../PurrLobby/LobbyScenes/LobbySample.unity | 1 + Assets/PurrLobby/Runtime/Lobby/Lobby.cs | 1 + Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs | 36 +++++++++++++++ .../PurrLobby/Runtime/Lobby/LobbyCode.cs.meta | 2 + .../PurrLobby/Runtime/Lobby/LobbyManager.cs | 13 ++++++ Assets/PurrLobby/Runtime/Misc/Encoders.meta | 8 ++++ .../Runtime/Misc/Encoders/Base36Encoder.cs | 46 +++++++++++++++++++ .../Misc/Encoders/Base36Encoder.cs.meta | 2 + .../Runtime/Misc/Encoders/Base62Encoder.cs | 45 ++++++++++++++++++ .../Misc/Encoders/Base62Encoder.cs.meta | 2 + .../Runtime/Misc/Encoders/IBaseEncoder.cs | 10 ++++ .../Misc/Encoders/IBaseEncoder.cs.meta | 2 + .../PurrLobby/Runtime/Misc/UI/JoinButton.cs | 2 +- .../PurrLobby/Runtime/Misc/UI/LobbyEntry.cs | 2 +- .../Runtime/Providers/SteamLobbyProvider.cs | 4 ++ .../Runtime/ViewManagement/Views/LobbyView.cs | 2 +- 17 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs create mode 100644 Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs.meta create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders.meta create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs.meta create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs.meta create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs create mode 100644 Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs.meta diff --git a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs index 8949778..e01ed9e 100644 --- a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs +++ b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs @@ -1,5 +1,7 @@ #if UNITY_EDITOR +using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; @@ -14,6 +16,14 @@ public class LobbyManagerEditor : UnityEditor.Editor private bool showEvents = false; private bool showRoomStatus = true; private Dictionary memberFoldouts = new Dictionary(); + private List encoderTypes; + private string[] encoderNames; + + private void OnEnable() + { + encoderTypes = LobbyCode.GetEncoderTypes(); + encoderNames = encoderTypes.Select(t => t.Name).ToArray(); + } public override void OnInspectorGUI() { @@ -22,7 +32,11 @@ public override void OnInspectorGUI() DrawProviderDropdown(lobbyManager); EditorGUILayout.Space(); - + + DrawEncoderDropdown(); + + EditorGUILayout.Space(); + DrawCreateRoomArgs(); EditorGUILayout.Space(); @@ -73,6 +87,20 @@ private void DrawProviderDropdown(LobbyManager lobbyManager) } } + private void DrawEncoderDropdown() + { + var property = serializedObject.FindProperty("lobbyCodeEncoderType"); + + EditorGUI.BeginChangeCheck(); + var encoderSelectedIndex = Array.IndexOf(encoderNames, property.stringValue); + encoderSelectedIndex = EditorGUILayout.Popup("Lobby Code Encoder", encoderSelectedIndex, encoderNames); + if (EditorGUI.EndChangeCheck()) + { + property.stringValue = encoderNames[encoderSelectedIndex]; + serializedObject.ApplyModifiedProperties(); + } + } + private void DrawCreateRoomArgs() { var serializedObject = new SerializedObject(target); diff --git a/Assets/PurrLobby/LobbyScenes/LobbySample.unity b/Assets/PurrLobby/LobbyScenes/LobbySample.unity index 107e76f..04b2c98 100644 --- a/Assets/PurrLobby/LobbyScenes/LobbySample.unity +++ b/Assets/PurrLobby/LobbyScenes/LobbySample.unity @@ -2401,6 +2401,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: currentProvider: {fileID: 1097043114} + lobbyCodeEncoderType: Base36Encoder createRoomArgs: maxPlayers: 5 roomProperties: diff --git a/Assets/PurrLobby/Runtime/Lobby/Lobby.cs b/Assets/PurrLobby/Runtime/Lobby/Lobby.cs index d2b4c4a..b862f1a 100644 --- a/Assets/PurrLobby/Runtime/Lobby/Lobby.cs +++ b/Assets/PurrLobby/Runtime/Lobby/Lobby.cs @@ -40,6 +40,7 @@ public static Lobby Create(string name, string lobbyId, int maxPlayers, bool isO Name = name, IsValid = true, LobbyId = lobbyId, + LobbyCode = LobbyCode.Encode(uint.Parse(lobbyId)), MaxPlayers = maxPlayers, Properties = properties ?? new Dictionary(), IsOwner = isOwner, diff --git a/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs new file mode 100644 index 0000000..5a6577a --- /dev/null +++ b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PurrLobby +{ + public static class LobbyCode + { + private static IBaseEncoder encoder; + public static string Encode(ulong value) + { + return encoder.Encode(value); + } + public static ulong Decode(string value) + { + return encoder.Decode(value); + } + + public static List GetEncoderTypes() => + AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(t => typeof(IBaseEncoder).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract) + .ToList(); + + public static void AssignEncoder(string name) + { + var types = GetEncoderTypes(); + var type = types.FirstOrDefault(t => t.Name == name); + if (type == null) + { + return; + } + encoder = (IBaseEncoder)Activator.CreateInstance(type); + } + } +} \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs.meta b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs.meta new file mode 100644 index 0000000..f336376 --- /dev/null +++ b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ea608e60a23615f47af8a5a0b5251053 \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Lobby/LobbyManager.cs b/Assets/PurrLobby/Runtime/Lobby/LobbyManager.cs index cfb297d..c99b086 100644 --- a/Assets/PurrLobby/Runtime/Lobby/LobbyManager.cs +++ b/Assets/PurrLobby/Runtime/Lobby/LobbyManager.cs @@ -11,6 +11,7 @@ namespace PurrLobby public class LobbyManager : MonoBehaviour { [SerializeField] private MonoBehaviour currentProvider; + [SerializeField] private string lobbyCodeEncoderType; private ILobbyProvider _currentProvider; private readonly Queue _delayedActions = new Queue(); @@ -64,6 +65,8 @@ private void Awake() else PurrLogger.LogWarning("No lobby provider assigned to LobbyManager."); + LobbyCode.AssignEncoder(lobbyCodeEncoderType); + SetupDataHolder(); } @@ -268,6 +271,16 @@ public void LeaveLobby(string lobbyId) OnRoomLeft?.Invoke(); }); } + + /// + /// Join the lobby with the given lobby code + /// + /// lobby code of the lobby to join + public void JoinLobbyByCode(string lobbyCode) + { + var roomId = LobbyCode.Decode(lobbyCode); + JoinLobby(roomId.ToString()); + } /// /// Join the lobby with the given ID diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders.meta b/Assets/PurrLobby/Runtime/Misc/Encoders.meta new file mode 100644 index 0000000..97b63e2 --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c0f9035c43177b4f992fe6b08bab529 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs new file mode 100644 index 0000000..51cec4f --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs @@ -0,0 +1,46 @@ +using System; + +namespace PurrLobby +{ + public class Base36Encoder : IBaseEncoder + { + private const string Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public string Encode(ulong value) + { + if (value == 0) + { + return "0"; + } + + var result = ""; + while (value > 0) + { + result = Chars[(int)(value % 36)] + result; + value /= 36; + } + return result; + } + + public ulong Decode(string value) + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentException("Value cannot be null or empty."); + } + + value = value.ToUpper().Trim(); + ulong result = 0; + foreach (var c in value) + { + var digit = Chars.IndexOf(c); + if (digit < 0) + { + throw new FormatException($"Invalid Base36 character: {c}"); + } + result = result * 36 + (ulong)digit; + } + return result; + } + } +} \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs.meta b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs.meta new file mode 100644 index 0000000..912762f --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2ccd612de43709a45b011ebcd9adb91d \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs new file mode 100644 index 0000000..a473810 --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs @@ -0,0 +1,45 @@ +using System; + +namespace PurrLobby +{ + public class Base62Encoder : IBaseEncoder + { + private const string Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public string Encode(ulong value) + { + if (value == 0) + { + return "0"; + } + + var result = ""; + while (value > 0) + { + result = Chars[(int)(value % 62)] + result; + value /= 62; + } + return result; + } + + public ulong Decode(string value) + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentException("Value cannot be null or empty."); + } + + ulong result = 0; + foreach (var c in value) + { + var digit = Chars.IndexOf(c); + if (digit < 0) + { + throw new FormatException($"Invalid Base62 character: {c}"); + } + result = result * 62 + (ulong)digit; + } + return result; + } + } +} \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs.meta b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs.meta new file mode 100644 index 0000000..e8fc536 --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3b6986bb8c055a2459b407a27decd1b1 \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs new file mode 100644 index 0000000..3c4bd58 --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +namespace PurrLobby +{ + public interface IBaseEncoder + { + public string Encode(ulong value); + public ulong Decode(string value); + } +} diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs.meta b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs.meta new file mode 100644 index 0000000..91bae2b --- /dev/null +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a01f3e2b3475440408fe722c2488a963 \ No newline at end of file diff --git a/Assets/PurrLobby/Runtime/Misc/UI/JoinButton.cs b/Assets/PurrLobby/Runtime/Misc/UI/JoinButton.cs index 2d72ea0..1a42f2f 100644 --- a/Assets/PurrLobby/Runtime/Misc/UI/JoinButton.cs +++ b/Assets/PurrLobby/Runtime/Misc/UI/JoinButton.cs @@ -19,7 +19,7 @@ public void JoinRoom() } onStartJoin?.Invoke(); - lobbyManager.JoinLobby(roomIdInput.text); + lobbyManager.JoinLobbyByCode(roomIdInput.text); } } } diff --git a/Assets/PurrLobby/Runtime/Misc/UI/LobbyEntry.cs b/Assets/PurrLobby/Runtime/Misc/UI/LobbyEntry.cs index 1c1d3ce..8f62ef1 100644 --- a/Assets/PurrLobby/Runtime/Misc/UI/LobbyEntry.cs +++ b/Assets/PurrLobby/Runtime/Misc/UI/LobbyEntry.cs @@ -21,7 +21,7 @@ public void Init(Lobby room, LobbyManager lobbyManager) public void OnClick() { - _lobbyManager.JoinLobby(_room.LobbyId); + _lobbyManager.JoinLobbyByCode(_room.LobbyCode); } } } diff --git a/Assets/PurrLobby/Runtime/Providers/SteamLobbyProvider.cs b/Assets/PurrLobby/Runtime/Providers/SteamLobbyProvider.cs index 7ab06f4..c8af870 100644 --- a/Assets/PurrLobby/Runtime/Providers/SteamLobbyProvider.cs +++ b/Assets/PurrLobby/Runtime/Providers/SteamLobbyProvider.cs @@ -113,6 +113,7 @@ public async Task CreateLobbyAsync(int maxPlayers, Dictionary JoinLobbyAsync(string lobbyId) var lobby = LobbyFactory.Create( Steamworks.SteamMatchmaking.GetLobbyData(_currentLobby, "Name"), lobbyId, + LobbyCode.Encode(cLobbyId.m_SteamID), Steamworks.SteamMatchmaking.GetLobbyMemberLimit(_currentLobby), false, GetLobbyUsers(cLobbyId), @@ -570,6 +572,7 @@ private void OnLobbyDataUpdate(Steamworks.LobbyDataUpdate_t callback) var updatedLobby = LobbyFactory.Create( Steamworks.SteamMatchmaking.GetLobbyData(_currentLobby, "Name"), _currentLobby.m_SteamID.ToString(), + LobbyCode.Encode(_currentLobby.m_SteamID), Steamworks.SteamMatchmaking.GetLobbyMemberLimit(_currentLobby), isOwner, updatedLobbyUsers, @@ -640,6 +643,7 @@ private void OnLobbyChatUpdate(Steamworks.LobbyChatUpdate_t callback) var updatedLobby = LobbyFactory.Create( data, _currentLobby.m_SteamID.ToString(), + LobbyCode.Encode(_currentLobby.m_SteamID), Steamworks.SteamMatchmaking.GetLobbyMemberLimit(_currentLobby), isOwner, updatedLobbyUsers, diff --git a/Assets/PurrLobby/Runtime/ViewManagement/Views/LobbyView.cs b/Assets/PurrLobby/Runtime/ViewManagement/Views/LobbyView.cs index ffc1002..dea88fb 100644 --- a/Assets/PurrLobby/Runtime/ViewManagement/Views/LobbyView.cs +++ b/Assets/PurrLobby/Runtime/ViewManagement/Views/LobbyView.cs @@ -9,7 +9,7 @@ public class LobbyView : View public override void OnShow() { - codeButton.Init(lobbyManager.CurrentLobby.LobbyId); + codeButton.Init(lobbyManager.CurrentLobby.LobbyCode); } } } From 6030797068d649c33512c75078a6f330a32a692d Mon Sep 17 00:00:00 2001 From: ripercheto Date: Mon, 23 Feb 2026 22:16:34 +0100 Subject: [PATCH 2/6] Added option to not give an encoder --- Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs index 5a6577a..810f43d 100644 --- a/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs +++ b/Assets/PurrLobby/Runtime/Lobby/LobbyCode.cs @@ -9,10 +9,18 @@ public static class LobbyCode private static IBaseEncoder encoder; public static string Encode(ulong value) { + if (encoder == null) + { + return value.ToString(); + } return encoder.Encode(value); } public static ulong Decode(string value) { + if (encoder == null) + { + return ulong.Parse(value); + } return encoder.Decode(value); } @@ -24,6 +32,10 @@ public static List GetEncoderTypes() => public static void AssignEncoder(string name) { + if (string.IsNullOrEmpty(name)) + { + return; + } var types = GetEncoderTypes(); var type = types.FirstOrDefault(t => t.Name == name); if (type == null) From 606ebfdbde2a91a30de60f29bc2e3c21d6d2bbdf Mon Sep 17 00:00:00 2001 From: ripercheto Date: Mon, 23 Feb 2026 22:17:42 +0100 Subject: [PATCH 3/6] Removed unused using --- Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs index 3c4bd58..8a10f0f 100644 --- a/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/IBaseEncoder.cs @@ -1,5 +1,3 @@ -using UnityEngine; - namespace PurrLobby { public interface IBaseEncoder @@ -7,4 +5,4 @@ public interface IBaseEncoder public string Encode(ulong value); public ulong Decode(string value); } -} +} \ No newline at end of file From 06ea594459a8046e00073d2cb8e772fcdd83ebfd Mon Sep 17 00:00:00 2001 From: ripercheto Date: Sat, 28 Feb 2026 11:44:45 +0100 Subject: [PATCH 4/6] Fixed inspector error if no implementations of IBaseEncoder are found --- Assets/PurrLobby/Editor/LobbyManagerEditor.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs index e01ed9e..8982352 100644 --- a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs +++ b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs @@ -90,6 +90,11 @@ private void DrawProviderDropdown(LobbyManager lobbyManager) private void DrawEncoderDropdown() { var property = serializedObject.FindProperty("lobbyCodeEncoderType"); + if (encoderTypes.Count == 0) + { + EditorGUILayout.HelpBox($"No implementation of {nameof(IBaseEncoder)} found.", MessageType.Warning); + return; + } EditorGUI.BeginChangeCheck(); var encoderSelectedIndex = Array.IndexOf(encoderNames, property.stringValue); From cbd548ef6668f47c227962a22ec96642cbef99bc Mon Sep 17 00:00:00 2001 From: ripercheto Date: Sat, 28 Feb 2026 11:56:42 +0100 Subject: [PATCH 5/6] Added foldout for the lobby code encoder type --- Assets/PurrLobby/Editor/LobbyManagerEditor.cs | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs index 8982352..54b6776 100644 --- a/Assets/PurrLobby/Editor/LobbyManagerEditor.cs +++ b/Assets/PurrLobby/Editor/LobbyManagerEditor.cs @@ -11,18 +11,21 @@ namespace PurrLobby.Editor [CustomEditor(typeof(LobbyManager))] public class LobbyManagerEditor : UnityEditor.Editor { + private bool showLobbyCodeEncoder = false; private bool showCreateRoomArgs = false; private bool showSearchRoomArgs = false; private bool showEvents = false; private bool showRoomStatus = true; private Dictionary memberFoldouts = new Dictionary(); - private List encoderTypes; private string[] encoderNames; private void OnEnable() { - encoderTypes = LobbyCode.GetEncoderTypes(); - encoderNames = encoderTypes.Select(t => t.Name).ToArray(); + var encoderTypes = LobbyCode.GetEncoderTypes(); + if (encoderTypes.Count > 0) + { + encoderNames = encoderTypes.Select(t => t.Name).ToArray(); + } } public override void OnInspectorGUI() @@ -32,13 +35,13 @@ public override void OnInspectorGUI() DrawProviderDropdown(lobbyManager); EditorGUILayout.Space(); - + DrawEncoderDropdown(); - + EditorGUILayout.Space(); - + DrawCreateRoomArgs(); - + EditorGUILayout.Space(); DrawSearchRoomArgs(); @@ -54,7 +57,7 @@ public override void OnInspectorGUI() private void DrawProviderDropdown(LobbyManager lobbyManager) { - var providers = FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); + var providers = FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); var providerOptions = new List(); foreach (var provider in providers) { @@ -89,23 +92,35 @@ private void DrawProviderDropdown(LobbyManager lobbyManager) private void DrawEncoderDropdown() { - var property = serializedObject.FindProperty("lobbyCodeEncoderType"); - if (encoderTypes.Count == 0) + var serializedObject = new SerializedObject(target); + var lobbyCodeProp = serializedObject.FindProperty("lobbyCodeEncoderType"); + if (lobbyCodeProp != null) { - EditorGUILayout.HelpBox($"No implementation of {nameof(IBaseEncoder)} found.", MessageType.Warning); - return; - } + showLobbyCodeEncoder = EditorGUILayout.Foldout(showLobbyCodeEncoder, "Lobby Code Encoder", true); + if (showLobbyCodeEncoder) + { + EditorGUI.indentLevel++; + if (encoderNames.Length == 0) + { + EditorGUILayout.HelpBox($"No implementation of {nameof(IBaseEncoder)} found.", MessageType.Warning); + return; + } - EditorGUI.BeginChangeCheck(); - var encoderSelectedIndex = Array.IndexOf(encoderNames, property.stringValue); - encoderSelectedIndex = EditorGUILayout.Popup("Lobby Code Encoder", encoderSelectedIndex, encoderNames); - if (EditorGUI.EndChangeCheck()) - { - property.stringValue = encoderNames[encoderSelectedIndex]; - serializedObject.ApplyModifiedProperties(); + EditorGUI.BeginChangeCheck(); + var encoderSelectedIndex = Array.IndexOf(encoderNames, lobbyCodeProp.stringValue); + encoderSelectedIndex = EditorGUILayout.Popup("Type", encoderSelectedIndex, encoderNames); + if (EditorGUI.EndChangeCheck()) + { + lobbyCodeProp.stringValue = encoderNames[encoderSelectedIndex]; + serializedObject.ApplyModifiedProperties(); + } + EditorGUI.indentLevel--; + } } + + serializedObject.ApplyModifiedProperties(); } - + private void DrawCreateRoomArgs() { var serializedObject = new SerializedObject(target); @@ -192,13 +207,13 @@ private void DrawRoomStatus(LobbyManager lobbyManager) if (!lobbyManager) return; - + var currentRoom = lobbyManager.CurrentLobby; if (currentRoom.IsValid) { EditorGUILayout.LabelField("Room ID:", currentRoom.LobbyId); - if(!string.IsNullOrWhiteSpace(currentRoom.LobbyCode)) + if (!string.IsNullOrWhiteSpace(currentRoom.LobbyCode)) { EditorGUILayout.LabelField("Lobby Code:", currentRoom.LobbyCode); } From 8297036a3b2364050ebc020189b6d70ade174736 Mon Sep 17 00:00:00 2001 From: ripercheto Date: Sat, 28 Feb 2026 11:57:07 +0100 Subject: [PATCH 6/6] Added format exceptions for the encoder implementations --- Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs | 6 ++++++ Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs index 51cec4f..3f62b96 100644 --- a/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base36Encoder.cs @@ -4,6 +4,7 @@ namespace PurrLobby { public class Base36Encoder : IBaseEncoder { + private const int MaxBase36Length = 13; // ceil(log36(ulong.MaxValue)) private const string Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public string Encode(ulong value) @@ -30,6 +31,11 @@ public ulong Decode(string value) } value = value.ToUpper().Trim(); + if (value.Length > MaxBase36Length) + { + throw new FormatException($"Input exceeds maximum Base36 length ({MaxBase36Length})."); + } + ulong result = 0; foreach (var c in value) { diff --git a/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs index a473810..60899de 100644 --- a/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs +++ b/Assets/PurrLobby/Runtime/Misc/Encoders/Base62Encoder.cs @@ -4,6 +4,7 @@ namespace PurrLobby { public class Base62Encoder : IBaseEncoder { + private const int MaxBase62Length = 11; // ceil(log62(ulong.MaxValue)) private const string Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; public string Encode(ulong value) @@ -29,6 +30,11 @@ public ulong Decode(string value) throw new ArgumentException("Value cannot be null or empty."); } + if (value.Length > MaxBase62Length) + { + throw new FormatException($"Input exceeds maximum Base62 length ({MaxBase62Length})."); + } + ulong result = 0; foreach (var c in value) {