First pass of optimisations for /undo - use O(1) lookup instead of O(n) lookup for Block.canPlace.

This commit is contained in:
UnknownShadow200 2016-03-12 12:16:42 +11:00
parent 5f0146da3e
commit fe0b16b33f
5 changed files with 89 additions and 144 deletions

View File

@ -151,7 +151,7 @@ namespace MCGalaxy.Commands
if (b != Block.Zero) if (b != Block.Zero)
{ {
Player.SendMessage(p, "Block \"" + message + "\" appears as &b" + Block.Name(Block.Convert(b))); 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); Player.SendMessage(p, "Rank needed: " + foundRank.color + foundRank.name);
return; return;
} }

View File

@ -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; } 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); Block.BlockList[foundBlock].lowestRank = newPerm;
newBlock.lowestRank = newPerm;
Block.BlockList[Block.BlockList.FindIndex(bL => bL.type == foundBlock)] = newBlock;
Block.SaveBlocks(Block.BlockList); Block.SaveBlocks(Block.BlockList);
Player[] players = PlayerInfo.Online; Player[] players = PlayerInfo.Online;
foreach (Player pl in players) { foreach (Player pl in players) {
@ -59,6 +55,7 @@ namespace MCGalaxy.Commands
if (p == null) if (p == null)
Player.SendMessage(p, Block.Name(foundBlock) + "'s permission was changed to " + Level.PermissionToName(newPerm)); Player.SendMessage(p, Block.Name(foundBlock) + "'s permission was changed to " + Level.PermissionToName(newPerm));
} }
public override void Help(Player p) public override void Help(Player p)
{ {
Player.SendMessage(p, "/blockset [block] [rank] - Changes [block] rank to [rank]"); Player.SendMessage(p, "/blockset [block] [rank] - Changes [block] rank to [rank]");

View File

@ -93,7 +93,9 @@ namespace MCGalaxy.Commands
} }
Level saveLevel = null; Level saveLevel = null;
DateTime start = DateTime.UtcNow;
PerformUndo(p, seconds, who.UndoBuffer, ref saveLevel); PerformUndo(p, seconds, who.UndoBuffer, ref saveLevel);
Server.s.Log( "undo time: " + (DateTime.UtcNow - start).TotalMilliseconds.ToString());
bool foundUser = false; bool foundUser = false;
UndoFile.UndoPlayer(p, whoName.ToLower(), seconds, ref foundUser); UndoFile.UndoPlayer(p, whoName.ToLower(), seconds, ref foundUser);

View File

@ -23,53 +23,47 @@ namespace MCGalaxy
{ {
public sealed partial class Block public sealed partial class Block
{ {
public static List<Blocks> BlockList = new List<Blocks>(); public static Blocks[] BlockList = new Blocks[256];
public class Blocks public class Blocks
{ {
public byte type;
public LevelPermission lowestRank; public LevelPermission lowestRank;
public List<LevelPermission> disallow = new List<LevelPermission>(); public List<LevelPermission> disallow = new List<LevelPermission>();
public List<LevelPermission> allow = new List<LevelPermission>(); public List<LevelPermission> allow = new List<LevelPermission>();
public byte type;
public bool IncludeInBlockProperties() public bool IncludeInBlockProperties()
{ {
if (Block.Name(type).ToLower() == "unknown") if (Block.Name(type).ToLower() == "unknown")
return false; return false;
if(type == Block.flagbase) if(type == Block.flagbase)
return false; return false;
if (type >= Block.odoor1_air && type <= Block.odoor7_air) if (type >= Block.odoor1_air && type <= Block.odoor7_air)
return false; return false;
if (type >= Block.odoor8_air && type <= Block.odoor12_air) if (type >= Block.odoor8_air && type <= Block.odoor12_air)
return false; return false;
return true; return true;
} }
} }
public static void SetBlocks() public static void SetBlocks() {
{ InitDefaults();
BlockList = new List<Blocks>(); // Custom permissions set by the user.
Blocks b = new Blocks(); if (File.Exists("properties/block.properties")) {
b.lowestRank = LevelPermission.Guest; string[] lines = File.ReadAllLines("properties/block.properties");
if (lines.Length > 0 && lines[0] == "#Version 2") {
for (int i = 0; i < 256; i++) LoadVersion2(lines);
{ } else {
b = new Blocks(); LoadVersion1(lines);
b.type = (byte)i; }
BlockList.Add(b); }
SaveBlocks(BlockList);
} }
List<Blocks> storedList = new List<Blocks>(); static void InitDefaults() {
for (int i = 0; i < 256; i++) {
foreach (Blocks bs in BlockList) Blocks b = new Blocks();
{ b.type = (byte)i;
b = new Blocks(); switch (i)
b.type = bs.type;
switch (bs.type)
{ {
case Zero: case Zero:
b.lowestRank = LevelPermission.Admin; b.lowestRank = LevelPermission.Admin;
@ -271,7 +265,6 @@ namespace MCGalaxy
case odoor10: case odoor10:
case odoor11: case odoor11:
case odoor12: case odoor12:
b.lowestRank = LevelPermission.Builder; b.lowestRank = LevelPermission.Builder;
break; break;
@ -279,97 +272,57 @@ namespace MCGalaxy
b.lowestRank = LevelPermission.Banned; b.lowestRank = LevelPermission.Banned;
break; break;
} }
BlockList[i] = b;
storedList.Add(b); }
} }
//CHECK FOR SPECIAL RANK ALLOWANCES SET BY USER static void LoadVersion2(string[] lines) {
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[] { " : " }; string[] colon = new string[] { " : " };
foreach (string line in lines) foreach (string line in lines) {
{ if (line == "" || line[0] == '#') continue;
if (line != "" && line[0] != '#')
{
//Name : Lowest : Disallow : Allow //Name : Lowest : Disallow : Allow
string[] block = line.Split(colon, StringSplitOptions.None); string[] block = line.Split(colon, StringSplitOptions.None);
Blocks newBlock = new Blocks(); Blocks newBlock = new Blocks();
if (Block.Byte(block[0]) == Block.Zero) if (Block.Byte(block[0]) == Block.Zero) continue;
{
continue;
}
newBlock.type = Block.Byte(block[0]); newBlock.type = Block.Byte(block[0]);
string[] disallow = new string[0]; string[] disallow = new string[0];
if (block[2] != "") if (block[2] != "") disallow = block[2].Split(',');
disallow = block[2].Split(',');
string[] allow = new string[0]; string[] allow = new string[0];
if (block[3] != "") if (block[3] != "") allow = block[3].Split(',');
allow = block[3].Split(',');
try try {
{
newBlock.lowestRank = (LevelPermission)int.Parse(block[1]); newBlock.lowestRank = (LevelPermission)int.Parse(block[1]);
foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); } foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); }
foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); } foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); }
} } catch {
catch
{
Server.s.Log("Hit an error on the block " + line); Server.s.Log("Hit an error on the block " + line);
continue; continue;
} }
BlockList[newBlock.type] = newBlock;
}
}
int current = 0; static void LoadVersion1(string[] lines) {
foreach (Blocks bS in storedList) foreach (string s in lines) {
{ if (s[0] == '#') continue;
if (newBlock.type == bS.type)
{ try {
storedList[current] = newBlock; byte type = Block.Byte(s.Split(' ')[0]);
break; LevelPermission lowestRank = Level.PermissionFromName(s.Split(' ')[2]);
} if (lowestRank != LevelPermission.Null)
current++; BlockList[type].lowestRank = lowestRank;
}
}
}
}
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 else
throw new Exception(); throw new Exception();
} }
catch { Server.s.Log("Could not find the rank given on " + s + ". Using default"); } catch { Server.s.Log("Could not find the rank given on " + s + ". Using default"); }
} }
} }
}
}
BlockList.Clear(); public static void SaveBlocks(IEnumerable<Blocks> givenList) {
BlockList.AddRange(storedList); try {
SaveBlocks(BlockList); using (StreamWriter w = File.CreateText("properties/block.properties")) {
}
public static void SaveBlocks(List<Blocks> givenList)
{
try
{
using (StreamWriter w = File.CreateText("properties/block.properties"))
{
w.WriteLine("#Version 2"); w.WriteLine("#Version 2");
w.WriteLine("# This file dictates what levels may use what blocks"); 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"); 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("# lava : 60 : 80,67 : 40,41,55");
w.WriteLine(""); w.WriteLine("");
foreach (Blocks bs in givenList) foreach (Blocks bs in givenList) {
{ if (bs.IncludeInBlockProperties()) {
if (bs.IncludeInBlockProperties())
{
string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : " + GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow); string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : " + GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow);
w.WriteLine(line); w.WriteLine(line);
} }
@ -393,19 +344,15 @@ namespace MCGalaxy
catch (Exception e) { Server.ErrorLog(e); } catch (Exception e) { Server.ErrorLog(e); }
} }
public static bool canPlace(Player p, byte b) { return canPlace(p.group.Permission, b); } public static bool canPlace(Player p, byte type) {
public static bool canPlace(LevelPermission givenPerm, byte givenBlock) Blocks b = BlockList[type];
{ LevelPermission perm = p.group.Permission;
foreach (Blocks b in BlockList) return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm));
{
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(LevelPermission perm, byte type) {
Blocks b = BlockList[type];
return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm));
} }
} }
} }

View File

@ -164,7 +164,6 @@ namespace MCGalaxy {
} }
bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte type) { 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)) if (!(type == Block.tnt || type == Block.bigtnt || type == Block.nuketnt || type == Block.smalltnt))
return true; return true;
@ -287,14 +286,14 @@ namespace MCGalaxy {
if (!Block.AllowBreak(b) && !Block.canPlace(p, b) && !Block.BuildIn(b)) { if (!Block.AllowBreak(b) && !Block.canPlace(p, b) && !Block.BuildIn(b)) {
return false; return false;
} }
if (!CheckTNTWarsChange(p, x, y, z, ref type)) if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref type))
return false; return false;
string Owners = ""; string Owners = "";
bool AllowBuild = true, inZone = false; bool AllowBuild = true, inZone = false;
if (!CheckZones(p, x, y, z, b, ref AllowBuild, ref inZone, ref Owners)) if (!CheckZones(p, x, y, z, b, ref AllowBuild, ref inZone, ref Owners))
return false; 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 false;
return true; return true;
} }