using System; using System.Reflection; using GameNetworkLayer.Shared; using GameServer; using HarmonyLib; using NetworkFramework.Server; using Svelto.Context; namespace CLre_server.API.MainServer { public class Server { // static private static Server _instance = null; public static Server Instance { get { if (_instance == null) _instance = new Server(); return _instance; } } // instance events public event EventHandler InitStart { add => MainGameServer_Constructor_Patch.preConstructor += value; remove => MainGameServer_Constructor_Patch.preConstructor -= value; } public event EventHandler InitComplete { add => ServerReadyEngine.serverEngineReady += value; remove => ServerReadyEngine.serverEngineReady -= value; } public event EventHandler FrameworkReady { add => ServerReadyEngine.serverFrameworkReady += value; remove => ServerReadyEngine.serverFrameworkReady -= value; } public event EventHandler FrameworkExit { add => ServerReadyEngine.serverFrameworkDestroyed += value; remove => ServerReadyEngine.serverFrameworkDestroyed -= value; } public event EventHandler Connected { add => PhotonNetwork_ConnectUsingSettings_Patch.postConnect += value; remove => PhotonNetwork_ConnectUsingSettings_Patch.postConnect -= value; } public event EventHandler PlayerConnect { add => MainGameServer_SetupContainer_Patch.playerConnected += value; remove => MainGameServer_SetupContainer_Patch.playerConnected -= value; } public event EventHandler PlayerDisconnect { add => MainGameServer_SetupContainer_Patch.playerDisconnected += value; remove => MainGameServer_SetupContainer_Patch.playerDisconnected -= value; } // properties public GameServerSettings GameServerSettings { get => MainGameServer_SetupMods_Patch._gameServerSettings; set { MainGameServer_SetupMods_Patch._gameServerSettings = value; Traverse.Create(MainGameServer_Constructor_Patch.mgs).Field("_gameServerSettings").Value = value; } } private Server() { new ServerReadyEngine(); } } [HarmonyPatch] class MainGameServer_SetupMods_Patch { internal static GameServerSettings _gameServerSettings; [HarmonyPostfix] public static void AfterMethodCall(GameServerSettings ____gameServerSettings) { #if DEBUG Utility.Logging.MetaLog("Got GameServerSettings"); #endif _gameServerSettings = ____gameServerSettings; } [HarmonyTargetMethod] public static MethodBase Target() { return AccessTools.Method("GameServer.GameFramework.MainGameServer:SetupMods"); } } [HarmonyPatch] class MainGameServer_Constructor_Patch { internal static ICompositionRoot mgs = null; internal static event EventHandler preConstructor; internal static event EventHandler postConstructor; [HarmonyPrefix] public static void BeforeMethodCall() { if (preConstructor != null) preConstructor(null, default(StartingEventArgs)); } [HarmonyPostfix] public static void AfterMethodCall(ICompositionRoot __instance) { mgs = __instance; if (postConstructor != null) postConstructor(__instance, default(StartingEventArgs)); } [HarmonyTargetMethod] public static MethodBase Target() { return AccessTools.Constructor(AccessTools.TypeByName("GameServer.GameFramework.MainGameServer")); } } [HarmonyPatch(typeof(PhotonNetwork), "ConnectUsingSettings")] class PhotonNetwork_ConnectUsingSettings_Patch { internal static event EventHandler preConnect; internal static event EventHandler postConnect; [HarmonyPostfix] public static void AfterMethodCall(string gameVersion) { if (postConnect != null) postConnect(null, new StartedEventArgs { photonVersion = gameVersion, photonRegion = PhotonNetwork.CloudRegion, worldName = MainGameServer_SetupMods_Patch._gameServerSettings.GetWorldName(), gameGuid = MainGameServer_SetupMods_Patch._gameServerSettings.GetGameGuid(), }); } [HarmonyPrefix] public static void BeforeMethodCall(string gameVersion) { if (preConnect != null) preConnect(null, new StartedEventArgs { photonVersion = gameVersion, photonRegion = PhotonNetwork.CloudRegion, worldName = MainGameServer_SetupMods_Patch._gameServerSettings.GetWorldName(), gameGuid = MainGameServer_SetupMods_Patch._gameServerSettings.GetGameGuid(), }); } } [HarmonyPatch(typeof(GameServer.GameFramework.MainGameServer), "SetupContainer")] class MainGameServer_SetupContainer_Patch { internal static event EventHandler playerConnected; internal static event EventHandler playerDisconnected; private static GameServer.GameFramework.MainGameServer mgs = null; [HarmonyPostfix] public static void AfterMethodCall(GameServer.GameFramework.MainGameServer __instance, ref IPlayerConnectedCallbacks ____playerConnectedCallbacks) { mgs = __instance; ____playerConnectedCallbacks.OnPlayerConnected += OnConnect; ____playerConnectedCallbacks.OnPlayerDisconnected += OnDisconnect; } public static void OnConnect(int playerId) { Synergy.Clients.RegisterClient(playerId); if (playerConnected != null) playerConnected(mgs, new PlayerConnectArgs { PlayerId = playerId, }); } public static void OnDisconnect(int playerId) { Synergy.Clients.RemoveClient(playerId); if (playerDisconnected != null) playerDisconnected(mgs, new PlayerConnectArgs { PlayerId = playerId, }); } } }