Merge pull request #22 from Casimir255/PluginLoader

Plugin loader
This commit is contained in:
Garrett
2022-02-14 20:54:37 -06:00
committed by GitHub
7 changed files with 364 additions and 75 deletions

View File

@@ -18,6 +18,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers; using System.Timers;
using System.Windows.Forms; using System.Windows.Forms;
using VRage.Game.ModAPI;
using VRage.Input; using VRage.Input;
using VRage.Plugins; using VRage.Plugins;
using VRage.Utils; using VRage.Utils;
@@ -107,13 +108,13 @@ namespace SeamlessClientPlugin
public static string Version = "1.3.04"; public static string Version = "1.3.04";
public static bool Debug = false; public static bool Debug = true;
private static bool Initilized = false; private static bool Initilized = false;
public const ushort SeamlessClientNetID = 2936; public const ushort SeamlessClientNetID = 2936;
private static System.Timers.Timer PingTimer = new System.Timers.Timer(3000); private static System.Timers.Timer PingTimer = new System.Timers.Timer(500);
public static bool IsSwitching = false; public static bool IsSwitching = false;
public static bool RanJoin = false; public static bool RanJoin = false;
@@ -122,10 +123,13 @@ namespace SeamlessClientPlugin
public void Init(object gameInstance) public void Init(object gameInstance)
{ {
Patches.GetPatches();
TryShow("Running Seamless Client Plugin v[" + Version + "]"); TryShow("Running Seamless Client Plugin v[" + Version + "]");
PingTimer.Elapsed += PingTimer_Elapsed;
PingTimer.Start();
} }
@@ -134,41 +138,19 @@ namespace SeamlessClientPlugin
if (MyAPIGateway.Multiplayer == null) if (MyAPIGateway.Multiplayer == null)
return; return;
if (!Initilized) if (!Initilized)
{ {
Patches.GetPatches();
TryShow("Initilizing Communications!"); TryShow("Initilizing Communications!");
RunInitilizations(); RunInitilizations();
} }
//OnNewPlayerRequest
//throw new NotImplementedException();
} }
private void PingTimer_Elapsed(object sender, ElapsedEventArgs e)
{
// Terrible way to make sure server knows we are running seamless client
try
{
ClientMessage PingServer = new ClientMessage(ClientMessageType.FirstJoin);
MyAPIGateway.Multiplayer?.SendMessageToServer(SeamlessClientNetID, Utilities.Utility.Serialize(PingServer));
}
catch (Exception ex)
{
//TryShow(ex.ToString());
}
}
public static void RunInitilizations() public static void RunInitilizations()
{ {
MyAPIGateway.Multiplayer.RegisterSecureMessageHandler(SeamlessClientNetID, MessageHandler); MyAPIGateway.Multiplayer.RegisterSecureMessageHandler(SeamlessClientNetID, MessageHandler);
@@ -177,7 +159,6 @@ namespace SeamlessClientPlugin
public static void DisposeInitilizations() public static void DisposeInitilizations()
{ {
PingTimer.Stop();
MyAPIGateway.Multiplayer?.UnregisterSecureMessageHandler(SeamlessClientNetID, MessageHandler); MyAPIGateway.Multiplayer?.UnregisterSecureMessageHandler(SeamlessClientNetID, MessageHandler);
Initilized = false; Initilized = false;
@@ -189,12 +170,17 @@ namespace SeamlessClientPlugin
try try
{ {
ClientMessage Recieved = Utilities.Utility.Deserialize<ClientMessage>(obj2); ClientMessage Recieved = Utilities.Utility.Deserialize<ClientMessage>(obj2);
if (Recieved.MessageType == ClientMessageType.TransferServer)
if(Recieved.MessageType == ClientMessageType.FirstJoin)
{ {
//Server sent a first join message! Send a reply back so the server knows what version we are on
ClientMessage PingServer = new ClientMessage(ClientMessageType.FirstJoin);
MyAPIGateway.Multiplayer?.SendMessageToServer(SeamlessClientNetID, Utilities.Utility.Serialize(PingServer));
}
else if (Recieved.MessageType == ClientMessageType.TransferServer)
{
//Server sent a transfer message! Begin transfer via seamless
Transfer TransferMessage = Recieved.GetTransferData(); Transfer TransferMessage = Recieved.GetTransferData();
ServerPing.StartServerPing(TransferMessage); ServerPing.StartServerPing(TransferMessage);
} }
} }
@@ -213,6 +199,8 @@ namespace SeamlessClientPlugin
MyLog.Default?.WriteLineAndConsole($"SeamlessClient: {message}"); MyLog.Default?.WriteLineAndConsole($"SeamlessClient: {message}");
} }
public void Dispose() public void Dispose()
{ {
DisposeInitilizations(); DisposeInitilizations();

View File

@@ -163,6 +163,7 @@
<Compile Include="SeamlessClient.cs" /> <Compile Include="SeamlessClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SeamlessTransfer\ModLoader.cs" /> <Compile Include="SeamlessTransfer\ModLoader.cs" />
<Compile Include="SeamlessTransfer\MyScriptManagerLoader.cs" />
<Compile Include="SeamlessTransfer\PingServer.cs" /> <Compile Include="SeamlessTransfer\PingServer.cs" />
<Compile Include="Messages\Transfer.cs" /> <Compile Include="Messages\Transfer.cs" />
<Compile Include="Utilities\Patches.cs" /> <Compile Include="Utilities\Patches.cs" />

View File

@@ -1,12 +1,20 @@
using System; using Sandbox.Definitions;
using Sandbox.Engine.Networking;
using Sandbox.Game.World;
using Sandbox.ModAPI;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using VRage.Game;
using VRage.Game.GUI;
namespace SeamlessClientPlugin.SeamlessTransfer namespace SeamlessClientPlugin.SeamlessTransfer
{ {
public class ModLoader public static class ModLoader
{ {
/* Mod loader should download and load missing mods for target server, and unload ones that arent needed /* Mod loader should download and load missing mods for target server, and unload ones that arent needed
* *
@@ -22,5 +30,144 @@ namespace SeamlessClientPlugin.SeamlessTransfer
* *
*/ */
//Mods that are currently loaded in this instance.
private static List<MyObjectBuilder_Checkpoint.ModItem> CurrentLoadedMods = new List<MyObjectBuilder_Checkpoint.ModItem>();
//Mods that we need to Load
private static List<MyObjectBuilder_Checkpoint.ModItem> TargetLoadMods = new List<MyObjectBuilder_Checkpoint.ModItem>();
//Mods that we need to UnLoad
private static List<MyObjectBuilder_Checkpoint.ModItem> TargetUnLoadMods = new List<MyObjectBuilder_Checkpoint.ModItem>();
private static bool FinishedDownloadingMods = false;
private static bool DownloadSuccess = false;
private static DateTime DownloadTimeout;
private static MethodInfo PrepareBaseSession = typeof(MySession).GetMethod("PreloadModels", BindingFlags.Static | BindingFlags.NonPublic);
private static FieldInfo ScriptManager = typeof(MySession).GetField("ScriptManager", BindingFlags.Instance | BindingFlags.Public);
public static void DownloadNewMods(List<MyObjectBuilder_Checkpoint.ModItem> Target)
{
CurrentLoadedMods = MySession.Static.Mods;
//Loop through our current mods
foreach(var mod in CurrentLoadedMods)
{
if (!Target.Contains(mod))
TargetUnLoadMods.Add(mod);
}
//Loop through our TargetMods
foreach(var mod in Target)
{
if (!CurrentLoadedMods.Contains(mod))
TargetLoadMods.Add(mod);
}
DownloadTimeout = DateTime.Now + TimeSpan.FromMinutes(5);
SeamlessClient.TryShow("Downloading New Mods");
MyWorkshop.DownloadModsAsync(TargetLoadMods, ModDownloadingFinished);
}
private static void ModDownloadingFinished(bool Success)
{
if (Success)
{
SeamlessClient.TryShow("Mod Downloading Finished!");
FinishedDownloadingMods = true;
DownloadSuccess = true;
//May need to wait seamless loading if mods have yet to finish downloading
}
else
{
DownloadSuccess = false;
FinishedDownloadingMods = true;
}
}
public static void ReadyModSwitch(MyObjectBuilder_Checkpoint checkpoint, MyObjectBuilder_Sector sector)
{
while (!FinishedDownloadingMods)
{
//Break out of loop
if (DownloadTimeout < DateTime.Now)
break;
Thread.Sleep(20);
}
FinishedDownloadingMods = false;
//Skip mod switch
if (!DownloadSuccess)
return;
//Create new script manager?
ScriptManager.SetValue(MySession.Static, new MyScriptManager());
MyGuiTextures.Static.Unload();
MySession.Static.ScriptManager.Init(checkpoint.ScriptManagerData);
//MyDefinitionManager.Static.LoadData(TargetServerMods);
PrepareBaseSession.Invoke(null, new object[] { sector });
MyLocalCache.PreloadLocalInventoryConfig();
//SeamlessClient.TryShow("Finished transfering!");
// PrepareBaseSession.Invoke(MySession.Static, new object[] { TargetServerMods, null });
}
private static void UnloadOldScripts()
{
// MySandboxGame.Log.WriteLine(string.Format("Script loaded: {0}", value.FullName));
int amount = 0;
foreach (var mod in TargetUnLoadMods)
{
var val = MySession.Static.ScriptManager.Scripts.FirstOrDefault(x => x.Value.FullName.Contains(mod.PublishedFileId.ToString()));
MySession.Static.ScriptManager.Scripts.Remove(val.Key);
amount++;
}
SeamlessClient.TryShow($"Removed {amount} old scripts!");
}
} }
} }

View File

@@ -0,0 +1,83 @@
using Sandbox;
using Sandbox.Game.World;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SeamlessClientPlugin.SeamlessTransfer
{
public class MyScriptManagerLoader
{
/*
public void LoadData(MyScriptManager __instance)
{
MySandboxGame.Log.WriteLine("MyScriptManager.LoadData() - START");
MySandboxGame.Log.IncreaseIndent();
MyScriptManager.Static = __instance;
__instance.Scripts.Clear();
__instance.EntityScripts.Clear();
__instance.SubEntityScripts.Clear();
TryAddEntityScripts(MyModContext.BaseGame, MyPlugins.SandboxAssembly);
TryAddEntityScripts(MyModContext.BaseGame, MyPlugins.SandboxGameAssembly);
if (MySession.Static.CurrentPath != null)
{
LoadScripts(MySession.Static.CurrentPath, MyModContext.BaseGame);
}
if (MySession.Static.Mods != null)
{
bool isServer = Sync.IsServer;
foreach (MyObjectBuilder_Checkpoint.ModItem mod in MySession.Static.Mods)
{
bool flag = false;
if (mod.IsModData())
{
ListReader<string> tags = mod.GetModData().Tags;
if (tags.Contains(MySteamConstants.TAG_SERVER_SCRIPTS) && !isServer)
{
continue;
}
flag = tags.Contains(MySteamConstants.TAG_NO_SCRIPTS);
}
MyModContext myModContext = (MyModContext)mod.GetModContext();
try
{
LoadScripts(mod.GetPath(), myModContext);
}
catch (MyLoadingRuntimeCompilationNotSupportedException)
{
if (flag)
{
MyVRage.Platform.Scripting.ReportIncorrectBehaviour(MyCommonTexts.ModRuleViolation_RuntimeScripts);
continue;
}
throw;
}
catch (Exception ex2)
{
MyLog.Default.WriteLine(string.Format("Fatal error compiling {0}:{1} - {2}. This item is likely not a mod and should be removed from the mod list.", myModContext.ModServiceName, myModContext.ModId, myModContext.ModName));
MyLog.Default.WriteLine(ex2);
throw;
}
}
}
foreach (Assembly value in Scripts.Values)
{
if (MyFakes.ENABLE_TYPES_FROM_MODS)
{
MyGlobalTypeMetadata.Static.RegisterAssembly(value);
}
MySandboxGame.Log.WriteLine(string.Format("Script loaded: {0}", value.FullName));
}
MyTextSurfaceScriptFactory.LoadScripts();
MyUseObjectFactory.RegisterAssemblyTypes(Scripts.Values.ToArray());
MySandboxGame.Log.DecreaseIndent();
MySandboxGame.Log.WriteLine("MyScriptManager.LoadData() - END");
}
*/
}
}

View File

@@ -40,13 +40,10 @@ namespace SeamlessClientPlugin.SeamlessTransfer
SeamlessClient.TryShow("Beginning Redirect to server: " + Transfer.TargetServerID); SeamlessClient.TryShow("Beginning Redirect to server: " + Transfer.TargetServerID);
SwitchServers Switcher = new SwitchServers(E, Request.DeserializeWorldData()); SwitchServers Switcher = new SwitchServers(E, Request.DeserializeWorldData());
Switcher.BeginSwitch(); Switcher.BeginSwitch();
// MyGameService.OnPingServerResponded += PingResponded;
//MyGameService.OnPingServerFailedToRespond += FailedToRespond;
//MyGameService.PingServer(Transfer.IPAdress);
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using Sandbox; using Sandbox;
using Sandbox.Definitions;
using Sandbox.Engine.Multiplayer; using Sandbox.Engine.Multiplayer;
using Sandbox.Engine.Networking; using Sandbox.Engine.Networking;
using Sandbox.Game; using Sandbox.Game;
@@ -9,8 +10,10 @@ using Sandbox.Game.Multiplayer;
using Sandbox.Game.SessionComponents; using Sandbox.Game.SessionComponents;
using Sandbox.Game.World; using Sandbox.Game.World;
using Sandbox.Game.World.Generator; using Sandbox.Game.World.Generator;
using Sandbox.Graphics.GUI;
using Sandbox.ModAPI; using Sandbox.ModAPI;
using SeamlessClientPlugin.Utilities; using SeamlessClientPlugin.Utilities;
using SpaceEngineers.Game.GUI;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@@ -19,6 +22,7 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using VRage; using VRage;
using VRage.Collections;
using VRage.Game; using VRage.Game;
using VRage.Game.Components; using VRage.Game.Components;
using VRage.Game.ModAPI; using VRage.Game.ModAPI;
@@ -27,6 +31,7 @@ using VRage.Steam;
using VRage.Utils; using VRage.Utils;
using VRageMath; using VRageMath;
using VRageRender; using VRageRender;
using VRageRender.Messages;
namespace SeamlessClientPlugin.SeamlessTransfer namespace SeamlessClientPlugin.SeamlessTransfer
{ {
@@ -38,10 +43,15 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private string OldArmorSkin { get; set; } = string.Empty; private string OldArmorSkin { get; set; } = string.Empty;
public SwitchServers(MyGameServerItem TargetServer, MyObjectBuilder_World TargetWorld) public SwitchServers(MyGameServerItem TargetServer, MyObjectBuilder_World TargetWorld)
{ {
this.TargetServer = TargetServer; this.TargetServer = TargetServer;
this.TargetWorld = TargetWorld; this.TargetWorld = TargetWorld;
//ModLoader.DownloadNewMods(TargetWorld.Checkpoint.Mods);
} }
@@ -55,7 +65,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed); MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed);
UnloadCurrentServer(); UnloadCurrentServer();
SetNewMultiplayerClient(); SetNewMultiplayerClient();
SeamlessClient.IsSwitching = false;
}, "SeamlessClient"); }, "SeamlessClient");
@@ -90,10 +100,6 @@ namespace SeamlessClientPlugin.SeamlessTransfer
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName); Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
Sync.Players.RegisterEvents(); Sync.Players.RegisterEvents();
} }
@@ -112,30 +118,60 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private void ForceClientConnection() private void ForceClientConnection()
{ {
//Set World Settings
SetWorldSettings();
//Load force load any connected players
LoadConnectedClients();
MySector.InitEnvironmentSettings(TargetWorld.Sector.Environment);
string text = ((!string.IsNullOrEmpty(TargetWorld.Checkpoint.CustomSkybox)) ? TargetWorld.Checkpoint.CustomSkybox : MySector.EnvironmentDefinition.EnvironmentTexture);
MyRenderProxy.PreloadTextures(new string[1] { text }, TextureType.CubeMap);
MyModAPIHelper.Initialize();
MySession.Static.LoadDataComponents();
//MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents);
MyModAPIHelper.Initialize();
// MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents);
//MethodInfo A = typeof(MySession).GetMethod("LoadGameDefinition", BindingFlags.Instance | BindingFlags.NonPublic);
// A.Invoke(MySession.Static, new object[] { TargetWorld.Checkpoint });
MyHud.Chat.RegisterChat(MyMultiplayer.Static);
MyMultiplayer.Static.OnSessionReady(); MyMultiplayer.Static.OnSessionReady();
LoadConnectedClients();
LoadOnlinePlayers();
SetWorldSettings();
RemoveOldEntities(); RemoveOldEntities();
UpdateWorldGenerator(); UpdateWorldGenerator();
StartEntitySync(); StartEntitySync();
MyModAPIHelper.Initialize();
MyHud.Chat.RegisterChat(MyMultiplayer.Static);
Patches.GPSRegisterChat.Invoke(MySession.Static.Gpss, new object[] { MyMultiplayer.Static });
// Allow the game to start proccessing incoming messages in the buffer // Allow the game to start proccessing incoming messages in the buffer
MyMultiplayer.Static.StartProcessingClientMessages(); MyMultiplayer.Static.StartProcessingClientMessages();
//Recreate all controls... Will fix weird gui/paint/crap //Recreate all controls... Will fix weird gui/paint/crap
MyGuiScreenHudSpace.Static.RecreateControls(true); MyGuiScreenHudSpace.Static.RecreateControls(true);
//MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin; //MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin;
} }
private void LoadOnlinePlayers() private void LoadOnlinePlayers()
{ {
//Get This players ID //Get This players ID
@@ -289,7 +325,6 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private void LoadConnectedClients() private void LoadConnectedClients()
{ {
Patches.LoadMembersFromWorld.Invoke(MySession.Static, new object[] { TargetWorld, MyMultiplayer.Static }); Patches.LoadMembersFromWorld.Invoke(MySession.Static, new object[] { TargetWorld, MyMultiplayer.Static });
@@ -297,13 +332,9 @@ namespace SeamlessClientPlugin.SeamlessTransfer
object VirtualClientsValue = Patches.VirtualClients.GetValue(MySession.Static); object VirtualClientsValue = Patches.VirtualClients.GetValue(MySession.Static);
Patches.InitVirtualClients.Invoke(VirtualClientsValue, null); Patches.InitVirtualClients.Invoke(VirtualClientsValue, null);
/*
SeamlessClient.TryShow("Loading exsisting Members From World!"); //load online players
foreach (var Client in TargetWorld.Checkpoint.Clients) LoadOnlinePlayers();
{
SeamlessClient.TryShow("Adding New Client: " + Client.Name);
Sync.Clients.AddClient(Client.SteamId, Client.Name);
}*/
} }
@@ -342,6 +373,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
MyMultiplayer.Static.PendingReplicablesDone -= MyMultiplayer_PendingReplicablesDone; MyMultiplayer.Static.PendingReplicablesDone -= MyMultiplayer_PendingReplicablesDone;
} }
private void UpdateWorldGenerator() private void UpdateWorldGenerator()
{ {
//This will re-init the MyProceduralWorldGenerator. (Not doing this will result in asteroids not rendering in properly) //This will re-init the MyProceduralWorldGenerator. (Not doing this will result in asteroids not rendering in properly)
@@ -361,12 +393,9 @@ namespace SeamlessClientPlugin.SeamlessTransfer
Generator.Init(GeneratorSettings); Generator.Init(GeneratorSettings);
} }
//Force component to reload, re-syncing settings and seeds to the destination server //Force component to reload, re-syncing settings and seeds to the destination server
Generator.LoadData(); Generator.LoadData();
//We need to go in and force planets to be empty areas in the generator. This is originially done on planet init. //We need to go in and force planets to be empty areas in the generator. This is originially done on planet init.
FieldInfo PlanetInitArgs = typeof(MyPlanet).GetField("m_planetInitValues", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); FieldInfo PlanetInitArgs = typeof(MyPlanet).GetField("m_planetInitValues", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
foreach (var Planet in MyEntities.GetEntities().OfType<MyPlanet>()) foreach (var Planet in MyEntities.GetEntities().OfType<MyPlanet>())
@@ -401,6 +430,12 @@ namespace SeamlessClientPlugin.SeamlessTransfer
MyMultiplayer.Static.ReplicationLayer.Dispose(); MyMultiplayer.Static.ReplicationLayer.Dispose();
MyMultiplayer.Static.Dispose(); MyMultiplayer.Static.Dispose();
MyMultiplayer.Static = null; MyMultiplayer.Static = null;
//Close any respawn screens that are open
MyGuiScreenMedicals.Close();
//MySession.Static.UnloadDataComponents();
} }
private void RemoveOldEntities() private void RemoveOldEntities()

View File

@@ -3,12 +3,15 @@ using Sandbox.Engine.Analytics;
using Sandbox.Engine.Multiplayer; using Sandbox.Engine.Multiplayer;
using Sandbox.Engine.Networking; using Sandbox.Engine.Networking;
using Sandbox.Game; using Sandbox.Game;
using Sandbox.Game.Entities;
using Sandbox.Game.Gui; using Sandbox.Game.Gui;
using Sandbox.Game.Multiplayer; using Sandbox.Game.Multiplayer;
using Sandbox.Game.World; using Sandbox.Game.World;
using Sandbox.Game.World.Generator; using Sandbox.Game.World.Generator;
using Sandbox.Graphics; using Sandbox.Graphics;
using Sandbox.Graphics.GUI; using Sandbox.Graphics.GUI;
using Sandbox.ModAPI;
using SeamlessClientPlugin.ClientMessages;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -17,8 +20,10 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using VRage; using VRage;
using VRage.Collections;
using VRage.FileSystem; using VRage.FileSystem;
using VRage.Game; using VRage.Game;
using VRage.Game.Entity;
using VRage.GameServices; using VRage.GameServices;
using VRage.Network; using VRage.Network;
using VRage.Utils; using VRage.Utils;
@@ -64,6 +69,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
public static MethodInfo LoadPlayerInternal { get; private set; } public static MethodInfo LoadPlayerInternal { get; private set; }
public static MethodInfo LoadMembersFromWorld { get; private set; } public static MethodInfo LoadMembersFromWorld { get; private set; }
public static MethodInfo LoadMultiplayer { get; private set; } public static MethodInfo LoadMultiplayer { get; private set; }
public static MethodInfo GPSRegisterChat { get; private set; }
public static MethodInfo SendPlayerData; public static MethodInfo SendPlayerData;
@@ -77,6 +83,8 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private static FieldInfo MBuffer;
public static void GetPatches() public static void GetPatches()
{ {
//Get reflected values and store them //Get reflected values and store them
@@ -99,7 +107,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
RemoteAdminSettings = GetField(typeof(MySession), "m_remoteAdminSettings", BindingFlags.Instance | BindingFlags.NonPublic); RemoteAdminSettings = GetField(typeof(MySession), "m_remoteAdminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
MPlayerGPSCollection = GetField(typeof(MyPlayerCollection), "m_players", BindingFlags.Instance | BindingFlags.NonPublic); MPlayerGPSCollection = GetField(typeof(MyPlayerCollection), "m_players", BindingFlags.Instance | BindingFlags.NonPublic);
MBuffer = GetField(MyTransportLayerType, "m_buffer", BindingFlags.Instance | BindingFlags.NonPublic);
/* Get Methods */ /* Get Methods */
@@ -111,27 +119,46 @@ namespace SeamlessClientPlugin.SeamlessTransfer
LoadMultiplayer = GetMethod(typeof(MySession), "LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic); LoadMultiplayer = GetMethod(typeof(MySession), "LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic);
SendPlayerData = GetMethod(ClientType, "SendPlayerData", BindingFlags.Instance | BindingFlags.NonPublic); SendPlayerData = GetMethod(ClientType, "SendPlayerData", BindingFlags.Instance | BindingFlags.NonPublic);
UnloadProceduralWorldGenerator = GetMethod(typeof(MyProceduralWorldGenerator), "UnloadData", BindingFlags.Instance | BindingFlags.NonPublic); UnloadProceduralWorldGenerator = GetMethod(typeof(MyProceduralWorldGenerator), "UnloadData", BindingFlags.Instance | BindingFlags.NonPublic);
GPSRegisterChat = GetMethod(typeof(MyGpsCollection), "RegisterChat", BindingFlags.Instance | BindingFlags.NonPublic);
//MethodInfo ConnectToServer = GetMethod(typeof(MyGameService), "ConnectToServer", BindingFlags.Static | BindingFlags.Public);
MethodInfo ConnectToServer = GetMethod(typeof(MyGameService), "ConnectToServer", BindingFlags.Static | BindingFlags.Public);
MethodInfo LoadingScreenDraw = GetMethod(typeof(MyGuiScreenLoading), "DrawInternal", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo LoadingScreenDraw = GetMethod(typeof(MyGuiScreenLoading), "DrawInternal", BindingFlags.Instance | BindingFlags.NonPublic);
//Test patches
//MethodInfo SetPlayerDed = GetMethod(typeof(MyPlayerCollection), "SetPlayerDeadInternal", BindingFlags.Instance | BindingFlags.NonPublic);
Patcher.Patch(LoadingScreenDraw, prefix: new HarmonyMethod(GetPatchMethod(nameof(DrawInternal)))); Patcher.Patch(LoadingScreenDraw, prefix: new HarmonyMethod(GetPatchMethod(nameof(DrawInternal))));
Patcher.Patch(OnJoin, postfix: new HarmonyMethod(GetPatchMethod(nameof(OnUserJoined)))); Patcher.Patch(OnJoin, postfix: new HarmonyMethod(GetPatchMethod(nameof(OnUserJoined))));
Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession)))); Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession))));
//Patcher.Patch(ConnectToServer, prefix: new HarmonyMethod(GetPatchMethod(nameof(OnConnectToServer)))); //Patcher.Patch(SetPlayerDed, prefix: new HarmonyMethod(GetPatchMethod(nameof(SetPlayerDeadInternal))));
} }
private static MethodInfo GetPatchMethod(string v) private static MethodInfo GetPatchMethod(string v)
{ {
return typeof(Patches).GetMethod(v, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); return typeof(Patches).GetMethod(v, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
} }
#region LoadingScreen #region LoadingScreen
/* Loading Screen Stuff */ /* Loading Screen Stuff */
@@ -142,6 +169,9 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession) private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
{ {
//
MyLog.Default.WriteLine("LoadSession() - Start"); MyLog.Default.WriteLine("LoadSession() - Start");
if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, allowLocalMods: false)) if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, allowLocalMods: false))
@@ -150,6 +180,11 @@ namespace SeamlessClientPlugin.SeamlessTransfer
MyLog.Default.WriteLine("LoadSession() - End"); MyLog.Default.WriteLine("LoadSession() - End");
return false; return false;
} }
MyLog.Default.WriteLine("Seamless Downloading mods!");
MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, delegate (bool success) MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, delegate (bool success)
{ {
if (success) if (success)
@@ -302,6 +337,9 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
} }
private static bool OnConnectToServer(MyGameServerItem server, Action<JoinResult> onDone) private static bool OnConnectToServer(MyGameServerItem server, Action<JoinResult> onDone)
{ {
if (SeamlessClient.IsSwitching) if (SeamlessClient.IsSwitching)
@@ -315,6 +353,10 @@ namespace SeamlessClientPlugin.SeamlessTransfer
/* Patch Utils */
private static MethodInfo GetMethod(Type type, string MethodName, BindingFlags Flags) private static MethodInfo GetMethod(Type type, string MethodName, BindingFlags Flags)
{ {
try try
@@ -393,10 +435,6 @@ namespace SeamlessClientPlugin.SeamlessTransfer
{ {
throw Ex; throw Ex;
} }
}
}
} }
} }