mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 03:55:18 -04:00
First step of rewriting zones. (also, maps made using /eco level now set realm owner and build perms)
This commit is contained in:
parent
0d10747695
commit
9e2ca5e683
@ -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;
|
||||
}
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -25,14 +25,11 @@ namespace MCGalaxy {
|
||||
public abstract class AccessController {
|
||||
|
||||
/// <summary> Lowest allowed rank. </summary>
|
||||
public abstract LevelPermission Min { get; set; }
|
||||
|
||||
public abstract LevelPermission Min { get; set; }
|
||||
/// <summary> Highest allowed rank. </summary>
|
||||
public abstract LevelPermission Max { get; set; }
|
||||
|
||||
public abstract LevelPermission Max { get; set; }
|
||||
/// <summary> List of always allowed players, overrides rank allowances. </summary>
|
||||
public abstract List<string> Whitelisted { get; }
|
||||
|
||||
public abstract List<string> Whitelisted { get; }
|
||||
/// <summary> List of never allowed players, ignores rank allowances. </summary>
|
||||
public abstract List<string> Blacklisted { get; }
|
||||
|
||||
@ -217,8 +214,7 @@ namespace MCGalaxy {
|
||||
this.lvlName = levelName;
|
||||
IsVisit = isVisit;
|
||||
}
|
||||
|
||||
/// <summary> Lowest allowed rank. </summary>
|
||||
|
||||
public override LevelPermission Min {
|
||||
get { return IsVisit ? cfg.VisitMin : cfg.BuildMin; }
|
||||
set {
|
||||
@ -226,8 +222,7 @@ namespace MCGalaxy {
|
||||
else cfg.BuildMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Highest allowed rank. </summary>
|
||||
|
||||
public override LevelPermission Max {
|
||||
get { return IsVisit ? cfg.VisitMax : cfg.BuildMax; }
|
||||
set {
|
||||
@ -235,13 +230,11 @@ namespace MCGalaxy {
|
||||
else cfg.BuildMax = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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; }
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the block at the given coordinates. </summary>
|
||||
/// <returns> Block.Invalid if coordinates outside map. </returns>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Gets whether the block at the given coordinates is air. </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Gets whether the block at the given coordinates is air. </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns: <br/>
|
||||
/// <summary> Returns: <br/>
|
||||
/// 0 - block change was not performed <br/>
|
||||
/// 1 - old block was same as new block visually (e.g. white to door_white)<br/>
|
||||
/// 2 - old block was different to new block visually </summary>
|
||||
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
@ -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 = "";
|
||||
/// <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 byte Weather;
|
||||
|
||||
/// <summary> Elevation of the "ocean" that surrounds maps. Default is map height / 2. </summary>
|
||||
[ConfigInt("EdgeLevel", "Env", -1, short.MinValue, short.MaxValue)]
|
||||
@ -109,37 +130,24 @@ 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)]
|
||||
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)]
|
||||
|
@ -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
104
MCGalaxy/Levels/Zone.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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" />
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user