diff --git a/Commands/Information/CmdAbout.cs b/Commands/Information/CmdAbout.cs index 11d9db028..14e171f1f 100644 --- a/Commands/Information/CmdAbout.cs +++ b/Commands/Information/CmdAbout.cs @@ -84,11 +84,12 @@ namespace MCGalaxy.Commands for (int i = 0; i < inCache.Count; i++) { foundOne = true; - Deleted = inCache[i].deleted; + Deleted = (inCache[i].flags & 1) != 0; Username = inCache[i].name; - DateTime time = Server.StartTimeLocal.AddSeconds(inCache[i].timeDelta); + DateTime time = Server.StartTimeLocal.AddSeconds(inCache[i].flags >> 2); TimePerformed = time.ToString("yyyy-MM-dd HH:mm:ss"); - BlockUsed = Block.Name(inCache[i].type); + byte inBlock = (inCache[i].flags & 2) != 0 ? Block.custom_block : inCache[i].rawType; + BlockUsed = Block.Name(inBlock); if (!Deleted) Player.SendMessage(p, "&3Created by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed); diff --git a/Commands/Moderation/CmdFreeze.cs b/Commands/Moderation/CmdFreeze.cs index 86e2cb8e8..502245a6b 100644 --- a/Commands/Moderation/CmdFreeze.cs +++ b/Commands/Moderation/CmdFreeze.cs @@ -28,10 +28,10 @@ namespace MCGalaxy.Commands public override void Use(Player p, string message) { if (message == "") { Help(p); return; } - Player who = PlayerInfo.FindOrShowMatches(message); + Player who = PlayerInfo.FindOrShowMatches(p, message); if (who == null) return; if (p == who) { Player.SendMessage(p, "Cannot freeze yourself."); return; } - if (p != nul && who.group.Permission >= p.group.Permission) { + if (p != null && who.group.Permission >= p.group.Permission) { Player.SendMessage(p, "Cannot freeze someone of equal or greater rank."); return; } diff --git a/Commands/building/CmdUndo.cs b/Commands/building/CmdUndo.cs index 8950fd359..1ad78c6b1 100644 --- a/Commands/building/CmdUndo.cs +++ b/Commands/building/CmdUndo.cs @@ -206,17 +206,20 @@ namespace MCGalaxy.Commands } bool CheckBlockPhysics(Player p, long seconds, int i, Level.UndoPos undo) { - byte b = p.level.GetTile(undo.location); - DateTime time = Server.StartTime.AddTicks(undo.timeDelta * TimeSpan.TicksPerSecond); + byte b = p.level.GetTile(undo.index); + DateTime time = Server.StartTime.AddTicks((undo.flags >> 2) * TimeSpan.TicksPerSecond); if (time.AddTicks(seconds * TimeSpan.TicksPerSecond) < DateTime.UtcNow) return false; - if (b == undo.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) { + byte newType = (undo.flags & 2) != 0 ? Block.custom_block : undo.newRawType; + if (b == newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) { ushort x, y, z; - p.level.IntToPos(undo.location, out x, out y, out z); + p.level.IntToPos(undo.index, out x, out y, out z); int undoIndex = p.level.currentUndo; p.level.currentUndo = i; p.level.currentUndo = undoIndex; - p.level.Blockchange(x, y, z, undo.oldType, true, "", undo.oldExtType, false); + byte oldType = (undo.flags & 1) != 0 ? Block.custom_block : undo.oldRawType; + byte oldExtType = (undo.flags & 1) != 0 ? undo.oldRawType : (byte)0; + p.level.Blockchange(x, y, z, oldType, true, "", oldExtType, false); } return true; } diff --git a/Levels/BlockQueue.cs b/Levels/BlockQueue.cs index 59a9ccfb1..b978624de 100644 --- a/Levels/BlockQueue.cs +++ b/Levels/BlockQueue.cs @@ -62,20 +62,17 @@ namespace MCGalaxy { int count = blockupdates; if (l.blockqueue.Count < blockupdates || l.players.Count == 0) count = l.blockqueue.Count; - Level.BlockPos bP; + Level.BlockPos bP = default(Level.BlockPos); for (int c = 0; c < count; c++) { block item = l.blockqueue[c]; bP.name = item.p.name; - bP.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; ushort x, y, z; l.IntToPos(item.index, out x, out y, out z); bP.index = item.index; - bP.type = item.type; - bP.extType = item.extType; - bP.deleted = bP.type == 0; - l.Blockchange(item.p, x, y, z, bP.type, bP.extType); + bP.SetData(item.type, item.extType, item.type == 0); + l.Blockchange(item.p, x, y, z, item.type, item.extType); l.blockCache.Add(bP); } l.blockqueue.RemoveRange(0, count); diff --git a/Levels/Level.Blocks.cs b/Levels/Level.Blocks.cs index dbb5dff8e..98d5983e2 100644 --- a/Levels/Level.Blocks.cs +++ b/Levels/Level.Blocks.cs @@ -145,13 +145,10 @@ namespace MCGalaxy { if (p == null) return; - Level.BlockPos bP; + Level.BlockPos bP = default(Level.BlockPos); bP.name = p.name; - bP.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; bP.index = b; - bP.type = type; - bP.extType = extType; - bP.deleted = bP.type == 0; + bP.SetData(type, extType, type == 0); blockCache.Add(bP); Player.UndoPos Pos; @@ -395,11 +392,9 @@ namespace MCGalaxy { PhysSpongeRemoved(b, true); if (addUndo) { - UndoPos uP; - uP.location = b; - uP.newType = type; uP.newExtType = extType; - uP.oldType = oldBlock; uP.oldExtType = oldExtType; - uP.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; + UndoPos uP = default(UndoPos); + uP.index = b; + uP.SetData(oldBlock, oldExtType, type, extType); if (currentUndo > Server.physUndo) { currentUndo = 0; diff --git a/Levels/Level.cs b/Levels/Level.cs index 5811c900f..a8c1c02e9 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -23,6 +23,7 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using MCGalaxy.SQL; using Timer = System.Timers.Timer; @@ -390,14 +391,14 @@ namespace MCGalaxy BlockPos bP = tempCache[i]; IntToPos(bP.index, out x, out y, out z); nameP.Value = bP.name; - DateTime time = Server.StartTimeLocal.AddTicks(bP.timeDelta * TimeSpan.TicksPerSecond); + DateTime time = Server.StartTimeLocal.AddTicks((bP.flags >> 2) * TimeSpan.TicksPerSecond); MakeInt(time.Year, 4, 0, ptr); MakeInt(time.Month, 2, 5, ptr); MakeInt(time.Day, 2, 8, ptr); MakeInt(time.Hour, 2, 11, ptr); MakeInt(time.Minute, 2, 14, ptr); MakeInt(time.Second, 2, 17, ptr); timeP.Value = date; xP.Value = x; yP.Value = y; zP.Value = z; - tileP.Value = bP.type; - delP.Value = bP.deleted; + tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawType; + delP.Value = (bP.flags & 1) != 0; if (!DatabaseTransactionHelper.Execute(template, cmd)) { cmd.Dispose(); @@ -730,19 +731,45 @@ namespace MCGalaxy return players.Where(p => p.level == this).ToList(); } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct BlockPos { - public string name; - public int timeDelta; - public int index; - public byte type, extType; - public bool deleted; + public string name; + public int flags, index; // bit 0 = is old ext, bit 1 = is new ext, rest bits = time delta + public byte rawType; + + public void SetData(byte type, byte extType, bool delete) { + TimeSpan delta = DateTime.UtcNow.Subtract(Server.StartTime); + flags = (int)delta.TotalSeconds << 2; + flags |= (byte)(delete ? 1 : 0); + + if (type == Block.custom_block) { + rawType = extType; flags |= 2; + } else { + rawType = type; + } + } } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct UndoPos { - public int location; - public byte newType, newExtType; - public byte oldType, oldExtType; - public int timeDelta; + public int flags, index; // bit 0 = is old ext, bit 1 = is new ext, rest bits = time delta + public byte oldRawType, newRawType; + + public void SetData(byte oldType, byte oldExtType, byte newType, byte newExtType) { + TimeSpan delta = DateTime.UtcNow.Subtract(Server.StartTime); + flags = (int)delta.TotalSeconds << 2; + + if (oldType == Block.custom_block) { + oldRawType = oldExtType; flags |= 1; + } else { + oldRawType = oldType; + } + if (newType == Block.custom_block) { + newRawType = newExtType; flags |= 2; + } else { + newRawType = newType; + } + } } public struct Zone { diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs index 7a609052e..a36e24d59 100644 --- a/Player/Player.Handlers.cs +++ b/Player/Player.Handlers.cs @@ -64,17 +64,15 @@ namespace MCGalaxy { RevertBlock(x, y, z); return; } - Level.BlockPos bP; + Level.BlockPos bP = default(Level.BlockPos); bP.name = name; - bP.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; bP.index = level.PosToInt(x, y, z); - bP.type = type; - bP.extType = extType; + bP.SetData(type, extType, false); lastClick[0] = x; lastClick[1] = y; lastClick[2] = z; if ( Blockchange != null ) { if ( Blockchange.Method.ToString().IndexOf("AboutBlockchange") == -1 && !level.IsMuseum ) { - bP.deleted = true; + bP.flags |= 1; level.blockCache.Add(bP); } @@ -84,10 +82,7 @@ namespace MCGalaxy { if ( PlayerBlockChange != null ) PlayerBlockChange(this, x, y, z, type, extType); OnBlockChangeEvent.Call(this, x, y, z, type, extType); - if ( cancelBlock ) { - cancelBlock = false; - return; - } + if ( cancelBlock ) { cancelBlock = false; return; } if ( group.Permission == LevelPermission.Banned ) return; if ( group.Permission == LevelPermission.Guest ) { @@ -133,12 +128,10 @@ namespace MCGalaxy { if ( Block.portal(b) ) { HandlePortal(this, x, y, z, b); return; } if ( Block.mb(b) ) { HandleMsgBlock(this, x, y, z, b); return; } } - - bP.deleted = true; + bP.flags |= 1; level.blockCache.Add(bP); DeleteBlock(b, x, y, z, type, extType); } else { - bP.deleted = false; level.blockCache.Add(bP); PlaceBlock(b, x, y, z, type, extType); }