From 355223048f295946b9cc0bc9aa8f92961b9b9979 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 4 Jan 2017 17:40:02 +1100 Subject: [PATCH] Physics: fire now properly kills custom blocks which are killed by lava. (Thanks Odd0002) also minor perf optimisations --- MCGalaxy/Blocks/Block.Permissions.cs | 225 ++++++++++---------- MCGalaxy/Blocks/Physics/FirePhysics.cs | 41 ++-- MCGalaxy/Commands/Moderation/CmdBlockSet.cs | 3 +- MCGalaxy/Levels/Level.Blocks.cs | 8 +- MCGalaxy/Player/Group/Group.cs | 7 + MCGalaxy/Player/Group/GroupCommands.cs | 3 +- 6 files changed, 159 insertions(+), 128 deletions(-) diff --git a/MCGalaxy/Blocks/Block.Permissions.cs b/MCGalaxy/Blocks/Block.Permissions.cs index b394edcc1..4e656ea70 100644 --- a/MCGalaxy/Blocks/Block.Permissions.cs +++ b/MCGalaxy/Blocks/Block.Permissions.cs @@ -64,8 +64,125 @@ namespace MCGalaxy } } SaveBlocks(BlockList); + UpdateRankPerms(); } + internal static void UpdateRankPerms() { + foreach (Group grp in Group.GroupList) { + grp.FillBlocks(); + } + } + + + public static bool canPlace(Player p, byte block) { + Blocks b = BlockList[block]; + LevelPermission perm = p.Rank; + return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm))) + && (b.disallow == null || !b.disallow.Contains(perm)); + } + + public static bool canPlace(LevelPermission perm, byte block) { + Blocks b = BlockList[block]; + return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm))) + && (b.disallow == null || !b.disallow.Contains(perm)); + } + + public static void ResendBlockPermissions(byte block) { + Player[] players = PlayerInfo.Online.Items; + foreach (Player pl in players) { + if (!pl.HasCpeExt(CpeExt.BlockPermissions)) continue; + + int count = pl.hasCustomBlocks ? Block.CpeCount : Block.OriginalCount; + if (block < count) { + bool canAffect = Block.canPlace(pl, block); + pl.Send(Packet.BlockPermission(block, canAffect, canAffect)); + } + } + } + + + static void LoadVersion2(string[] lines) { + string[] colon = new string[] { " : " }; + foreach (string line in lines) { + if (line == "" || line[0] == '#') continue; + //Name : Lowest : Disallow : Allow + string[] block = line.Split(colon, StringSplitOptions.None); + Blocks newBlock = new Blocks(); + + if (Block.Byte(block[0]) == Block.Invalid) continue; + newBlock.type = Block.Byte(block[0]); + + string[] disallow = null; + if (block[2] != "") disallow = block[2].Split(','); + string[] allow = null; + if (block[3] != "") allow = block[3].Split(','); + + try { + newBlock.lowestRank = (LevelPermission)int.Parse(block[1]); + if (disallow != null) { + newBlock.disallow = new List(); + foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); } + } + if (allow != null) { + newBlock.allow = new List(); + foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); } + } + } catch { + Server.s.Log("Hit an error on the block " + line); + continue; + } + BlockList[newBlock.type] = newBlock; + } + } + + static void LoadVersion1(string[] lines) { + foreach (string line in lines) { + if (line == "" || line[0] == '#') continue; + + try { + byte block = Block.Byte(line.Split(' ')[0]); + LevelPermission lowestRank = Level.PermissionFromName(line.Split(' ')[2]); + if (lowestRank != LevelPermission.Null) + BlockList[block].lowestRank = lowestRank; + else + throw new InvalidDataException("Line " + line + " is invalid."); + } + catch { Server.s.Log("Could not find the rank given on " + line + ". Using default"); } + } + } + + static readonly object saveLock = new object(); + public static void SaveBlocks(IEnumerable givenList) { + try { + lock (saveLock) + SaveBlocksCore(givenList); + } catch (Exception e) { + Server.ErrorLog(e); + } + } + + static void SaveBlocksCore(IEnumerable givenList) { + using (StreamWriter w = new StreamWriter("properties/block.properties")) { + w.WriteLine("#Version 2"); + w.WriteLine("# This file dictates which ranks may use what blocks"); + w.WriteLine("# If someone has royally screwed up the ranks, just delete this file and let the server restart"); + w.WriteLine("# Allowed ranks: " + Group.concatList(false, false, true)); + w.WriteLine("# Disallow and allow can be left empty, just make sure there's 2 spaces between the colons"); + w.WriteLine("# This works entirely on permission values, not names. Do not enter a rank name. Use its permission value"); + w.WriteLine("# BlockName : LowestRank : Disallow : Allow"); + w.WriteLine("# lava : 60 : 80,67 : 40,41,55"); + w.WriteLine(""); + + foreach (Blocks bs in givenList) { + if (!bs.IncludeInBlockProperties()) continue; + string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : " + + GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow); + w.WriteLine(line); + } + } + } + + static void InitDefaults() { for (int i = 0; i < 256; i++) { Blocks b = new Blocks(); @@ -282,113 +399,5 @@ namespace MCGalaxy BlockList[i] = b; } } - - public static bool canPlace(Player p, byte block) { - Blocks b = BlockList[block]; - LevelPermission perm = p.Rank; - return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm))) - && (b.disallow == null || !b.disallow.Contains(perm)); - } - - public static bool canPlace(LevelPermission perm, byte block) { - Blocks b = BlockList[block]; - return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm))) - && (b.disallow == null || !b.disallow.Contains(perm)); - } - - public static void ResendBlockPermissions(byte block) { - Player[] players = PlayerInfo.Online.Items; - foreach (Player pl in players) { - if (!pl.HasCpeExt(CpeExt.BlockPermissions)) continue; - - int count = pl.hasCustomBlocks ? Block.CpeCount : Block.OriginalCount; - if (block < count) { - bool canAffect = Block.canPlace(pl, block); - pl.Send(Packet.BlockPermission(block, canAffect, canAffect)); - } - } - } - - - static void LoadVersion2(string[] lines) { - string[] colon = new string[] { " : " }; - foreach (string line in lines) { - if (line == "" || line[0] == '#') continue; - //Name : Lowest : Disallow : Allow - string[] block = line.Split(colon, StringSplitOptions.None); - Blocks newBlock = new Blocks(); - - if (Block.Byte(block[0]) == Block.Invalid) continue; - newBlock.type = Block.Byte(block[0]); - - string[] disallow = null; - if (block[2] != "") disallow = block[2].Split(','); - string[] allow = null; - if (block[3] != "") allow = block[3].Split(','); - - try { - newBlock.lowestRank = (LevelPermission)int.Parse(block[1]); - if (disallow != null) { - newBlock.disallow = new List(); - foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); } - } - if (allow != null) { - newBlock.allow = new List(); - foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); } - } - } catch { - Server.s.Log("Hit an error on the block " + line); - continue; - } - BlockList[newBlock.type] = newBlock; - } - } - - static void LoadVersion1(string[] lines) { - foreach (string line in lines) { - if (line == "" || line[0] == '#') continue; - - try { - byte block = Block.Byte(line.Split(' ')[0]); - LevelPermission lowestRank = Level.PermissionFromName(line.Split(' ')[2]); - if (lowestRank != LevelPermission.Null) - BlockList[block].lowestRank = lowestRank; - else - throw new InvalidDataException("Line " + line + " is invalid."); - } - catch { Server.s.Log("Could not find the rank given on " + line + ". Using default"); } - } - } - - static readonly object saveLock = new object(); - public static void SaveBlocks(IEnumerable givenList) { - try { - lock (saveLock) - SaveBlocksCore(givenList); - } catch (Exception e) { - Server.ErrorLog(e); - } - } - - static void SaveBlocksCore(IEnumerable givenList) { - using (StreamWriter w = new StreamWriter("properties/block.properties")) { - w.WriteLine("#Version 2"); - w.WriteLine("# This file dictates which ranks may use what blocks"); - w.WriteLine("# If someone has royally screwed up the ranks, just delete this file and let the server restart"); - w.WriteLine("# Allowed ranks: " + Group.concatList(false, false, true)); - w.WriteLine("# Disallow and allow can be left empty, just make sure there's 2 spaces between the colons"); - w.WriteLine("# This works entirely on permission values, not names. Do not enter a rank name. Use its permission value"); - w.WriteLine("# BlockName : LowestRank : Disallow : Allow"); - w.WriteLine("# lava : 60 : 80,67 : 40,41,55"); - w.WriteLine(""); - - foreach (Blocks bs in givenList) { - if (!bs.IncludeInBlockProperties()) continue; - string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : " - + GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow); - w.WriteLine(line); - } - } - } } } diff --git a/MCGalaxy/Blocks/Physics/FirePhysics.cs b/MCGalaxy/Blocks/Physics/FirePhysics.cs index 15bf43593..842f221c2 100644 --- a/MCGalaxy/Blocks/Physics/FirePhysics.cs +++ b/MCGalaxy/Blocks/Physics/FirePhysics.cs @@ -30,28 +30,41 @@ namespace MCGalaxy.Blocks.Physics { } static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z, - int xOffset, int yOffset, int zOffset) { - if (!Block.FireKill(lvl.GetTile((ushort)(x + xOffset), - (ushort)(y + yOffset), (ushort)(z + zOffset)))) - return; + int dx, int dy, int dz) { + byte block = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); + if (block == Block.air) return; - if (xOffset != 0) - lvl.AddUpdate(lvl.PosToInt((ushort)(x + xOffset), y, z), Block.fire); - if (yOffset != 0) - lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + yOffset), z), Block.fire); - if (zOffset != 0) - lvl.AddUpdate(lvl.PosToInt(x, y, (ushort)(z + zOffset)), Block.fire); + if (block == Block.custom_block) { + block = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); + if (!lvl.CustomBlockProps[block].LavaKills) return; + } else { + if (!Block.Props[block].LavaKills) return; + } + + if (dx != 0) + lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), y, z), Block.fire); + if (dy != 0) + lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + dy), z), Block.fire); + if (dz != 0) + lvl.AddUpdate(lvl.PosToInt(x, y, (ushort)(z + dz)), Block.fire); } static void ExpandAvanced(Level lvl, int x, int y, int z) { int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); if (index < 0) return; - byte block = lvl.blocks[index]; - if (Block.FireKill(block)) - lvl.AddUpdate(index, Block.fire); - else if (block == Block.tnt) + byte block = lvl.blocks[index]; + if (block == Block.air) return; + + if (block == Block.tnt) { lvl.MakeExplosion((ushort)x, (ushort)y, (ushort)z, -1); + } else if (block == Block.custom_block) { + block = lvl.GetExtTileNoCheck((ushort)x, (ushort)y, (ushort)z); + if (lvl.CustomBlockProps[block].LavaKills) + lvl.AddUpdate(index, Block.fire); + } else if (Block.Props[block].LavaKills) { + lvl.AddUpdate(index, Block.fire); + } } public static void Do(Level lvl, ref Check C) { diff --git a/MCGalaxy/Commands/Moderation/CmdBlockSet.cs b/MCGalaxy/Commands/Moderation/CmdBlockSet.cs index 51cf02966..dca15e54b 100644 --- a/MCGalaxy/Commands/Moderation/CmdBlockSet.cs +++ b/MCGalaxy/Commands/Moderation/CmdBlockSet.cs @@ -37,8 +37,9 @@ namespace MCGalaxy.Commands { if (p != null && !Block.canPlace(p, block)) { Formatter.MessageBlock(p, "change permissions of ", block); return; } Block.BlockList[block].lowestRank = grp.Permission; + Block.UpdateRankPerms(); Block.SaveBlocks(Block.BlockList); - Block.ResendBlockPermissions(block); + Block.ResendBlockPermissions(block); // TODO: custom blocks permissions Chat.MessageAll("&d{0}%S's permission was changed to {1}", Block.Name(block), grp.ColoredName); diff --git a/MCGalaxy/Levels/Level.Blocks.cs b/MCGalaxy/Levels/Level.Blocks.cs index 1b377140a..2affe8f03 100644 --- a/MCGalaxy/Levels/Level.Blocks.cs +++ b/MCGalaxy/Levels/Level.Blocks.cs @@ -52,8 +52,8 @@ namespace MCGalaxy { } public byte GetExtTile(ushort x, ushort y, ushort z) { - int index = PosToInt(x, y, z); - if (index < 0 || blocks == null) return Block.Invalid; + if (x >= Width || y >= Height || z >= Length || blocks == null) + return Block.Invalid; int cx = x >> 4, cy = y >> 4, cz = z >> 4; byte[] chunk = CustomBlocks[(cy * ChunksZ + cz) * ChunksX + cx]; @@ -241,8 +241,8 @@ namespace MCGalaxy { } public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z, - byte b, byte block, byte extBlock = 0) { - if (!Block.AllowBreak(b) && !Block.canPlace(p, b) && !Block.BuildIn(b)) return false; + byte old, byte block, byte extBlock = 0) { + if (!p.group.CanModify[old] && !Block.AllowBreak(old) && !Block.BuildIn(old)) return false; if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref block)) return false; bool inZone = false; diff --git a/MCGalaxy/Player/Group/Group.cs b/MCGalaxy/Player/Group/Group.cs index 643b83a45..f4e0ca828 100644 --- a/MCGalaxy/Player/Group/Group.cs +++ b/MCGalaxy/Player/Group/Group.cs @@ -51,6 +51,7 @@ namespace MCGalaxy { public string fileName; public PlayerList playerList; public string MOTD = ""; + public bool[] CanModify = new bool[256]; /// Create a new group object public Group() { @@ -90,6 +91,12 @@ namespace MCGalaxy { commands = _commands; } + /// Fill the blocks that this group can use + public void FillBlocks() { + for (int i = 0; i < CanModify.Length; i++) + CanModify[i] = Block.canPlace(Permission, (byte)i); + } + public bool CanExecute(string cmdName) { return commands.Contains(Command.all.Find(cmdName)); } diff --git a/MCGalaxy/Player/Group/GroupCommands.cs b/MCGalaxy/Player/Group/GroupCommands.cs index 551ce2307..240c060a9 100644 --- a/MCGalaxy/Player/Group/GroupCommands.cs +++ b/MCGalaxy/Player/Group/GroupCommands.cs @@ -69,8 +69,9 @@ namespace MCGalaxy { Save(allowedCommands); } - foreach (Group grp in Group.GroupList) + foreach (Group grp in Group.GroupList) { grp.fillCommands(); + } } static void ReadVersion2(string[] lines, List cmdNames) {