Abstract access controller class to allow for extending.

This commit is contained in:
UnknownShadow200 2017-02-01 16:05:02 +11:00
parent 865fa8f424
commit 11c5007898
8 changed files with 141 additions and 104 deletions

View File

@ -41,8 +41,8 @@ namespace MCGalaxy.Commands {
static string FormatMap(Player p, Level lvl) {
bool canVisit = Player.IsSuper(p);
if (!canVisit) {
LevelAccess access = lvl.VisitAccess.Check(p);
canVisit = access == LevelAccess.Allowed || access == LevelAccess.Whitelisted;
AccessResult access = lvl.VisitAccess.Check(p);
canVisit = access == AccessResult.Allowed || access == AccessResult.Whitelisted;
}
string physics = " [" + lvl.physics + "]";

View File

@ -50,8 +50,8 @@ namespace MCGalaxy.Commands.Moderation {
who.color = newRank.color;
who.group = newRank;
LevelAccess access = who.level.BuildAccess.Check(who);
who.AllowBuild = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;
AccessResult access = who.level.BuildAccess.Check(who);
who.AllowBuild = access == AccessResult.Whitelisted || access == AccessResult.Allowed;
who.SetPrefix();
who.Send(Packet.UserType(who));

View File

@ -78,20 +78,20 @@ namespace MCGalaxy.Commands {
}
static bool CheckVisitPerm(Player p, Player who, bool confirmed) {
LevelAccess result = p.level.VisitAccess.Check(who);
if (result == LevelAccess.Allowed) return true;
if (result == LevelAccess.Whitelisted) return true;
if (result == LevelAccess.AboveMaxRank && confirmed) return true;
if (result == LevelAccess.BelowMinRank && confirmed) return true;
AccessResult result = p.level.VisitAccess.Check(who);
if (result == AccessResult.Allowed) return true;
if (result == AccessResult.Whitelisted) return true;
if (result == AccessResult.AboveMaxRank && confirmed) return true;
if (result == AccessResult.BelowMinRank && confirmed) return true;
if (result == LevelAccess.Blacklisted) {
if (result == AccessResult.Blacklisted) {
Player.Message(p, "{0} %Sis blacklisted from visiting this map.", who.ColoredName);
return false;
} else if (result == LevelAccess.BelowMinRank) {
} else if (result == AccessResult.BelowMinRank) {
Player.Message(p, "Only {0}%S+ may normally visit this map. {1}%S is ranked {2}",
Group.GetColoredName(p.level.permissionvisit),
who.ColoredName, who.group.ColoredName);
} else if (result == LevelAccess.AboveMaxRank) {
} else if (result == AccessResult.AboveMaxRank) {
Player.Message(p, "Only {0}%S and below may normally visit this map. {1}%S is ranked {2}",
Group.GetColoredName(p.level.pervisitmax),
who.ColoredName, who.group.ColoredName);

View File

@ -51,7 +51,7 @@ namespace MCGalaxy.Drawing.Ops {
Player.Message(p, "Drawing commands are turned off on this map.");
return false;
}
if (op.Level != null && op.Level.BuildAccess.Check(p) == LevelAccess.Blacklisted) {
if (op.Level != null && op.Level.BuildAccess.Check(p) == AccessResult.Blacklisted) {
Player.Message(p, "You are blacklisted from building in this map, " +
"hence you cannot draw in this map");
return false;

View File

@ -20,84 +20,61 @@ using System.Collections.Generic;
namespace MCGalaxy {
/// <summary> Encapuslates access permissions (visit or build) for a level. </summary>
public sealed class LevelAccessController {
/// <summary> Whether these access permissions apply to
/// visit (true) or build (false) permission for the level. </summary>
public readonly bool IsVisit;
readonly Level lvl;
public LevelAccessController(Level lvl, bool isVisit) {
this.lvl = lvl;
IsVisit = isVisit;
}
/// <summary> Encapuslates access permissions (visit or build) for a level/zone. </summary>
public abstract class AccessController {
/// <summary> Lowest allowed rank. </summary>
public LevelPermission Min {
get { return IsVisit ? lvl.permissionvisit : lvl.permissionbuild; }
set {
if (IsVisit) lvl.permissionvisit = value;
else lvl.permissionbuild = value;
}
}
public abstract LevelPermission Min { get; set; }
/// <summary> Highest allowed rank. </summary>
public LevelPermission Max {
get { return IsVisit ? lvl.pervisitmax : lvl.perbuildmax; }
set {
if (IsVisit) lvl.pervisitmax = value;
else lvl.perbuildmax = value;
}
}
public abstract LevelPermission Max { get; set; }
/// <summary> List of always allowed players, overrides rank allowances. </summary>
public List<string> Whitelisted {
get { return IsVisit ? lvl.VisitWhitelist : lvl.BuildWhitelist; }
}
public abstract List<string> Whitelisted { get; }
/// <summary> List of never allowed players, ignores rank allowances. </summary>
public List<string> Blacklisted {
get { return IsVisit ? lvl.VisitBlacklist : lvl.BuildBlacklist; }
}
public abstract List<string> Blacklisted { get; }
/// <summary> Returns the formatted name for the level/zone containing these access permissions. </summary>
protected abstract string ColoredName { get; }
protected abstract string Action { get; }
protected abstract string ActionIng { get; }
protected abstract string Type { get; }
protected abstract string MaxCmd { get; }
/// <summary> Returns the allowed state for the given player. </summary>
public LevelAccess Check(Player p) {
public AccessResult Check(Player p) {
if (Blacklisted.CaselessContains(p.name))
return LevelAccess.Blacklisted;
return AccessResult.Blacklisted;
if (Whitelisted.CaselessContains(p.name))
return LevelAccess.Whitelisted;
return AccessResult.Whitelisted;
if (p.Rank < Min)
return LevelAccess.BelowMinRank;
string maxCmd = IsVisit ? "pervisitmax" : "perbuildmax";
if (p.Rank > Max && !p.group.CanExecute(maxCmd))
return LevelAccess.AboveMaxRank;
return LevelAccess.Allowed;
if (p.Rank < Min) return AccessResult.BelowMinRank;
if (p.Rank > Max && MaxCmd != null && !p.group.CanExecute(MaxCmd))
return AccessResult.AboveMaxRank;
return AccessResult.Allowed;
}
/// <summary> Returns whether the given player is allowed for these access permissions. </summary>
/// <remarks> If the player is not allowed by these access permissions,
/// sends a message to the player describing why they are not. </remarks>
public bool CheckDetailed(Player p, bool ignoreRankPerm = false) {
LevelAccess result = Check(p);
if (result == LevelAccess.Allowed) return true;
if (result == LevelAccess.Whitelisted) return true;
if (result == LevelAccess.AboveMaxRank && ignoreRankPerm) return true;
if (result == LevelAccess.BelowMinRank && ignoreRankPerm) return true;
AccessResult result = Check(p);
if (result == AccessResult.Allowed) return true;
if (result == AccessResult.Whitelisted) return true;
if (result == AccessResult.AboveMaxRank && ignoreRankPerm) return true;
if (result == AccessResult.BelowMinRank && ignoreRankPerm) return true;
if (result == LevelAccess.Blacklisted) {
string action = IsVisit ? "going to" : "building in";
Player.Message(p, "You are blacklisted from {1} {0}%S.", lvl.ColoredName, action);
} else if (result == LevelAccess.BelowMinRank) {
string action = IsVisit? "go to" : "build in";
if (result == AccessResult.Blacklisted) {
Player.Message(p, "You are blacklisted from {1} {0}%S.", ColoredName, ActionIng);
} else if (result == AccessResult.BelowMinRank) {
Player.Message(p, "Only {2}%S+ may {1} {0}%S.",
lvl.ColoredName, action, Group.GetColoredName(Min));
} else if (result == LevelAccess.AboveMaxRank) {
string action = IsVisit? "go to" : "build in";
ColoredName, Action, Group.GetColoredName(Min));
} else if (result == AccessResult.AboveMaxRank) {
Player.Message(p, "Only {2} %Sand below may {1} {0}%S.",
lvl.ColoredName, action, Group.GetColoredName(Max));
ColoredName, Action, Group.GetColoredName(Max));
}
return false;
}
@ -107,12 +84,12 @@ namespace MCGalaxy {
/// <returns> true if the minimum rank was changed, false if the given player
/// had insufficient permission to change the minimum rank. </returns>
public bool SetMin(Player p, Group grp) {
string type = IsVisit ? "Min visit" : "Min build";
if (!CheckRank(p, Min, type, false)) return false;
if (!CheckRank(p, grp.Permission, type, true)) return false;
string minType = "Min " + Type;
if (!CheckRank(p, Min, minType, false)) return false;
if (!CheckRank(p, grp.Permission, minType, true)) return false;
Min = grp.Permission;
OnPermissionChanged(p, grp, type);
OnPermissionChanged(p, grp, minType);
return true;
}
@ -120,13 +97,13 @@ namespace MCGalaxy {
/// <returns> true if the minimum rank was changed, false if the given player
/// had insufficient permission to change the minimum rank. </returns>
public bool SetMax(Player p, Group grp) {
string type = IsVisit ? "Max visit" : "Max build";
string maxType = "Max " + Type;
const LevelPermission ignore = LevelPermission.Nobody;
if (Max != ignore && !CheckRank(p, Max, type, false)) return false;
if (grp.Permission != ignore && !CheckRank(p, grp.Permission, type, true)) return false;
if (Max != ignore && !CheckRank(p, Max, maxType, false)) return false;
if (grp.Permission != ignore && !CheckRank(p, grp.Permission, maxType, true)) return false;
Max = grp.Permission;
OnPermissionChanged(p, grp, type);
OnPermissionChanged(p, grp, maxType);
return true;
}
@ -180,7 +157,82 @@ namespace MCGalaxy {
/// <summary> Messages all player on the level (and source player) notifying them that the
/// min or max rank changed, rechecks access permissions for all players on the level,
/// and finally saves the level properties file. </summary>
public void OnPermissionChanged(Player p, Group grp, string type) {
public abstract void OnPermissionChanged(Player p, Group grp, string type);
/// <summary> Messages all player on the level (and source player) notifying them that the
/// target player was whitelisted or blacklisted, rechecks access permissions
/// for all players on the level, and finally saves the level properties file. </summary>
public abstract void OnListChanged(Player p, string name, bool whitelist, bool removedFromOpposite);
/// <summary> Returns true if the player is allowed to modify these access permissions,
/// and is also allowed to change the access permissions for the target player. </summary>
bool CheckList(Player p, string name, bool whitelist) {
string mode = whitelist ? "whitelist" : "blacklist";
if (p != null && !CheckDetailed(p)) {
Player.Message(p, "Hence you cannot modify the {0} {1}.", Type, mode); return false;
}
if (p != null && PlayerInfo.GetGroup(name).Permission > p.Rank) {
Player.Message(p, "You cannot {0} players of a higher rank.", mode); return false;
}
return true;
}
}
/// <summary> Encapuslates access permissions (visit or build) for a level. </summary>
public sealed class LevelAccessController : AccessController {
/// <summary> Whether these access permissions apply to
/// visit (true) or build (false) permission for the level. </summary>
public readonly bool IsVisit;
readonly Level lvl;
public LevelAccessController(Level lvl, bool isVisit) {
this.lvl = lvl;
IsVisit = isVisit;
}
/// <summary> Lowest allowed rank. </summary>
public override LevelPermission Min {
get { return IsVisit ? lvl.permissionvisit : lvl.permissionbuild; }
set {
if (IsVisit) lvl.permissionvisit = value;
else lvl.permissionbuild = value;
}
}
/// <summary> Highest allowed rank. </summary>
public override LevelPermission Max {
get { return IsVisit ? lvl.pervisitmax : lvl.perbuildmax; }
set {
if (IsVisit) lvl.pervisitmax = value;
else lvl.perbuildmax = value;
}
}
/// <summary> List of always allowed players, overrides rank allowances. </summary>
public override List<string> Whitelisted {
get { return IsVisit ? lvl.VisitWhitelist : lvl.BuildWhitelist; }
}
/// <summary> List of never allowed players, ignores rank allowances. </summary>
public override List<string> Blacklisted {
get { return IsVisit ? lvl.VisitBlacklist : lvl.BuildBlacklist; }
}
protected override string ColoredName { get { return lvl.ColoredName; } }
protected override string Action { get { return IsVisit ? "go to" : "build in"; } }
protected override string ActionIng { get { return IsVisit ? "going to" : "building in"; } }
protected override string Type { get { return IsVisit ? "visit" : "build"; } }
protected override string MaxCmd { get { return IsVisit ? "pervisitmax" : "perbuildmax"; } }
/// <summary> Messages all player on the level (and source player) notifying them that the
/// min or max rank changed, rechecks access permissions for all players on the level,
/// and finally saves the level properties file. </summary>
public override void OnPermissionChanged(Player p, Group grp, string type) {
Update();
Server.s.Log(type + " rank changed to " + grp.trueName + " on " + lvl.name + ".");
Chat.MessageLevel(lvl, type + " rank changed to " + grp.ColoredName + "%S.");
@ -191,7 +243,7 @@ namespace MCGalaxy {
/// <summary> Messages all player on the level (and source player) notifying them that the
/// target player was whitelisted or blacklisted, rechecks access permissions
/// for all players on the level, and finally saves the level properties file. </summary>
public void OnListChanged(Player p, string name, bool whitelist, bool removedFromOpposite) {
public override void OnListChanged(Player p, string name, bool whitelist, bool removedFromOpposite) {
string type = IsVisit ? "visit" : "build";
string msg = PlayerInfo.GetColoredName(p, name);
if (removedFromOpposite) {
@ -208,21 +260,6 @@ namespace MCGalaxy {
}
/// <summary> Returns true if the player is allowed to modify these access permissions,
/// and is also allowed to change the access permissions for the target player. </summary>
bool CheckList(Player p, string name, bool whitelist) {
string type = IsVisit ? "visit" : "build";
string mode = whitelist ? "whitelist" : "blacklist";
if (p != null && !CheckDetailed(p)) {
Player.Message(p, "Hence you cannot modify the {0} {1}.", type, mode); return false;
}
if (p != null && PlayerInfo.GetGroup(name).Permission > p.Rank) {
Player.Message(p, "You cannot {0} players of a higher rank.", mode); return false;
}
return true;
}
void Update() {
Level.SaveSettings(lvl);
UpdateAllowBuild();
@ -235,8 +272,8 @@ namespace MCGalaxy {
foreach (Player p in players) {
if (p.level != lvl) continue;
LevelAccess access = Check(p);
p.AllowBuild = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;
AccessResult access = Check(p);
p.AllowBuild = access == AccessResult.Whitelisted || access == AccessResult.Allowed;
}
}
@ -246,8 +283,8 @@ namespace MCGalaxy {
foreach (Player p in players) {
if (p.level != lvl) continue;
LevelAccess access = Check(p);
bool allowVisit = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;
AccessResult access = Check(p);
bool allowVisit = access == AccessResult.Whitelisted || access == AccessResult.Allowed;
if (allowVisit) continue;
Player.Message(p, "&cNo longer allowed to visit %S{0}", lvl.ColoredName);
@ -256,7 +293,7 @@ namespace MCGalaxy {
}
}
public enum LevelAccess {
public enum AccessResult {
/// <summary> The player is whitelisted and always allowed. </summary>
Whitelisted,

View File

@ -235,9 +235,9 @@ namespace MCGalaxy {
}
if (p.level == this) return p.AllowBuild;
LevelAccess access = BuildAccess.Check(p);
return access == LevelAccess.Whitelisted
|| access == LevelAccess.Allowed;
AccessResult access = BuildAccess.Check(p);
return access == AccessResult.Whitelisted
|| access == AccessResult.Allowed;
}
public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z,

View File

@ -518,7 +518,7 @@
<Compile Include="Levels\IO\MapFormats.cs" />
<Compile Include="Levels\Level.Blocks.cs" />
<Compile Include="Levels\Level.Fields.cs" />
<Compile Include="Levels\LevelAccess.cs" />
<Compile Include="Levels\AccessController.cs" />
<Compile Include="Levels\LevelDB.cs" />
<Compile Include="Levels\Level.Physics.cs" />
<Compile Include="Levels\LevelActions.cs" />

View File

@ -302,8 +302,8 @@ namespace MCGalaxy {
useCheckpointSpawn = false;
lastCheckpointIndex = -1;
LevelAccess access = level.BuildAccess.Check(this);
AllowBuild = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;
AccessResult access = level.BuildAccess.Check(this);
AllowBuild = access == AccessResult.Whitelisted || access == AccessResult.Allowed;
try {
if (hasBlockDefs) {