mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 03:55:18 -04:00
Initial WIP on having zones show stuff.
This commit is contained in:
parent
d423f067a8
commit
c557b4128c
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"); }
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user