From fe0b16b33ff93aa9a816d605d90216d8ac72bc8d Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 12 Mar 2016 12:16:42 +1100 Subject: [PATCH] First pass of optimisations for /undo - use O(1) lookup instead of O(n) lookup for Block.canPlace. --- Commands/Information/CmdHelp.cs | 2 +- Commands/Moderation/CmdBlockSet.cs | 7 +- Commands/building/CmdUndo.cs | 2 + Levels/Block.Permissions.cs | 217 +++++++++++------------------ Levels/Level.Blocks.cs | 5 +- 5 files changed, 89 insertions(+), 144 deletions(-) diff --git a/Commands/Information/CmdHelp.cs b/Commands/Information/CmdHelp.cs index 482b51301..433a9567c 100644 --- a/Commands/Information/CmdHelp.cs +++ b/Commands/Information/CmdHelp.cs @@ -151,7 +151,7 @@ namespace MCGalaxy.Commands if (b != Block.Zero) { Player.SendMessage(p, "Block \"" + message + "\" appears as &b" + Block.Name(Block.Convert(b))); - Group foundRank = Group.findPerm(Block.BlockList.Find(bs => bs.type == b).lowestRank); + Group foundRank = Group.findPerm(Block.BlockList[b].lowestRank); Player.SendMessage(p, "Rank needed: " + foundRank.color + foundRank.name); return; } diff --git a/Commands/Moderation/CmdBlockSet.cs b/Commands/Moderation/CmdBlockSet.cs index 818891e61..c173a4613 100644 --- a/Commands/Moderation/CmdBlockSet.cs +++ b/Commands/Moderation/CmdBlockSet.cs @@ -38,11 +38,7 @@ namespace MCGalaxy.Commands if (p != null && !Block.canPlace(p, foundBlock)) { Player.SendMessage(p, "Cannot modify a block set for a higher rank"); return; } - Block.Blocks newBlock = Block.BlockList.Find(bs => bs.type == foundBlock); - newBlock.lowestRank = newPerm; - - Block.BlockList[Block.BlockList.FindIndex(bL => bL.type == foundBlock)] = newBlock; - + Block.BlockList[foundBlock].lowestRank = newPerm; Block.SaveBlocks(Block.BlockList); Player[] players = PlayerInfo.Online; foreach (Player pl in players) { @@ -59,6 +55,7 @@ namespace MCGalaxy.Commands if (p == null) Player.SendMessage(p, Block.Name(foundBlock) + "'s permission was changed to " + Level.PermissionToName(newPerm)); } + public override void Help(Player p) { Player.SendMessage(p, "/blockset [block] [rank] - Changes [block] rank to [rank]"); diff --git a/Commands/building/CmdUndo.cs b/Commands/building/CmdUndo.cs index 27d381a10..9f012e96b 100644 --- a/Commands/building/CmdUndo.cs +++ b/Commands/building/CmdUndo.cs @@ -93,7 +93,9 @@ namespace MCGalaxy.Commands } Level saveLevel = null; + DateTime start = DateTime.UtcNow; PerformUndo(p, seconds, who.UndoBuffer, ref saveLevel); + Server.s.Log( "undo time: " + (DateTime.UtcNow - start).TotalMilliseconds.ToString()); bool foundUser = false; UndoFile.UndoPlayer(p, whoName.ToLower(), seconds, ref foundUser); diff --git a/Levels/Block.Permissions.cs b/Levels/Block.Permissions.cs index bc1439f1a..82df05fca 100644 --- a/Levels/Block.Permissions.cs +++ b/Levels/Block.Permissions.cs @@ -14,7 +14,7 @@ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses. -*/ + */ using System; using System.Collections.Generic; using System.IO; @@ -23,53 +23,47 @@ namespace MCGalaxy { public sealed partial class Block { - public static List BlockList = new List(); + public static Blocks[] BlockList = new Blocks[256]; public class Blocks { - public byte type; public LevelPermission lowestRank; public List disallow = new List(); public List allow = new List(); + public byte type; public bool IncludeInBlockProperties() { if (Block.Name(type).ToLower() == "unknown") return false; - if(type == Block.flagbase) return false; - if (type >= Block.odoor1_air && type <= Block.odoor7_air) return false; - if (type >= Block.odoor8_air && type <= Block.odoor12_air) return false; - return true; } } - public static void SetBlocks() - { - BlockList = new List(); - Blocks b = new Blocks(); - b.lowestRank = LevelPermission.Guest; - - for (int i = 0; i < 256; i++) - { - b = new Blocks(); - b.type = (byte)i; - BlockList.Add(b); + public static void SetBlocks() { + InitDefaults(); + // Custom permissions set by the user. + if (File.Exists("properties/block.properties")) { + string[] lines = File.ReadAllLines("properties/block.properties"); + if (lines.Length > 0 && lines[0] == "#Version 2") { + LoadVersion2(lines); + } else { + LoadVersion1(lines); + } } - - List storedList = new List(); - - foreach (Blocks bs in BlockList) - { - b = new Blocks(); - b.type = bs.type; - - switch (bs.type) + SaveBlocks(BlockList); + } + + static void InitDefaults() { + for (int i = 0; i < 256; i++) { + Blocks b = new Blocks(); + b.type = (byte)i; + switch (i) { case Zero: b.lowestRank = LevelPermission.Admin; @@ -143,7 +137,7 @@ namespace MCGalaxy case door_dirt_air: case door_blue_air: case door_book_air: - case door_red_air: + case door_red_air: case door_darkpink_air: case door_darkgrey_air: case door_lightgrey_air: @@ -271,7 +265,6 @@ namespace MCGalaxy case odoor10: case odoor11: case odoor12: - b.lowestRank = LevelPermission.Builder; break; @@ -279,97 +272,57 @@ namespace MCGalaxy b.lowestRank = LevelPermission.Banned; break; } - - storedList.Add(b); + BlockList[i] = b; } - - //CHECK FOR SPECIAL RANK ALLOWANCES SET BY USER - if (File.Exists("properties/block.properties")) - { - string[] lines = File.ReadAllLines("properties/block.properties"); - - //if (lines.Length == 0) ; // this is useless? - /*else */if (lines[0] == "#Version 2") - { - string[] colon = new string[] { " : " }; - foreach (string line in lines) - { - if (line != "" && line[0] != '#') - { - //Name : Lowest : Disallow : Allow - string[] block = line.Split(colon, StringSplitOptions.None); - Blocks newBlock = new Blocks(); - - if (Block.Byte(block[0]) == Block.Zero) - { - continue; - } - newBlock.type = Block.Byte(block[0]); - - string[] disallow = new string[0]; - if (block[2] != "") - disallow = block[2].Split(','); - string[] allow = new string[0]; - if (block[3] != "") - allow = block[3].Split(','); - - try - { - newBlock.lowestRank = (LevelPermission)int.Parse(block[1]); - foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); } - foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); } - } - catch - { - Server.s.Log("Hit an error on the block " + line); - continue; - } - - int current = 0; - foreach (Blocks bS in storedList) - { - if (newBlock.type == bS.type) - { - storedList[current] = newBlock; - break; - } - current++; - } - } - } - } - else - { - foreach (string s in lines) - { - if (s[0] != '#') - { - try - { - Blocks newBlock = new Blocks(); - newBlock.type = Block.Byte(s.Split(' ')[0]); - newBlock.lowestRank = Level.PermissionFromName(s.Split(' ')[2]); - if (newBlock.lowestRank != LevelPermission.Null) - storedList[storedList.FindIndex(sL => sL.type == newBlock.type)] = newBlock; - else - throw new Exception(); - } - catch { Server.s.Log("Could not find the rank given on " + s + ". Using default"); } - } - } - } - } - - BlockList.Clear(); - BlockList.AddRange(storedList); - SaveBlocks(BlockList); } - public static void SaveBlocks(List givenList) - { - try - { - using (StreamWriter w = File.CreateText("properties/block.properties")) - { + + 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.Zero) continue; + newBlock.type = Block.Byte(block[0]); + + string[] disallow = new string[0]; + if (block[2] != "") disallow = block[2].Split(','); + string[] allow = new string[0]; + if (block[3] != "") allow = block[3].Split(','); + + try { + newBlock.lowestRank = (LevelPermission)int.Parse(block[1]); + foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); } + 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 s in lines) { + if (s[0] == '#') continue; + + try { + byte type = Block.Byte(s.Split(' ')[0]); + LevelPermission lowestRank = Level.PermissionFromName(s.Split(' ')[2]); + if (lowestRank != LevelPermission.Null) + BlockList[type].lowestRank = lowestRank; + else + throw new Exception(); + } + catch { Server.s.Log("Could not find the rank given on " + s + ". Using default"); } + } + } + + public static void SaveBlocks(IEnumerable givenList) { + try { + using (StreamWriter w = File.CreateText("properties/block.properties")) { w.WriteLine("#Version 2"); w.WriteLine("# This file dictates what levels may use what blocks"); w.WriteLine("# If someone has royally screwed up the ranks, just delete this file and let the server restart"); @@ -380,10 +333,8 @@ namespace MCGalaxy w.WriteLine("# lava : 60 : 80,67 : 40,41,55"); w.WriteLine(""); - foreach (Blocks bs in givenList) - { - if (bs.IncludeInBlockProperties()) - { + foreach (Blocks bs in givenList) { + if (bs.IncludeInBlockProperties()) { string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : " + GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow); w.WriteLine(line); } @@ -393,19 +344,15 @@ namespace MCGalaxy catch (Exception e) { Server.ErrorLog(e); } } - public static bool canPlace(Player p, byte b) { return canPlace(p.group.Permission, b); } - public static bool canPlace(LevelPermission givenPerm, byte givenBlock) - { - foreach (Blocks b in BlockList) - { - if (givenBlock == b.type) - { - if ((b.lowestRank <= givenPerm && !b.disallow.Contains(givenPerm)) || b.allow.Contains(givenPerm)) return true; - return false; - } - } - - return false; + public static bool canPlace(Player p, byte type) { + Blocks b = BlockList[type]; + LevelPermission perm = p.group.Permission; + return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm)); + } + + public static bool canPlace(LevelPermission perm, byte type) { + Blocks b = BlockList[type]; + return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm)); } } } diff --git a/Levels/Level.Blocks.cs b/Levels/Level.Blocks.cs index e536f8695..9635ddb7e 100644 --- a/Levels/Level.Blocks.cs +++ b/Levels/Level.Blocks.cs @@ -164,7 +164,6 @@ namespace MCGalaxy { } bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte type) { - if (!p.PlayingTntWars) return true; if (!(type == Block.tnt || type == Block.bigtnt || type == Block.nuketnt || type == Block.smalltnt)) return true; @@ -287,14 +286,14 @@ namespace MCGalaxy { if (!Block.AllowBreak(b) && !Block.canPlace(p, b) && !Block.BuildIn(b)) { return false; } - if (!CheckTNTWarsChange(p, x, y, z, ref type)) + if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref type)) return false; string Owners = ""; bool AllowBuild = true, inZone = false; if (!CheckZones(p, x, y, z, b, ref AllowBuild, ref inZone, ref Owners)) return false; - if (Owners == "" && !CheckRank(p, x, y, z, AllowBuild, inZone)) + if (Owners.Length == 0 && !CheckRank(p, x, y, z, AllowBuild, inZone)) return false; return true; }