First step of rewriting zones. (also, maps made using /eco level now set realm owner and build perms)

This commit is contained in:
UnknownShadow200 2018-01-28 07:47:17 +11:00
parent 0d10747695
commit 9e2ca5e683
17 changed files with 409 additions and 328 deletions

View File

@ -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<Level.Zone> 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;
}

View File

@ -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.");
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -26,13 +26,10 @@ namespace MCGalaxy {
/// <summary> Lowest allowed rank. </summary>
public abstract LevelPermission Min { get; set; }
/// <summary> Highest allowed rank. </summary>
public abstract LevelPermission Max { get; set; }
/// <summary> List of always allowed players, overrides rank allowances. </summary>
public abstract List<string> Whitelisted { get; }
/// <summary> List of never allowed players, ignores rank allowances. </summary>
public abstract List<string> Blacklisted { get; }
@ -218,7 +215,6 @@ namespace MCGalaxy {
IsVisit = isVisit;
}
/// <summary> Lowest allowed rank. </summary>
public override LevelPermission Min {
get { return IsVisit ? cfg.VisitMin : cfg.BuildMin; }
set {
@ -227,7 +223,6 @@ namespace MCGalaxy {
}
}
/// <summary> Highest allowed rank. </summary>
public override LevelPermission Max {
get { return IsVisit ? cfg.VisitMax : cfg.BuildMax; }
set {
@ -236,12 +231,10 @@ namespace MCGalaxy {
}
}
/// <summary> List of always allowed players, overrides rank allowances. </summary>
public override List<string> Whitelisted {
get { return IsVisit ? cfg.VisitWhitelist : cfg.BuildWhitelist; }
}
/// <summary> List of never allowed players, ignores rank allowances. </summary>
public override List<string> Blacklisted {
get { return IsVisit ? cfg.VisitBlacklist : cfg.BuildBlacklist; }
}

View File

@ -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<Check> items,
byte[] buffer, byte* ptr) {
static void WritePhysicsEntries(Stream gs, FastList<Check> 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<Zone> 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);
}
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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,22 +193,41 @@ 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);
}
}
/// <summary> Returns: <br/>

View File

@ -75,7 +75,7 @@ namespace MCGalaxy {
BufferedBlockSender bulkSender;
public List<UndoPos> UndoBuffer = new List<UndoPos>();
public List<Zone> ZoneList;
public List<Zone> Zones;
public bool backedup;
public BlockDB BlockDB;
public LevelAccessController VisitAccess, BuildAccess;

View File

@ -73,7 +73,7 @@ namespace MCGalaxy {
spawnz = (ushort)(Length / 2);
rotx = 0; roty = 0;
ZoneList = new List<Zone>();
Zones = new List<Zone>();
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) {
@ -440,12 +440,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;
return CustomBlockDefs[block.RawID] != BlockDefinition.GlobalDefs[block.RawID];

View File

@ -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);
}
}
}

View File

@ -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<string> BuildWhitelist = new List<string>();
[ConfigStringList("BuildBlacklist", "Permissions")]
public List<string> BuildBlacklist = new List<string>();
// Env settings
[ConfigString("Texture", "Env", "", true, null, NetUtils.StringSize)]
public string Terrain = "";
[ConfigString("TexturePack", "Env", "", true, null, NetUtils.StringSize)]
public string TexturePack = "";
/// <summary> Color of the clouds (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("CloudColor", "Env", "", true)]
public string CloudColor = "";
/// <summary> Color of the fog (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("FogColor", "Env", "", true)]
public string FogColor = "";
/// <summary> Color of the sky (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("SkyColor", "Env", "", true)]
public string SkyColor = "";
/// <summary> Color of the blocks in shadows (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("ShadowColor", "Env", "", true)]
public string ShadowColor = "";
/// <summary> Color of the blocks in the light (RGB packed into an int). Set to -1 to use client defaults. </summary>
[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)]
@ -54,25 +94,6 @@ namespace MCGalaxy {
// 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 = "";
/// <summary> Color of the clouds (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("CloudColor", "Env", "", true)]
public string CloudColor = "";
/// <summary> Color of the fog (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("FogColor", "Env", "", true)]
public string FogColor = "";
/// <summary> Color of the sky (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("SkyColor", "Env", "", true)]
public string SkyColor = "";
/// <summary> Color of the blocks in shadows (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("ShadowColor", "Env", "", true)]
public string ShadowColor = "";
/// <summary> Color of the blocks in the light (RGB packed into an int). Set to -1 to use client defaults. </summary>
[ConfigString("LightColor", "Env", "", true)]
public string LightColor = "";
/// <summary> Elevation of the "ocean" that surrounds maps. Default is map height / 2. </summary>
[ConfigInt("EdgeLevel", "Env", -1, short.MinValue, short.MaxValue)]
@ -109,36 +130,23 @@ namespace MCGalaxy {
/// <summary> The block which will be displayed on the edge of the map. </summary>
[ConfigByte("EdgeBlock", "Env", Block.Bedrock)]
public byte EdgeBlock = Block.Bedrock;
/// <summary> Whether exponential fog mode is used client-side. </summary>
/// <summary> Whether exponential fog mode is used client-side. </summary>
[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<string> VisitWhitelist = new List<string>();
[ConfigStringList("VisitBlacklist", "Permissions")]
public List<string> VisitBlacklist = new List<string>();
[ConfigStringList("BuildWhitelist", "Permissions")]
public List<string> BuildWhitelist = new List<string>();
[ConfigStringList("BuildBlacklist", "Permissions")]
public List<string> BuildBlacklist = new List<string>();
// Physics settings
[ConfigInt("Physics", "Physics", 0, 0, 5)]

View File

@ -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),
};
}
}

104
MCGalaxy/Levels/Zone.cs Normal file
View File

@ -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); } }
}
/// <summary> Encapuslates build access permissions for a zone. </summary>
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<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; } }
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;
}
}
}

View File

@ -575,6 +575,7 @@
<Compile Include="Blocks\Physics\TrainPhysics.cs" />
<Compile Include="Blocks\Physics\TntPhysics.cs" />
<Compile Include="Blocks\Physics\ZombiePhysics.cs" />
<Compile Include="Levels\Zone.cs" />
<Compile Include="Network\Heartbeat\ClassiCube.cs" />
<Compile Include="Network\Heartbeat\Heartbeat.cs" />
<Compile Include="Network\IRCPlugin\IRCBot.cs" />

View File

@ -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;

View File

@ -249,7 +249,6 @@ namespace MCGalaxy.Tasks {
}
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) {
}
}
}