diff --git a/MCGalaxy/Blocks/Block.Convert.cs b/MCGalaxy/Blocks/Block.Convert.cs
index ff827e6b8..ea754ea0f 100644
--- a/MCGalaxy/Blocks/Block.Convert.cs
+++ b/MCGalaxy/Blocks/Block.Convert.cs
@@ -71,7 +71,7 @@ namespace MCGalaxy
}
public static string GetColoredName(Player p, BlockID block) {
- BlockPerms perms = BlockPerms.Find(block);
+ BlockPerms perms = BlockPerms.GetPlace(block); // TODO check Delete perms too?
return Group.GetColor(perms.MinRank) + Block.GetName(p, block);
}
diff --git a/MCGalaxy/Commands/CommandParser.cs b/MCGalaxy/Commands/CommandParser.cs
index 782bb1cf2..0f8f537cc 100644
--- a/MCGalaxy/Commands/CommandParser.cs
+++ b/MCGalaxy/Commands/CommandParser.cs
@@ -222,8 +222,8 @@ 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.group.Blocks[block]) return true;
- BlockPerms.Find(block).MessageCannotUse(p, action);
+ if (p.group.CanPlace[block]) return true;
+ BlockPerms.GetPlace(block).MessageCannotUse(p, action); // TODO: Delete permissions too?
return false;
}
diff --git a/MCGalaxy/Commands/Information/CmdBlocks.cs b/MCGalaxy/Commands/Information/CmdBlocks.cs
index fdd51f277..adfa57170 100644
--- a/MCGalaxy/Commands/Information/CmdBlocks.cs
+++ b/MCGalaxy/Commands/Information/CmdBlocks.cs
@@ -52,7 +52,7 @@ namespace MCGalaxy.Commands.Info
Group grp = Group.Find(type);
p.Message("Blocks which {0} &Scan place: ", grp.ColoredName);
OutputBlocks(p, type, modifier,
- b => grp.Blocks[b]);
+ b => grp.CanPlace[b]);
} else if (args.Length > 1) {
Help(p);
} else {
diff --git a/MCGalaxy/Commands/Information/CmdHelp.cs b/MCGalaxy/Commands/Information/CmdHelp.cs
index bdd589d42..c2fc2e1bc 100644
--- a/MCGalaxy/Commands/Information/CmdHelp.cs
+++ b/MCGalaxy/Commands/Information/CmdHelp.cs
@@ -136,7 +136,9 @@ namespace MCGalaxy.Commands.Info
p.Message("Block \"{0}\" appears as &b{1}",
message, Block.GetName(p, Block.Convert(block)));
- BlockPerms.Find(block).MessageCannotUse(p, "use");
+
+ BlockPerms.GetPlace(block) .MessageCannotUse(p, "use");
+ BlockPerms.GetDelete(block).MessageCannotUse(p, "delete");
DescribePhysics(p, message, block);
return true;
diff --git a/MCGalaxy/Commands/Moderation/CmdBlockSet.cs b/MCGalaxy/Commands/Moderation/CmdBlockSet.cs
index 7b52f7c1b..c663cc22d 100644
--- a/MCGalaxy/Commands/Moderation/CmdBlockSet.cs
+++ b/MCGalaxy/Commands/Moderation/CmdBlockSet.cs
@@ -29,15 +29,19 @@ namespace MCGalaxy.Commands.Moderation {
BlockID block;
if (!CommandParser.GetBlockIfAllowed(p, args[0], "change permissions of", out block)) return;
- BlockPerms perms = BlockPerms.Find(block);
+ // TODO rethink messaging
+ BlockPerms perms = BlockPerms.GetPlace(block);
SetPerms(p, args, data, perms, "block");
}
- protected override void UpdatePerms(ItemPerms perms, Player p, string msg) {
+ protected override void UpdatePerms(ItemPerms perms, Player p, string msg) {
+ BlockID block = ((BlockPerms)perms).ID;
+
+ // TODO better solution
+ perms.CopyPermissionsTo(BlockPerms.GetDelete(block));
BlockPerms.Save();
BlockPerms.ApplyChanges();
- BlockID block = ((BlockPerms)perms).ID;
if (!Block.IsPhysicsType(block)) {
BlockPerms.ResendAllBlockPermissions();
}
diff --git a/MCGalaxy/Commands/Moderation/ItemPermsCmd.cs b/MCGalaxy/Commands/Moderation/ItemPermsCmd.cs
index d14411625..317bc16cf 100644
--- a/MCGalaxy/Commands/Moderation/ItemPermsCmd.cs
+++ b/MCGalaxy/Commands/Moderation/ItemPermsCmd.cs
@@ -17,8 +17,10 @@
*/
using System.Collections.Generic;
-namespace MCGalaxy.Commands.Moderation {
- public abstract class ItemPermsCmd : Command2 {
+namespace MCGalaxy.Commands.Moderation
+{
+ public abstract class ItemPermsCmd : Command2
+ {
public override string type { get { return CommandTypes.Moderation; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
diff --git a/MCGalaxy/Commands/building/CmdCopy.cs b/MCGalaxy/Commands/building/CmdCopy.cs
index 679e16a07..d1db95753 100644
--- a/MCGalaxy/Commands/building/CmdCopy.cs
+++ b/MCGalaxy/Commands/building/CmdCopy.cs
@@ -139,7 +139,7 @@ namespace MCGalaxy.Commands.Building
for (ushort x = minX; x <= maxX; ++x)
{
block = p.level.GetBlock(x, y, z);
- if (!p.group.Blocks[block]) { index++; continue; }
+ if (!p.group.CanPlace[block]) { index++; continue; }
if (block != Block.Air || cState.PasteAir) cState.UsedBlocks++;
cState.Set(block, index);
diff --git a/MCGalaxy/Config/Permissions/BlockPerms.cs b/MCGalaxy/Config/Permissions/BlockPerms.cs
index 2486ae168..ed66ad329 100644
--- a/MCGalaxy/Config/Permissions/BlockPerms.cs
+++ b/MCGalaxy/Config/Permissions/BlockPerms.cs
@@ -28,7 +28,8 @@ namespace MCGalaxy.Blocks
public BlockID ID;
public override string ItemName { get { return ID.ToString(); } }
- static BlockPerms[] List = new BlockPerms[Block.SUPPORTED_COUNT];
+ static BlockPerms[] PlaceList = new BlockPerms[Block.SUPPORTED_COUNT];
+ static BlockPerms[] DeleteList = new BlockPerms[Block.SUPPORTED_COUNT];
public BlockPerms(BlockID id, LevelPermission min) : base(min) {
@@ -41,8 +42,8 @@ namespace MCGalaxy.Blocks
}
- /// Find the permissions for the given block.
- public static BlockPerms Find(BlockID b) { return List[b]; }
+ public static BlockPerms GetPlace(BlockID b) { return PlaceList[b]; }
+ public static BlockPerms GetDelete(BlockID b) { return DeleteList[b]; }
public static void ResendAllBlockPermissions() {
@@ -67,10 +68,15 @@ namespace MCGalaxy.Blocks
}
static void SaveCore() {
- using (StreamWriter w = new StreamWriter(Paths.BlockPermsFile)) {
- WriteHeader(w, "block", "each block", "Block ID", "lava");
+ SaveList(Paths.PlacePermsFile, PlaceList, "use");
+ SaveList(Paths.DeletePermsFile, DeleteList, "delete");
+ }
+
+ static void SaveList(string path, BlockPerms[] list, string action) {
+ using (StreamWriter w = new StreamWriter(path)) {
+ WriteHeader(w, "block", "each block", "Block ID", "lava", action);
- foreach (BlockPerms perms in List)
+ foreach (BlockPerms perms in list)
{
if (Block.Undefined(perms.ID)) continue;
w.WriteLine(perms.Serialise());
@@ -88,9 +94,14 @@ namespace MCGalaxy.Blocks
}
public static void SetUsable(Group grp) {
- foreach (BlockPerms perms in List)
+ SetUsableList(PlaceList, grp.CanPlace, grp);
+ SetUsableList(DeleteList, grp.CanDelete, grp);
+ }
+
+ static void SetUsableList(BlockPerms[] list, bool[] permsList, Group grp) {
+ foreach (BlockPerms perms in list)
{
- grp.Blocks[perms.ID] = perms.UsableBy(grp.Permission);
+ permsList[perms.ID] = perms.UsableBy(grp.Permission);
}
}
@@ -103,14 +114,33 @@ namespace MCGalaxy.Blocks
static void LoadCore() {
SetDefaultPerms();
- if (!File.Exists(Paths.BlockPermsFile)) { Save(); return; }
+ bool placeExists = File.Exists(Paths.PlacePermsFile);
+ bool deleteExists = File.Exists(Paths.DeletePermsFile);
- using (StreamReader r = new StreamReader(Paths.BlockPermsFile)) {
- ProcessLines(r);
+ if (placeExists) LoadFile(Paths.PlacePermsFile, PlaceList);
+ if (deleteExists) LoadFile(Paths.DeletePermsFile, DeleteList);
+ if (placeExists || deleteExists) return;
+
+ if (File.Exists(Paths.BlockPermsFile)) {
+ LoadFile(Paths.BlockPermsFile, PlaceList);
+
+ // TODO proper migration
+ for (int i = 0; i < Block.SUPPORTED_COUNT; i++)
+ PlaceList[i].CopyPermissionsTo(DeleteList[i]);
+ SetDefaultSpecialDeletePerms();
+
+ File.Move(Paths.BlockPermsFile, Paths.BlockPermsFile + ".bak");
+ }
+ Save();
+ }
+
+ static void LoadFile(string path, BlockPerms[] list) {
+ using (StreamReader r = new StreamReader(path)) {
+ ProcessLines(r, list);
}
}
- static void ProcessLines(StreamReader r) {
+ static void ProcessLines(StreamReader r, BlockPerms[] list) {
string[] args = new string[4];
string line;
@@ -131,7 +161,7 @@ namespace MCGalaxy.Blocks
List allowed, disallowed;
Deserialise(args, 1, out min, out allowed, out disallowed);
- Set(block, min, allowed, disallowed);
+ Set(block, min, list, allowed, disallowed);
} catch {
Logger.Log(LogType.Warning, "Hit an error on the block " + line);
continue;
@@ -139,19 +169,20 @@ namespace MCGalaxy.Blocks
}
}
- static void Set(BlockID b, LevelPermission min,
+ static void Set(BlockID b, LevelPermission min, BlockPerms[] list,
List allowed, List disallowed) {
- BlockPerms perms = List[b];
+ BlockPerms perms = list[b];
if (perms == null) {
perms = new BlockPerms(b, min);
- List[b] = perms;
+ list[b] = perms;
}
perms.Init(min, allowed, disallowed);
}
-
+
static void SetDefaultPerms() {
- for (BlockID block = 0; block < Block.SUPPORTED_COUNT; block++) {
+ for (BlockID block = 0; block < Block.SUPPORTED_COUNT; block++)
+ {
BlockProps props = Block.Props[block];
LevelPermission min;
@@ -167,8 +198,15 @@ namespace MCGalaxy.Blocks
min = DefaultPerm(block);
}
- Set(block, min, null, null);
+ Set(block, min, PlaceList, null, null);
+ Set(block, min, DeleteList, null, null);
}
+ SetDefaultSpecialDeletePerms();
+ }
+
+ static void SetDefaultSpecialDeletePerms() {
+ for (BlockID b = Block.Water; b <= Block.StillLava; b++)
+ DeleteList[b].MinRank = LevelPermission.Guest;
}
static LevelPermission DefaultPerm(BlockID block) {
diff --git a/MCGalaxy/Config/Permissions/CommandExtraPerms.cs b/MCGalaxy/Config/Permissions/CommandExtraPerms.cs
index 15e228753..ee9189269 100644
--- a/MCGalaxy/Config/Permissions/CommandExtraPerms.cs
+++ b/MCGalaxy/Config/Permissions/CommandExtraPerms.cs
@@ -88,7 +88,7 @@ namespace MCGalaxy.Commands
static void SaveCore() {
using (StreamWriter w = new StreamWriter(Paths.CmdExtraPermsFile)) {
WriteHeader(w, "extra command permissions", "extra permissions in some commands",
- "CommandName:ExtraPermissionNumber", "countdown:1");
+ "CommandName:ExtraPermissionNumber", "countdown:1", "use");
foreach (CommandExtraPerms perms in list) {
w.WriteLine(perms.Serialise());
diff --git a/MCGalaxy/Config/Permissions/CommandPerms.cs b/MCGalaxy/Config/Permissions/CommandPerms.cs
index 85ee39706..f45aa98e9 100644
--- a/MCGalaxy/Config/Permissions/CommandPerms.cs
+++ b/MCGalaxy/Config/Permissions/CommandPerms.cs
@@ -77,7 +77,7 @@ namespace MCGalaxy.Commands
static void SaveCore() {
using (StreamWriter w = new StreamWriter(Paths.CmdPermsFile)) {
- WriteHeader(w, "command", "each command", "CommandName", "gun");
+ WriteHeader(w, "command", "each command", "CommandName", "gun", "use");
foreach (CommandPerms perms in List)
{
diff --git a/MCGalaxy/Config/Permissions/ItemPerms.cs b/MCGalaxy/Config/Permissions/ItemPerms.cs
index 2fb521d23..b88a43b7e 100644
--- a/MCGalaxy/Config/Permissions/ItemPerms.cs
+++ b/MCGalaxy/Config/Permissions/ItemPerms.cs
@@ -99,13 +99,13 @@ namespace MCGalaxy
protected static void WriteHeader(StreamWriter w, string itemName, string itemDesc,
- string headerName, string headerExample) {
+ string headerName, string headerExample, string action) {
w.WriteLine("#Version 2");
- w.WriteLine("# This file contains the permissions to use {0}", itemDesc);
+ w.WriteLine("# This file contains the permissions to {1} {0}", itemDesc, action);
w.WriteLine("# How permissions work:");
- w.WriteLine("# - If the player's rank is in Disallowed, they cannot use the {0}", itemName);
- w.WriteLine("# - Otherwise if the player's rank is in Allowed, they can use the {0}", itemName);
- w.WriteLine("# - Otherwise if the player's rank is >= Lowest Rank, they can use the {0}", itemName);
+ w.WriteLine("# - If the player's rank is in Disallowed, they cannot {1} the {0}", itemName, action);
+ w.WriteLine("# - Otherwise if the player's rank is in Allowed, they can {1} the {0}", itemName, action);
+ w.WriteLine("# - Otherwise if the player's rank is >= Lowest Rank, they can {1} the {0}", itemName, action);
w.WriteLine("#");
w.WriteLine("# Layout: {0} : LowestRank : Disallowed : Allowed", headerName);
w.WriteLine("# e.g. {0} : 60 : 80,67 : 40,41,55", headerExample);
diff --git a/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs b/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
index 865e71db5..575e51134 100644
--- a/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
+++ b/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
@@ -160,7 +160,7 @@ namespace MCGalaxy.Drawing.Ops
#endif
// Check to make sure the block is actually different and that can be used
- if (old == b.Block || !p.group.Blocks[old] || !p.group.Blocks[b.Block]) return;
+ if (old == b.Block || !p.group.CanDelete[old] || !p.group.CanPlace[b.Block]) return;
// Check if player can affect block at coords in world
AccessController denier = lvl.CanAffect(p, b.X, b.Y, b.Z);
diff --git a/MCGalaxy/Levels/Level.Blocks.cs b/MCGalaxy/Levels/Level.Blocks.cs
index 53f6f80f8..9f5855ff9 100644
--- a/MCGalaxy/Levels/Level.Blocks.cs
+++ b/MCGalaxy/Levels/Level.Blocks.cs
@@ -220,13 +220,7 @@ namespace MCGalaxy {
blocks[index] = (BlockRaw)block;
}
}
-
-
- internal bool BuildIn(BlockID block) {
- if (block == Block.Op_Water || block == Block.Op_Lava || Props[block].IsPortal || Props[block].IsMessageBlock) return false;
- block = Block.Convert(block);
- return block >= Block.Water && block <= Block.StillLava;
- }
+
/// Returns the AccessController denying the player from changing blocks at the given coordinates.
/// If no AccessController denies the player, returns null.
@@ -265,7 +259,7 @@ namespace MCGalaxy {
}
public bool CheckAffect(Player p, ushort x, ushort y, ushort z, BlockID old, BlockID block) {
- if (!p.group.Blocks[old] || !p.group.Blocks[block]) return false;
+ if (!p.group.CanDelete[old] || !p.group.CanPlace[block]) return false;
AccessController denier = CanAffect(p, x, y, z);
if (denier == null) return true;
diff --git a/MCGalaxy/Network/Player.Networking.cs b/MCGalaxy/Network/Player.Networking.cs
index 968ed3a88..386930246 100644
--- a/MCGalaxy/Network/Player.Networking.cs
+++ b/MCGalaxy/Network/Player.Networking.cs
@@ -205,13 +205,14 @@ namespace MCGalaxy
int size = extBlocks ? 5 : 4;
byte[] bulk = new byte[count * size];
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
BlockID block = Block.FromRaw((BlockID)i);
- bool place = group.Blocks[block] && level.CanPlace;
+ bool place = group.CanPlace[block] && level.CanPlace;
// NOTE: If you can't delete air, then you're no longer able to place blocks
// (see ClassiCube client #815)
// TODO: Maybe better solution than this?
- bool delete = group.Blocks[block] && (level.CanDelete || i == Block.Air);
+ bool delete = group.CanDelete[block] && (level.CanDelete || i == Block.Air);
// 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/Group.cs b/MCGalaxy/Player/Group.cs
index 62e5ecdb7..cfe296024 100644
--- a/MCGalaxy/Player/Group.cs
+++ b/MCGalaxy/Player/Group.cs
@@ -69,7 +69,8 @@ namespace MCGalaxy
internal string filename;
public PlayerList Players;
- public bool[] Blocks = new bool[Block.SUPPORTED_COUNT];
+ public bool[] CanPlace = new bool[Block.SUPPORTED_COUNT];
+ public bool[] CanDelete = new bool[Block.SUPPORTED_COUNT];
public Group() { }
private Group(LevelPermission perm, int drawLimit, int undoMins, string name, string color, int volume, int realms) {
@@ -100,7 +101,8 @@ namespace MCGalaxy
public static Group Find(string name) {
MapName(ref name);
- foreach (Group grp in GroupList) {
+ foreach (Group grp in GroupList)
+ {
if (grp.Name.CaselessEq(name)) return grp;
}
return null;
diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs
index b3e267eea..aa33f799f 100644
--- a/MCGalaxy/Player/Player.Handlers.cs
+++ b/MCGalaxy/Player/Player.Handlers.cs
@@ -132,9 +132,9 @@ namespace MCGalaxy
}
internal bool CheckManualChange(BlockID old, bool deleteMode) {
- if (!group.Blocks[old] && !level.BuildIn(old) && !Block.AllowBreak(old)) {
+ if (!group.CanDelete[old] && !Block.AllowBreak(old)) {
string action = deleteMode ? "delete" : "replace";
- BlockPerms.Find(old).MessageCannotUse(this, action);
+ BlockPerms.GetDelete(old).MessageCannotUse(this, action);
return false;
}
return true;
diff --git a/MCGalaxy/Player/Player.cs b/MCGalaxy/Player/Player.cs
index 5f79003ca..d392b47f8 100644
--- a/MCGalaxy/Player/Player.cs
+++ b/MCGalaxy/Player/Player.cs
@@ -331,7 +331,7 @@ namespace MCGalaxy {
public const string USERNAME_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890._";
- internal byte UserType() { return group.Blocks[Block.Bedrock] ? (byte)100 : (byte)0; }
+ internal byte UserType() { return group.CanPlace[Block.Bedrock] ? (byte)100 : (byte)0; }
#endregion
diff --git a/MCGalaxy/Server/Paths.cs b/MCGalaxy/Server/Paths.cs
index 2cbef0bee..71e63a62c 100644
--- a/MCGalaxy/Server/Paths.cs
+++ b/MCGalaxy/Server/Paths.cs
@@ -38,7 +38,10 @@ namespace MCGalaxy
public const string JokerFile = "text/joker.txt";
public const string EightBallFile = "text/8ball.txt";
- public const string BlockPermsFile = "properties/block.properties";
+ public const string BlockPermsFile = "properties/block.properties";
+ public const string PlacePermsFile = "properties/place.properties";
+ public const string DeletePermsFile = "properties/delete.properties";
+
public const string CmdPermsFile = "properties/command.properties";
public const string CmdExtraPermsFile = "properties/ExtraCommandPermissions.properties";
public const string EconomyPropsFile = "properties/economy.properties";