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

@ -14,7 +14,7 @@
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -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>(); }
foreach (Blocks bs in BlockList) static void InitDefaults() {
{ for (int i = 0; i < 256; i++) {
b = new Blocks(); Blocks b = new Blocks();
b.type = bs.type; b.type = (byte)i;
switch (i)
switch (bs.type)
{ {
case Zero: case Zero:
b.lowestRank = LevelPermission.Admin; b.lowestRank = LevelPermission.Admin;
@ -143,7 +137,7 @@ namespace MCGalaxy
case door_dirt_air: case door_dirt_air:
case door_blue_air: case door_blue_air:
case door_book_air: case door_book_air:
case door_red_air: case door_red_air:
case door_darkpink_air: case door_darkpink_air:
case door_darkgrey_air: case door_darkgrey_air:
case door_lightgrey_air: case door_lightgrey_air:
@ -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
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<Blocks> givenList)
{ static void LoadVersion2(string[] lines) {
try string[] colon = new string[] { " : " };
{ foreach (string line in lines) {
using (StreamWriter w = File.CreateText("properties/block.properties")) 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<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)
{ public static bool canPlace(LevelPermission perm, byte type) {
if ((b.lowestRank <= givenPerm && !b.disallow.Contains(givenPerm)) || b.allow.Contains(givenPerm)) return true; Blocks b = BlockList[type];
return false; return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm));
}
}
return false;
} }
} }
} }

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;
} }