Initial WIP on having zones show stuff.

This commit is contained in:
UnknownShadow200 2018-01-28 13:14:35 +11:00
parent d423f067a8
commit c557b4128c
8 changed files with 147 additions and 68 deletions

View File

@ -25,7 +25,11 @@ namespace MCGalaxy.Commands.Moderation {
public override string type { get { return CommandTypes.Moderation; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public override CommandAlias[] Aliases {
get { return new[] { new CommandAlias("ZRemove", "del"), new CommandAlias("ZDelete", "del"),
new CommandAlias("ZAdd"), new CommandAlias("ZEdit", "edit") }; }
}
public override void Use(Player p, string message) {
string[] args = message.SplitSpaces();
if (message.Length == 0) { Help(p); return; }
@ -34,17 +38,25 @@ namespace MCGalaxy.Commands.Moderation {
if (args.Length == 1) { Help(p); return; }
CreateZone(p, args, 1);
} else if (args[0].CaselessEq("del")) {
Player.Message(p, "Place a block where you would like to delete a zone.");
p.MakeSelection(1, null, DeleteZone);
if (args.Length == 1) { Help(p); return; }
DeleteZone(p, args);
} else if (args[0].CaselessEq("edit")) {
if (args.Length < 3) { Help(p); return; }
EditZone(p, args);
} else {
CreateZone(p, args, 0);
}
}
void CreateZone(Player p, string[] args, int offset) {
Zone z = new Zone(p.level);
if (p.level.FindZoneExact(args[offset]) != null) {
Player.Message(p, "A zone with that name already exists. Use %T/zedit %Sto change it.");
return;
}
Zone z = new Zone(p.level);
z.Config.Name = args[offset];
PermissionCmd.Do(p, args, offset + 1, false, z.Access);
if (!PermissionCmd.Do(p, args, offset + 1, false, z.Access)) return;
Player.Message(p, "Creating zone " + z.ColoredName);
Player.Message(p, "Place or break two blocks to determine the edges.");
@ -52,47 +64,60 @@ namespace MCGalaxy.Commands.Moderation {
}
bool AddZone(Player p, Vec3S32[] marks, object state, ExtBlock block) {
Zone z = (Zone)state;
z.MinX = (ushort)Math.Min(marks[0].X, marks[1].X);
z.MinY = (ushort)Math.Min(marks[0].Y, marks[1].Y);
z.MinZ = (ushort)Math.Min(marks[0].Z, marks[1].Z);
z.MaxX = (ushort)Math.Max(marks[0].X, marks[1].X);
z.MaxY = (ushort)Math.Max(marks[0].Y, marks[1].Y);
z.MaxZ = (ushort)Math.Max(marks[0].Z, marks[1].Z);
Zone zone = (Zone)state;
zone.MinX = (ushort)Math.Min(marks[0].X, marks[1].X);
zone.MinY = (ushort)Math.Min(marks[0].Y, marks[1].Y);
zone.MinZ = (ushort)Math.Min(marks[0].Z, marks[1].Z);
zone.MaxX = (ushort)Math.Max(marks[0].X, marks[1].X);
zone.MaxY = (ushort)Math.Max(marks[0].Y, marks[1].Y);
zone.MaxZ = (ushort)Math.Max(marks[0].Z, marks[1].Z);
p.level.Zones.Add(z);
p.level.Zones.Add(zone);
p.level.Save(true);
Player.Message(p, "Created zone " + z.ColoredName);
return false;
}
bool DeleteZone(Player p, Vec3S32[] marks, object state, ExtBlock block) {
Level lvl = p.level;
bool foundDel = false;
Vec3S32 P = marks[0];
for (int i = 0; i < lvl.Zones.Count; i++) {
Zone zn = lvl.Zones[i];
if (P.X < zn.MinX || P.X > zn.MaxX || P.Y < zn.MinY || P.Y > zn.MaxY || P.Z < zn.MinZ || P.Z > zn.MaxZ) continue;
if (!zn.Access.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot delete this zone.");
continue;
}
lvl.Zones.RemoveAt(i); i--;
Player.Message(p, "Zone " + zn.ColoredName + " %sdeleted");
foundDel = true;
}
if (!foundDel) Player.Message(p, "No zones found to delete.");
Player.Message(p, "Created zone " + zone.ColoredName);
return false;
}
void DeleteZone(Player p, string[] args) {
Level lvl = p.level;
Zone zone = Matcher.FindZones(p, lvl, args[1]);
if (zone == null) return;
if (!zone.Access.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot delete this zone."); return;
}
lvl.Zones.Remove(zone);
Player.Message(p, "Zone " + zone.ColoredName + " %Sdeleted");
lvl.Save();
}
void EditZone(Player p, string[] args) {
Level lvl = p.level;
Zone zone = Matcher.FindZones(p, lvl, args[1]);
if (zone == null) return;
if (!zone.Access.CheckDetailed(p)) {
Player.Message(p, "Hence, you cannot edit this zone."); return;
}
if (args[2].CaselessEq("col")) {
ColorDesc desc = default(ColorDesc);
if (!CommandParser.GetHex(p, args[3], ref desc)) return;
zone.Config.ShowColor = args[3];
zone.ShowAll(lvl);
} else if (args[2].CaselessEq("alpha")) {
if (!CommandParser.GetByte(p, args[3], "Alpha", ref zone.Config.ShowAlpha)) return;
zone.ShowAll(lvl);
} else if (!PermissionCmd.Do(p, args, 2, false, zone.Access)) {
return;
}
lvl.Save(true);
}
public override void Help(Player p) {
Player.Message(p, "%T/Zone add [name] %H- Creates a zone only [name] can build in");
Player.Message(p, "%T/Zone add [rank] %H- Creates a zone only [rank]+ can build in");
Player.Message(p, "%T/Zone del %H- Deletes the zone clicked");
Player.Message(p, "%T/Zone add [name] %H- Creates a new zone");
Player.Message(p, "%T/Zone del [name] %H- Deletes the given zone");
Player.Message(p, "%T/Zone edit [name] [args] %H- Edits/Updates the given zone");
}
}

View File

@ -24,19 +24,22 @@ namespace MCGalaxy.Commands.World {
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public static void Do(Player p, string[] args, int offset, bool max, AccessController access) {
public static bool Do(Player p, string[] args, int offset, bool max, AccessController access) {
for (int i = offset; i < args.Length; i++) {
string arg = args[i];
if (arg[0] == '+' || arg[0] == '-') {
SetList(p, access, arg);
if (!SetList(p, access, arg)) return false;
} else if (max) {
Group grp = Matcher.FindRanks(p, arg);
if (grp != null) access.SetMax(p, grp);
if (grp == null) return false;
access.SetMax(p, grp);
} else {
Group grp = Matcher.FindRanks(p, arg);
if (grp != null) access.SetMin(p, grp);
if (grp == null) return false;
access.SetMin(p, grp);
}
}
return true;
}
protected void DoLevel(Player p, string message, bool visit) {
@ -58,20 +61,21 @@ namespace MCGalaxy.Commands.World {
Do(p, args, offset, max, access);
}
static void SetList(Player p, AccessController access, string name) {
static bool SetList(Player p, AccessController access, string name) {
bool include = name[0] == '+';
string mode = include ? "whitelist" : "blacklist";
name = name.Substring(1);
if (name.Length == 0) {
Player.Message(p, "You must provide a player name to {0}.", mode); return;
Player.Message(p, "You must provide a player name to {0}.", mode);
return false;
}
if (!Formatter.ValidName(p, name, "player")) return;
if (!Formatter.ValidName(p, name, "player")) return false;
name = PlayerInfo.FindMatchesPreferOnline(p, name);
if (name == null) return;
if (name == null) return false;
if (p != null && name.CaselessEq(p.name)) {
Player.Message(p, "You cannot {0} yourself.", mode); return;
Player.Message(p, "You cannot {0} yourself.", mode); return false;
}
if (include) {
@ -79,8 +83,8 @@ namespace MCGalaxy.Commands.World {
} else {
access.Blacklist(p, name);
}
}
return true;
}
protected void ShowHelp(Player p, string action, string action2) {
Player.Message(p, "%T/{0} [level] [rank]", name);
@ -93,12 +97,12 @@ namespace MCGalaxy.Commands.World {
Player.Message(p, "%HPrevents [name] from {0}ing, even if their rank can.", action2);
}
}
public sealed class CmdPermissionBuild : PermissionCmd {
public override string name { get { return "PerBuild"; } }
public override string shortcut { get { return "WBuild"; } }
public override CommandAlias[] Aliases {
get { return new[] { new CommandAlias("WBuild"), new CommandAlias("WorldBuild"),
new CommandAlias("PerBuildMax", "-max") }; }
get { return new[] { new CommandAlias("WorldBuild"), new CommandAlias("PerBuildMax", "-max") }; }
}
public override CommandPerm[] ExtraPerms {
get { return new[] { new CommandPerm(LevelPermission.Operator, "+ bypasses max build rank restriction") }; }
@ -110,9 +114,9 @@ namespace MCGalaxy.Commands.World {
public sealed class CmdPermissionVisit : PermissionCmd {
public override string name { get { return "PerVisit"; } }
public override string shortcut { get { return "WAccess"; } }
public override CommandAlias[] Aliases {
get { return new[] { new CommandAlias("WAccess"), new CommandAlias("WorldAccess"),
new CommandAlias("PerVisitMax", "-max") }; }
get { return new[] { new CommandAlias("WorldAccess"), new CommandAlias("PerVisitMax", "-max") }; }
}
public override CommandPerm[] ExtraPerms {
get { return new[] { new CommandPerm(LevelPermission.Operator, "+ bypasses max visit rank restriction") }; }
@ -120,5 +124,5 @@ namespace MCGalaxy.Commands.World {
public override void Use(Player p, string message) { DoLevel(p, message, true); }
public override void Help(Player p) { ShowHelp(p, "visit", "visit"); }
}
}
}

View File

@ -56,6 +56,11 @@ namespace MCGalaxy.Core {
p.SendCurrentEnvColors();
p.SendCurrentMapAppearance();
p.SendCurrentBlockPermissions();
// TODO: unshow old zones here??
if (p.Supports(CpeExt.SelectionCuboid)) {
foreach (Zone zn in level.Zones) { zn.Show(p); }
}
if (!level.Config.Guns && p.aiming) {
p.aiming = false;

View File

@ -228,8 +228,9 @@ namespace MCGalaxy {
Update();
Logger.Log(LogType.UserActivity, "{0} rank changed to {1} on {2}.", type, grp.Name, lvl.name);
Chat.MessageLevel(lvl, type + " rank changed to " + grp.ColoredName + "%S.");
if (p != null && p.level != lvl)
if (p != null && p.level != lvl) {
Player.Message(p, "{0} rank changed to {1} %Son {2}%S.", type, grp.ColoredName, ColoredName);
}
}
public override void OnListChanged(Player p, string name, bool whitelist, bool removedFromOpposite) {
@ -244,8 +245,9 @@ namespace MCGalaxy {
Update();
Logger.Log(LogType.UserActivity, "{0} on {1}", msg, lvl.name);
Chat.MessageLevel(lvl, msg);
if (p != null && p.level != lvl)
if (p != null && p.level != lvl) {
Player.Message(p, "{0} on %S{1}", msg, ColoredName);
}
}

View File

@ -159,6 +159,8 @@ namespace MCGalaxy.Levels.IO {
string line = Encoding.UTF8.GetString(buffer, 0, size), key, value;
PropertiesFile.ParseLine(line, '=', out key, out value);
if (key == null) continue;
value = value.Trim();
ConfigElement.Parse(elems, key, value, z.Config);
}

View File

@ -103,6 +103,13 @@ namespace MCGalaxy {
if (Config.MOTD != "ignore") return Config.MOTD;
return String.IsNullOrEmpty(p.group.MOTD) ? ServerConfig.MOTD : p.group.MOTD;
}
public Zone FindZoneExact(string name) {
foreach (Zone zone in Zones) {
if (zone.Config.Name.CaselessEq(name)) return zone;
}
return null;
}
/// <summary> Whether block changes made on this level should be saved to the BlockDB and .lvl files. </summary>
public bool ShouldSaveChanges() {

View File

@ -18,16 +18,22 @@
using System;
using System.Collections.Generic;
using MCGalaxy.Config;
using MCGalaxy.Network;
using MCGalaxy.Maths;
namespace MCGalaxy {
public sealed class ZoneConfig : AreaConfig {
[ConfigString("Name", "General", "", true)]
public string Name = "";
[ConfigString("ShowColor", "General", "", true)]
public string ShowColor = "";
[ConfigByte("ShowAlpha", "General", 0)]
public byte ShowAlpha = 0;
public string Color { get { return Group.GetColor(BuildMin); } }
}
}
/// <summary> Encapuslates build access permissions for a zone. </summary>
public sealed class ZoneAccessController : AccessController {
@ -47,7 +53,7 @@ namespace MCGalaxy {
get { return cfg.BuildMax; } set { cfg.BuildMax = value; }
}
public override List<string> Whitelisted { get { return cfg.BuildWhitelist; } }
public override List<string> Whitelisted { get { return cfg.BuildWhitelist; } }
public override List<string> Blacklisted { get { return cfg.BuildBlacklist; } }
protected override string ColoredName { get { return "zone " + cfg.Color + cfg.Name; } }
@ -59,9 +65,10 @@ namespace MCGalaxy {
public override void OnPermissionChanged(Player p, Group grp, string type) {
Update();
Logger.Log(LogType.UserActivity, "{0} rank changed to {1} in zone {2}.", type, grp.Name, cfg.Name);
Chat.MessageLevel(lvl, type + " rank changed to " + grp.ColoredName + "%S.");
if (p != null && p.level != lvl)
Chat.MessageLevel(lvl, type + " rank changed to " + grp.ColoredName + " %Sin zone " + cfg.Color + cfg.Name);
if (p != null && p.level != lvl) {
Player.Message(p, "{0} rank changed to {1} %Sin {2}%S.", type, grp.ColoredName, ColoredName);
}
}
public override void OnListChanged(Player p, string name, bool whitelist, bool removedFromOpposite) {
@ -74,10 +81,11 @@ namespace MCGalaxy {
Update();
Logger.Log(LogType.UserActivity, "{0} in zone {1}", msg, cfg.Name);
Chat.MessageLevel(lvl, msg);
if (p != null && p.level != lvl)
Chat.MessageLevel(lvl, msg + " in zone " + cfg.Color + cfg.Name);
if (p != null && p.level != lvl) {
Player.Message(p, "{0} in %S{1}", msg, ColoredName);
}
}
}
void Update() { lvl.Save(true); }
}
@ -85,6 +93,7 @@ namespace MCGalaxy {
public class Zone {
public ushort MinX, MinY, MinZ;
public ushort MaxX, MaxY, MaxZ;
public byte ID;
public ZoneConfig Config;
public ZoneAccessController Access;
@ -95,10 +104,28 @@ namespace MCGalaxy {
}
public bool CoversMap(Level lvl) {
return MinX == 0 && MinY == 0 && MinZ == 0 &&
return MinX == 0 && MinY == 0 && MinZ == 0 &&
MaxX == lvl.Width - 1 && MaxY == lvl.Height - 1 && MaxZ == lvl.Length - 1;
}
public bool Shows { get { return Config.ShowAlpha != 0 && Config.ShowColor != ""; } }
public void Show(Player p) {
if (!p.Supports(CpeExt.SelectionCuboid) || !Shows) return;
ColorDesc col = Colors.ParseHex(Config.ShowColor);
p.Send(Packet.MakeSelection(
ID, "", new Vec3U16(MinX, MinY, MinZ),
new Vec3U16((ushort)(MaxX + 1), (ushort)(MaxY + 1), (ushort)(MaxZ + 1)),
col.R, col.G, col.B, Config.ShowAlpha, p.hasCP437));
}
public void ShowAll(Level lvl) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
if (p.level == lvl) Show(p);
}
}
public Zone(Level lvl) {
Config = new ZoneConfig();
Access = new ZoneAccessController(lvl, Config);

View File

@ -87,6 +87,13 @@ namespace MCGalaxy {
null, wp => wp.Name, group);
}
/// <summary> Find partial matches of 'name' against the list of zones in a map. </summary>
public static Zone FindZones(Player p, Level lvl, string name) {
int matches = 0;
return Find<Zone>(p, name, out matches, lvl.Zones,
null, z => z.Config.Name, "zones");
}
/// <summary> Finds partial matches of 'name' against the names of the items in the 'items' enumerable. </summary>
/// <returns> If exactly one match, the matching item. </returns>