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