@@ -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();
|
||||||
|
@@ -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" />
|
||||||
|
@@ -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!");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
83
SeamlessTransfer/MyScriptManagerLoader.cs
Normal file
83
SeamlessTransfer/MyScriptManagerLoader.cs
Normal 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");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user