Fix if game that changes the main level is running, that opening settings GUI or doing /server reload would cause server main level to get loaded

This commit is contained in:
UnknownShadow200 2023-05-11 19:41:30 +10:00
parent e541755bc5
commit 180b66eb52
8 changed files with 91 additions and 55 deletions

View File

@ -109,7 +109,7 @@ namespace MCGalaxy.Gui
SaveBlocks(); SaveBlocks();
SaveGameProps(); SaveGameProps();
SrvProperties.Load(); // loads when saving? SrvProperties.ApplyChanges();
} }
void btnDiscard_Click(object sender, EventArgs e) { Dispose(); } void btnDiscard_Click(object sender, EventArgs e) { Dispose(); }

View File

@ -49,8 +49,11 @@ namespace MCGalaxy.Commands.World {
if (!LevelInfo.Check(p, data.Rank, map, "set main to this map")) return; if (!LevelInfo.Check(p, data.Rank, map, "set main to this map")) return;
Server.SetMainLevel(map); Server.SetMainLevel(map);
Server.Config.MainLevel = map;
SrvProperties.Save(); SrvProperties.Save();
p.Message("Set main level to {0}", Server.mainLevel.ColoredName);
p.Message("Set main level to {0}",
LevelInfo.GetConfig(map).Color + map);
} }
} }

View File

@ -22,8 +22,8 @@ using BlockID = System.UInt16;
namespace MCGalaxy.Events.LevelEvents { namespace MCGalaxy.Events.LevelEvents {
public delegate void OnLevelLoaded(Level lvl); public delegate void OnLevelLoaded(Level lvl);
public sealed class OnLevelLoadedEvent : IEvent<OnLevelLoaded> { public sealed class OnLevelLoadedEvent : IEvent<OnLevelLoaded>
{
public static void Call(Level lvl) { public static void Call(Level lvl) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl)); CallCommon(pl => pl(lvl));
@ -31,11 +31,12 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelLoad(string name, string path, ref bool cancel); public delegate void OnLevelLoad(string name, string path, ref bool cancel);
public sealed class OnLevelLoadEvent : IEvent<OnLevelLoad> { public sealed class OnLevelLoadEvent : IEvent<OnLevelLoad>
{
public static void Call(string name, string path, ref bool cancel) { public static void Call(string name, string path, ref bool cancel) {
IEvent<OnLevelLoad>[] items = handlers.Items; IEvent<OnLevelLoad>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++) { for (int i = 0; i < items.Length; i++)
{
try { items[i].method(name, path, ref cancel); } try { items[i].method(name, path, ref cancel); }
catch (Exception ex) { LogHandlerException(ex, items[i]); } catch (Exception ex) { LogHandlerException(ex, items[i]); }
} }
@ -43,11 +44,12 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelSave(Level lvl, ref bool cancel); public delegate void OnLevelSave(Level lvl, ref bool cancel);
public sealed class OnLevelSaveEvent : IEvent<OnLevelSave> { public sealed class OnLevelSaveEvent : IEvent<OnLevelSave>
{
public static void Call(Level lvl, ref bool cancel) { public static void Call(Level lvl, ref bool cancel) {
IEvent<OnLevelSave>[] items = handlers.Items; IEvent<OnLevelSave>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++) { for (int i = 0; i < items.Length; i++)
{
try { items[i].method(lvl, ref cancel); } try { items[i].method(lvl, ref cancel); }
catch (Exception ex) { LogHandlerException(ex, items[i]); } catch (Exception ex) { LogHandlerException(ex, items[i]); }
} }
@ -55,11 +57,12 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelUnload(Level lvl, ref bool cancel); public delegate void OnLevelUnload(Level lvl, ref bool cancel);
public sealed class OnLevelUnloadEvent : IEvent<OnLevelUnload> { public sealed class OnLevelUnloadEvent : IEvent<OnLevelUnload>
{
public static void Call(Level lvl, ref bool cancel) { public static void Call(Level lvl, ref bool cancel) {
IEvent<OnLevelUnload>[] items = handlers.Items; IEvent<OnLevelUnload>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++) { for (int i = 0; i < items.Length; i++)
{
try { items[i].method(lvl, ref cancel); } try { items[i].method(lvl, ref cancel); }
catch (Exception ex) { LogHandlerException(ex, items[i]); } catch (Exception ex) { LogHandlerException(ex, items[i]); }
} }
@ -67,8 +70,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelAdded(Level lvl); public delegate void OnLevelAdded(Level lvl);
public sealed class OnLevelAddedEvent : IEvent<OnLevelAdded> { public sealed class OnLevelAddedEvent : IEvent<OnLevelAdded>
{
public static void Call(Level lvl) { public static void Call(Level lvl) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl)); CallCommon(pl => pl(lvl));
@ -76,8 +79,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelRemoved(Level lvl); public delegate void OnLevelRemoved(Level lvl);
public sealed class OnLevelRemovedEvent : IEvent<OnLevelRemoved> { public sealed class OnLevelRemovedEvent : IEvent<OnLevelRemoved>
{
public static void Call(Level lvl) { public static void Call(Level lvl) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl)); CallCommon(pl => pl(lvl));
@ -85,8 +88,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnPhysicsStateChanged(Level lvl, PhysicsState state); public delegate void OnPhysicsStateChanged(Level lvl, PhysicsState state);
public sealed class OnPhysicsStateChangedEvent : IEvent<OnPhysicsStateChanged> { public sealed class OnPhysicsStateChangedEvent : IEvent<OnPhysicsStateChanged>
{
public static void Call(Level lvl, PhysicsState state) { public static void Call(Level lvl, PhysicsState state) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl, state)); CallCommon(pl => pl(lvl, state));
@ -94,8 +97,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnPhysicsLevelChanged(Level lvl, int level); public delegate void OnPhysicsLevelChanged(Level lvl, int level);
public sealed class OnPhysicsLevelChangedEvent : IEvent<OnPhysicsLevelChanged> { public sealed class OnPhysicsLevelChangedEvent : IEvent<OnPhysicsLevelChanged>
{
public static void Call(Level lvl, int level) { public static void Call(Level lvl, int level) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl, level)); CallCommon(pl => pl(lvl, level));
@ -103,17 +106,17 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnPhysicsUpdate(ushort x, ushort y, ushort z, PhysicsArgs args, Level lvl); public delegate void OnPhysicsUpdate(ushort x, ushort y, ushort z, PhysicsArgs args, Level lvl);
public sealed class OnPhysicsUpdateEvent : IEvent<OnPhysicsUpdate> { public sealed class OnPhysicsUpdateEvent : IEvent<OnPhysicsUpdate>
{
public static void Call(ushort x, ushort y, ushort z, PhysicsArgs extraInfo, Level l) { public static void Call(ushort x, ushort y, ushort z, PhysicsArgs extraInfo, Level l) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(x, y, z, extraInfo, l)); CallCommon(pl => pl(x, y, z, extraInfo, l));
} }
} }
public delegate void OnLevelRenamed(string srcMap, string dstMap); public delegate void OnLevelRenamed(string srcMap, string dstMap);
public sealed class OnLevelRenamedEvent : IEvent<OnLevelRenamed> { public sealed class OnLevelRenamedEvent : IEvent<OnLevelRenamed>
{
public static void Call(string srcMap, string dstMap) { public static void Call(string srcMap, string dstMap) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(srcMap, dstMap)); CallCommon(pl => pl(srcMap, dstMap));
@ -121,8 +124,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelCopied(string srcMap, string dstMap); public delegate void OnLevelCopied(string srcMap, string dstMap);
public sealed class OnLevelCopiedEvent : IEvent<OnLevelCopied> { public sealed class OnLevelCopiedEvent : IEvent<OnLevelCopied>
{
public static void Call(string srcMap, string dstMap) { public static void Call(string srcMap, string dstMap) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(srcMap, dstMap)); CallCommon(pl => pl(srcMap, dstMap));
@ -130,8 +133,8 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnLevelDeleted(string map); public delegate void OnLevelDeleted(string map);
public sealed class OnLevelDeletedEvent : IEvent<OnLevelDeleted> { public sealed class OnLevelDeletedEvent : IEvent<OnLevelDeleted>
{
public static void Call(string map) { public static void Call(string map) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(map)); CallCommon(pl => pl(map));
@ -139,11 +142,24 @@ namespace MCGalaxy.Events.LevelEvents {
} }
public delegate void OnBlockHandlersUpdated(Level lvl, BlockID block); public delegate void OnBlockHandlersUpdated(Level lvl, BlockID block);
public sealed class OnBlockHandlersUpdatedEvent : IEvent<OnBlockHandlersUpdated> { public sealed class OnBlockHandlersUpdatedEvent : IEvent<OnBlockHandlersUpdated>
{
public static void Call(Level lvl, BlockID block) { public static void Call(Level lvl, BlockID block) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl, block)); CallCommon(pl => pl(lvl, block));
} }
} }
public delegate void OnMainLevelChanging(ref string map);
public sealed class OnMainLevelChangingEvent : IEvent<OnMainLevelChanging>
{
public static void Call(ref string map) {
IEvent<OnMainLevelChanging>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++)
{
try { items[i].method(ref map); }
catch (Exception ex) { LogHandlerException(ex, items[i]); }
}
}
}
} }

View File

@ -17,15 +17,16 @@
*/ */
using System; using System;
namespace MCGalaxy.Events.PlayerDBEvents { namespace MCGalaxy.Events.PlayerDBEvents
{
public delegate void OnInfoSave(Player p, ref bool cancel); public delegate void OnInfoSave(Player p, ref bool cancel);
/// <summary> Called whenever the server saves player's stats to the database. </summary> /// <summary> Called whenever the server saves player's stats to the database. </summary>
public sealed class OnInfoSaveEvent : IEvent<OnInfoSave> { public sealed class OnInfoSaveEvent : IEvent<OnInfoSave>
{
public static void Call(Player p, ref bool cancel) { public static void Call(Player p, ref bool cancel) {
IEvent<OnInfoSave>[] items = handlers.Items; IEvent<OnInfoSave>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++) { for (int i = 0; i < items.Length; i++)
{
try { items[i].method(p, ref cancel); } try { items[i].method(p, ref cancel); }
catch (Exception ex) { LogHandlerException(ex, items[i]); } catch (Exception ex) { LogHandlerException(ex, items[i]); }
} }
@ -34,8 +35,8 @@ namespace MCGalaxy.Events.PlayerDBEvents {
public delegate void OnInfoSwap(string src, string dst); public delegate void OnInfoSwap(string src, string dst);
/// <summary> Called when the information of two players is being swapped. </summary> /// <summary> Called when the information of two players is being swapped. </summary>
public sealed class OnInfoSwapEvent : IEvent<OnInfoSwap> { public sealed class OnInfoSwapEvent : IEvent<OnInfoSwap>
{
public static void Call(string src, string dst) { public static void Call(string src, string dst) {
if (handlers.Count == 0) return; if (handlers.Count == 0) return;
CallCommon(pl => pl(src, dst)); CallCommon(pl => pl(src, dst));

View File

@ -28,6 +28,8 @@ namespace MCGalaxy.Games {
protected virtual void HookEventHandlers() { protected virtual void HookEventHandlers() {
OnLevelUnloadEvent.Register(HandleLevelUnload, Priority.High); OnLevelUnloadEvent.Register(HandleLevelUnload, Priority.High);
OnMainLevelChangingEvent.Register(HandleMainChanged, Priority.High);
OnSendingHeartbeatEvent.Register(HandleSendingHeartbeat, Priority.High); OnSendingHeartbeatEvent.Register(HandleSendingHeartbeat, Priority.High);
OnInfoSaveEvent.Register(HandleSaveStats, Priority.High); OnInfoSaveEvent.Register(HandleSaveStats, Priority.High);
@ -38,6 +40,8 @@ namespace MCGalaxy.Games {
protected virtual void UnhookEventHandlers() { protected virtual void UnhookEventHandlers() {
OnLevelUnloadEvent.Unregister(HandleLevelUnload); OnLevelUnloadEvent.Unregister(HandleLevelUnload);
OnMainLevelChangingEvent.Unregister(HandleMainChanged);
OnSendingHeartbeatEvent.Unregister(HandleSendingHeartbeat); OnSendingHeartbeatEvent.Unregister(HandleSendingHeartbeat);
OnInfoSaveEvent.Unregister(HandleSaveStats); OnInfoSaveEvent.Unregister(HandleSaveStats);
@ -83,12 +87,6 @@ namespace MCGalaxy.Games {
} }
} }
protected void HandleLevelUnload(Level lvl, ref bool cancel) {
if (lvl != Map) return;
Logger.Log(LogType.GameActivity, "Unload cancelled! A {0} game is currently going on!", GameName);
cancel = true;
}
protected void HandlePlayerAction(Player p, PlayerAction action, string message, bool stealth) { protected void HandlePlayerAction(Player p, PlayerAction action, string message, bool stealth) {
if (!(action == PlayerAction.Referee || action == PlayerAction.UnReferee)) return; if (!(action == PlayerAction.Referee || action == PlayerAction.UnReferee)) return;
if (p.level != Map) return; if (p.level != Map) return;
@ -106,5 +104,18 @@ namespace MCGalaxy.Games {
Entities.GlobalSpawn(p, false, ""); Entities.GlobalSpawn(p, false, "");
TabList.Update(p, true); TabList.Update(p, true);
} }
void HandleLevelUnload(Level lvl, ref bool cancel) {
if (lvl != Map) return;
Logger.Log(LogType.GameActivity, "Unload cancelled! A {0} game is currently going on!", GameName);
cancel = true;
}
void HandleMainChanged(ref string map) {
Level cur = Map; // in case Map is changed by another thread
if (!GetConfig().SetMainLevel || cur == null) return;
map = cur.name;
}
} }
} }

View File

@ -42,7 +42,7 @@ namespace MCGalaxy.Scripting
if (!File.Exists(path)) { if (!File.Exists(path)) {
p.Message("File &9{0} &Snot found.", path); p.Message("File &9{0} &Snot found.", path);
return false; return false;
} } // TODO: Move error handling elsewhere
List<Plugin> plugins = IScripting.LoadPlugin(path, false); List<Plugin> plugins = IScripting.LoadPlugin(path, false);
if (plugins == null) { if (plugins == null) {

View File

@ -29,6 +29,7 @@ using MCGalaxy.Commands;
using MCGalaxy.DB; using MCGalaxy.DB;
using MCGalaxy.Drawing; using MCGalaxy.Drawing;
using MCGalaxy.Eco; using MCGalaxy.Eco;
using MCGalaxy.Events.LevelEvents;
using MCGalaxy.Events.ServerEvents; using MCGalaxy.Events.ServerEvents;
using MCGalaxy.Games; using MCGalaxy.Games;
using MCGalaxy.Network; using MCGalaxy.Network;
@ -307,6 +308,7 @@ namespace MCGalaxy
} }
public static bool SetMainLevel(string map) { public static bool SetMainLevel(string map) {
OnMainLevelChangingEvent.Call(ref map);
string main = mainLevel != null ? mainLevel.name : Server.Config.MainLevel; string main = mainLevel != null ? mainLevel.name : Server.Config.MainLevel;
if (map.CaselessEq(main)) return false; if (map.CaselessEq(main)) return false;
@ -315,13 +317,13 @@ namespace MCGalaxy
lvl = LevelActions.Load(Player.Console, map, false); lvl = LevelActions.Load(Player.Console, map, false);
if (lvl == null) return false; if (lvl == null) return false;
SetMainLevel(lvl); return true; SetMainLevel(lvl);
return true;
} }
public static void SetMainLevel(Level lvl) { public static void SetMainLevel(Level lvl) {
Level oldMain = mainLevel; Level oldMain = mainLevel;
mainLevel = lvl; mainLevel = lvl;
Server.Config.MainLevel = lvl.name;
oldMain.AutoUnload(); oldMain.AutoUnload();
} }

View File

@ -26,15 +26,18 @@ namespace MCGalaxy
{ {
public static void Load() { public static void Load() {
old = new OldPerms(); old = new OldPerms();
if (PropertiesFile.Read(Paths.ServerPropsFile, ref old, LineProcessor)) PropertiesFile.Read(Paths.ServerPropsFile, ref old, LineProcessor);
Server.SettingsUpdate();
Database.UpdateActiveBackend(); ApplyChanges();
Save();
}
public static void ApplyChanges() {
if (!Directory.Exists(Server.Config.BackupDirectory)) if (!Directory.Exists(Server.Config.BackupDirectory))
Server.Config.BackupDirectory = "levels/backups"; Server.Config.BackupDirectory = "levels/backups";
Save(); Server.SettingsUpdate();
Database.UpdateActiveBackend();
Server.SetMainLevel(Server.Config.MainLevel); Server.SetMainLevel(Server.Config.MainLevel);
} }