diff --git a/Commands/building/CmdAbort.cs b/Commands/building/CmdAbort.cs index 34182684c..d891978ac 100644 --- a/Commands/building/CmdAbort.cs +++ b/Commands/building/CmdAbort.cs @@ -39,7 +39,7 @@ namespace MCGalaxy.Commands.Building { p.DefaultBrushArgs = ""; lock (p.level.queueLock) - p.level.blockqueue.RemoveAll(b => b.SessionID == p.SessionID); + p.level.blockqueue.RemoveAll(b => (int)((b >> 9) & Player.SessionIDMask) == p.SessionID); Player.Message(p, "Every toggle or action was aborted."); } diff --git a/Levels/BlockQueue.cs b/Levels/BlockQueue.cs index 6dc21fac7..e0aabe66f 100644 --- a/Levels/BlockQueue.cs +++ b/Levels/BlockQueue.cs @@ -52,11 +52,18 @@ namespace MCGalaxy { public static void Addblock(Player p, int index, byte type, byte extType = 0) { if (index == -1) return; - QueuedBlock item; - item.SessionID = p.SessionID; item.Index = index; - item.Type = type; item.ExtType = extType; + // Bit packing format + // 32-63: index + // 9-31: session ID + // 8: is ext block or not + // 0-7: raw type + ulong flags = (ulong)index << 32; + flags |= (ulong)p.SessionID << 9; + flags |= (type == Block.custom_block ? 0x100UL : 0x000UL); + flags |= (type == Block.custom_block ? extType : type); + lock (p.level.queueLock) - p.level.blockqueue.Add(item); + p.level.blockqueue.Add(flags); } static void ProcessLevelBlocks(Level lvl) { @@ -67,9 +74,13 @@ namespace MCGalaxy { if (lvl.blockqueue.Count < blockupdates || !lvl.HasPlayers()) count = lvl.blockqueue.Count; - for (int c = 0; c < count; c++) { - QueuedBlock item = lvl.blockqueue[c]; - bulkSender.Add(item.Index, item.Type, item.ExtType); + for (int i = 0; i < count; i++) { + ulong flags = lvl.blockqueue[i]; + int index = (int)(flags >> 32); + byte type = (flags & 0x100) != 0 ? Block.custom_block : (byte)flags; + byte extType = (flags & 0x100) != 0 ? (byte)flags : Block.air; + + bulkSender.Add(index, type, extType); bulkSender.CheckIfSend(false); } bulkSender.CheckIfSend(true); @@ -80,7 +91,5 @@ namespace MCGalaxy { lvl.blockqueue.Clear(); } } - - public struct QueuedBlock { public int SessionID, Index; public byte Type, ExtType; } } } diff --git a/Levels/Level.cs b/Levels/Level.cs index a049cc4dd..8da3a22d4 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -235,7 +235,7 @@ namespace MCGalaxy public bool bufferblocks = Server.bufferblocks; internal readonly object queueLock = new object(), saveLock = new object(), savePropsLock = new object(); - public List blockqueue = new List(); + public List blockqueue = new List(); readonly object physThreadLock = new object(); BufferedBlockSender bulkSender; diff --git a/Player/Player.Fields.cs b/Player/Player.Fields.cs index c02a1f2a9..004d28fc8 100644 --- a/Player/Player.Fields.cs +++ b/Player/Player.Fields.cs @@ -183,6 +183,7 @@ namespace MCGalaxy { public bool voted = false; public bool flipHead = false; public GameProps Game = new GameProps(); + public const int SessionIDMask = (1 << 23) - 1; public int SessionID; //Countdown diff --git a/Player/Player.cs b/Player/Player.cs index c36801e76..f07a6e123 100644 --- a/Player/Player.cs +++ b/Player/Player.cs @@ -65,14 +65,14 @@ namespace MCGalaxy { name = playername; truename = playername; DisplayName = playername; - SessionID = Interlocked.Increment(ref sessionCounter); + SessionID = Interlocked.Increment(ref sessionCounter) & SessionIDMask; } public Player(Socket s) { try { socket = s; ip = socket.RemoteEndPoint.ToString().Split(':')[0]; - SessionID = Interlocked.Increment(ref sessionCounter); + SessionID = Interlocked.Increment(ref sessionCounter) & SessionIDMask; Server.s.Log(ip + " connected to the server."); for (byte i = 0; i < 128; i++) bindings[i] = i;