Fix /cd generate not properly replacing existing map if it is loaded.

This commit is contained in:
UnknownShadow200 2016-07-17 17:02:16 +10:00
parent 3b4966944e
commit a007213c7b
9 changed files with 91 additions and 84 deletions

View File

@ -440,7 +440,7 @@ namespace MCGalaxy.Commands.CPE {
if (pl.level == null || !pl.level.HasCustomBlocks) continue;
if (!pl.outdatedClient) continue;
CmdReload.ReloadMap(p, pl, true);
LevelActions.ReloadMap(p, pl, true);
}
}

View File

@ -21,6 +21,7 @@ using System;
using System.Net;
using System.Threading;
using MCGalaxy.Games;
using MCGalaxy.Commands.World;
namespace MCGalaxy.Commands {
@ -46,11 +47,11 @@ namespace MCGalaxy.Commands {
string cmd = args[0], arg1 = "", arg2 = "", arg3 = "";
if (args.Length > 1) arg1 = args[1];
if (args.Length > 2) arg2 = args[2];
if (args.Length > 3) arg3 = args[3];
if (args.Length > 3) arg3 = args[3];
switch (cmd) {
case "help":
Help(p); return;
Help(p); return;
case "goto":
PlayerActions.ChangeMap(p, "countdown"); return;
case "join":
@ -154,7 +155,7 @@ namespace MCGalaxy.Commands {
case CountdownGameStatus.AboutToStart:
Player.Message(p, "Players who are about to play:");
foreach (Player plya in Server.Countdown.players)
Player.Message(p, plya.ColoredName);
Player.Message(p, plya.ColoredName);
break;
case CountdownGameStatus.InProgress:
@ -176,7 +177,7 @@ namespace MCGalaxy.Commands {
}
void HandleRules(Player p, string target) {
bool hasPerm = CheckExtraPerm(p, 1);
bool hasPerm = CheckExtraPerm(p, 1);
if (target == "" || !hasPerm) {
Player.Message(p, "The aim of the game is to stay alive the longest.");
Player.Message(p, "Don't fall in the lava!!");
@ -204,7 +205,7 @@ namespace MCGalaxy.Commands {
Player who = PlayerInfo.FindMatches(p, target);
if (who == null) return;
if (p.Rank < who.Rank) {
MessageTooHighRank(p, "send countdown rules", true); return;
MessageTooHighRank(p, "send countdown rules", true); return;
} else {
Player.Message(who, "Countdown rules sent to you by " + p.ColoredName);
Player.Message(who, "The aim of the game is to stay alive the longest.");
@ -224,24 +225,26 @@ namespace MCGalaxy.Commands {
if (width < 32 || !MapGen.OkayAxis(width)) width = 32;
if (height < 32 || !MapGen.OkayAxis(height)) height = 32;
if (length < 32 || !MapGen.OkayAxis(length)) length = 32;
Level oldLevel = LevelInfo.FindExact("countdown");
if (oldLevel != null) {
oldLevel.permissionbuild = LevelPermission.Guest;
LevelActions.Delete("countdown");
}
if (!CmdNewLvl.CheckMapSize(p, width, height, length)) return;
Level lvl = CountdownMapGen.Generate(width, height, length);
lvl.Deletable = false;
lvl.Buildable = false;
lvl.permissionbuild = LevelPermission.Nobody;
lvl.motd = "Welcome to the Countdown map! -hax";
Level oldLvl = LevelInfo.FindExact("countdown");
if (oldLvl != null) LevelActions.Replace(oldLvl, lvl);
else LevelInfo.Loaded.Add(lvl);
lvl.Save();
if (Server.Countdown.gamestatus != CountdownGameStatus.Disabled)
Server.Countdown.mapon = lvl;
Server.Countdown.mapon = lvl;
const string format = "Generated map ({0}x{1}x{2}), sending you to it..";
Player.Message(p, format, width, height, length);
Command.all.Find("load").Use(p, "countdown");
PlayerActions.ChangeMap(p, "countdown");
p.level.permissionbuild = LevelPermission.Nobody;
p.level.motd = "Welcome to the Countdown map!!!! -hax";
const ushort x = 8 * 32 + 16;
const ushort y = 23 * 32 + 32;
const ushort z = 17 * 32 + 16;
@ -252,12 +255,18 @@ namespace MCGalaxy.Commands {
if (Server.Countdown.gamestatus == CountdownGameStatus.Disabled) {
Command.all.Find("load").Use(null, "countdown");
Server.Countdown.mapon = LevelInfo.FindExact("countdown");
if (Server.Countdown.mapon == null ) {
if (Server.Countdown.mapon == null) {
Player.Message(p, "countdown level not found, generating..");
HandleGenerate(p, "", "", "");
Server.Countdown.mapon = LevelInfo.FindExact("countdown");
}
Server.Countdown.mapon.Deletable = false;
Server.Countdown.mapon.Buildable = false;
Server.Countdown.mapon.permissionbuild = LevelPermission.Nobody;
Server.Countdown.mapon.motd = "Welcome to the Countdown map! -hax";
Server.Countdown.gamestatus = CountdownGameStatus.Enabled;
Player.GlobalMessage("Countdown has been enabled!!");
} else {

View File

@ -43,7 +43,7 @@ namespace MCGalaxy.Commands {
if (p != null && who.Rank > p.Rank) {
MessageTooHighRank(p, "reload the map for", true); return;
}
ReloadMap(p, who, true);
LevelActions.ReloadMap(p, who, true);
}
GC.Collect();
GC.WaitForPendingFinalizers();
@ -64,24 +64,11 @@ namespace MCGalaxy.Commands {
Player[] players = PlayerInfo.Online.Items;
foreach (Player who in players) {
if (who.level == lvl)
ReloadMap(p, who, true);
LevelActions.ReloadMap(p, who, true);
}
return true;
}
internal static void ReloadMap(Player p, Player who, bool showMessage) {
who.Loading = true;
Entities.DespawnEntities(who);
who.SendUserMOTD(); who.SendMap(who.level);
Entities.SpawnEntities(who);
who.Loading = false;
if (!showMessage) return;
if (p != null && !p.hidden) { who.SendMessage("&bMap reloaded by " + p.name); }
if (p != null && p.hidden) { who.SendMessage("&bMap reloaded"); }
Player.Message(p, "&4Finished reloading for " + who.name);
}
public override void Help(Player p) {
Player.Message(p, "%T/reload %H- Reloads the map you are in, just for you.");
Player.Message(p, "%T/reload <name> %H- Reloads the map for [name].");

View File

@ -19,8 +19,7 @@ using System.IO;
using System.Text;
namespace MCGalaxy.Commands {
public sealed class CmdRestore : Command {
public sealed class CmdRestore : Command {
public override string name { get { return "restore"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.World; } }
@ -60,20 +59,7 @@ namespace MCGalaxy.Commands {
File.Copy(LevelInfo.BackupPath(lvl.name, backup), LevelInfo.LevelPath(lvl.name), true);
Level restore = Level.Load(lvl.name);
if (restore != null) {
LevelInfo.Loaded.Remove(lvl);
LevelInfo.Loaded.Add(restore);
restore.StartPhysics();
lvl.setPhysics(0);
lvl.ClearPhysics();
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != lvl) continue;
pl.level = restore;
CmdReload.ReloadMap(null, pl, false);
}
lvl.Unload(true, false);
LevelActions.Replace(lvl, restore);
} else {
Server.s.Log("Restore nulled");
File.Copy(LevelInfo.LevelPath(lvl.name) + ".backup", LevelInfo.LevelPath(lvl.name), true);

View File

@ -172,11 +172,10 @@ namespace MCGalaxy.Drawing.Ops {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level.name.CaselessEq(lvl.name))
CmdReload.ReloadMap(p, pl, true);
LevelActions.ReloadMap(p, pl, true);
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
}

View File

@ -33,7 +33,7 @@ namespace MCGalaxy {
try {
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
lock (lvl.queueLock)
lock (lvl.queueLock)
ProcessLevelBlocks(lvl);
}
bulkSender.level = null;
@ -51,17 +51,17 @@ namespace MCGalaxy {
public static void Resume() { blocktimer.Enabled = true; }
public static void Addblock(Player p, int index, byte type, byte extType = 0) {
if (index == -1) return;
// Bit packing format
// 32-63: index
// 9-31: session ID
// 8: is ext block or not
// 0-7: raw type
ulong flags = (ulong)index << 32;
flags |= (ulong)p.SessionID << 9;
flags |= (type == Block.custom_block ? 0x100UL : 0x000UL);
flags |= (type == Block.custom_block ? extType : type);
if (index == -1) return;
// Bit packing format
// 32-63: index
// 9-31: session ID
// 8: is ext block or not
// 0-7: raw type
ulong flags = (ulong)index << 32;
flags |= (ulong)p.SessionID << 9;
flags |= (type == Block.custom_block ? 0x100UL : 0x000UL);
flags |= (type == Block.custom_block ? extType : type);
lock (p.level.queueLock)
p.level.blockqueue.Add(flags);
}
@ -75,11 +75,11 @@ namespace MCGalaxy {
count = lvl.blockqueue.Count;
for (int i = 0; i < count; i++) {
ulong flags = lvl.blockqueue[i];
int index = (int)(flags >> 32);
byte type = (flags & 0x100) != 0 ? Block.custom_block : (byte)flags;
byte extType = (flags & 0x100) != 0 ? (byte)flags : Block.air;
ulong flags = lvl.blockqueue[i];
int index = (int)(flags >> 32);
byte type = (flags & 0x100) != 0 ? Block.custom_block : (byte)flags;
byte extType = (flags & 0x100) != 0 ? (byte)flags : Block.air;
bulkSender.Add(index, type, extType);
bulkSender.CheckIfSend(false);
}

View File

@ -39,9 +39,7 @@ namespace MCGalaxy {
public void StartPhysics() {
lock (physThreadLock) {
if (physThread != null) {
if (physThread.ThreadState == System.Threading.ThreadState.Running) return;
}
if (physThread != null && physThread.ThreadState == ThreadState.Running) return;
if (ListCheck.Count == 0 || physicssate) return;
physThread = new Thread(PhysicsLoop);

View File

@ -440,7 +440,7 @@ namespace MCGalaxy
void MovePlayersToMain() {
Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) {
if (p.level.name.ToLower() == name.ToLower()) {
if (p.level == this) {
Player.Message(p, "You were moved to the main level as " + name + " was unloaded.");
PlayerActions.ChangeMap(p, Server.mainLevel.name);
}
@ -562,26 +562,24 @@ namespace MCGalaxy
}
}
public static Level Load(string givenName) {
return Load(givenName, 0);
}
public static Level Load(string name) { return Load(name, 0); }
//givenName is safe against SQL injections, it gets checked in CmdLoad.cs
public static Level Load(string givenName, byte phys) {
if (LevelLoad != null) LevelLoad(givenName);
OnLevelLoadEvent.Call(givenName);
public static Level Load(string name, byte phys) {
if (LevelLoad != null) LevelLoad(name);
OnLevelLoadEvent.Call(name);
if (cancelload) { cancelload = false; return null; }
LevelDB.CreateTables(givenName);
LevelDB.CreateTables(name);
string path = LevelInfo.LevelPath(givenName);
string path = LevelInfo.LevelPath(name);
if (File.Exists(path))
{
try
{
Level level = LvlFile.Load(givenName, path);
Level level = LvlFile.Load(name, path);
level.setPhysics(phys);
level.backedup = true;
LevelDB.LoadZones(level, givenName);
LevelDB.LoadZones(level, name);
level.jailx = (ushort)(level.spawnx * 32);
level.jaily = (ushort)(level.spawny * 32);
@ -591,7 +589,7 @@ namespace MCGalaxy
level.StartPhysics();
try {
LevelDB.LoadMetadata(level, givenName);
LevelDB.LoadMetadata(level, name);
} catch (Exception e) {
Server.ErrorLog(e);
}

View File

@ -130,5 +130,35 @@ namespace MCGalaxy {
Database.executeQuery("DROP TABLE `Messages" + name + "`");
Database.executeQuery("DROP TABLE `Zone" + name + "`");
}
public static void Replace(Level old, Level lvl) {
LevelInfo.Loaded.Remove(old);
LevelInfo.Loaded.Add(lvl);
old.setPhysics(0);
old.ClearPhysics();
lvl.StartPhysics();
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != old) continue;
pl.level = lvl;
ReloadMap(null, pl, false);
}
old.Unload(true, false);
}
public static void ReloadMap(Player p, Player who, bool showMessage) {
who.Loading = true;
Entities.DespawnEntities(who);
who.SendUserMOTD(); who.SendMap(who.level);
Entities.SpawnEntities(who);
who.Loading = false;
if (!showMessage) return;
if (p != null && !p.hidden) { who.SendMessage("&bMap reloaded by " + p.name); }
if (p != null && p.hidden) { who.SendMessage("&bMap reloaded"); }
Player.Message(p, "&4Finished reloading for " + who.name);
}
}
}