diff --git a/MCGalaxy/Blocks/BlockPerms.cs b/MCGalaxy/Blocks/BlockPerms.cs index 1a9949e7d..488c8ba15 100644 --- a/MCGalaxy/Blocks/BlockPerms.cs +++ b/MCGalaxy/Blocks/BlockPerms.cs @@ -27,17 +27,9 @@ namespace MCGalaxy.Blocks { /// Represents which ranks are allowed (and which are disallowed) to use a block. public class BlockPerms { - - /// Extended block ID these permissions are for. public BlockID ID; - - /// Minimum rank normally able to use the block. public LevelPermission MinRank; - - /// Ranks specifically allowed to use the block public List Allowed; - - /// Ranks specifically prevented from using the block. public List Disallowed; public BlockPerms(BlockID id, LevelPermission minRank, List allowed, @@ -54,28 +46,18 @@ namespace MCGalaxy.Blocks { Disallowed = disallowed; } - /// Creates a copy of this instance. public BlockPerms Copy() { List allowed = new List(Allowed); List disallowed = new List(Disallowed); return new BlockPerms(ID, MinRank, allowed, disallowed); } - public static BlockPerms[] List = new BlockPerms[Block.ExtendedCount]; - - - /// Returns whether the given rank can modify the given block. - public static bool UsableBy(Player p, BlockID block) { - BlockPerms b = List[block]; - LevelPermission perm = p.Rank; - return (perm >= b.MinRank || b.Allowed.Contains(perm)) && !b.Disallowed.Contains(perm); + public bool UsableBy(LevelPermission perm) { + return (perm >= MinRank || Allowed.Contains(perm)) && !Disallowed.Contains(perm); } - /// Returns whether the given rank can modify the given block. - public static bool UsableBy(LevelPermission perm, BlockID block) { - BlockPerms b = List[block]; - return (perm >= b.MinRank || b.Allowed.Contains(perm)) && !b.Disallowed.Contains(perm); - } + public static BlockPerms[] List = new BlockPerms[Block.ExtendedCount]; + public static void ResendAllBlockPermissions() { Player[] players = PlayerInfo.Online.Items; @@ -94,18 +76,15 @@ namespace MCGalaxy.Blocks { static readonly object saveLock = new object(); - - /// Saves the list of all block permissions. public static void Save() { try { - lock (saveLock) - SaveCore(List); + lock (saveLock) SaveCore(); } catch (Exception e) { Logger.LogError(e); } } - static void SaveCore(IEnumerable list) { + static void SaveCore() { using (StreamWriter w = new StreamWriter(Paths.BlockPermsFile)) { w.WriteLine("#Version 2"); w.WriteLine("# This file list the ranks that can use each block"); @@ -116,7 +95,7 @@ namespace MCGalaxy.Blocks { w.WriteLine("# lava : 60 : 80,67 : 40,41,55"); w.WriteLine(""); - foreach (BlockPerms perms in list) { + foreach (BlockPerms perms in List) { if (Block.Undefined(perms.ID)) continue; string line = perms.ID + " : " + (int)perms.MinRank + " : " @@ -127,7 +106,6 @@ namespace MCGalaxy.Blocks { } - /// Loads the list of all block permissions. public static void Load() { SetDefaultPerms(); diff --git a/MCGalaxy/Commands/Command.cs b/MCGalaxy/Commands/Command.cs index 917cd8d78..8d99b5a7e 100644 --- a/MCGalaxy/Commands/Command.cs +++ b/MCGalaxy/Commands/Command.cs @@ -22,7 +22,7 @@ using MCGalaxy.Commands; using MCGalaxy.Scripting; namespace MCGalaxy { - + public abstract partial class Command { public abstract string name { get; } @@ -61,9 +61,10 @@ namespace MCGalaxy { public static List CopyAll() { return new List(allCmds); } public static void InitAll() { - allCmds.Clear(); - coreCmds.Clear(); Type[] types = Assembly.GetExecutingAssembly().GetTypes(); + allCmds.Clear(); + coreCmds.Clear(); + foreach (Group grp in Group.GroupList) { grp.Commands.Clear(); } for (int i = 0; i < types.Length; i++) { Type type = types[i]; @@ -80,10 +81,19 @@ namespace MCGalaxy { public static void Register(Command cmd) { allCmds.Add(cmd); - CommandPerm[] perms = cmd.ExtraPerms; - if (perms != null) { - for (int i = 0; i < perms.Length; i++) { - CommandExtraPerms.Set(cmd.name, perms[i].Perm, perms[i].Description, i + 1); + CommandPerms perms = CommandPerms.Find(cmd.name); + if (perms == null) { + perms = new CommandPerms(cmd.name, cmd.defaultRank, null, null); + CommandPerms.List.Add(perms); + } + foreach (Group grp in Group.GroupList) { + if (perms.UsableBy(grp.Permission)) grp.Commands.Add(cmd); + } + + CommandPerm[] extra = cmd.ExtraPerms; + if (extra != null) { + for (int i = 0; i < extra.Length; i++) { + CommandExtraPerms.Set(cmd.name, extra[i].Perm, extra[i].Description, i + 1); } } @@ -102,11 +112,12 @@ namespace MCGalaxy { return null; } - public static void Unregister(Command cmd) { - allCmds.Remove(cmd); + public static bool Unregister(Command cmd) { + bool removed = allCmds.Remove(cmd); foreach (Group grp in Group.GroupList) { grp.Commands.Remove(cmd); } + return removed; } public static void Search(ref string cmdName, ref string cmdArgs) { @@ -118,6 +129,7 @@ namespace MCGalaxy { if (!cmd.shortcut.CaselessEq(cmdName)) continue; cmdName = cmd.name; return; } + return; } cmdName = alias.Target; @@ -130,12 +142,12 @@ namespace MCGalaxy { } } - // Kept around for backwards compatibility - public sealed class CommandList { + // Kept around for backwards compatibility + public sealed class CommandList { [Obsolete("Use Command.Register() instead")] - public void Add(Command cmd) { Command.allCmds.Add(cmd); } + public void Add(Command cmd) { Command.Register(cmd); } [Obsolete("Use CommandUnregister() instead")] - public bool Remove(Command cmd) { return Command.allCmds.Remove(cmd); } + public bool Remove(Command cmd) { return Command.Unregister(cmd); } [Obsolete("Use Command.Find() instead")] public Command FindByName(string name) { return Command.Find(name); } @@ -147,7 +159,7 @@ namespace MCGalaxy { return null; } } - + [Flags] public enum CommandEnable { Always = 0, Economy = 1, Zombie = 2, Lava = 4, diff --git a/MCGalaxy/Commands/CommandParser.cs b/MCGalaxy/Commands/CommandParser.cs index de469c12f..1bbc7af4b 100644 --- a/MCGalaxy/Commands/CommandParser.cs +++ b/MCGalaxy/Commands/CommandParser.cs @@ -186,7 +186,7 @@ namespace MCGalaxy.Commands { /// Returns whether the player is allowed to place/modify/delete the given block. /// Outputs information of which ranks can modify the block if not. public static bool IsBlockAllowed(Player p, string action, BlockID block) { - if (p == null || BlockPerms.UsableBy(p, block)) return true; + if (p == null || p.group.Blocks[block]) return true; BlockPerms.List[block].MessageCannotUse(p, action); return false; } diff --git a/MCGalaxy/Commands/CommandPerms.cs b/MCGalaxy/Commands/CommandPerms.cs index 1f928f3e6..7fec8c967 100644 --- a/MCGalaxy/Commands/CommandPerms.cs +++ b/MCGalaxy/Commands/CommandPerms.cs @@ -25,17 +25,9 @@ namespace MCGalaxy.Commands { /// Represents which ranks are allowed (and which are disallowed) to use a command. public class CommandPerms { - - /// Name of the command these permissions are for. public string CmdName; - - /// Minimum rank normally able to use the command. public LevelPermission MinRank; - - /// Ranks specifically allowed to use the command. public List Allowed; - - /// Ranks specifically prevented from using the command. public List Disallowed; public CommandPerms(string cmd, LevelPermission minRank, List allowed, @@ -52,38 +44,32 @@ namespace MCGalaxy.Commands { Disallowed = disallowed; } - /// Creates a copy of this instance. public CommandPerms Copy() { List allowed = new List(Allowed); List disallowed = new List(Disallowed); return new CommandPerms(CmdName, MinRank, allowed, disallowed); } - static List list = new List(); + public bool UsableBy(LevelPermission perm) { + return (perm >= MinRank || Allowed.Contains(perm)) && !Disallowed.Contains(perm); + } + + public static List List = new List(); - /// Finds the rank permissions for a given command. - /// null if rank permissions were not found for the given command. public static CommandPerms Find(string cmd) { - foreach (CommandPerms perms in list) { + foreach (CommandPerms perms in List) { if (perms.CmdName.CaselessEq(cmd)) return perms; } return null; } - /// Returns the lowest rank that can use the given command. public static LevelPermission MinPerm(Command cmd) { CommandPerms perms = Find(cmd.name); return perms == null ? cmd.defaultRank : perms.MinRank; } - - /// Retrieves a copy of list of all rank permissions for commands. - public static List CopyAll() { - return new List(list); - } - - /// Sets the rank permissions for a given command. + public static void Set(string cmd, LevelPermission min, List allowed, List disallowed) { if (min > LevelPermission.Nobody) return; @@ -92,20 +78,18 @@ namespace MCGalaxy.Commands { CommandPerms perms = Find(cmd); if (perms == null) { perms = new CommandPerms(cmd, min, allowed, disallowed); - list.Add(perms); + List.Add(perms); } else { perms.Init(cmd, min, allowed, disallowed); } } - - /// Joins a list of rank permissions into a single string, comma separated. + public static string JoinPerms(List list) { if (list == null || list.Count == 0) return ""; return list.Join(p => ((int)p).ToString(), ","); } - - /// Expands a comma separated string into a list of rank permissions. + public static List ExpandPerms(string input) { List perms = new List(); if (input == null || input.Length == 0) return perms; @@ -114,21 +98,7 @@ namespace MCGalaxy.Commands { perms.Add((LevelPermission)int.Parse(perm)); } return perms; - } - - - /// Gets the list of all loaded commands that the given rank can use. - public static List AllCommandsUsableBy(LevelPermission perm) { - List commands = new List(); - foreach (CommandPerms perms in list) { - bool canUse = perms.MinRank <= perm && !perms.Disallowed.Contains(perm); - if (canUse || perms.Allowed.Contains(perm)) { - Command cmd = Command.Find(perms.CmdName); - if (cmd != null) commands.Add(cmd); - } - } - return commands; - } + } public void MessageCannotUse(Player p) { StringBuilder builder = new StringBuilder("Only "); @@ -139,37 +109,33 @@ namespace MCGalaxy.Commands { static readonly object saveLock = new object(); - - /// Saves the list of all command permissions. public static void Save() { - lock (saveLock) - SaveCore(list); + try { + lock (saveLock) SaveCore(); + } catch (Exception e) { + Logger.Log(LogType.Warning, "SAVE FAILED! command.properties"); + Logger.LogError(e); + } } - static void SaveCore(List givenList) { - try { - using (StreamWriter w = new StreamWriter(Paths.CmdPermsFile)) { - w.WriteLine("#Version 2"); - w.WriteLine("# This file list the ranks that can use each command."); - w.WriteLine("# Disallow and allow can be left empty."); - w.WriteLine("# Works entirely on rank permission values, not rank names."); - w.WriteLine("#"); - w.WriteLine("# Layout: CommandName : LowestRank : Disallow : Allow"); - w.WriteLine("# gun : 60 : 80,67 : 40,41,55"); - w.WriteLine(""); + static void SaveCore() { + using (StreamWriter w = new StreamWriter(Paths.CmdPermsFile)) { + w.WriteLine("#Version 2"); + w.WriteLine("# This file list the ranks that can use each command."); + w.WriteLine("# Disallow and allow can be left empty."); + w.WriteLine("# Works entirely on rank permission values, not rank names."); + w.WriteLine("#"); + w.WriteLine("# Layout: CommandName : LowestRank : Disallow : Allow"); + w.WriteLine("# gun : 60 : 80,67 : 40,41,55"); + w.WriteLine(""); - foreach (CommandPerms perms in givenList) { - w.WriteLine(perms.CmdName + " : " + (int)perms.MinRank + " : " + JoinPerms(perms.Disallowed) + " : " + JoinPerms(perms.Allowed)); - } + foreach (CommandPerms perms in List) { + w.WriteLine(perms.CmdName + " : " + (int)perms.MinRank + " : " + JoinPerms(perms.Disallowed) + " : " + JoinPerms(perms.Allowed)); } - } catch (Exception ex) { - Logger.Log(LogType.Warning, "SAVE FAILED! command.properties"); - Logger.LogError(ex); } } - /// Loads the list of all command permissions. public static void Load() { foreach (Command cmd in Command.CopyAll()) { Set(cmd.name, cmd.defaultRank, null, null); diff --git a/MCGalaxy/Commands/Information/CmdBlocks.cs b/MCGalaxy/Commands/Information/CmdBlocks.cs index e7964ff2f..5d46670a8 100644 --- a/MCGalaxy/Commands/Information/CmdBlocks.cs +++ b/MCGalaxy/Commands/Information/CmdBlocks.cs @@ -78,7 +78,7 @@ namespace MCGalaxy.Commands.Info { static List RankBlocks(LevelPermission perm) { List blocks = new List(Block.Count); foreach (BlockPerms perms in BlockPerms.List) { - if (!BlockPerms.UsableBy(perm, perms.ID)) continue; + if (!perms.UsableBy(perm)) continue; if (!Block.ExistsGlobal(perms.ID)) continue; blocks.Add(perms.ID); } diff --git a/MCGalaxy/Commands/Scripting/CmdCmdLoad.cs b/MCGalaxy/Commands/Scripting/CmdCmdLoad.cs index 7e2075cb8..8154f2b9d 100644 --- a/MCGalaxy/Commands/Scripting/CmdCmdLoad.cs +++ b/MCGalaxy/Commands/Scripting/CmdCmdLoad.cs @@ -38,7 +38,6 @@ namespace MCGalaxy.Commands.Scripting { string error = IScripting.Load(path); if (error != null) { Player.Message(p, error); return; } - CommandPerms.Load(); Player.Message(p, "Command was successfully loaded."); } diff --git a/MCGalaxy/Network/Packets/Packet.cs b/MCGalaxy/Network/Packets/Packet.cs index 69f8018c6..a840e2a4b 100644 --- a/MCGalaxy/Network/Packets/Packet.cs +++ b/MCGalaxy/Network/Packets/Packet.cs @@ -40,7 +40,7 @@ namespace MCGalaxy.Network { NetUtils.Write(motd, buffer, 66, p.hasCP437); } - buffer[130] = BlockPerms.UsableBy(p, Block.Bedrock) ? (byte)100 : (byte)0; + buffer[130] = p.group.Blocks[Block.Bedrock] ? (byte)100 : (byte)0; return buffer; } @@ -111,7 +111,7 @@ namespace MCGalaxy.Network { public static byte[] UserType(Player p) { byte[] buffer = new byte[2]; buffer[0] = Opcode.SetPermission; - buffer[1] = BlockPerms.UsableBy(p, Block.Bedrock) ? (byte)100 : (byte)0; + buffer[1] = p.group.Blocks[Block.Bedrock] ? (byte)100 : (byte)0; return buffer; } diff --git a/MCGalaxy/Player/Group/Group.cs b/MCGalaxy/Player/Group/Group.cs index 96cb1a5c6..d666eb2da 100644 --- a/MCGalaxy/Player/Group/Group.cs +++ b/MCGalaxy/Player/Group/Group.cs @@ -70,12 +70,19 @@ namespace MCGalaxy { public void SetUsableCommands() { - Commands = CommandPerms.AllCommandsUsableBy(Permission); + List commands = new List(); + foreach (CommandPerms perms in CommandPerms.List) { + if (!perms.UsableBy(Permission)) continue; + + Command cmd = Command.Find(perms.CmdName); + if (cmd != null) commands.Add(cmd); + } + Commands = commands; } public void SetUsableBlocks() { - for (int i = 0; i < Blocks.Length; i++) { - Blocks[i] = BlockPerms.UsableBy(Permission, (BlockID)i); + foreach (BlockPerms perms in BlockPerms.List) { + Blocks[perms.ID] = perms.UsableBy(Permission); } } diff --git a/MCGalaxy/Player/Player.CPE.cs b/MCGalaxy/Player/Player.CPE.cs index d0d534e17..8ab94e765 100644 --- a/MCGalaxy/Player/Player.CPE.cs +++ b/MCGalaxy/Player/Player.CPE.cs @@ -168,8 +168,8 @@ namespace MCGalaxy { for (int i = 0; i < count; i++) { BlockID block = Block.FromRaw((BlockID)i); - bool place = BlockPerms.UsableBy(this, block) && level.CanPlace; - bool delete = BlockPerms.UsableBy(this, block) && level.CanDelete; + bool place = group.Blocks[block] && level.CanPlace; + bool delete = group.Blocks[block] && level.CanDelete; // Placing air is the same as deleting existing block at that position in the world if (block == Block.Air) place &= delete; diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index b4d47d121..c0b92a129 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -119,7 +119,7 @@ namespace MCGalaxy { } internal bool CheckManualChange(BlockID old, BlockID block, bool deleteMode) { - if (!BlockPerms.UsableBy(this, old) && !level.BuildIn(old) && !Block.AllowBreak(old)) { + if (!group.Blocks[old] && !level.BuildIn(old) && !Block.AllowBreak(old)) { string action = deleteMode ? "delete" : "replace"; BlockPerms.List[old].MessageCannotUse(this, action); return false; diff --git a/MCGalaxy/Server/Server.cs b/MCGalaxy/Server/Server.cs index f33b235f7..0a410b6b3 100644 --- a/MCGalaxy/Server/Server.cs +++ b/MCGalaxy/Server/Server.cs @@ -199,8 +199,8 @@ namespace MCGalaxy { SrvProperties.Load(); Group.InitAll(); - Command.InitAll(); CommandPerms.Load(); + Command.InitAll(); Block.SetBlocks(); Awards.Load(); Economy.Load();