From 9e2ca5e6830336e6ebc755ba2abc0a1d2f7cc6b6 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 28 Jan 2018 07:47:17 +1100 Subject: [PATCH] First step of rewriting zones. (also, maps made using /eco level now set realm owner and build perms) --- MCGalaxy/Commands/Moderation/CmdZone.cs | 124 ++++++------------ .../Commands/World/CmdOverseer.SubCommands.cs | 47 ++++--- MCGalaxy/Config/PropertiesFile.cs | 27 ++-- MCGalaxy/Economy/LevelItem.cs | 14 +- MCGalaxy/Levels/AccessController.cs | 21 +-- MCGalaxy/Levels/IO/Exporters/LvlExporter.cs | 38 +++++- MCGalaxy/Levels/IO/Importers/LvlImporter.cs | 60 ++++++++- MCGalaxy/Levels/Level.Blocks.cs | 106 ++++++--------- MCGalaxy/Levels/Level.Fields.cs | 2 +- MCGalaxy/Levels/Level.cs | 24 ++-- MCGalaxy/Levels/LevelActions.cs | 4 - MCGalaxy/Levels/LevelConfig.cs | 88 +++++++------ MCGalaxy/Levels/LevelDB.cs | 67 ++++------ MCGalaxy/Levels/Zone.cs | 104 +++++++++++++++ MCGalaxy/MCGalaxy_.csproj | 1 + MCGalaxy/Server/Server.cs | 3 +- MCGalaxy/Server/Tasks/UpgradeTasks.cs | 7 +- 17 files changed, 409 insertions(+), 328 deletions(-) create mode 100644 MCGalaxy/Levels/Zone.cs diff --git a/MCGalaxy/Commands/Moderation/CmdZone.cs b/MCGalaxy/Commands/Moderation/CmdZone.cs index 82df2868f..e816f0c90 100644 --- a/MCGalaxy/Commands/Moderation/CmdZone.cs +++ b/MCGalaxy/Commands/Moderation/CmdZone.cs @@ -32,9 +32,6 @@ namespace MCGalaxy.Commands.Moderation { new CommandPerm(LevelPermission.Operator, "+ can create zones"), }; } } - public override CommandAlias[] Aliases { - get { return new[] { new CommandAlias("OZone", "map"), new CommandAlias("oz", "map") }; } - } public override void Use(Player p, string message) { string[] args = message.SplitSpaces(); @@ -47,65 +44,23 @@ namespace MCGalaxy.Commands.Moderation { Player.Message(p, "Place or break two blocks to determine the edges."); Player.Message(p, "Zone for: &b" + args[1] + "."); p.MakeSelection(2, args[1], AddZone); - } else if (args[0].CaselessEq("map")) { - if (!CheckAdd(p, args, "Zone map")) return; - - ZoneAll(p.level, args[1]); - Player.Message(p, "Added zone for &b" + args[1]); - } else if (args[0].CaselessEq("del") && args.Length > 1 && args[1].CaselessEq("all")) { - if (!CheckExtraPerm(p, 2)) return; - DeleteAll(p); } else if (args[0].CaselessEq("del")) { if (!CheckExtraPerm(p, 1)) return; - if (p.canBuild) { //Checks if player can build there - Player.Message(p, "Place a block where you would like to delete a zone."); - p.MakeSelection(1, null, DeleteZone); - } else { //if they cant, it warns them, the ops and logs it on the server! - Player.Message(p, "You can't delete a zone which is above your rank!"); - Chat.MessageOps(p.name + " tried to delete a zone that is above their rank!"); - Logger.Log(LogType.SuspiciousActivity, "{0} tried to delete a zone that is above their rank!", p.name); - } + Player.Message(p, "Place a block where you would like to delete a zone."); + p.MakeSelection(1, null, DeleteZone); } else if (args[0].CaselessEq("list")) { string modifier = args.Length > 1 ? args[1] : ""; - MultiPageOutput.Output(p, p.level.ZoneList, FormatZone, "Zone list", "zones", modifier, true); + MultiPageOutput.Output(p, p.level.Zones, FormatZone, "Zone list", "zones", modifier, true); } else { Help(p); } } - static string FormatZone(Level.Zone zone) { - return "&b(" + zone.MinX + ", " + zone.MinY + ", " + zone.MinZ - + ") to (" + zone.MaxX + ", " + zone.MaxY + ", " + zone.MaxZ + ") &F" + zone.Owner; - } - - internal static void ZoneAll(Level lvl, string owner) { - Level.Zone zn = default(Level.Zone); - zn.MaxX = (ushort)(lvl.Width - 1); - zn.MaxY = (ushort)(lvl.Height - 1); - zn.MaxZ = (ushort)(lvl.Length - 1); - zn.Owner = owner; - - lvl.ZoneList.Add(zn); - LevelDB.CreateZone(lvl.name, zn); - } - - internal static void DeleteAll(Player p) { - DeleteWhere(p, zone => true); - } - - internal static void DeleteWhere(Player p, Predicate filter) { - int count = p.level.ZoneList.Count, removed = 0; - for (int i = count - 1; i >= 0; i--) { - Level.Zone zone = p.level.ZoneList[i]; - if (!filter(zone)) continue; - LevelDB.DeleteZone(p.level.name, zone); - - removed++; - Player.Message(p, "Zone deleted for &b" + zone.Owner); - p.level.ZoneList.Remove(p.level.ZoneList[i]); - } - Player.Message(p, "Removed {0} zone{1}.", removed, count == 1 ? "s" : ""); + static string FormatZone(Zone zone) { + return zone.ColoredName + + " &b- (" + zone.MinX + ", " + zone.MinY + ", " + zone.MinZ + + ") to (" + zone.MaxX + ", " + zone.MaxY + ", " + zone.MaxZ + ")"; } bool CheckAdd(Player p, string[] args, string cmd) { @@ -120,8 +75,20 @@ namespace MCGalaxy.Commands.Moderation { bool CheckZone(Player p, Vec3S32[] marks, object state, ExtBlock block) { Vec3S32 P = marks[0]; - string zoneMsg = p.level.FindZoneOwners(p, (ushort)P.X, (ushort)P.Y, (ushort)P.Z); - Player.Message(p, zoneMsg); + Level lvl = p.level; + bool found = false; + + for (int i = 0; i < lvl.Zones.Count; i++) { + Zone z = lvl.Zones[i]; + if (!z.Contains(P.X, P.Y, P.Z)) continue; + found = true; + + AccessResult status = z.Acess.Check(p); + bool allowed = status == AccessResult.Allowed || status == AccessResult.Whitelisted; + Player.Message(p, " Zone {0} %S- {1}{2}", z.ColoredName, allowed ? "&a" : "&c", status ); + } + + if (!found) { Player.Message(p, "No zones affect this block."); } return true; } @@ -130,29 +97,17 @@ namespace MCGalaxy.Commands.Moderation { bool foundDel = false; Vec3S32 P = marks[0]; - for (int i = 0; i < lvl.ZoneList.Count; i++) { - Level.Zone zn = lvl.ZoneList[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; + 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.Owner.Length >= 3 && zn.Owner.StartsWith("grp")) { - Group group = Group.Find(zn.Owner.Substring(3)); - if (group != null && p.Rank < group.Permission) { - Player.Message(p, "Cannot delete zone for rank {0}", group.ColoredName); - continue; - } - } else if (zn.Owner.Length > 0 && !zn.Owner.CaselessEq(p.name)) { - Group group = Group.GroupIn(zn.Owner); - if (p.Rank < group.Permission) { - Player.Message(p, "Cannot delete zone for {0} %S- they are ranked {1}", - PlayerInfo.GetColoredName(p, zn.Owner), group.ColoredName); - continue; - } + if (!zn.Acess.CheckDetailed(p)) { + Player.Message(p, "Hence, you cannot delete this zone."); + continue; } - LevelDB.DeleteZone(lvl.name, zn); - lvl.ZoneList.RemoveAt(i); i--; - Player.Message(p, "Zone deleted for &b" + zn.Owner); + lvl.Zones.RemoveAt(i); i--; + Player.Message(p, "Zone " + zn.ColoredName + " %sdeleted"); foundDel = true; } @@ -161,17 +116,18 @@ namespace MCGalaxy.Commands.Moderation { } bool AddZone(Player p, Vec3S32[] marks, object state, ExtBlock block) { - Level.Zone Zn; - Zn.MinX = (ushort)Math.Min(marks[0].X, marks[1].X); - Zn.MinY = (ushort)Math.Min(marks[0].Y, marks[1].Y); - Zn.MinZ = (ushort)Math.Min(marks[0].Z, marks[1].Z); - Zn.MaxX = (ushort)Math.Max(marks[0].X, marks[1].X); - Zn.MaxY = (ushort)Math.Max(marks[0].Y, marks[1].Y); - Zn.MaxZ = (ushort)Math.Max(marks[0].Z, marks[1].Z); - Zn.Owner = (string)state; + Zone z = Zone.Create(); + 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); + z.Owner = (string)state; + z.Config.Name = state + state; - p.level.ZoneList.Add(Zn); - LevelDB.CreateZone(p.level.name, Zn); + p.level.Zones.Add(z); + p.level.Save(true); Player.Message(p, "Added zone for &b" + (string)state); return false; } diff --git a/MCGalaxy/Commands/World/CmdOverseer.SubCommands.cs b/MCGalaxy/Commands/World/CmdOverseer.SubCommands.cs index 0c420842f..bd68b5c7e 100644 --- a/MCGalaxy/Commands/World/CmdOverseer.SubCommands.cs +++ b/MCGalaxy/Commands/World/CmdOverseer.SubCommands.cs @@ -162,7 +162,12 @@ namespace MCGalaxy.Commands.World { args = (level + " " + value).SplitSpaces(); Level lvl = newLvl.GenerateMap(p, args); if (lvl == null) return; - SetPerms(p, lvl); + + if (SetPerms(p, lvl)) { + Group grp = Group.Find(ServerConfig.OSPerbuildDefault); + Player.Message(p, "Use %T/os zone add [name] %Sto allow " + + "players ranked below " + grp.ColoredName + " %Sto build in the map."); + } try { lvl.Save(true); @@ -172,18 +177,16 @@ namespace MCGalaxy.Commands.World { } } - static void SetPerms(Player p, Level lvl) { + internal static bool SetPerms(Player p, Level lvl) { lvl.Config.RealmOwner = p.name; lvl.BuildAccess.Whitelist(null, p.name); lvl.VisitAccess.Whitelist(null, p.name); - - LevelPermission osPerm = ServerConfig.OSPerbuildDefault; - Group grp = Group.Find(osPerm); - if (grp == null) return; + + Group grp = Group.Find(ServerConfig.OSPerbuildDefault); + if (grp == null) return false; lvl.BuildAccess.SetMin(null, grp); - Player.Message(p, "Use %T/os zone add [name] %Sto allow " + - "players ranked below " + grp.ColoredName + " %Sto build in the map."); + return true; } static void DeleteMap(Player p, string value) { @@ -244,18 +247,13 @@ namespace MCGalaxy.Commands.World { } } - static void AddBuildPlayer(Player p, string name) { - string[] zoneArgs = name.SplitSpaces(); - name = zoneArgs[0]; - string reason = zoneArgs.Length > 1 ? zoneArgs[1] : ""; - name = CmdZone.FindZoneOwner(p, "os zone add", name, ref reason); + static void AddBuildPlayer(Player p, string rawArgs) { + string[] args = rawArgs.SplitSpaces(); + string reason = args.Length > 1 ? args[1] : ""; + string name = ModActionCmd.FindName(p, "zone", "os zone add", "", args[0], ref reason); if (name == null) return; - if (p.level.ZoneList.Count > 0) { - CmdZone.ZoneAll(p.level, name); - } Player.Message(p, "Added zone for &b" + name); - LevelAccessController access = p.level.BuildAccess; if (access.Blacklisted.CaselessRemove(name)) { access.OnListChanged(p, name, true, true); @@ -267,14 +265,13 @@ namespace MCGalaxy.Commands.World { } static void DeleteBuildPlayer(Player p, string name) { - if (name.CaselessEq("all")) { - CmdZone.DeleteAll(p); - } else if (Formatter.ValidName(p, name, "player")) { - CmdZone.DeleteWhere(p, zone => zone.Owner.CaselessEq(name)); - LevelAccessController access = p.level.BuildAccess; - if (access.Whitelisted.CaselessRemove(name)) { - access.OnListChanged(p, name, false, true); - } + if (!Formatter.ValidName(p, name, "player")) return; + + LevelAccessController access = p.level.BuildAccess; + if (access.Whitelisted.CaselessRemove(name)) { + access.OnListChanged(p, name, false, true); + } else { + Player.Message(p, name + " was not whitelisted."); } } diff --git a/MCGalaxy/Config/PropertiesFile.cs b/MCGalaxy/Config/PropertiesFile.cs index 354feca43..cb144afe0 100644 --- a/MCGalaxy/Config/PropertiesFile.cs +++ b/MCGalaxy/Config/PropertiesFile.cs @@ -39,15 +39,13 @@ namespace MCGalaxy { if (!File.Exists(path)) return false; using (StreamReader reader = new StreamReader(path)) { - string line; + string line, key, value; while ((line = reader.ReadLine()) != null) { - int index = ParseLine(line, path, separator); - if (index == -1) continue; - - string key = line.Substring(0, index), value = line.Substring(index + 1); - if (trimValue) value = value.Trim(); - + ParseLine(line, separator, out key, out value); + if (key == null) continue; + try { + if (trimValue) value = value.Trim(); processor(key.Trim(), value, ref state); } catch (Exception ex) { Logger.LogError(ex); @@ -58,14 +56,15 @@ namespace MCGalaxy { return true; } - static int ParseLine(string line, string path, char separator) { - if (line.Length == 0 || line[0] == '#') return -1; + internal static void ParseLine(string line, char separator, out string key, out string value) { + key = null; value = null; + if (line.Length == 0 || line[0] == '#') return; + int index = line.IndexOf(separator); - if (index == -1) { - Logger.Log(LogType.Warning, "Line \"{0}\" in {1} is missing a value", line, path); - return -1; - } - return index; + if (index == -1) return; + + key = line.Substring(0, index).Trim(); + value = line.Substring(index + 1); } } } diff --git a/MCGalaxy/Economy/LevelItem.cs b/MCGalaxy/Economy/LevelItem.cs index 5af000d94..4f0ed029a 100644 --- a/MCGalaxy/Economy/LevelItem.cs +++ b/MCGalaxy/Economy/LevelItem.cs @@ -90,21 +90,11 @@ namespace MCGalaxy.Eco { CmdLoad.LoadLevel(null, name); Level level = LevelInfo.FindExact(name); - if (level.BuildAccess.Min > p.Rank) level.BuildAccess.Min = p.Rank; - if (level.VisitAccess.Min > p.Rank) level.VisitAccess.Min = p.Rank; + CmdOverseer.SetPerms(p, level); + Level.SaveSettings(level); PlayerActions.ChangeMap(p, name); Player.Message(p, "%aSuccessfully created your map: '%f" + name + "%a'"); - try { - Level.Zone zn = default(Level.Zone); - zn.MaxX = (ushort)(level.Width - 1); - zn.MaxY = (ushort)(level.Height - 1); - zn.MaxZ = (ushort)(level.Length - 1); - zn.Owner = p.name; - level.ZoneList.Add(zn); - LevelDB.CreateZone(level.name, zn); - Player.Message(p, "%aZoning Succesful"); - } catch { Player.Message(p, "%cZoning Failed"); } } catch { Player.Message(p, "%cSomething went wrong, Money untouched"); return; } diff --git a/MCGalaxy/Levels/AccessController.cs b/MCGalaxy/Levels/AccessController.cs index 2c2046c4b..ac0069153 100644 --- a/MCGalaxy/Levels/AccessController.cs +++ b/MCGalaxy/Levels/AccessController.cs @@ -25,14 +25,11 @@ namespace MCGalaxy { public abstract class AccessController { /// Lowest allowed rank. - public abstract LevelPermission Min { get; set; } - + public abstract LevelPermission Min { get; set; } /// Highest allowed rank. - public abstract LevelPermission Max { get; set; } - + public abstract LevelPermission Max { get; set; } /// List of always allowed players, overrides rank allowances. - public abstract List Whitelisted { get; } - + public abstract List Whitelisted { get; } /// List of never allowed players, ignores rank allowances. public abstract List Blacklisted { get; } @@ -217,8 +214,7 @@ namespace MCGalaxy { this.lvlName = levelName; IsVisit = isVisit; } - - /// Lowest allowed rank. + public override LevelPermission Min { get { return IsVisit ? cfg.VisitMin : cfg.BuildMin; } set { @@ -226,8 +222,7 @@ namespace MCGalaxy { else cfg.BuildMin = value; } } - - /// Highest allowed rank. + public override LevelPermission Max { get { return IsVisit ? cfg.VisitMax : cfg.BuildMax; } set { @@ -235,13 +230,11 @@ namespace MCGalaxy { else cfg.BuildMax = value; } } - - /// List of always allowed players, overrides rank allowances. + public override List Whitelisted { get { return IsVisit ? cfg.VisitWhitelist : cfg.BuildWhitelist; } } - - /// List of never allowed players, ignores rank allowances. + public override List Blacklisted { get { return IsVisit ? cfg.VisitBlacklist : cfg.BuildBlacklist; } } diff --git a/MCGalaxy/Levels/IO/Exporters/LvlExporter.cs b/MCGalaxy/Levels/IO/Exporters/LvlExporter.cs index c7418b34c..3fb33256c 100644 --- a/MCGalaxy/Levels/IO/Exporters/LvlExporter.cs +++ b/MCGalaxy/Levels/IO/Exporters/LvlExporter.cs @@ -16,15 +16,17 @@ permissions and limitations under the Licenses. */ using System; +using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Text; using MCGalaxy.Util; namespace MCGalaxy.Levels.IO { //WARNING! DO NOT CHANGE THE WAY THE LEVEL IS SAVED/LOADED! //You MUST make it able to save and load as a new version other wise you will make old levels incompatible! - public sealed class LvlExporter : IMapExporter { + public unsafe sealed class LvlExporter : IMapExporter { public override string Extension { get { return ".lvl"; } } @@ -40,6 +42,7 @@ namespace MCGalaxy.Levels.IO { WriteBlocksSection(lvl, gs, buffer); WriteBlockDefsSection(lvl, gs, buffer); WritePhysicsSection(lvl, gs, buffer); + WriteZonesSection(lvl, gs, buffer); } } @@ -87,7 +90,7 @@ namespace MCGalaxy.Levels.IO { } } - unsafe static void WritePhysicsSection(Level lvl, Stream gs, byte[] buffer) { + static void WritePhysicsSection(Level lvl, Stream gs, byte[] buffer) { lock (lvl.physStepLock) { // Count the number of physics checks with extra info int used = 0, count = lvl.ListCheck.Count; @@ -108,8 +111,7 @@ namespace MCGalaxy.Levels.IO { } } - unsafe static void WritePhysicsEntries(Stream gs, FastList items, - byte[] buffer, byte* ptr) { + static void WritePhysicsEntries(Stream gs, FastList items, byte[] buffer, byte* ptr) { Check[] checks = items.Items; int entries = 0, count = items.Count; int* ptrInt = (int*)ptr; @@ -133,5 +135,33 @@ namespace MCGalaxy.Levels.IO { if (entries == 0) return; gs.Write(buffer, 0, entries * 8); } + + static void WriteZonesSection(Level lvl, Stream gs, byte[] buffer) { + List zones = lvl.Zones; + if (zones.Count == 0) return; + + gs.WriteByte(0x51); + NetUtils.WriteI32(zones.Count, buffer, 0); + gs.Write(buffer, 0, sizeof(int)); + + foreach (Zone z in zones) { + NetUtils.WriteU16(z.MinX, buffer, 0 * 2); NetUtils.WriteU16(z.MaxX, buffer, 1 * 2); + NetUtils.WriteU16(z.MinY, buffer, 2 * 2); NetUtils.WriteU16(z.MaxY, buffer, 3 * 2); + NetUtils.WriteU16(z.MinZ, buffer, 4 * 2); NetUtils.WriteU16(z.MaxZ, buffer, 5 * 2); + gs.Write(buffer, 0, 6 * 2); + + // Write all metadata of the zone + ConfigElement[] elem = Server.zoneConfig; + NetUtils.WriteI32(elem.Length, buffer, 0); + gs.Write(buffer, 0, sizeof(int)); + + for (int i = 0; i < elem.Length; i++) { + string value = elem[i].Format(z.Config); + int count = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, 2); + NetUtils.WriteU16((ushort)count, buffer, 0); + gs.Write(buffer, 0, count + 2); + } + } + } } } \ No newline at end of file diff --git a/MCGalaxy/Levels/IO/Importers/LvlImporter.cs b/MCGalaxy/Levels/IO/Importers/LvlImporter.cs index 7eaea4a27..bd5b843de 100644 --- a/MCGalaxy/Levels/IO/Importers/LvlImporter.cs +++ b/MCGalaxy/Levels/IO/Importers/LvlImporter.cs @@ -18,13 +18,14 @@ using System; using System.IO; using System.IO.Compression; +using System.Text; using MCGalaxy.Maths; namespace MCGalaxy.Levels.IO { //WARNING! DO NOT CHANGE THE WAY THE LEVEL IS SAVED/LOADED! //You MUST make it able to save and load as a new version other wise you will make old levels incompatible! - public sealed class LvlImporter : IMapImporter { + public unsafe sealed class LvlImporter : IMapImporter { public override string Extension { get { return ".lvl"; } } @@ -55,9 +56,12 @@ namespace MCGalaxy.Levels.IO { for (;;) { int section = gs.ReadByte(); - if (section == 0xFC) { + if (section == 0xFC) { // 'ph'ysics 'c'hecks ReadPhysicsSection(lvl, gs); continue; } + if (section == 0x51) { // 'z'one 'l'ist + ReadZonesSection(lvl, gs); continue; + } return lvl; } } @@ -102,18 +106,17 @@ namespace MCGalaxy.Levels.IO { } } - unsafe static void ReadPhysicsSection(Level lvl, Stream gs) { + static void ReadPhysicsSection(Level lvl, Stream gs) { byte[] buffer = new byte[sizeof(int)]; - int read = gs.Read(buffer, 0, sizeof(int)); - if (read < sizeof(int)) return; + int count = TryRead_I32(buffer, gs); + if (count == 0) return; - int count = NetUtils.ReadI32(buffer, 0); lvl.ListCheck.Count = count; lvl.ListCheck.Items = new Check[count]; ReadPhysicsEntries(lvl, gs, count); } - unsafe static void ReadPhysicsEntries(Level lvl, Stream gs, int count) { + static void ReadPhysicsEntries(Level lvl, Stream gs, int count) { byte[] buffer = new byte[Math.Min(count, 1024) * 8]; Check C; @@ -132,5 +135,48 @@ namespace MCGalaxy.Levels.IO { } } } + + static void ReadZonesSection(Level lvl, Stream gs) { + byte[] buffer = new byte[sizeof(int)]; + int count = TryRead_I32(buffer, gs); + if (count == 0) return; + + for (int i = 0; i < count; i++) { + Zone z = Zone.Create(); + if (!TryRead_U16(buffer, gs, ref z.MinX) || !TryRead_U16(buffer, gs, ref z.MaxX)) return; + if (!TryRead_U16(buffer, gs, ref z.MinY) || !TryRead_U16(buffer, gs, ref z.MaxY)) return; + if (!TryRead_U16(buffer, gs, ref z.MinZ) || !TryRead_U16(buffer, gs, ref z.MaxZ)) return; + + int metaCount = TryRead_I32(buffer, gs); + ConfigElement[] elems = Server.zoneConfig; + + for (int j = 0; j < metaCount; j++) { + ushort size = 0; + if (!TryRead_U16(buffer, gs, ref size)) return; + if (size > buffer.Length) buffer = new byte[size + 16]; + gs.Read(buffer, 0, size); + + string line = Encoding.UTF8.GetString(buffer, 0, size), key, value; + PropertiesFile.ParseLine(line, '=', out key, out value); + if (key == null) continue; + ConfigElement.Parse(elems, key, value, z.Config); + } + + lvl.Zones.Add(z); + } + } + + static int TryRead_I32(byte[] buffer, Stream gs) { + int read = gs.Read(buffer, 0, sizeof(int)); + if (read < sizeof(int)) return 0; + return NetUtils.ReadI32(buffer, 0); + } + + static bool TryRead_U16(byte[] buffer, Stream gs, ref ushort value) { + int read = gs.Read(buffer, 0, sizeof(ushort)); + if (read < sizeof(ushort)) return false; + value = NetUtils.ReadU16(buffer, 0); + return true; + } } } \ No newline at end of file diff --git a/MCGalaxy/Levels/Level.Blocks.cs b/MCGalaxy/Levels/Level.Blocks.cs index 3f78af2e5..839468a26 100644 --- a/MCGalaxy/Levels/Level.Blocks.cs +++ b/MCGalaxy/Levels/Level.Blocks.cs @@ -54,7 +54,7 @@ namespace MCGalaxy { block.BlockID = blocks[x + Width * (z + y * Length)]; block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.Air; return block; - } + } /// Gets the block at the given coordinates. /// Block.Invalid if coordinates outside map. @@ -66,14 +66,14 @@ namespace MCGalaxy { block.BlockID = blocks[index]; block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.Air; return block; - } - + } + /// Gets whether the block at the given coordinates is air. public bool IsAirAt(ushort x, ushort y, ushort z) { - if (x >= Width || y >= Height || z >= Length || blocks == null) return false; + if (x >= Width || y >= Height || z >= Length || blocks == null) return false; return blocks[x + Width * (z + y * Length)] == Block.Air; } - + /// Gets whether the block at the given coordinates is air. public bool IsAirAt(ushort x, ushort y, ushort z, out int index) { if (x >= Width || y >= Height || z >= Length || blocks == null) { index = -1; return false; } @@ -88,7 +88,7 @@ namespace MCGalaxy { } public byte GetExtTile(ushort x, ushort y, ushort z) { - if (x >= Width || y >= Height || z >= Length || blocks == null) + if (x >= Width || y >= Height || z >= Length || blocks == null) return Block.Invalid; int cx = x >> 4, cy = y >> 4, cz = z >> 4; @@ -159,7 +159,7 @@ namespace MCGalaxy { public void RevertExtTileNoCheck(ushort x, ushort y, ushort z) { int cx = x >> 4, cy = y >> 4, cz = z >> 4; - int cIndex = (cy * ChunksZ + cz) * ChunksX + cx; + int cIndex = (cy * ChunksZ + cz) * ChunksX + cx; byte[] chunk = CustomBlocks[cIndex]; if (chunk == null) return; @@ -185,49 +185,6 @@ namespace MCGalaxy { return true; } - bool CheckZonePerms(Player p, ushort x, ushort y, ushort z, ref bool inZone) { - bool zoneAllow = true; - for (int i = 0; i < ZoneList.Count; i++) { - Zone zn = ZoneList[i]; - if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ) - continue; - - inZone = true; - if (zn.Owner.Length >= 3 && zn.Owner.StartsWith("grp")) { - Group grp = Group.Find(zn.Owner.Substring(3)); - if (grp != null && grp.Permission <= p.Rank) return true; - } else { - if (zn.Owner.CaselessEq(p.name)) return true; - } - zoneAllow = false; - } - - if (zoneAllow) return true; - if (p.ZoneSpam > DateTime.UtcNow) return false; - - Player.Message(p, FindZoneOwners(p, x, y, z)); - p.ZoneSpam = DateTime.UtcNow.AddSeconds(2); - return false; - } - - internal string FindZoneOwners(Player p, ushort x, ushort y, ushort z) { - string owners = ""; - for (int i = 0; i < ZoneList.Count; i++) { - Zone zn = ZoneList[i]; - if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ) - continue; - - if (zn.Owner.Length >= 3 && zn.Owner.StartsWith("grp")) { - owners += ", " + Group.GetColoredName(zn.Owner.Substring(3)); - } else { - owners += ", " + PlayerInfo.GetColoredName(p, zn.Owner); - } - } - - if (owners.Length == 0) return "No zones affect this block"; - return "This zone belongs to " + owners.Remove(0, 2) + "."; - } - bool CheckRank(Player p) { if (p.ZoneSpam <= DateTime.UtcNow) { BuildAccess.CheckDetailed(p); @@ -236,25 +193,44 @@ namespace MCGalaxy { if (p.level == this) return p.AllowBuild; AccessResult access = BuildAccess.Check(p); - return access == AccessResult.Whitelisted - || access == AccessResult.Allowed; + return access == AccessResult.Whitelisted || access == AccessResult.Allowed; } public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z, ExtBlock old, ExtBlock block) { if (!p.group.Blocks[old.BlockID] && !Block.AllowBreak(old.BlockID) && !Block.BuildIn(old.BlockID)) return false; if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref block.BlockID)) return false; + if (Zones.Count == 0) return CheckRank(p); - bool inZone = false; - if (ZoneList.Count > 0 && !CheckZonePerms(p, x, y, z, ref inZone)) return false; - return inZone || CheckRank(p); + // Check zones specifically allowed in + for (int i = 0; i < Zones.Count; i++) { + Zone zn = Zones[i]; + if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ) continue; + AccessResult access = zn.Acess.Check(p); + if (access == AccessResult.Allowed || access == AccessResult.Whitelisted) return true; + } + + // Check zones denied from + for (int i = 0; i < Zones.Count; i++) { + Zone zn = Zones[i]; + if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ) continue; + AccessResult access = zn.Acess.Check(p); + if (access == AccessResult.Allowed || access == AccessResult.Whitelisted) continue; + + if (p.ZoneSpam > DateTime.UtcNow) return false; + zn.Acess.CheckDetailed(p); + p.ZoneSpam = DateTime.UtcNow.AddSeconds(2); + return false; + } + return CheckRank(p); } public void Blockchange(Player p, ushort x, ushort y, ushort z, ExtBlock block) { - if (DoBlockchange(p, x, y, z, block) == 2) + if (DoBlockchange(p, x, y, z, block) == 2) { Player.GlobalBlockchange(this, x, y, z, block); + } } - /// Returns:
+ /// Returns:
/// 0 - block change was not performed
/// 1 - old block was same as new block visually (e.g. white to door_white)
/// 2 - old block was different to new block visually
@@ -279,11 +255,11 @@ namespace MCGalaxy { p.SessionModified++; p.TotalModified++; - + if (drawn) p.TotalDrawn++; else if (block.BlockID == Block.Air) p.TotalDeleted++; else p.TotalPlaced++; - + errorLocation = "Setting tile"; SetTile(x, y, z, block.BlockID); if (old.BlockID == Block.custom_block && block.BlockID != Block.custom_block) @@ -302,7 +278,7 @@ namespace MCGalaxy { } catch (Exception e) { Logger.LogError(e); Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName + ", %Sat location: " + errorLocation); - Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}", + Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}", p.name, ColoredName, errorLocation); return 0; } @@ -317,13 +293,13 @@ namespace MCGalaxy { AddCheck(b, false, args); } - public void Blockchange(int b, ExtBlock block, bool overRide = false, + public void Blockchange(int b, ExtBlock block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), bool addUndo = true) { //Block change made by physics if (DoPhysicsBlockchange(b, block, overRide, data, addUndo)) Player.GlobalBlockchange(this, b, block); } - public void Blockchange(ushort x, ushort y, ushort z, ExtBlock block, bool overRide = false, + public void Blockchange(ushort x, ushort y, ushort z, ExtBlock block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), bool addUndo = true) { Blockchange(PosToInt(x, y, z), block, overRide, data, addUndo); //Block change made by physics } @@ -332,7 +308,7 @@ namespace MCGalaxy { Blockchange(PosToInt(x, y, z), block, false, default(PhysicsArgs)); //Block change made by physics } - internal bool DoPhysicsBlockchange(int b, ExtBlock block, bool overRide = false, + internal bool DoPhysicsBlockchange(int b, ExtBlock block, bool overRide = false, PhysicsArgs data = default(PhysicsArgs), bool addUndo = true) { if (blocks == null || b < 0 || b >= blocks.Length) return false; ExtBlock old; @@ -342,7 +318,7 @@ namespace MCGalaxy { try { if (!overRide) { - if (Props[old.Index].OPBlock || (Props[block.Index].OPBlock && data.Raw != 0)) + if (Props[old.Index].OPBlock || (Props[block.Index].OPBlock && data.Raw != 0)) return false; } @@ -377,7 +353,7 @@ namespace MCGalaxy { ushort x, y, z; IntToPos(b, out x, out y, out z); RevertExtTileNoCheck(x, y, z); - } + } if (physics > 0 && (ActivatesPhysics(block) || data.Raw != 0)) AddCheck(b, false, data); diff --git a/MCGalaxy/Levels/Level.Fields.cs b/MCGalaxy/Levels/Level.Fields.cs index 18cbe7ea6..08e678dde 100644 --- a/MCGalaxy/Levels/Level.Fields.cs +++ b/MCGalaxy/Levels/Level.Fields.cs @@ -75,7 +75,7 @@ namespace MCGalaxy { BufferedBlockSender bulkSender; public List UndoBuffer = new List(); - public List ZoneList; + public List Zones; public bool backedup; public BlockDB BlockDB; public LevelAccessController VisitAccess, BuildAccess; diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index a81d9f1e9..c3c348a5f 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -73,7 +73,7 @@ namespace MCGalaxy { spawnz = (ushort)(Length / 2); rotx = 0; roty = 0; - ZoneList = new List(); + Zones = new List(); VisitAccess = new LevelAccessController(this, true); BuildAccess = new LevelAccessController(this, false); listCheckExists = new SparseBitSet(Width, Height, Length); @@ -89,7 +89,7 @@ namespace MCGalaxy { ListUpdate.Clear(); listUpdateExists.Clear(); UndoBuffer.Clear(); BlockDB.Cache.Clear(); - ZoneList.Clear(); + Zones.Clear(); lock (queueLock) blockqueue.Clear(); @@ -221,22 +221,20 @@ namespace MCGalaxy { return x >= Width || y >= Height || z >= Length || !listCheckExists.Get(x, y, z); } - public void Save(bool Override = false, bool clearPhysics = false) { - if (blocks == null || IsMuseum) return; // museums do not save properties + public bool Save(bool force = false, bool clearPhysics = false) { + if (blocks == null || IsMuseum) return false; // museums do not save properties string path = LevelInfo.MapPath(MapName); OnLevelSaveEvent.Call(this); - if (cancelsave) { cancelsave = false; return; } + if (cancelsave) { cancelsave = false; return false; } try { if (!Directory.Exists("levels")) Directory.CreateDirectory("levels"); if (!Directory.Exists("levels/level properties")) Directory.CreateDirectory("levels/level properties"); if (!Directory.Exists("levels/prev")) Directory.CreateDirectory("levels/prev"); - if (Changed || !File.Exists(path) || Override || (physicschanged && clearPhysics)) { - lock (saveLock) - SaveCore(path); - + if (Changed || !File.Exists(path) || force || (physicschanged && clearPhysics)) { + lock (saveLock) SaveCore(path); if (clearPhysics) ClearPhysics(); } else { Logger.Log(LogType.SystemActivity, "Skipping level save for " + name + "."); @@ -245,8 +243,10 @@ namespace MCGalaxy { Logger.Log(LogType.Warning, "FAILED TO SAVE :" + name); Chat.MessageGlobal("FAILED TO SAVE {0}", ColoredName); Logger.LogError(e); + return false; } Server.DoGC(); + return true; } void SaveCore(string path) { @@ -439,12 +439,6 @@ namespace MCGalaxy { } } } - - public struct Zone { - public string Owner; - public ushort MaxX, MaxY, MaxZ; - public ushort MinX, MinY, MinZ; - } internal bool HasCustomProps(ExtBlock block) { if (block.IsPhysicsType) return false; diff --git a/MCGalaxy/Levels/LevelActions.cs b/MCGalaxy/Levels/LevelActions.cs index 731360cac..81fb84808 100644 --- a/MCGalaxy/Levels/LevelActions.cs +++ b/MCGalaxy/Levels/LevelActions.cs @@ -240,10 +240,6 @@ namespace MCGalaxy { Database.Backend.CreateTable("Messages" + dst, LevelDB.createMessages); Database.Backend.CopyAllRows("Messages" + src, "Messages" + dst); } - if (Database.TableExists("Zone" + src)) { - Database.Backend.CreateTable("Zone" + dst, LevelDB.createZones); - Database.Backend.CopyAllRows("Zone" + src, "Zone" + dst); - } } } diff --git a/MCGalaxy/Levels/LevelConfig.cs b/MCGalaxy/Levels/LevelConfig.cs index 60909039e..6b86e8b73 100644 --- a/MCGalaxy/Levels/LevelConfig.cs +++ b/MCGalaxy/Levels/LevelConfig.cs @@ -22,10 +22,50 @@ using MCGalaxy.Config; using MCGalaxy.Games; namespace MCGalaxy { - public sealed class LevelConfig { - + public abstract class AreaConfig { [ConfigString("MOTD", "General", "ignore", true, null, 128)] public string MOTD = "ignore"; + + // Permission settings + [ConfigBool("Buildable", "Permissions", true)] + public bool Buildable = true; + [ConfigBool("Deletable", "Permissions", true)] + public bool Deletable = true; + + [ConfigPerm("PerBuild", "Permissions", LevelPermission.Guest)] + public LevelPermission BuildMin = LevelPermission.Guest; + [ConfigPerm("PerBuildMax", "Permissions", LevelPermission.Nobody)] + public LevelPermission BuildMax = LevelPermission.Nobody; + + // Other blacklists/whitelists + [ConfigStringList("BuildWhitelist", "Permissions")] + public List BuildWhitelist = new List(); + [ConfigStringList("BuildBlacklist", "Permissions")] + public List BuildBlacklist = new List(); + + // Env settings + [ConfigString("Texture", "Env", "", true, null, NetUtils.StringSize)] + public string Terrain = ""; + [ConfigString("TexturePack", "Env", "", true, null, NetUtils.StringSize)] + public string TexturePack = ""; + /// Color of the clouds (RGB packed into an int). Set to -1 to use client defaults. + [ConfigString("CloudColor", "Env", "", true)] + public string CloudColor = ""; + /// Color of the fog (RGB packed into an int). Set to -1 to use client defaults. + [ConfigString("FogColor", "Env", "", true)] + public string FogColor = ""; + /// Color of the sky (RGB packed into an int). Set to -1 to use client defaults. + [ConfigString("SkyColor", "Env", "", true)] + public string SkyColor = ""; + /// Color of the blocks in shadows (RGB packed into an int). Set to -1 to use client defaults. + [ConfigString("ShadowColor", "Env", "", true)] + public string ShadowColor = ""; + /// Color of the blocks in the light (RGB packed into an int). Set to -1 to use client defaults. + [ConfigString("LightColor", "Env", "", true)] + public string LightColor = ""; + } + + public sealed class LevelConfig : AreaConfig { [ConfigBool("LoadOnGoto", "General", true)] public bool LoadOnGoto = true; [ConfigString("Theme", "General", "Normal", true)] @@ -49,30 +89,11 @@ namespace MCGalaxy { [ConfigInt("JailY", "Jail", 0, 0, 65535)] public int JailY; [ConfigInt("JailZ", "Jail", 0, 0, 65535)] - public int JailZ; + public int JailZ; // Environment settings [ConfigByte("Weather", "Env", 0, 0, 2)] - public byte Weather; - [ConfigString("Texture", "Env", "", true, null, NetUtils.StringSize)] - public string Terrain = ""; - [ConfigString("TexturePack", "Env", "", true, null, NetUtils.StringSize)] - public string TexturePack = ""; - /// Color of the clouds (RGB packed into an int). Set to -1 to use client defaults. - [ConfigString("CloudColor", "Env", "", true)] - public string CloudColor = ""; - /// Color of the fog (RGB packed into an int). Set to -1 to use client defaults. - [ConfigString("FogColor", "Env", "", true)] - public string FogColor = ""; - /// Color of the sky (RGB packed into an int). Set to -1 to use client defaults. - [ConfigString("SkyColor", "Env", "", true)] - public string SkyColor = ""; - /// Color of the blocks in shadows (RGB packed into an int). Set to -1 to use client defaults. - [ConfigString("ShadowColor", "Env", "", true)] - public string ShadowColor = ""; - /// Color of the blocks in the light (RGB packed into an int). Set to -1 to use client defaults. - [ConfigString("LightColor", "Env", "", true)] - public string LightColor = ""; + public byte Weather; /// Elevation of the "ocean" that surrounds maps. Default is map height / 2. [ConfigInt("EdgeLevel", "Env", -1, short.MinValue, short.MaxValue)] @@ -109,37 +130,24 @@ namespace MCGalaxy { /// The block which will be displayed on the edge of the map. [ConfigByte("EdgeBlock", "Env", Block.Bedrock)] public byte EdgeBlock = Block.Bedrock; - /// Whether exponential fog mode is used client-side. + /// Whether exponential fog mode is used client-side. [ConfigBool("ExpFog", "Env", false)] public bool ExpFog; // Permission settings [ConfigString("RealmOwner", "Permissions", "", true)] public string RealmOwner = ""; - [ConfigBool("Buildable", "Permissions", true)] - public bool Buildable = true; - [ConfigBool("Deletable", "Permissions", true)] - public bool Deletable = true; - [ConfigPerm("PerVisit", "Permissions", LevelPermission.Guest)] public LevelPermission VisitMin = LevelPermission.Guest; [ConfigPerm("PerVisitMax", "Permissions", LevelPermission.Nobody)] public LevelPermission VisitMax = LevelPermission.Nobody; - [ConfigPerm("PerBuild", "Permissions", LevelPermission.Guest)] - public LevelPermission BuildMin = LevelPermission.Guest; - [ConfigPerm("PerBuildMax", "Permissions", LevelPermission.Nobody)] - public LevelPermission BuildMax = LevelPermission.Nobody; - + // Other blacklists/whitelists [ConfigStringList("VisitWhitelist", "Permissions")] public List VisitWhitelist = new List(); [ConfigStringList("VisitBlacklist", "Permissions")] public List VisitBlacklist = new List(); - [ConfigStringList("BuildWhitelist", "Permissions")] - public List BuildWhitelist = new List(); - [ConfigStringList("BuildBlacklist", "Permissions")] - public List BuildBlacklist = new List(); - + // Physics settings [ConfigInt("Physics", "Physics", 0, 0, 5)] public int Physics; @@ -174,7 +182,7 @@ namespace MCGalaxy { [ConfigBool("Survival death", "Survival", false)] public bool SurvivalDeath; [ConfigBool("Killer blocks", "Survival", true)] - public bool KillerBlocks = true; + public bool KillerBlocks = true; // Games settings [ConfigInt("Likes", "Game", 0)] diff --git a/MCGalaxy/Levels/LevelDB.cs b/MCGalaxy/Levels/LevelDB.cs index e0cf773d1..ef3fdaa4b 100644 --- a/MCGalaxy/Levels/LevelDB.cs +++ b/MCGalaxy/Levels/LevelDB.cs @@ -30,7 +30,7 @@ namespace MCGalaxy { using (IDisposable wLock = lvl.BlockDB.Locker.AccquireWrite(60 * 1000)) { if (wLock == null) { - Logger.Log(LogType.Warning, "Couldn't accquire BlockDB write lock on {0}, skipping save", lvl.name); + Logger.Log(LogType.Warning, "Couldn't accquire BlockDB write lock on {0}, skipping save", lvl.name); return; } lvl.BlockDB.WriteEntries(); @@ -40,19 +40,36 @@ namespace MCGalaxy { internal static void LoadZones(Level level, string name) { if (!Database.TableExists("Zone" + name)) return; + int id = 0; + object ; // add to map perbuild.combine and modularise perbuild cmds using (DataTable table = Database.Backend.GetRows("Zone" + name, "*")) { - Level.Zone Zn; foreach (DataRow row in table.Rows) { - Zn.MinX = ushort.Parse(row["SmallX"].ToString()); - Zn.MinY = ushort.Parse(row["SmallY"].ToString()); - Zn.MinZ = ushort.Parse(row["SmallZ"].ToString()); - Zn.MaxX = ushort.Parse(row["BigX"].ToString()); - Zn.MaxY = ushort.Parse(row["BigY"].ToString()); - Zn.MaxZ = ushort.Parse(row["BigZ"].ToString()); - Zn.Owner = row["Owner"].ToString(); - level.ZoneList.Add(Zn); + Zone z = Zone.Create(); + z.MinX = ushort.Parse(row["SmallX"].ToString()); + z.MinY = ushort.Parse(row["SmallY"].ToString()); + z.MinZ = ushort.Parse(row["SmallZ"].ToString()); + z.MaxX = ushort.Parse(row["BigX"].ToString()); + z.MaxY = ushort.Parse(row["BigY"].ToString()); + z.MaxZ = ushort.Parse(row["BigZ"].ToString()); + + string owner = row["Owner"].ToString(); + if (owner.StartsWith("grp")) { + Group grp = Group.Find(owner.Substring(3)); + if (grp != null) z.Config.BuildMin = grp.Permission; + } else { + z.Config.BuildWhitelist.Add(owner); + z.Config.BuildMin = LevelPermission.Admin; + } + + z.Config.Name = "Zone" + id; + id++; + level.Zones.Add(z); } } + + if (level.Zones.Count > 0 && !level.Save(true)) return; + Database.Backend.DeleteTable("Zone" + name); + Logger.Log(LogType.SystemActivity, "Upgraded zones for map " + name); } internal static void LoadPortals(Level level, string name) { @@ -91,26 +108,6 @@ namespace MCGalaxy { } } - public static void DeleteZone(string level, Level.Zone zn) { - object locker = ThreadSafeCache.DBCache.GetLocker(level); - lock (locker) { - if (!Database.TableExists("Zone" + level)) return; - Database.Backend.DeleteRows("Zone" + level, "WHERE Owner=@0 AND SmallX=@1 AND SMALLY=@2 " + - "AND SMALLZ=@3 AND BIGX=@4 AND BIGY=@5 AND BIGZ=@6", - zn.Owner, zn.MinX, zn.MinY, zn.MinZ, zn.MaxX, zn.MaxY, zn.MaxZ); - } - } - - public static void CreateZone(string level, Level.Zone zn) { - object locker = ThreadSafeCache.DBCache.GetLocker(level); - lock (locker) { - Database.Backend.CreateTable("Zone" + level, LevelDB.createZones); - Database.Backend.AddRow("Zone" + level, "Owner, SmallX, SmallY, SmallZ, BigX, BigY, BigZ", - zn.Owner, zn.MinX, zn.MinY, zn.MinZ, zn.MaxX, zn.MaxY, zn.MaxZ); - } - } - - internal static ColumnDesc[] createPortals = new ColumnDesc[] { new ColumnDesc("EntryX", ColumnType.UInt16), new ColumnDesc("EntryY", ColumnType.UInt16), @@ -127,15 +124,5 @@ namespace MCGalaxy { new ColumnDesc("Z", ColumnType.UInt16), new ColumnDesc("Message", ColumnType.Char, 255), }; - - internal static ColumnDesc[] createZones = new ColumnDesc[] { - new ColumnDesc("SmallX", ColumnType.UInt16), - new ColumnDesc("SmallY", ColumnType.UInt16), - new ColumnDesc("SmallZ", ColumnType.UInt16), - new ColumnDesc("BigX", ColumnType.UInt16), - new ColumnDesc("BigY", ColumnType.UInt16), - new ColumnDesc("BigZ", ColumnType.UInt16), - new ColumnDesc("Owner", ColumnType.VarChar, 20), - }; } } \ No newline at end of file diff --git a/MCGalaxy/Levels/Zone.cs b/MCGalaxy/Levels/Zone.cs new file mode 100644 index 000000000..f8b15d0fc --- /dev/null +++ b/MCGalaxy/Levels/Zone.cs @@ -0,0 +1,104 @@ +/* + Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy) + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; +using System.Collections.Generic; +using MCGalaxy.Config; + +namespace MCGalaxy { + + public sealed class ZoneConfig : AreaConfig { + [ConfigString("Name", "General", "", true)] + public string Name = ""; + + public string Color { get { return Group.GetColor(BuildMin); } } + } + + /// Encapuslates build access permissions for a zone. + public sealed class ZoneAccessController : AccessController { + + readonly Level lvl; + readonly ZoneConfig cfg; + + public ZoneAccessController(Level lvl, ZoneConfig cfg) { + this.lvl = lvl; + this.cfg = cfg; + } + + public override LevelPermission Min { + get { return cfg.BuildMin; } set { cfg.BuildMin = value; } + } + + public override LevelPermission Max { + get { return cfg.BuildMax; } set { cfg.BuildMax = value; } + } + + public override List Whitelisted { get { return cfg.BuildWhitelist; } } + public override List Blacklisted { get { return cfg.BuildBlacklist; } } + + protected override string ColoredName { get { return "zone " + cfg.Color + cfg.Name; } } + protected override string Action { get { return "build in"; } } + protected override string ActionIng { get { return "building in"; } } + protected override string Type { get { return "build"; } } + protected override string MaxCmd { get { return null; } } + + 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) + 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) { + string msg = PlayerInfo.GetColoredName(p, name); + if (removedFromOpposite) { + msg += " %Swas removed from the build" + (whitelist ? " blacklist" : " whitelist"); + } else { + msg += " %Swas build" + (whitelist ? " whitelisted" : " blacklisted"); + } + + Update(); + Logger.Log(LogType.UserActivity, "{0} in zone {1}", msg, cfg.Name); + Chat.MessageLevel(lvl, msg); + if (p != null && p.level != lvl) + Player.Message(p, "{0} in %S{1}", msg, ColoredName); + } + + void Update() { lvl.Save(true); } + } + + public struct Zone { + public ushort MinX, MinY, MinZ; + public ushort MaxX, MaxY, MaxZ; + + public ZoneConfig Config; + public ZoneAccessController Acess; + public string ColoredName { get { return Config.Color + Config.Name; } } + + public bool Contains(int x, int y, int z) { + return x >= MinX && x <= MaxX && y >= MinY && y <= MaxY && z >= MinZ && z <= MaxZ; + } + + public static Zone Create() { + Zone zone = new Zone(); + zone.Config = new ZoneConfig(); + zone.Acess = new ZoneAccessController(); + return zone; + } + } +} \ No newline at end of file diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index 90cec692d..f2f26889c 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -575,6 +575,7 @@ + diff --git a/MCGalaxy/Server/Server.cs b/MCGalaxy/Server/Server.cs index 7cf6b5ced..53b0c878a 100644 --- a/MCGalaxy/Server/Server.cs +++ b/MCGalaxy/Server/Server.cs @@ -71,11 +71,12 @@ namespace MCGalaxy { } } - internal static ConfigElement[] serverConfig, levelConfig, zombieConfig; + internal static ConfigElement[] serverConfig, levelConfig, zombieConfig, zoneConfig; public static void Start() { serverConfig = ConfigElement.GetAll(typeof(ServerConfig)); zombieConfig = ConfigElement.GetAll(typeof(ZSConfig)); levelConfig = ConfigElement.GetAll(typeof(LevelConfig)); + zoneConfig = ConfigElement.GetAll(typeof(ZoneConfig)); #pragma warning disable 0618 Player.players = PlayerInfo.Online.list; diff --git a/MCGalaxy/Server/Tasks/UpgradeTasks.cs b/MCGalaxy/Server/Tasks/UpgradeTasks.cs index 04a3c1e9b..69818381f 100644 --- a/MCGalaxy/Server/Tasks/UpgradeTasks.cs +++ b/MCGalaxy/Server/Tasks/UpgradeTasks.cs @@ -248,8 +248,7 @@ namespace MCGalaxy.Tasks { } } - static void UpgradePlayerTimeSpents() { - + static void UpgradePlayerTimeSpents() { using (BulkTransaction bulk = Database.Backend.CreateBulk()) { IDataParameter idParam = bulk.CreateParam("@0", DbType.Int32); IDataParameter secsParam = bulk.CreateParam("@1", DbType.Int64); @@ -268,5 +267,9 @@ namespace MCGalaxy.Tasks { bulk.Commit(); } } + + internal static void UpgradeZones(SchedulerTask task) { + + } } } \ No newline at end of file