diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs index 348e7832c..2d130d632 100644 --- a/Player/Player.Handlers.cs +++ b/Player/Player.Handlers.cs @@ -372,7 +372,7 @@ namespace MCGalaxy { group = foundGrp; Loading = true; if (disconnected) return; - id = FreeId(); + id = NextFreeId(); if (type != 0x42) CompleteLoginProcess(); @@ -483,7 +483,7 @@ namespace MCGalaxy { SendBlockchange(0, 0, 0, 0); timeLogged = DateTime.Now; lastLogin = DateTime.Now; - p.time = new TimeSpan(0, 0, 0, 1); + time = new TimeSpan(0, 0, 0, 1); DataTable playerDb = Database.Fill("SELECT * FROM Players WHERE Name=@0", name); if (playerDb.Rows.Count == 0) diff --git a/Player/Player.cs b/Player/Player.cs index a242e08dd..ffea9987f 100644 --- a/Player/Player.cs +++ b/Player/Player.cs @@ -380,24 +380,24 @@ catch { }*/ [Obsolete("Use PlayerInfo.FindNick(name)")] public static Player FindNick(string name) { return PlayerInfo.FindNick(null, name); } - static byte FreeId() { - /* -for (byte i = 0; i < 255; i++) -{ -foreach (Player p in players) -{ -if (p.id == i) { goto Next; } -} return i; -Next: continue; -} unchecked { return 0xFF; }*/ + unsafe static byte NextFreeId() { + byte* used = stackalloc byte[256]; + for (int i = 0; i < 256; i++) + used[i] = 0; - for ( byte i = 0; i < 255; i++ ) { - bool used = PlayerInfo.players.Any(p => p.id == i); - - if ( !used ) - return i; + // Lock to ensure that no two players can end up with the same playerid + lock (PlayerInfo.Online.locker) { + Player[] players = PlayerInfo.Online.Items; + for (int i = 0; i < players.Length; i++) { + byte id = players[i].id; + used[id] = 1; + } } - return (byte)1; + + for (byte i = 0; i < 255; i++ ) { + if (used[i] == 0) return i; + } + return 1; } public static bool ValidName(string name) { diff --git a/util/VolatileArray.cs b/util/VolatileArray.cs index 3fd993636..787917bc7 100644 --- a/util/VolatileArray.cs +++ b/util/VolatileArray.cs @@ -19,17 +19,21 @@ using System; using System.Collections.Generic; namespace MCGalaxy { - public sealed class VolatileArray { - - public List list; /// Note this field is highly volatile, you should cache references to it. public volatile T[] Items = new T[0]; + /// Returns the number of items in this array. public int Count { get { return Items.Length; } } - readonly object locker = new object(); + /// Object used to sychronise Add/Remove calls to this array. + /// When locking on this object from external code, you should try + /// to minimise the amount of time the object is locked for. + public readonly object locker = new object(); + + public List list; + readonly bool useList; public VolatileArray(bool useList) {