mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Remove very obsolete methods from Level class
This commit is contained in:
parent
8afba63ae6
commit
3ae3e25493
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user