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();
SaveGameProps();
SrvProperties.Load(); // loads when saving?
SrvProperties.ApplyChanges();
}
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;
Server.SetMainLevel(map);
Server.Config.MainLevel = map;
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 {
public delegate void OnLevelLoaded(Level lvl);
public sealed class OnLevelLoadedEvent : IEvent<OnLevelLoaded> {
public sealed class OnLevelLoadedEvent : IEvent<OnLevelLoaded>
{
public static void Call(Level lvl) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl));
@ -31,11 +31,12 @@ namespace MCGalaxy.Events.LevelEvents {
}
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) {
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); }
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 sealed class OnLevelSaveEvent : IEvent<OnLevelSave> {
public sealed class OnLevelSaveEvent : IEvent<OnLevelSave>
{
public static void Call(Level lvl, ref bool cancel) {
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); }
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 sealed class OnLevelUnloadEvent : IEvent<OnLevelUnload> {
public sealed class OnLevelUnloadEvent : IEvent<OnLevelUnload>
{
public static void Call(Level lvl, ref bool cancel) {
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); }
catch (Exception ex) { LogHandlerException(ex, items[i]); }
}
@ -67,8 +70,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
public delegate void OnLevelAdded(Level lvl);
public sealed class OnLevelAddedEvent : IEvent<OnLevelAdded> {
public sealed class OnLevelAddedEvent : IEvent<OnLevelAdded>
{
public static void Call(Level lvl) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl));
@ -76,8 +79,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
public delegate void OnLevelRemoved(Level lvl);
public sealed class OnLevelRemovedEvent : IEvent<OnLevelRemoved> {
public sealed class OnLevelRemovedEvent : IEvent<OnLevelRemoved>
{
public static void Call(Level lvl) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl));
@ -85,8 +88,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
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) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(lvl, state));
@ -94,8 +97,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
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) {
if (handlers.Count == 0) return;
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 sealed class OnPhysicsUpdateEvent : IEvent<OnPhysicsUpdate> {
public static void Call(ushort x, ushort y, ushort z, PhysicsArgs extraInfo, Level l) {
public sealed class OnPhysicsUpdateEvent : IEvent<OnPhysicsUpdate>
{
public static void Call(ushort x, ushort y, ushort z, PhysicsArgs extraInfo, Level l) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(x, y, z, extraInfo, l));
}
}
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) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(srcMap, dstMap));
@ -121,8 +124,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
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) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(srcMap, dstMap));
@ -130,8 +133,8 @@ namespace MCGalaxy.Events.LevelEvents {
}
public delegate void OnLevelDeleted(string map);
public sealed class OnLevelDeletedEvent : IEvent<OnLevelDeleted> {
public sealed class OnLevelDeletedEvent : IEvent<OnLevelDeleted>
{
public static void Call(string map) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(map));
@ -139,11 +142,24 @@ namespace MCGalaxy.Events.LevelEvents {
}
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) {
if (handlers.Count == 0) return;
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;
namespace MCGalaxy.Events.PlayerDBEvents {
namespace MCGalaxy.Events.PlayerDBEvents
{
public delegate void OnInfoSave(Player p, ref bool cancel);
/// <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) {
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); }
catch (Exception ex) { LogHandlerException(ex, items[i]); }
}
@ -34,8 +35,8 @@ namespace MCGalaxy.Events.PlayerDBEvents {
public delegate void OnInfoSwap(string src, string dst);
/// <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) {
if (handlers.Count == 0) return;
CallCommon(pl => pl(src, dst));

View File

@ -27,7 +27,9 @@ namespace MCGalaxy.Games {
public abstract partial class RoundsGame : IGame {
protected virtual void HookEventHandlers() {
OnLevelUnloadEvent.Register(HandleLevelUnload, Priority.High);
OnLevelUnloadEvent.Register(HandleLevelUnload, Priority.High);
OnMainLevelChangingEvent.Register(HandleMainChanged, Priority.High);
OnSendingHeartbeatEvent.Register(HandleSendingHeartbeat, Priority.High);
OnInfoSaveEvent.Register(HandleSaveStats, Priority.High);
@ -38,6 +40,8 @@ namespace MCGalaxy.Games {
protected virtual void UnhookEventHandlers() {
OnLevelUnloadEvent.Unregister(HandleLevelUnload);
OnMainLevelChangingEvent.Unregister(HandleMainChanged);
OnSendingHeartbeatEvent.Unregister(HandleSendingHeartbeat);
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) {
if (!(action == PlayerAction.Referee || action == PlayerAction.UnReferee)) return;
if (p.level != Map) return;
@ -106,5 +104,18 @@ namespace MCGalaxy.Games {
Entities.GlobalSpawn(p, false, "");
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)) {
p.Message("File &9{0} &Snot found.", path);
return false;
}
} // TODO: Move error handling elsewhere
List<Plugin> plugins = IScripting.LoadPlugin(path, false);
if (plugins == null) {

View File

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

View File

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