Remove very obsolete methods from Level class

This commit is contained in:
UnknownShadow200 2017-05-22 14:13:05 +10:00 committed by GitHub
parent 8afba63ae6
commit 3ae3e25493

View File

@ -1,20 +1,20 @@
/* /*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy) Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -27,487 +27,478 @@ using MCGalaxy.Games;
using MCGalaxy.Generator; using MCGalaxy.Generator;
using MCGalaxy.Levels.IO; using MCGalaxy.Levels.IO;
using MCGalaxy.Util; using MCGalaxy.Util;
//WARNING! DO NOT CHANGE THE WAY THE LEVEL IS SAVED/LOADED! //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! //You MUST make it able to save and load as a new version other wise you will make old levels incompatible!
namespace MCGalaxy { namespace MCGalaxy {
public enum LevelPermission { public enum LevelPermission {
Banned = -20, Guest = 0, Builder = 30, Banned = -20, Guest = 0, Builder = 30,
AdvBuilder = 50, Operator = 80, AdvBuilder = 50, Operator = 80,
Admin = 100, Nobody = 120, Null = 150 Admin = 100, Nobody = 120, Null = 150
} }
public enum BuildType { Normal, ModifyOnly, NoModify }; public enum BuildType { Normal, ModifyOnly, NoModify };
public sealed partial class Level : IDisposable { public sealed partial class Level : IDisposable {
public Level(string n, ushort x, ushort y, ushort z) { Init(n, x, y, z); } public Level(string n, ushort x, ushort y, ushort z) { Init(n, x, y, z); }
[Obsolete("Use MapGen.Generate instead")] [Obsolete("Use MapGen.Generate instead")]
public Level(string n, ushort x, ushort y, ushort z, string theme, int seed = 0, bool useSeed = false) { public Level(string n, ushort x, ushort y, ushort z, string theme, int seed = 0, bool useSeed = false) {
Init(n, x, y, z); Init(n, x, y, z);
string args = useSeed ? seed.ToString() : ""; string args = useSeed ? seed.ToString() : "";
MapGen.Generate(this, theme, args, null); MapGen.Generate(this, theme, args, null);
} }
[Obsolete("Use MapGen.Generate instead")] [Obsolete("Use MapGen.Generate instead")]
public Level(string n, ushort x, ushort y, ushort z, string theme, string genArgs) { public Level(string n, ushort x, ushort y, ushort z, string theme, string genArgs) {
Init(n, x, y, z); Init(n, x, y, z);
MapGen.Generate(this, theme, genArgs, null); MapGen.Generate(this, theme, genArgs, null);
} }
void Init(string n, ushort x, ushort y, ushort z) { void Init(string n, ushort x, ushort y, ushort z) {
Width = x; Height = y; Length = z; Width = x; Height = y; Length = z;
if (Width < 16) Width = 16; if (Width < 16) Width = 16;
if (Height < 16) Height = 16; if (Height < 16) Height = 16;
if (Length < 16) Length = 16; if (Length < 16) Length = 16;
#pragma warning disable 0612 #pragma warning disable 0612
width = Width; width = Width;
length = Height; length = Height;
height = Length; depth = Length; height = Length; depth = Length;
#pragma warning restore 0612 #pragma warning restore 0612
CustomBlockDefs = new BlockDefinition[256]; CustomBlockDefs = new BlockDefinition[256];
for (int i = 0; i < CustomBlockDefs.Length; i++) for (int i = 0; i < CustomBlockDefs.Length; i++)
CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i]; CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i];
CustomBlockProps = new BlockProps[256]; CustomBlockProps = new BlockProps[256];
for (int i = 0; i < CustomBlockProps.Length; i++) for (int i = 0; i < CustomBlockProps.Length; i++)
CustomBlockProps[i] = BlockDefinition.GlobalProps[i]; CustomBlockProps[i] = BlockDefinition.GlobalProps[i];
name = n; MapName = n.ToLower(); name = n; MapName = n.ToLower();
BlockDB = new BlockDB(this); BlockDB = new BlockDB(this);
EdgeLevel = (short)(y / 2); EdgeLevel = (short)(y / 2);
CloudsHeight = (short)(y + 2); CloudsHeight = (short)(y + 2);
blocks = new byte[Width * Height * Length]; blocks = new byte[Width * Height * Length];
ChunksX = Utils.CeilDiv16(Width); ChunksX = Utils.CeilDiv16(Width);
ChunksY = Utils.CeilDiv16(Height); ChunksY = Utils.CeilDiv16(Height);
ChunksZ = Utils.CeilDiv16(Length); ChunksZ = Utils.CeilDiv16(Length);
CustomBlocks = new byte[ChunksX * ChunksY * ChunksZ][]; CustomBlocks = new byte[ChunksX * ChunksY * ChunksZ][];
spawnx = (ushort)(Width / 2); spawnx = (ushort)(Width / 2);
spawny = (ushort)(Height * 0.75f); spawny = (ushort)(Height * 0.75f);
spawnz = (ushort)(Length / 2); spawnz = (ushort)(Length / 2);
rotx = 0; roty = 0; rotx = 0; roty = 0;
ZoneList = new List<Zone>(); ZoneList = new List<Zone>();
VisitAccess = new LevelAccessController(this, true); VisitAccess = new LevelAccessController(this, true);
BuildAccess = new LevelAccessController(this, false); BuildAccess = new LevelAccessController(this, false);
listCheckExists = new SparseBitSet(Width, Height, Length); listCheckExists = new SparseBitSet(Width, Height, Length);
listUpdateExists = new SparseBitSet(Width, Height, Length); listUpdateExists = new SparseBitSet(Width, Height, Length);
} }
public List<Player> players { get { return getPlayers(); } } public List<Player> players { get { return getPlayers(); } }
public void Dispose() { public void Dispose() {
Extras.Clear(); Extras.Clear();
liquids.Clear(); liquids.Clear();
leaves.Clear(); leaves.Clear();
ListCheck.Clear(); listCheckExists.Clear(); ListCheck.Clear(); listCheckExists.Clear();
ListUpdate.Clear(); listUpdateExists.Clear(); ListUpdate.Clear(); listUpdateExists.Clear();
UndoBuffer.Clear(); UndoBuffer.Clear();
BlockDB.Cache.Clear(); BlockDB.Cache.Clear();
ZoneList.Clear(); ZoneList.Clear();
lock (queueLock) lock (queueLock)
blockqueue.Clear(); blockqueue.Clear();
lock (saveLock) { lock (saveLock) {
blocks = null; blocks = null;
CustomBlocks = null; CustomBlocks = null;
} }
} }
public string GetMotd(Player p) { public string GetMotd(Player p) {
if (motd != "ignore") return motd; if (motd != "ignore") return motd;
return String.IsNullOrEmpty(p.group.MOTD) ? Server.motd : p.group.MOTD; return String.IsNullOrEmpty(p.group.MOTD) ? Server.motd : p.group.MOTD;
} }
/// <summary> Whether block changes made on this level should be /// <summary> Whether block changes made on this level should be
/// saved to the BlockDB and .lvl files. </summary> /// saved to the BlockDB and .lvl files. </summary>
public bool ShouldSaveChanges() { public bool ShouldSaveChanges() {
if (!saveLevel) return false; if (!saveLevel) return false;
ZombieGame zs = Server.zombie; ZombieGame zs = Server.zombie;
if (zs.Running && !ZombieGameProps.SaveLevelBlockchanges && if (zs.Running && !ZombieGameProps.SaveLevelBlockchanges &&
(name.CaselessEq(zs.CurLevelName) || name.CaselessEq(zs.LastLevelName))) (name.CaselessEq(zs.CurLevelName) || name.CaselessEq(zs.LastLevelName)))
return false; return false;
if (Server.lava.active && Server.lava.HasMap(name)) if (Server.lava.active && Server.lava.HasMap(name))
return false; return false;
return true; return true;
} }
public bool ShouldShowJoinMessage(Level prev) { public bool ShouldShowJoinMessage(Level prev) {
ZombieGame zs = Server.zombie; ZombieGame zs = Server.zombie;
if (zs.Running && name.CaselessEq(zs.CurLevelName) && if (zs.Running && name.CaselessEq(zs.CurLevelName) &&
(prev == this || zs.LastLevelName == "" || prev.name.CaselessEq(zs.LastLevelName))) (prev == this || zs.LastLevelName == "" || prev.name.CaselessEq(zs.LastLevelName)))
return false; return false;
if (Server.lava.active && Server.lava.HasMap(name)) if (Server.lava.active && Server.lava.HasMap(name))
return false; return false;
return true; return true;
} }
/// <summary> The currently active game running on this map, /// <summary> The currently active game running on this map,
/// or null if there is no game running. </summary> /// or null if there is no game running. </summary>
public IGame CurrentGame() { public IGame CurrentGame() {
if (Server.zombie.Running && name.CaselessEq(Server.zombie.CurLevelName)) if (Server.zombie.Running && name.CaselessEq(Server.zombie.CurLevelName))
return Server.zombie; return Server.zombie;
if (Server.lava.active && Server.lava.map == this) if (Server.lava.active && Server.lava.map == this)
return Server.lava; return Server.lava;
return null; return null;
} }
public bool CanJoin(Player p, bool ignorePerms = false) { public bool CanJoin(Player p, bool ignorePerms = false) {
if (p == null) return true; if (p == null) return true;
if (!VisitAccess.CheckDetailed(p, ignorePerms)) return false; if (!VisitAccess.CheckDetailed(p, ignorePerms)) return false;
if (Server.lockdown.Contains(name)) { if (Server.lockdown.Contains(name)) {
Player.Message(p, "The level " + name + " is locked."); return false; Player.Message(p, "The level " + name + " is locked."); return false;
} }
return true; return true;
} }
public bool Unload(bool silent = false, bool save = true) { public bool Unload(bool silent = false, bool save = true) {
if (Server.mainLevel == this || IsMuseum) return false; if (Server.mainLevel == this || IsMuseum) return false;
if (Server.lava.active && Server.lava.map == this) return false; if (Server.lava.active && Server.lava.map == this) return false;
if (LevelUnload != null) if (LevelUnload != null)
LevelUnload(this); LevelUnload(this);
OnLevelUnloadEvent.Call(this); OnLevelUnloadEvent.Call(this);
if (cancelunload) { if (cancelunload) {
Server.s.Log("Unload canceled by Plugin! (Map: " + name + ")"); Server.s.Log("Unload canceled by Plugin! (Map: " + name + ")");
cancelunload = false; return false; cancelunload = false; return false;
} }
MovePlayersToMain(); MovePlayersToMain();
if (save && changed && ShouldSaveChanges()) Save(false, true); if (save && changed && ShouldSaveChanges()) Save(false, true);
if (save && ShouldSaveChanges()) saveChanges(); if (save && ShouldSaveChanges()) saveChanges();
if (TntWarsGame.Find(this) != null) { if (TntWarsGame.Find(this) != null) {
foreach (TntWarsGame.player pl in TntWarsGame.Find(this).Players) { foreach (TntWarsGame.player pl in TntWarsGame.Find(this).Players) {
pl.p.CurrentTntGameNumber = -1; pl.p.CurrentTntGameNumber = -1;
Player.Message(pl.p, "TNT Wars: The TNT Wars game you are currently playing has been deleted!"); Player.Message(pl.p, "TNT Wars: The TNT Wars game you are currently playing has been deleted!");
pl.p.PlayingTntWars = false; pl.p.PlayingTntWars = false;
pl.p.canBuild = true; pl.p.canBuild = true;
TntWarsGame.SetTitlesAndColor(pl, true); TntWarsGame.SetTitlesAndColor(pl, true);
} }
Server.s.Log("TNT Wars: Game deleted on " + name); Server.s.Log("TNT Wars: Game deleted on " + name);
TntWarsGame.GameList.Remove(TntWarsGame.Find(this)); TntWarsGame.GameList.Remove(TntWarsGame.Find(this));
} }
MovePlayersToMain(); MovePlayersToMain();
LevelInfo.Loaded.Remove(this); LevelInfo.Loaded.Remove(this);
try { try {
PlayerBot.UnloadFromLevel(this); PlayerBot.UnloadFromLevel(this);
physThread.Abort(); physThread.Abort();
physThread.Join(); physThread.Join();
} catch { } catch {
} finally { } finally {
Dispose(); Dispose();
Server.DoGC(); Server.DoGC();
if (!silent) Chat.MessageOps(ColoredName + " %Swas unloaded."); if (!silent) Chat.MessageOps(ColoredName + " %Swas unloaded.");
Server.s.Log(name + " was unloaded."); Server.s.Log(name + " was unloaded.");
} }
return true; return true;
} }
void MovePlayersToMain() { void MovePlayersToMain() {
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) { foreach (Player p in players) {
if (p.level == this) { if (p.level == this) {
Player.Message(p, "You were moved to the main level as " + ColoredName + " %Swas unloaded."); Player.Message(p, "You were moved to the main level as " + ColoredName + " %Swas unloaded.");
PlayerActions.ChangeMap(p, Server.mainLevel); PlayerActions.ChangeMap(p, Server.mainLevel);
} }
} }
} }
/// <summary> Returns whether the given coordinates are insides the boundaries of this level. </summary> /// <summary> Returns whether the given coordinates are insides the boundaries of this level. </summary>
public bool InBound(ushort x, ushort y, ushort z) { public bool InBound(ushort x, ushort y, ushort z) {
return x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Length; return x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Length;
} }
[Obsolete] [Obsolete]
public static Level Find(string name) { return LevelInfo.Find(name); } public static Level Find(string name) { return LevelInfo.Find(name); }
[Obsolete] [Obsolete]
public static Level FindExact(string name) { return LevelInfo.FindExact(name); } public static Level FindExact(string name) { return LevelInfo.FindExact(name); }
public static void SaveSettings(Level lvl) { public static void SaveSettings(Level lvl) {
if (lvl.IsMuseum) return; // museums do not save properties if (lvl.IsMuseum) return; // museums do not save properties
lock (lvl.savePropsLock) lock (lvl.savePropsLock)
LvlProperties.Save(lvl, LevelInfo.PropertiesPath(lvl.MapName)); LvlProperties.Save(lvl, LevelInfo.PropertiesPath(lvl.MapName));
} }
// Returns true if ListCheck does not already have an check in the position. // Returns true if ListCheck does not already have an check in the position.
// Useful for fireworks, which depend on two physics blocks being checked, one with extraInfo. // Useful for fireworks, which depend on two physics blocks being checked, one with extraInfo.
public bool CheckClear(ushort x, ushort y, ushort z) { public bool CheckClear(ushort x, ushort y, ushort z) {
return x >= Width || y >= Height || z >= Length || !listCheckExists.Get(x, y, z); return x >= Width || y >= Height || z >= Length || !listCheckExists.Get(x, y, z);
} }
public void Save(bool Override = false, bool clearPhysics = false) { public void Save(bool Override = false, bool clearPhysics = false) {
if (blocks == null || IsMuseum) return; // museums do not save properties if (blocks == null || IsMuseum) return; // museums do not save properties
string path = LevelInfo.MapPath(MapName); string path = LevelInfo.MapPath(MapName);
if (LevelSave != null) LevelSave(this); if (LevelSave != null) LevelSave(this);
OnLevelSaveEvent.Call(this); OnLevelSaveEvent.Call(this);
if (cancelsave1) { cancelsave1 = false; return; } if (cancelsave1) { cancelsave1 = false; return; }
if (cancelsave) { cancelsave = false; return; } if (cancelsave) { cancelsave = false; return; }
try { try {
if (!Directory.Exists("levels")) Directory.CreateDirectory("levels"); if (!Directory.Exists("levels")) Directory.CreateDirectory("levels");
if (!Directory.Exists("levels/level properties")) Directory.CreateDirectory("levels/level properties"); if (!Directory.Exists("levels/level properties")) Directory.CreateDirectory("levels/level properties");
if (!Directory.Exists("levels/prev")) Directory.CreateDirectory("levels/prev"); if (!Directory.Exists("levels/prev")) Directory.CreateDirectory("levels/prev");
if (changed || !File.Exists(path) || Override || (physicschanged && clearPhysics)) { if (changed || !File.Exists(path) || Override || (physicschanged && clearPhysics)) {
lock (saveLock) lock (saveLock)
SaveCore(path); SaveCore(path);
if (clearPhysics) ClearPhysics(); if (clearPhysics) ClearPhysics();
} else { } else {
Server.s.Log("Skipping level save for " + name + "."); Server.s.Log("Skipping level save for " + name + ".");
} }
} catch (Exception e) { } catch (Exception e) {
Server.s.Log("FAILED TO SAVE :" + name); Server.s.Log("FAILED TO SAVE :" + name);
Chat.MessageGlobal("FAILED TO SAVE {0}", ColoredName); Chat.MessageGlobal("FAILED TO SAVE {0}", ColoredName);
Server.ErrorLog(e); Server.ErrorLog(e);
} }
Server.DoGC(); Server.DoGC();
} }
void SaveCore(string path) { void SaveCore(string path) {
if (blocks == null) return; if (blocks == null) return;
if (File.Exists(path)) { if (File.Exists(path)) {
string prevPath = LevelInfo.PrevPath(name); string prevPath = LevelInfo.PrevPath(name);
if (File.Exists(prevPath)) File.Delete(prevPath); if (File.Exists(prevPath)) File.Delete(prevPath);
File.Copy(path, prevPath, true); File.Copy(path, prevPath, true);
File.Delete(path); File.Delete(path);
} }
IMapExporter.Formats[0].Write(path + ".backup", this); IMapExporter.Formats[0].Write(path + ".backup", this);
File.Copy(path + ".backup", path); File.Copy(path + ".backup", path);
SaveSettings(this); SaveSettings(this);
Server.s.Log(string.Format("SAVED: Level \"{0}\". ({1}/{2}/{3})", name, players.Count, Server.s.Log(string.Format("SAVED: Level \"{0}\". ({1}/{2}/{3})", name, players.Count,
PlayerInfo.Online.Count, Server.players)); PlayerInfo.Online.Count, Server.players));
changed = false; changed = false;
} }
public int Backup(bool Forced = false, string backupName = "") { public int Backup(bool Forced = false, string backupName = "") {
if (!backedup || Forced) { if (!backedup || Forced) {
int backupNumber = 1; int backupNumber = 1;
string dir = Path.Combine(Server.backupLocation, name); string dir = Path.Combine(Server.backupLocation, name);
backupNumber = IncrementBackup(dir); backupNumber = IncrementBackup(dir);
string path = Path.Combine(dir, backupNumber.ToString()); string path = Path.Combine(dir, backupNumber.ToString());
if (backupName != "") if (backupName != "")
path = Path.Combine(dir, backupName); path = Path.Combine(dir, backupName);
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
string backup = Path.Combine(path, name + ".lvl"); string backup = Path.Combine(path, name + ".lvl");
string current = LevelInfo.MapPath(name); string current = LevelInfo.MapPath(name);
try { try {
File.Copy(current, backup, true); File.Copy(current, backup, true);
backedup = true; backedup = true;
return backupNumber; return backupNumber;
} catch (Exception e) { } catch (Exception e) {
Server.ErrorLog(e); Server.ErrorLog(e);
Server.s.Log("FAILED TO INCREMENTAL BACKUP :" + name); Server.s.Log("FAILED TO INCREMENTAL BACKUP :" + name);
return -1; return -1;
} }
} }
Server.s.Log("Level unchanged, skipping backup"); Server.s.Log("Level unchanged, skipping backup");
return -1; return -1;
} }
int IncrementBackup(string dir) { int IncrementBackup(string dir) {
if (Directory.Exists(dir)) { if (Directory.Exists(dir)) {
int max = 0; int max = 0;
string[] backups = Directory.GetDirectories(dir); string[] backups = Directory.GetDirectories(dir);
foreach (string s in backups) { foreach (string s in backups) {
string name = s.Substring(s.LastIndexOf(Path.DirectorySeparatorChar) + 1); string name = s.Substring(s.LastIndexOf(Path.DirectorySeparatorChar) + 1);
int num; int num;
if (!int.TryParse(name, out num)) continue; if (!int.TryParse(name, out num)) continue;
max = Math.Max(num, max); max = Math.Max(num, max);
} }
return max + 1; return max + 1;
} else { } else {
Directory.CreateDirectory(dir); Directory.CreateDirectory(dir);
return 1; return 1;
} }
} }
public static Level Load(string name) { return Load(name, LevelInfo.MapPath(name)); } public static Level Load(string name) { return Load(name, LevelInfo.MapPath(name)); }
public static Level Load(string name, string path) { public static Level Load(string name, string path) {
if (LevelLoad != null) LevelLoad(name); if (LevelLoad != null) LevelLoad(name);
OnLevelLoadEvent.Call(name); OnLevelLoadEvent.Call(name);
if (cancelload) { cancelload = false; return null; } if (cancelload) { cancelload = false; return null; }
if (!File.Exists(path)) { if (!File.Exists(path)) {
Server.s.Log("Attempted to load " + name + ", but the level file does not exist."); Server.s.Log("Attempted to load " + name + ", but the level file does not exist.");
return null; return null;
} }
try { try {
Level lvl = IMapImporter.Formats[0].Read(path, name, true); Level lvl = IMapImporter.Formats[0].Read(path, name, true);
lvl.backedup = true; lvl.backedup = true;
lvl.jailx = (ushort)(lvl.spawnx * 32); lvl.jailx = (ushort)(lvl.spawnx * 32);
lvl.jaily = (ushort)(lvl.spawny * 32); lvl.jaily = (ushort)(lvl.spawny * 32);
lvl.jailz = (ushort)(lvl.spawnz * 32); lvl.jailz = (ushort)(lvl.spawnz * 32);
lvl.jailrotx = lvl.rotx; lvl.jailrotx = lvl.rotx;
lvl.jailroty = lvl.roty; lvl.jailroty = lvl.roty;
LoadMetadata(lvl); LoadMetadata(lvl);
Bots.BotsFile.LoadBots(lvl); Bots.BotsFile.LoadBots(lvl);
object locker = ThreadSafeCache.DBCache.Get(name); object locker = ThreadSafeCache.DBCache.Get(name);
lock (locker) { lock (locker) {
LevelDB.LoadZones(lvl, name); LevelDB.LoadZones(lvl, name);
LevelDB.LoadPortals(lvl, name); LevelDB.LoadPortals(lvl, name);
LevelDB.LoadMessages(lvl, name); LevelDB.LoadMessages(lvl, name);
} }
Server.s.Log(string.Format("Level \"{0}\" loaded.", lvl.name)); Server.s.Log(string.Format("Level \"{0}\" loaded.", lvl.name));
if (LevelLoaded != null) if (LevelLoaded != null)
LevelLoaded(lvl); LevelLoaded(lvl);
OnLevelLoadedEvent.Call(lvl); OnLevelLoadedEvent.Call(lvl);
return lvl; return lvl;
} catch (Exception ex) { } catch (Exception ex) {
Server.ErrorLog(ex); Server.ErrorLog(ex);
return null; return null;
} }
} }
public static void LoadMetadata(Level lvl) { public static void LoadMetadata(Level lvl) {
try { try {
string propsPath = LevelInfo.FindPropertiesFile(lvl.MapName); string propsPath = LevelInfo.FindPropertiesFile(lvl.MapName);
if (propsPath != null) { if (propsPath != null) {
LvlProperties.Load(lvl, propsPath); LvlProperties.Load(lvl, propsPath);
} else { } else {
Server.s.Log(".properties file for level " + lvl.MapName + " was not found."); Server.s.Log(".properties file for level " + lvl.MapName + " was not found.");
} }
// Backwards compatibility for older levels which had .env files. // Backwards compatibility for older levels which had .env files.
LvlProperties.LoadEnv(lvl); LvlProperties.LoadEnv(lvl);
} catch (Exception e) { } catch (Exception e) {
Server.ErrorLog(e); Server.ErrorLog(e);
} }
lvl.BlockDB.Cache.Enabled = lvl.UseBlockDB; lvl.BlockDB.Cache.Enabled = lvl.UseBlockDB;
BlockDefinition[] defs = BlockDefinition.Load(false, lvl); BlockDefinition[] defs = BlockDefinition.Load(false, lvl);
for (int i = 0; i < defs.Length; i++) { for (int i = 0; i < defs.Length; i++) {
if (defs[i] == null) continue; if (defs[i] == null) continue;
lvl.CustomBlockDefs[i] = defs[i]; lvl.CustomBlockDefs[i] = defs[i];
lvl.CustomBlockProps[i] = new BlockProps((byte)i); lvl.CustomBlockProps[i] = new BlockProps((byte)i);
} }
BlockProps.Load("lvl_" + lvl.MapName, lvl.CustomBlockProps); BlockProps.Load("lvl_" + lvl.MapName, lvl.CustomBlockProps);
} }
public static bool CheckLoadOnGoto(string givenName) { public static bool CheckLoadOnGoto(string givenName) {
string value = LevelInfo.FindOfflineProperty(givenName, "loadongoto"); string value = LevelInfo.FindOfflineProperty(givenName, "loadongoto");
if (value == null) return true; if (value == null) return true;
bool load; bool load;
if (!bool.TryParse(value, out load)) return true; if (!bool.TryParse(value, out load)) return true;
return load; return load;
} }
public void ChatLevel(string message) { public void ChatLevel(string message) {
ChatLevel(message, LevelPermission.Banned); ChatLevel(message, LevelPermission.Banned);
} }
public void ChatLevelOps(string message) { public void ChatLevelOps(string message) {
LevelPermission rank = CommandExtraPerms.MinPerm("opchat", LevelPermission.Operator); LevelPermission rank = CommandExtraPerms.MinPerm("opchat", LevelPermission.Operator);
ChatLevel(message, rank); ChatLevel(message, rank);
} }
public void ChatLevelAdmins(string message) { public void ChatLevelAdmins(string message) {
LevelPermission rank = CommandExtraPerms.MinPerm("adminchat", LevelPermission.Admin); LevelPermission rank = CommandExtraPerms.MinPerm("adminchat", LevelPermission.Admin);
ChatLevel(message, rank); ChatLevel(message, rank);
} }
/// <summary> Sends a chat messages to all players in the level, who have at least the minPerm rank. </summary> /// <summary> Sends a chat messages to all players in the level, who have at least the minPerm rank. </summary>
public void ChatLevel(string message, LevelPermission minPerm) { public void ChatLevel(string message, LevelPermission minPerm) {
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) { foreach (Player pl in players) {
if (pl.level != this) continue; if (pl.level != this) continue;
if (pl.Rank < minPerm) continue; if (pl.Rank < minPerm) continue;
Player.Message(pl, message); Player.Message(pl, message);
} }
} }
public void UpdateBlockPermissions() { public void UpdateBlockPermissions() {
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) { foreach (Player p in players) {
if (p.level != this) continue; if (p.level != this) continue;
if (!p.HasCpeExt(CpeExt.BlockPermissions)) continue; if (!p.HasCpeExt(CpeExt.BlockPermissions)) continue;
p.SendCurrentBlockPermissions(); p.SendCurrentBlockPermissions();
} }
} }
[Obsolete("Use Group.Find()")] public bool HasPlayers() {
public static LevelPermission PermissionFromName(string name) { Player[] players = PlayerInfo.Online.Items;
Group grp = Group.Find(name); foreach (Player p in players)
return grp != null ? grp.Permission : LevelPermission.Null; if (p.level == this) return true;
} return false;
}
[Obsolete("Use Group.GetName()")]
public static string PermissionToName(LevelPermission perm) { return Group.GetName(perm); } readonly object dbLock = new object();
public void saveChanges() {
public bool HasPlayers() { lock (dbLock)
Player[] players = PlayerInfo.Online.Items; LevelDB.SaveBlockDB(this);
foreach (Player p in players) }
if (p.level == this) return true;
return false; public List<Player> getPlayers() {
} Player[] players = PlayerInfo.Online.Items;
List<Player> onLevel = new List<Player>();
readonly object dbLock = new object();
public void saveChanges() { foreach (Player p in players) {
lock (dbLock) if (p.level == this) onLevel.Add(p);
LevelDB.SaveBlockDB(this); }
} return onLevel;
}
public List<Player> getPlayers() {
Player[] players = PlayerInfo.Online.Items; [StructLayout(LayoutKind.Sequential, Pack = 1)]
List<Player> onLevel = new List<Player>(); public struct UndoPos {
public int flags, index; // bit 0 = is old ext, bit 1 = is new ext, rest bits = time delta
foreach (Player p in players) { public byte oldRaw, newRaw;
if (p.level == this) onLevel.Add(p);
} public void SetData(ExtBlock oldBlock, ExtBlock newBlock) {
return onLevel; TimeSpan delta = DateTime.UtcNow.Subtract(Server.StartTime);
} flags = (int)delta.TotalSeconds << 2;
[StructLayout(LayoutKind.Sequential, Pack = 1)] if (oldBlock.BlockID == Block.custom_block) {
public struct UndoPos { oldRaw = oldBlock.ExtID; flags |= 1;
public int flags, index; // bit 0 = is old ext, bit 1 = is new ext, rest bits = time delta } else {
public byte oldRaw, newRaw; oldRaw = oldBlock.BlockID;
}
public void SetData(ExtBlock oldBlock, ExtBlock newBlock) {
TimeSpan delta = DateTime.UtcNow.Subtract(Server.StartTime); if (newBlock.BlockID == Block.custom_block) {
flags = (int)delta.TotalSeconds << 2; newRaw = newBlock.ExtID; flags |= 2;
} else {
if (oldBlock.BlockID == Block.custom_block) { newRaw = newBlock.BlockID;
oldRaw = oldBlock.ExtID; flags |= 1; }
} else { }
oldRaw = oldBlock.BlockID; }
}
public struct Zone {
if (newBlock.BlockID == Block.custom_block) { public string Owner;
newRaw = newBlock.ExtID; flags |= 2; public ushort bigX, bigY, bigZ;
} else { public ushort smallX, smallY, smallZ;
newRaw = newBlock.BlockID; }
} }
} }
}
public struct Zone {
public string Owner;
public ushort bigX, bigY, bigZ;
public ushort smallX, smallY, smallZ;
}
}
}