Merge pull request #787 from UnknownShadow200/PlaceDeletePermissions

Split up Block permissions into Place and Delete permissions
This commit is contained in:
UnknownShadow200 2023-12-26 10:30:59 +11:00 committed by GitHub
commit ffab090303
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 217 additions and 111 deletions

View File

@ -30,13 +30,14 @@ namespace MCGalaxy.Gui {
// need to keep a list of changed block perms, because we don't want // need to keep a list of changed block perms, because we don't want
// to modify the server's live permissions if user clicks 'discard' // to modify the server's live permissions if user clicks 'discard'
BlockPerms blockPermsOrig, blockPermsCopy; BlockPerms placePermsOrig, placePermsCopy;
List<BlockPerms> blockPermsChanged = new List<BlockPerms>(); List<BlockPerms> placePermsChanged = new List<BlockPerms>();
BlockProps[] blockPropsChanged = new BlockProps[Block.Props.Length]; BlockProps[] blockPropsChanged = new BlockProps[Block.Props.Length];
// TODO delete permissions too
void LoadBlocks() { void LoadBlocks() {
blk_list.Items.Clear(); blk_list.Items.Clear();
blockPermsChanged.Clear(); placePermsChanged.Clear();
blockIDMap = new List<BlockID>(); blockIDMap = new List<BlockID>();
for (int b = 0; b < blockPropsChanged.Length; b++) for (int b = 0; b < blockPropsChanged.Length; b++)
@ -59,7 +60,7 @@ namespace MCGalaxy.Gui {
} }
void SaveBlocks() { void SaveBlocks() {
if (blockPermsChanged.Count > 0) if (placePermsChanged.Count > 0)
SaveBlockPermissions(); SaveBlockPermissions();
if (AnyBlockPropsChanged()) if (AnyBlockPropsChanged())
SaveBlockProps(); SaveBlockProps();
@ -68,10 +69,13 @@ namespace MCGalaxy.Gui {
} }
void SaveBlockPermissions() { void SaveBlockPermissions() {
foreach (BlockPerms changed in blockPermsChanged) foreach (BlockPerms changed in placePermsChanged)
{ {
BlockPerms orig = BlockPerms.Find(changed.ID); BlockPerms pOrig = BlockPerms.GetPlace(changed.ID);
changed.CopyPermissionsTo(orig); changed.CopyPermissionsTo(pOrig);
BlockPerms dOrig = BlockPerms.GetDelete(changed.ID);
changed.CopyPermissionsTo(dOrig);
} }
BlockPerms.Save(); BlockPerms.Save();
@ -101,8 +105,9 @@ namespace MCGalaxy.Gui {
void blk_list_SelectedIndexChanged(object sender, EventArgs e) { void blk_list_SelectedIndexChanged(object sender, EventArgs e) {
curBlock = blockIDMap[blk_list.SelectedIndex]; curBlock = blockIDMap[blk_list.SelectedIndex];
blockPermsOrig = BlockPerms.Find(curBlock); placePermsOrig = BlockPerms.GetPlace(curBlock);
blockPermsCopy = blockPermsChanged.Find(p => p.ID == curBlock); placePermsCopy = placePermsChanged.Find(p => p.ID == curBlock);
BlockInitSpecificArrays(); BlockInitSpecificArrays();
blockItems.SupressEvents = true; blockItems.SupressEvents = true;
@ -119,7 +124,7 @@ namespace MCGalaxy.Gui {
blk_cbLava.Checked = props.LavaKills; blk_cbLava.Checked = props.LavaKills;
blk_cbWater.Checked = props.WaterKills; blk_cbWater.Checked = props.WaterKills;
BlockPerms perms = blockPermsCopy != null ? blockPermsCopy : blockPermsOrig; BlockPerms perms = placePermsCopy != null ? placePermsCopy : placePermsOrig;
blockItems.Update(perms); blockItems.Update(perms);
} }
@ -132,10 +137,10 @@ namespace MCGalaxy.Gui {
} }
ItemPerms BlockGetOrAddPermsChanged() { ItemPerms BlockGetOrAddPermsChanged() {
if (blockPermsCopy != null) return blockPermsCopy; if (placePermsCopy != null) return placePermsCopy;
blockPermsCopy = blockPermsOrig.Copy(); placePermsCopy = placePermsOrig.Copy();
blockPermsChanged.Add(blockPermsCopy); placePermsChanged.Add(placePermsCopy);
return blockPermsCopy; return placePermsCopy;
} }

View File

@ -71,7 +71,7 @@ namespace MCGalaxy
} }
public static string GetColoredName(Player p, BlockID block) { 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); return Group.GetColor(perms.MinRank) + Block.GetName(p, block);
} }

View File

@ -222,8 +222,8 @@ namespace MCGalaxy.Commands
/// <summary> Returns whether the player is allowed to place/modify/delete the given block. </summary> /// <summary> Returns whether the player is allowed to place/modify/delete the given block. </summary>
/// <remarks> Outputs information of which ranks can modify the block if not. </remarks> /// <remarks> Outputs information of which ranks can modify the block if not. </remarks>
public static bool IsBlockAllowed(Player p, string action, BlockID block) { public static bool IsBlockAllowed(Player p, string action, BlockID block) {
if (p.group.Blocks[block]) return true; if (p.group.CanPlace[block]) return true;
BlockPerms.Find(block).MessageCannotUse(p, action); BlockPerms.GetPlace(block).MessageCannotUse(p, action); // TODO: Delete permissions too?
return false; return false;
} }

View File

@ -52,7 +52,7 @@ namespace MCGalaxy.Commands.Info
Group grp = Group.Find(type); Group grp = Group.Find(type);
p.Message("Blocks which {0} &Scan place: ", grp.ColoredName); p.Message("Blocks which {0} &Scan place: ", grp.ColoredName);
OutputBlocks(p, type, modifier, OutputBlocks(p, type, modifier,
b => grp.Blocks[b]); b => grp.CanPlace[b]);
} else if (args.Length > 1) { } else if (args.Length > 1) {
Help(p); Help(p);
} else { } else {

View File

@ -136,7 +136,9 @@ namespace MCGalaxy.Commands.Info
p.Message("Block \"{0}\" appears as &b{1}", p.Message("Block \"{0}\" appears as &b{1}",
message, Block.GetName(p, Block.Convert(block))); 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); DescribePhysics(p, message, block);
return true; return true;

View File

@ -18,42 +18,82 @@
using MCGalaxy.Blocks; using MCGalaxy.Blocks;
using BlockID = System.UInt16; using BlockID = System.UInt16;
namespace MCGalaxy.Commands.Moderation { namespace MCGalaxy.Commands.Moderation
public sealed class CmdBlockSet : ItemPermsCmd { {
public sealed class CmdBlockSet : ItemPermsCmd
{
public override string name { get { return "BlockSet"; } } public override string name { get { return "BlockSet"; } }
public override void Use(Player p, string message, CommandData data) { public override void Use(Player p, string message, CommandData data) {
bool canPlace = true; const string PLACE_PREFIX = "place ";
bool canDelete = true; const string DELETE_PREFIX = "delete ";
string placeMsg = null, deleteMsg = null;
if (message.CaselessStarts(PLACE_PREFIX)) {
canDelete = false;
message = message.Substring(PLACE_PREFIX.Length);
} else if (message.CaselessStarts(DELETE_PREFIX)) {
canPlace = false;
message = message.Substring(DELETE_PREFIX.Length);
}
string[] args = message.SplitSpaces(2); string[] args = message.SplitSpaces(2);
if (args.Length < 2) { Help(p); return; } if (args.Length < 2) { Help(p); return; }
BlockID block; BlockID block;
if (!CommandParser.GetBlockIfAllowed(p, args[0], "change permissions of", out block)) return; if (!CommandParser.GetBlockIfAllowed(p, args[0], "change permissions of", out block)) return;
BlockPerms perms = BlockPerms.Find(block); // TODO avoid showing message twice
SetPerms(p, args, data, perms, "block"); if (canPlace) {
BlockPerms perms = BlockPerms.GetPlace(block);
placeMsg = SetPerms(p, args, data, perms, "block", "use", "usable");
}
if (canDelete) {
BlockPerms perms = BlockPerms.GetDelete(block);
deleteMsg = SetPerms(p, args, data, perms, "block", "delete", "deletable");
} }
protected override void UpdatePerms(ItemPerms perms, Player p, string msg) { if (placeMsg == null && deleteMsg == null) return;
UpdatePerms(block, p, placeMsg, deleteMsg);
}
void UpdatePerms(BlockID block, Player p, string placeMsg, string deleteMsg) {
BlockPerms.Save(); BlockPerms.Save();
BlockPerms.ApplyChanges(); BlockPerms.ApplyChanges();
BlockID block = ((BlockPerms)perms).ID;
if (!Block.IsPhysicsType(block)) { if (!Block.IsPhysicsType(block)) {
BlockPerms.ResendAllBlockPermissions(); BlockPerms.ResendAllBlockPermissions();
} }
string name = Block.GetName(p, block); string name = Block.GetName(p, block);
Announce(p, name + msg);
if (placeMsg != null && deleteMsg != null) {
Announce(p, name + placeMsg.Replace("usable", "usable and deletable"));
} else if (placeMsg != null) {
Announce(p, name + placeMsg);
} else {
Announce(p, name + deleteMsg);
}
} }
public override void Help(Player p) { public override void Help(Player p) {
p.Message("&T/BlockSet [block] [rank]"); p.Message("&T/BlockSet [block] [rank]");
p.Message("&HSets lowest rank that can modify/use [block] to [rank]"); p.Message("&HSets lowest rank that can use and delete [block] to [rank]");
p.Message("&T/BlockSet place [block] [rank]");
p.Message("&HSets lowest rank that can use/modify [block] to [rank]");
p.Message("&T/BlockSet delete [block] [rank]");
p.Message("&HSets lowest rank that can delete [block] to [rank]");
p.Message("&H- For more advanced permissions, see &T/Help blockset advanced");
p.Message("&H- To see available ranks, type &T/ViewRanks");
}
public override void Help(Player p, string message) {
if (!message.CaselessEq("advanced")) { base.Help(p, message); return; }
p.Message("&T/BlockSet [block] +[rank]"); p.Message("&T/BlockSet [block] +[rank]");
p.Message("&HAllows a specific rank to modify/use [block]"); p.Message("&HAllows a specific rank to use and delete [block]");
p.Message("&T/BlockSet [block] -[rank]"); p.Message("&T/BlockSet [block] -[rank]");
p.Message("&HPrevents a specific rank from modifying/using [block]"); p.Message("&HPrevents a specific rank from using or deleting [block]");
p.Message("&HTo see available ranks, type &T/ViewRanks"); // TODO place and delete messages
} }
} }
} }

View File

@ -15,15 +15,17 @@
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.
*/ */
namespace MCGalaxy.Commands.Moderation { namespace MCGalaxy.Commands.Moderation
public sealed class CmdCmdSet : ItemPermsCmd { {
public sealed class CmdCmdSet : ItemPermsCmd
{
public override string name { get { return "CmdSet"; } } public override string name { get { return "CmdSet"; } }
public override void Use(Player p, string message, CommandData data) { public override void Use(Player p, string message, CommandData data) {
string[] args = message.SplitSpaces(3); string[] args = message.SplitSpaces(3);
if (args.Length < 2) { Help(p); return; } if (args.Length < 2) { Help(p); return; }
string cmdName = args[0], cmdArgs = ""; string cmdName = args[0], cmdArgs = "", msg;
Command.Search(ref cmdName, ref cmdArgs); Command.Search(ref cmdName, ref cmdArgs);
Command cmd = Command.Find(cmdName); Command cmd = Command.Find(cmdName);
@ -35,8 +37,11 @@ namespace MCGalaxy.Commands.Moderation {
} }
if (args.Length == 2) { if (args.Length == 2) {
SetPerms(p, args, data, cmd.Permissions, "command"); msg = SetPerms(p, args, data, cmd.Permissions, "command", "use", "usable");
if (msg != null)
UpdateCommandPerms(cmd.Permissions, p, msg);
} else { } else {
int num = 0; int num = 0;
if (!CommandParser.GetInt(p, args[2], "Extra permission number", ref num)) return; if (!CommandParser.GetInt(p, args[2], "Extra permission number", ref num)) return;
@ -44,33 +49,41 @@ namespace MCGalaxy.Commands.Moderation {
if (perms == null) { if (perms == null) {
p.Message("This command has no extra permission by that number."); return; p.Message("This command has no extra permission by that number."); return;
} }
SetPerms(p, args, data, perms, "extra permission");
msg = SetPerms(p, args, data, perms, "extra permission", "use", "usable");
if (msg != null)
UpdateExtraPerms(perms, p, msg);
} }
} }
protected override void UpdatePerms(ItemPerms perms, Player p, string msg) { void UpdateCommandPerms(ItemPerms perms, Player p, string msg) {
if (perms is CommandPerms) {
CommandPerms.Save(); CommandPerms.Save();
CommandPerms.ApplyChanges(); CommandPerms.ApplyChanges();
Announce(p, perms.ItemName + msg); Announce(p, perms.ItemName + msg);
} else {
CommandExtraPerms.Save();
CommandExtraPerms ex = (CommandExtraPerms)perms;
//Announce(p, cmd.name + "&S's extra permission " + idx + " was set to " + grp.ColoredName);
Announce(p, ex.CmdName + " extra permission #" + ex.Num + msg);
} }
void UpdateExtraPerms(CommandExtraPerms perms, Player p, string msg) {
CommandExtraPerms.Save();
//Announce(p, cmd.name + "&S's extra permission " + idx + " was set to " + grp.ColoredName);
Announce(p, perms.CmdName + " extra permission #" + perms.Num + msg);
} }
public override void Help(Player p) { public override void Help(Player p) {
p.Message("&T/CmdSet [cmd] [rank]"); p.Message("&T/CmdSet [cmd] [rank]");
p.Message("&HSets lowest rank that can use [cmd] to [rank]"); p.Message("&HSets lowest rank that can use [cmd] to [rank]");
p.Message("&T/CmdSet [cmd] [rank] [extra permission number]");
p.Message("&HSet the lowest rank that has that extra permission for [cmd]");
p.Message("&H- For more advanced permissions, see &T/Help cmdset advanced");
p.Message("&H- To see available ranks, type &T/ViewRanks");
}
public override void Help(Player p, string message) {
if (!message.CaselessEq("advanced")) { base.Help(p, message); return; }
p.Message("&T/CmdSet [cmd] +[rank]"); p.Message("&T/CmdSet [cmd] +[rank]");
p.Message("&HAllows a specific rank to use [cmd]"); p.Message("&HAllows a specific rank to use [cmd]");
p.Message("&T/CmdSet [cmd] -[rank]"); p.Message("&T/CmdSet [cmd] -[rank]");
p.Message("&HPrevents a specific rank from using [cmd]"); p.Message("&HPrevents a specific rank from using [cmd]");
p.Message("&T/CmdSet [cmd] [rank] [extra permission number]");
p.Message("&HSet the lowest rank that has that extra permission for [cmd]");
p.Message("&HTo see available ranks, type &T/ViewRanks");
} }
} }
} }

View File

@ -17,44 +17,45 @@
*/ */
using System.Collections.Generic; using System.Collections.Generic;
namespace MCGalaxy.Commands.Moderation { namespace MCGalaxy.Commands.Moderation
public abstract class ItemPermsCmd : Command2 { {
public abstract class ItemPermsCmd : Command2
{
public override string type { get { return CommandTypes.Moderation; } } public override string type { get { return CommandTypes.Moderation; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } } public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
protected void SetPerms(Player p, string[] args, CommandData data, ItemPerms perms, string type) { protected string SetPerms(Player p, string[] args, CommandData data, ItemPerms perms, string type,
string actionNoun, string actionAdjective) {
string grpName = args[1]; string grpName = args[1];
if (!perms.UsableBy(data.Rank)) { if (!perms.UsableBy(data.Rank)) {
p.Message("You rank cannot use this {0}.", type); return; p.Message("You rank cannot {1} this {0}.", type, actionNoun); return null;
} }
if (grpName[0] == '+') { if (grpName[0] == '+') {
Group grp = GetGroup(p, data, grpName.Substring(1)); Group grp = GetGroup(p, data, grpName.Substring(1));
if (grp == null) return; if (grp == null) return null;
perms.Allow(grp.Permission); perms.Allow(grp.Permission);
UpdatePerms(perms, p, " &Scan now be used by " + grp.ColoredName); return " &Sis now " + actionAdjective + " by " + grp.ColoredName;
} else if (grpName[0] == '-') { } else if (grpName[0] == '-') {
Group grp = GetGroup(p, data, grpName.Substring(1)); Group grp = GetGroup(p, data, grpName.Substring(1));
if (grp == null) return; if (grp == null) return null;
if (data.Rank == grp.Permission) { if (data.Rank == grp.Permission) {
p.Message("You cannot disallow your own rank from using a {0}.", type); return; p.Message("&WCannot deny permissions for your own rank"); return null;
} }
perms.Disallow(grp.Permission); perms.Disallow(grp.Permission);
UpdatePerms(perms, p, " &Sis no longer usable by " + grp.ColoredName); return " &Sis no longer " + actionAdjective + " by " + grp.ColoredName;
} else { } else {
Group grp = GetGroup(p, data, grpName); Group grp = GetGroup(p, data, grpName);
if (grp == null) return; if (grp == null) return null;
perms.MinRank = grp.Permission; perms.MinRank = grp.Permission;
UpdatePerms(perms, p, " &Sis now usable by " + grp.ColoredName + "&S+"); return " &Sis now " + actionAdjective + " by " + grp.ColoredName + "&S+";
} }
} }
protected abstract void UpdatePerms(ItemPerms perms, Player p, string msg);
protected static Group GetGroup(Player p, CommandData data, string grpName) { protected static Group GetGroup(Player p, CommandData data, string grpName) {
Group grp = Matcher.FindRanks(p, grpName); Group grp = Matcher.FindRanks(p, grpName);
if (grp == null) return null; if (grp == null) return null;

View File

@ -139,7 +139,7 @@ namespace MCGalaxy.Commands.Building
for (ushort x = minX; x <= maxX; ++x) for (ushort x = minX; x <= maxX; ++x)
{ {
block = p.level.GetBlock(x, y, z); 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++; if (block != Block.Air || cState.PasteAir) cState.UsedBlocks++;
cState.Set(block, index); cState.Set(block, index);

View File

@ -28,7 +28,8 @@ namespace MCGalaxy.Blocks
public BlockID ID; public BlockID ID;
public override string ItemName { get { return ID.ToString(); } } 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) { public BlockPerms(BlockID id, LevelPermission min) : base(min) {
@ -41,8 +42,8 @@ namespace MCGalaxy.Blocks
} }
/// <summary> Find the permissions for the given block. </summary> public static BlockPerms GetPlace(BlockID b) { return PlaceList[b]; }
public static BlockPerms Find(BlockID b) { return List[b]; } public static BlockPerms GetDelete(BlockID b) { return DeleteList[b]; }
public static void ResendAllBlockPermissions() { public static void ResendAllBlockPermissions() {
@ -67,10 +68,15 @@ namespace MCGalaxy.Blocks
} }
static void SaveCore() { static void SaveCore() {
using (StreamWriter w = new StreamWriter(Paths.BlockPermsFile)) { SaveList(Paths.PlacePermsFile, PlaceList, "use");
WriteHeader(w, "block", "each block", "Block ID", "lava"); SaveList(Paths.DeletePermsFile, DeleteList, "delete");
}
foreach (BlockPerms perms in List) 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)
{ {
if (Block.Undefined(perms.ID)) continue; if (Block.Undefined(perms.ID)) continue;
w.WriteLine(perms.Serialise()); w.WriteLine(perms.Serialise());
@ -88,9 +94,14 @@ namespace MCGalaxy.Blocks
} }
public static void SetUsable(Group grp) { 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,36 @@ namespace MCGalaxy.Blocks
static void LoadCore() { static void LoadCore() {
SetDefaultPerms(); 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)) { if (placeExists) LoadFile(Paths.PlacePermsFile, PlaceList);
ProcessLines(r); if (deleteExists) LoadFile(Paths.DeletePermsFile, DeleteList);
if (placeExists || deleteExists) return;
if (File.Exists(Paths.BlockPermsFile)) {
LoadFile(Paths.BlockPermsFile, PlaceList);
for (int i = 0; i < Block.SUPPORTED_COUNT; i++)
PlaceList[i].CopyPermissionsTo(DeleteList[i]);
SetDefaultSpecialDeletePerms();
try {
File.Move(Paths.BlockPermsFile, Paths.BlockPermsFile + ".bak");
} catch (Exception ex) {
Logger.LogError("Moving old block.properties file", ex);
}
}
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[] args = new string[4];
string line; string line;
@ -131,7 +164,7 @@ namespace MCGalaxy.Blocks
List<LevelPermission> allowed, disallowed; List<LevelPermission> allowed, disallowed;
Deserialise(args, 1, out min, out allowed, out disallowed); Deserialise(args, 1, out min, out allowed, out disallowed);
Set(block, min, allowed, disallowed); Set(block, min, list, allowed, disallowed);
} catch { } catch {
Logger.Log(LogType.Warning, "Hit an error on the block " + line); Logger.Log(LogType.Warning, "Hit an error on the block " + line);
continue; continue;
@ -139,19 +172,20 @@ namespace MCGalaxy.Blocks
} }
} }
static void Set(BlockID b, LevelPermission min, static void Set(BlockID b, LevelPermission min, BlockPerms[] list,
List<LevelPermission> allowed, List<LevelPermission> disallowed) { List<LevelPermission> allowed, List<LevelPermission> disallowed) {
BlockPerms perms = List[b]; BlockPerms perms = list[b];
if (perms == null) { if (perms == null) {
perms = new BlockPerms(b, min); perms = new BlockPerms(b, min);
List[b] = perms; list[b] = perms;
} }
perms.Init(min, allowed, disallowed); perms.Init(min, allowed, disallowed);
} }
static void SetDefaultPerms() { 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]; BlockProps props = Block.Props[block];
LevelPermission min; LevelPermission min;
@ -167,8 +201,15 @@ namespace MCGalaxy.Blocks
min = DefaultPerm(block); 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) { static LevelPermission DefaultPerm(BlockID block) {

View File

@ -88,7 +88,7 @@ namespace MCGalaxy.Commands
static void SaveCore() { static void SaveCore() {
using (StreamWriter w = new StreamWriter(Paths.CmdExtraPermsFile)) { using (StreamWriter w = new StreamWriter(Paths.CmdExtraPermsFile)) {
WriteHeader(w, "extra command permissions", "extra permissions in some commands", WriteHeader(w, "extra command permissions", "extra permissions in some commands",
"CommandName:ExtraPermissionNumber", "countdown:1"); "CommandName:ExtraPermissionNumber", "countdown:1", "use");
foreach (CommandExtraPerms perms in list) { foreach (CommandExtraPerms perms in list) {
w.WriteLine(perms.Serialise()); w.WriteLine(perms.Serialise());

View File

@ -77,7 +77,7 @@ namespace MCGalaxy.Commands
static void SaveCore() { static void SaveCore() {
using (StreamWriter w = new StreamWriter(Paths.CmdPermsFile)) { 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) foreach (CommandPerms perms in List)
{ {

View File

@ -99,13 +99,13 @@ namespace MCGalaxy
protected static void WriteHeader(StreamWriter w, string itemName, string itemDesc, 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("#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("# How permissions work:");
w.WriteLine("# - If the player's rank is in Disallowed, they cannot 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 use the {0}", itemName); 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 use the {0}", itemName); w.WriteLine("# - Otherwise if the player's rank is >= Lowest Rank, they can {1} the {0}", itemName, action);
w.WriteLine("#"); w.WriteLine("#");
w.WriteLine("# Layout: {0} : LowestRank : Disallowed : Allowed", headerName); w.WriteLine("# Layout: {0} : LowestRank : Disallowed : Allowed", headerName);
w.WriteLine("# e.g. {0} : 60 : 80,67 : 40,41,55", headerExample); w.WriteLine("# e.g. {0} : 60 : 80,67 : 40,41,55", headerExample);

View File

@ -159,8 +159,12 @@ namespace MCGalaxy.Drawing.Ops
if (old == Block.custom_block) old = (BlockID)(Block.Extended | lvl.FastGetExtTile(b.X, b.Y, b.Z)); if (old == Block.custom_block) old = (BlockID)(Block.Extended | lvl.FastGetExtTile(b.X, b.Y, b.Z));
#endif #endif
// Check to make sure the block is actually different and that can be used // Check to make sure the block is actually different
if (old == b.Block || !p.group.Blocks[old] || !p.group.Blocks[b.Block]) return; if (old == b.Block) return;
// And check that the block can be used
Group grp = p.group;
if (!grp.CanDelete[old] || !grp.CanPlace[b.Block]) return;
// Check if player can affect block at coords in world // Check if player can affect block at coords in world
AccessController denier = lvl.CanAffect(p, b.X, b.Y, b.Z); AccessController denier = lvl.CanAffect(p, b.X, b.Y, b.Z);

View File

@ -222,12 +222,6 @@ namespace MCGalaxy {
} }
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;
}
/// <summary> Returns the AccessController denying the player from changing blocks at the given coordinates. </summary> /// <summary> Returns the AccessController denying the player from changing blocks at the given coordinates. </summary>
/// <remarks> If no AccessController denies the player, returns null. </remarks> /// <remarks> If no AccessController denies the player, returns null. </remarks>
public AccessController CanAffect(Player p, ushort x, ushort y, ushort z) { public AccessController CanAffect(Player p, ushort x, ushort y, ushort z) {
@ -265,7 +259,7 @@ namespace MCGalaxy {
} }
public bool CheckAffect(Player p, ushort x, ushort y, ushort z, BlockID old, BlockID block) { 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); AccessController denier = CanAffect(p, x, y, z);
if (denier == null) return true; if (denier == null) return true;

View File

@ -205,13 +205,14 @@ namespace MCGalaxy
int size = extBlocks ? 5 : 4; int size = extBlocks ? 5 : 4;
byte[] bulk = new byte[count * size]; 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); 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 // NOTE: If you can't delete air, then you're no longer able to place blocks
// (see ClassiCube client #815) // (see ClassiCube client #815)
// TODO: Maybe better solution than this? // 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 // Placing air is the same as deleting existing block at that position in the world
if (block == Block.Air) place &= delete; if (block == Block.Air) place &= delete;

View File

@ -69,7 +69,8 @@ namespace MCGalaxy
internal string filename; internal string filename;
public PlayerList Players; 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() { } public Group() { }
private Group(LevelPermission perm, int drawLimit, int undoMins, string name, string color, int volume, int realms) { 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) { public static Group Find(string name) {
MapName(ref name); MapName(ref name);
foreach (Group grp in GroupList) { foreach (Group grp in GroupList)
{
if (grp.Name.CaselessEq(name)) return grp; if (grp.Name.CaselessEq(name)) return grp;
} }
return null; return null;

View File

@ -132,9 +132,9 @@ namespace MCGalaxy
} }
internal bool CheckManualChange(BlockID old, bool deleteMode) { 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"; string action = deleteMode ? "delete" : "replace";
BlockPerms.Find(old).MessageCannotUse(this, action); BlockPerms.GetDelete(old).MessageCannotUse(this, action);
return false; return false;
} }
return true; return true;

View File

@ -331,7 +331,7 @@ namespace MCGalaxy {
public const string USERNAME_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890._"; 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 #endregion

View File

@ -39,6 +39,9 @@ namespace MCGalaxy
public const string EightBallFile = "text/8ball.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 CmdPermsFile = "properties/command.properties";
public const string CmdExtraPermsFile = "properties/ExtraCommandPermissions.properties"; public const string CmdExtraPermsFile = "properties/ExtraCommandPermissions.properties";
public const string EconomyPropsFile = "properties/economy.properties"; public const string EconomyPropsFile = "properties/economy.properties";