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

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; }
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]");

View File

@ -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);

View File

@ -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<Blocks> BlockList = new List<Blocks>();
public static Blocks[] BlockList = new Blocks[256];
public class Blocks
{
public byte type;
public LevelPermission lowestRank;
public List<LevelPermission> disallow = new List<LevelPermission>();
public List<LevelPermission> allow = new List<LevelPermission>();
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>();
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<Blocks> storedList = new List<Blocks>();
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<Blocks> 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<Blocks> 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));
}
}
}

View File

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