fixes for nexus v3
This commit is contained in:
@@ -1,173 +1,136 @@
|
||||
using Sandbox.Definitions;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Game.World;
|
||||
using Sandbox.ModAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using VRage.Game;
|
||||
using VRage.Game.GUI;
|
||||
using VRage.GameServices;
|
||||
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer;
|
||||
|
||||
public static class ModLoader
|
||||
{
|
||||
public static class ModLoader
|
||||
/* Mod loader should download and load missing mods for target server, and unload ones that arent needed
|
||||
*
|
||||
* Sandbox.Game.World.MyScriptManager.LoadData() is where modded scripts get loaded and added
|
||||
* Sandbox.Game.World.MySession() calls MyDefinitionManager.Static.LoadData(mods); which loads mod data files
|
||||
*
|
||||
*
|
||||
* Need to be called in the following order:
|
||||
* ScriptManager.Init(checkpoint.ScriptManagerData);
|
||||
* MyDefinitionManager.Static.LoadData(checkpoint.Mods);
|
||||
* PreloadModels(sector);
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
//Mods that are currently loaded in this instance.
|
||||
private static List<MyObjectBuilder_Checkpoint.ModItem> _currentLoadedMods = [];
|
||||
|
||||
|
||||
//Mods that we need to Load
|
||||
private static readonly List<MyObjectBuilder_Checkpoint.ModItem> TargetLoadMods = [];
|
||||
|
||||
//Mods that we need to UnLoad
|
||||
private static readonly List<MyObjectBuilder_Checkpoint.ModItem> TargetUnLoadMods = [];
|
||||
|
||||
|
||||
private static bool _finishedDownloadingMods;
|
||||
private static bool _downloadSuccess;
|
||||
|
||||
private static DateTime _downloadTimeout;
|
||||
|
||||
|
||||
public static void DownloadNewMods(List<MyObjectBuilder_Checkpoint.ModItem> target)
|
||||
{
|
||||
/* Mod loader should download and load missing mods for target server, and unload ones that arent needed
|
||||
*
|
||||
* Sandbox.Game.World.MyScriptManager.LoadData() is where modded scripts get loaded and added
|
||||
* Sandbox.Game.World.MySession() calls MyDefinitionManager.Static.LoadData(mods); which loads mod data files
|
||||
*
|
||||
*
|
||||
* Need to be called in the following order:
|
||||
* ScriptManager.Init(checkpoint.ScriptManagerData);
|
||||
* MyDefinitionManager.Static.LoadData(checkpoint.Mods);
|
||||
* PreloadModels(sector);
|
||||
*
|
||||
*
|
||||
*/
|
||||
_currentLoadedMods = MySession.Static.Mods;
|
||||
|
||||
|
||||
//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!");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//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(MyGameServiceCallResult result)
|
||||
{
|
||||
if (result == MyGameServiceCallResult.OK)
|
||||
{
|
||||
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?
|
||||
MySession.Static.ScriptManager = new();
|
||||
|
||||
|
||||
MyGuiTextures.Static.Unload();
|
||||
MySession.Static.ScriptManager.Init(checkpoint.ScriptManagerData);
|
||||
//MyDefinitionManager.Static.LoadData(TargetServerMods);
|
||||
MySession.PreloadModels(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));
|
||||
var 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!");
|
||||
}
|
||||
}
|
@@ -1,83 +1,73 @@
|
||||
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;
|
||||
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer
|
||||
public class MyScriptManagerLoader
|
||||
{
|
||||
public class MyScriptManagerLoader
|
||||
/*
|
||||
public void LoadData(MyScriptManager __instance)
|
||||
{
|
||||
/*
|
||||
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();
|
||||
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);
|
||||
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");
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
*/
|
||||
}
|
@@ -1,51 +1,41 @@
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Game.Multiplayer;
|
||||
using SeamlessClientPlugin.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SeamlessClientPlugin.Messages;
|
||||
using VRage.GameServices;
|
||||
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer;
|
||||
|
||||
public class ServerPing
|
||||
{
|
||||
public class ServerPing
|
||||
private static Transfer _transfer;
|
||||
|
||||
private static WorldRequest Request => _transfer.WorldRequest;
|
||||
|
||||
|
||||
public static void StartServerPing(Transfer clientTransfer)
|
||||
{
|
||||
|
||||
private static WorldRequest Request { get { return Transfer.WorldRequest; } }
|
||||
private static Transfer Transfer;
|
||||
// We need to first ping the server to make sure its running and so we can get a connection
|
||||
_transfer = clientTransfer;
|
||||
|
||||
|
||||
public static void StartServerPing(Transfer ClientTransfer)
|
||||
if (_transfer.TargetServerId == 0)
|
||||
{
|
||||
// We need to first ping the server to make sure its running and so we can get a connection
|
||||
Transfer = ClientTransfer;
|
||||
|
||||
|
||||
if (Transfer.TargetServerID == 0)
|
||||
{
|
||||
SeamlessClient.TryShow("This is not a valid server!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MyGameServerItem E = new MyGameServerItem();
|
||||
E.ConnectionString = Transfer.IPAdress;
|
||||
E.SteamID = Transfer.TargetServerID;
|
||||
E.Name = Transfer.ServerName;
|
||||
|
||||
|
||||
|
||||
SeamlessClient.TryShow("Beginning Redirect to server: " + Transfer.TargetServerID);
|
||||
|
||||
|
||||
var world = Request.DeserializeWorldData();
|
||||
|
||||
|
||||
SwitchServers Switcher = new SwitchServers(E, world);
|
||||
Switcher.BeginSwitch();
|
||||
SeamlessClient.TryShow("This is not a valid server!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var e = new MyGameServerItem();
|
||||
e.ConnectionString = _transfer.IpAdress;
|
||||
e.SteamID = _transfer.TargetServerId;
|
||||
e.Name = _transfer.ServerName;
|
||||
|
||||
|
||||
SeamlessClient.TryShow($"Beginning Redirect to server: {_transfer.TargetServerId}");
|
||||
|
||||
|
||||
var world = Request.DeserializeWorldData();
|
||||
|
||||
|
||||
var switcher = new SwitchServers(e, world);
|
||||
switcher.BeginSwitch();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,4 @@
|
||||
using Sandbox;
|
||||
using Sandbox.Definitions;
|
||||
using Sandbox.Engine.Multiplayer;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Game;
|
||||
@@ -10,459 +9,383 @@ using Sandbox.Game.Multiplayer;
|
||||
using Sandbox.Game.SessionComponents;
|
||||
using Sandbox.Game.World;
|
||||
using Sandbox.Game.World.Generator;
|
||||
using Sandbox.Graphics.GUI;
|
||||
using Sandbox.ModAPI;
|
||||
using SeamlessClientPlugin.Utilities;
|
||||
using SpaceEngineers.Game.GUI;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VRage;
|
||||
using VRage.Collections;
|
||||
using VRage.Game;
|
||||
using VRage.Game.Components;
|
||||
using VRage.Game.ModAPI;
|
||||
using VRage.GameServices;
|
||||
using VRage.Steam;
|
||||
using VRage.Network;
|
||||
using VRage.Utils;
|
||||
using VRageMath;
|
||||
using VRageRender;
|
||||
using VRageRender.Messages;
|
||||
using Game = Sandbox.Engine.Platform.Game;
|
||||
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer;
|
||||
|
||||
public class SwitchServers
|
||||
{
|
||||
public class SwitchServers
|
||||
public SwitchServers(MyGameServerItem targetServer, MyObjectBuilder_World targetWorld)
|
||||
{
|
||||
public MyGameServerItem TargetServer { get; }
|
||||
public MyObjectBuilder_World TargetWorld { get; }
|
||||
|
||||
private string OldArmorSkin { get; set; } = string.Empty;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public SwitchServers(MyGameServerItem TargetServer, MyObjectBuilder_World TargetWorld)
|
||||
{
|
||||
this.TargetServer = TargetServer;
|
||||
this.TargetWorld = TargetWorld;
|
||||
|
||||
//ModLoader.DownloadNewMods(TargetWorld.Checkpoint.Mods);
|
||||
}
|
||||
|
||||
|
||||
public void BeginSwitch()
|
||||
{
|
||||
OldArmorSkin = MySession.Static.LocalHumanPlayer.BuildArmorSkin;
|
||||
|
||||
MySandboxGame.Static.Invoke(delegate
|
||||
{
|
||||
//Set camera controller to fixed spectator
|
||||
MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed);
|
||||
UnloadCurrentServer();
|
||||
SetNewMultiplayerClient();
|
||||
SeamlessClient.IsSwitching = false;
|
||||
|
||||
|
||||
}, "SeamlessClient");
|
||||
}
|
||||
|
||||
|
||||
private void SetNewMultiplayerClient()
|
||||
{
|
||||
// Following is called when the multiplayer is set successfully to target server
|
||||
Patches.OnJoinEvent += OnJoinEvent;
|
||||
|
||||
|
||||
MySandboxGame.Static.SessionCompatHelper.FixSessionComponentObjectBuilders(TargetWorld.Checkpoint, TargetWorld.Sector);
|
||||
|
||||
// Create constructors
|
||||
var LayerInstance = Patches.TransportLayerConstructor.Invoke(new object[] { 2 });
|
||||
var SyncInstance = Patches.SyncLayerConstructor.Invoke(new object[] { LayerInstance });
|
||||
var instance = Patches.ClientConstructor.Invoke(new object[] { TargetServer, SyncInstance });
|
||||
|
||||
|
||||
MyMultiplayer.Static = Utility.CastToReflected(instance, Patches.ClientType);
|
||||
MyMultiplayer.Static.ExperimentalMode = true;
|
||||
|
||||
|
||||
|
||||
// Set the new SyncLayer to the MySession.Static.SyncLayer
|
||||
Patches.MySessionLayer.SetValue(MySession.Static, MyMultiplayer.Static.SyncLayer);
|
||||
|
||||
SeamlessClient.TryShow("Successfully set MyMultiplayer.Static");
|
||||
|
||||
|
||||
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
|
||||
Sync.Players.RegisterEvents();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void OnJoinEvent(object sender, VRage.Network.JoinResultMsg e)
|
||||
{
|
||||
ForceClientConnection();
|
||||
|
||||
// Un-register the event
|
||||
Patches.OnJoinEvent -= OnJoinEvent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 });
|
||||
|
||||
|
||||
|
||||
MyMultiplayer.Static.OnSessionReady();
|
||||
|
||||
|
||||
UpdateWorldGenerator();
|
||||
|
||||
StartEntitySync();
|
||||
|
||||
|
||||
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
|
||||
MyMultiplayer.Static.StartProcessingClientMessages();
|
||||
|
||||
//Recreate all controls... Will fix weird gui/paint/crap
|
||||
MyGuiScreenHudSpace.Static.RecreateControls(true);
|
||||
//MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void LoadOnlinePlayers()
|
||||
{
|
||||
//Get This players ID
|
||||
|
||||
MyPlayer.PlayerId? savingPlayerId = new MyPlayer.PlayerId(Sync.MyId);
|
||||
if (!savingPlayerId.HasValue)
|
||||
{
|
||||
SeamlessClient.TryShow("SavingPlayerID is null! Creating Default!");
|
||||
savingPlayerId = new MyPlayer.PlayerId(Sync.MyId);
|
||||
}
|
||||
SeamlessClient.TryShow("Saving PlayerID: " + savingPlayerId.ToString());
|
||||
|
||||
Sync.Players.LoadConnectedPlayers(TargetWorld.Checkpoint, savingPlayerId);
|
||||
Sync.Players.LoadControlledEntities(TargetWorld.Checkpoint.ControlledEntities, TargetWorld.Checkpoint.ControlledObject, savingPlayerId);
|
||||
/*
|
||||
|
||||
|
||||
SeamlessClient.TryShow("Saving PlayerID: " + savingPlayerId.ToString());
|
||||
|
||||
|
||||
|
||||
foreach (KeyValuePair<MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player> item3 in TargetWorld.Checkpoint.AllPlayersData.Dictionary)
|
||||
{
|
||||
MyPlayer.PlayerId playerId5 = new MyPlayer.PlayerId(item3.Key.GetClientId(), item3.Key.SerialId);
|
||||
|
||||
SeamlessClient.TryShow($"ConnectedPlayer: {playerId5.ToString()}");
|
||||
if (savingPlayerId.HasValue && playerId5.SteamId == savingPlayerId.Value.SteamId)
|
||||
{
|
||||
playerId5 = new MyPlayer.PlayerId(Sync.MyId, playerId5.SerialId);
|
||||
}
|
||||
|
||||
Patches.LoadPlayerInternal.Invoke(MySession.Static.Players, new object[] { playerId5, item3.Value, false });
|
||||
ConcurrentDictionary<MyPlayer.PlayerId, MyPlayer> Players = (ConcurrentDictionary<MyPlayer.PlayerId, MyPlayer>)Patches.MPlayerGPSCollection.GetValue(MySession.Static.Players);
|
||||
//LoadPlayerInternal(ref playerId5, item3.Value);
|
||||
if (Players.TryGetValue(playerId5, out MyPlayer myPlayer))
|
||||
{
|
||||
List<Vector3> value2 = null;
|
||||
if (TargetWorld.Checkpoint.AllPlayersColors != null && TargetWorld.Checkpoint.AllPlayersColors.Dictionary.TryGetValue(item3.Key, out value2))
|
||||
{
|
||||
myPlayer.SetBuildColorSlots(value2);
|
||||
}
|
||||
else if (TargetWorld.Checkpoint.CharacterToolbar != null && TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList != null && TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList.Count > 0)
|
||||
{
|
||||
myPlayer.SetBuildColorSlots(TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
private void SetWorldSettings()
|
||||
{
|
||||
//MyEntities.MemoryLimitAddFailureReset();
|
||||
|
||||
//Clear old list
|
||||
MySession.Static.PromotedUsers.Clear();
|
||||
MySession.Static.CreativeTools.Clear();
|
||||
Dictionary<ulong, AdminSettingsEnum> AdminSettingsList = (Dictionary<ulong, AdminSettingsEnum>)Patches.RemoteAdminSettings.GetValue(MySession.Static);
|
||||
AdminSettingsList.Clear();
|
||||
|
||||
|
||||
|
||||
// Set new world settings
|
||||
MySession.Static.Name = MyStatControlText.SubstituteTexts(TargetWorld.Checkpoint.SessionName);
|
||||
MySession.Static.Description = TargetWorld.Checkpoint.Description;
|
||||
|
||||
MySession.Static.Mods = TargetWorld.Checkpoint.Mods;
|
||||
MySession.Static.Settings = TargetWorld.Checkpoint.Settings;
|
||||
MySession.Static.CurrentPath = MyLocalCache.GetSessionSavesPath(MyUtils.StripInvalidChars(TargetWorld.Checkpoint.SessionName), contentFolder: false, createIfNotExists: false);
|
||||
MySession.Static.WorldBoundaries = TargetWorld.Checkpoint.WorldBoundaries;
|
||||
MySession.Static.InGameTime = MyObjectBuilder_Checkpoint.DEFAULT_DATE;
|
||||
MySession.Static.ElapsedGameTime = new TimeSpan(TargetWorld.Checkpoint.ElapsedGameTime);
|
||||
MySession.Static.Settings.EnableSpectator = false;
|
||||
|
||||
MySession.Static.Password = TargetWorld.Checkpoint.Password;
|
||||
MySession.Static.PreviousEnvironmentHostility = TargetWorld.Checkpoint.PreviousEnvironmentHostility;
|
||||
MySession.Static.RequiresDX = TargetWorld.Checkpoint.RequiresDX;
|
||||
MySession.Static.CustomLoadingScreenImage = TargetWorld.Checkpoint.CustomLoadingScreenImage;
|
||||
MySession.Static.CustomLoadingScreenText = TargetWorld.Checkpoint.CustomLoadingScreenText;
|
||||
MySession.Static.CustomSkybox = TargetWorld.Checkpoint.CustomSkybox;
|
||||
|
||||
try
|
||||
{
|
||||
MySession.Static.Gpss = new MyGpsCollection();
|
||||
MySession.Static.Gpss.LoadGpss(TargetWorld.Checkpoint);
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
SeamlessClient.TryShow($"An error occured while loading GPS points! You will have an empty gps list! \n {ex.ToString()}");
|
||||
}
|
||||
|
||||
|
||||
MyRenderProxy.RebuildCullingStructure();
|
||||
//MySession.Static.Toolbars.LoadToolbars(checkpoint);
|
||||
|
||||
Sync.Players.RespawnComponent.InitFromCheckpoint(TargetWorld.Checkpoint);
|
||||
|
||||
|
||||
// Set new admin settings
|
||||
if (TargetWorld.Checkpoint.PromotedUsers != null)
|
||||
{
|
||||
MySession.Static.PromotedUsers = TargetWorld.Checkpoint.PromotedUsers.Dictionary;
|
||||
}
|
||||
else
|
||||
{
|
||||
MySession.Static.PromotedUsers = new Dictionary<ulong, MyPromoteLevel>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (KeyValuePair<MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player> item in TargetWorld.Checkpoint.AllPlayersData.Dictionary)
|
||||
{
|
||||
ulong clientId = item.Key.GetClientId();
|
||||
AdminSettingsEnum adminSettingsEnum = (AdminSettingsEnum)item.Value.RemoteAdminSettings;
|
||||
if (TargetWorld.Checkpoint.RemoteAdminSettings != null && TargetWorld.Checkpoint.RemoteAdminSettings.Dictionary.TryGetValue(clientId, out var value))
|
||||
{
|
||||
adminSettingsEnum = (AdminSettingsEnum)value;
|
||||
}
|
||||
if (!MyPlatformGameSettings.IsIgnorePcuAllowed)
|
||||
{
|
||||
adminSettingsEnum &= ~AdminSettingsEnum.IgnorePcu;
|
||||
adminSettingsEnum &= ~AdminSettingsEnum.KeepOriginalOwnershipOnPaste;
|
||||
}
|
||||
|
||||
|
||||
AdminSettingsList[clientId] = adminSettingsEnum;
|
||||
if (!Sync.IsDedicated && clientId == Sync.MyId)
|
||||
{
|
||||
Patches.AdminSettings.SetValue(MySession.Static, adminSettingsEnum);
|
||||
|
||||
//m_adminSettings = adminSettingsEnum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!MySession.Static.PromotedUsers.TryGetValue(clientId, out var value2))
|
||||
{
|
||||
value2 = MyPromoteLevel.None;
|
||||
}
|
||||
if (item.Value.PromoteLevel > value2)
|
||||
{
|
||||
MySession.Static.PromotedUsers[clientId] = item.Value.PromoteLevel;
|
||||
}
|
||||
if (!MySession.Static.CreativeTools.Contains(clientId) && item.Value.CreativeToolsEnabled)
|
||||
{
|
||||
MySession.Static.CreativeTools.Add(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void LoadConnectedClients()
|
||||
{
|
||||
|
||||
Patches.LoadMembersFromWorld.Invoke(MySession.Static, new object[] { TargetWorld, MyMultiplayer.Static });
|
||||
|
||||
|
||||
//Re-Initilize Virtual clients
|
||||
object VirtualClientsValue = Patches.VirtualClients.GetValue(MySession.Static);
|
||||
Patches.InitVirtualClients.Invoke(VirtualClientsValue, null);
|
||||
|
||||
|
||||
//load online players
|
||||
LoadOnlinePlayers();
|
||||
|
||||
}
|
||||
|
||||
private void StartEntitySync()
|
||||
{
|
||||
SeamlessClient.TryShow("Requesting Player From Server");
|
||||
Sync.Players.RequestNewPlayer(Sync.MyId, 0, MyGameService.UserName, null, realPlayer: true, initialPlayer: true);
|
||||
if (MySession.Static.ControlledEntity == null && Sync.IsServer && !Sandbox.Engine.Platform.Game.IsDedicated)
|
||||
{
|
||||
MyLog.Default.WriteLine("ControlledObject was null, respawning character");
|
||||
//m_cameraAwaitingEntity = true;
|
||||
MyPlayerCollection.RequestLocalRespawn();
|
||||
}
|
||||
|
||||
//Request client state batch
|
||||
(MyMultiplayer.Static as MyMultiplayerClientBase).RequestBatchConfirmation();
|
||||
MyMultiplayer.Static.PendingReplicablesDone += MyMultiplayer_PendingReplicablesDone;
|
||||
//typeof(MyGuiScreenTerminal).GetMethod("CreateTabs")
|
||||
|
||||
MySession.Static.LoadDataComponents();
|
||||
//MyGuiSandbox.LoadData(false);
|
||||
//MyGuiSandbox.AddScreen(MyGuiSandbox.CreateScreen(MyPerGameSettings.GUI.HUDScreen));
|
||||
MyRenderProxy.RebuildCullingStructure();
|
||||
MyRenderProxy.CollectGarbage();
|
||||
|
||||
SeamlessClient.TryShow("OnlinePlayers: " + MySession.Static.Players.GetOnlinePlayers().Count);
|
||||
SeamlessClient.TryShow("Loading Complete!");
|
||||
}
|
||||
|
||||
private void MyMultiplayer_PendingReplicablesDone()
|
||||
{
|
||||
if (MySession.Static.VoxelMaps.Instances.Count > 0)
|
||||
{
|
||||
MySandboxGame.AreClipmapsReady = false;
|
||||
}
|
||||
MyMultiplayer.Static.PendingReplicablesDone -= MyMultiplayer_PendingReplicablesDone;
|
||||
}
|
||||
|
||||
|
||||
private void UpdateWorldGenerator()
|
||||
{
|
||||
//This will re-init the MyProceduralWorldGenerator. (Not doing this will result in asteroids not rendering in properly)
|
||||
|
||||
|
||||
//This shoud never be null
|
||||
var Generator = MySession.Static.GetComponent<MyProceduralWorldGenerator>();
|
||||
|
||||
//Force component to unload
|
||||
Patches.UnloadProceduralWorldGenerator.Invoke(Generator, null);
|
||||
|
||||
//Re-call the generator init
|
||||
MyObjectBuilder_WorldGenerator GeneratorSettings = (MyObjectBuilder_WorldGenerator)TargetWorld.Checkpoint.SessionComponents.FirstOrDefault(x => x.GetType() == typeof(MyObjectBuilder_WorldGenerator));
|
||||
if (GeneratorSettings != null)
|
||||
{
|
||||
//Re-initilized this component (forces to update asteroid areas like not in planets etc)
|
||||
Generator.Init(GeneratorSettings);
|
||||
}
|
||||
|
||||
//Force component to reload, re-syncing settings and seeds to the destination server
|
||||
Generator.LoadData();
|
||||
|
||||
//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);
|
||||
foreach (var Planet in MyEntities.GetEntities().OfType<MyPlanet>())
|
||||
{
|
||||
MyPlanetInitArguments args = (MyPlanetInitArguments)PlanetInitArgs.GetValue(Planet);
|
||||
|
||||
float MaxRadius = args.MaxRadius;
|
||||
|
||||
Generator.MarkEmptyArea(Planet.PositionComp.GetPosition(), MaxRadius);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadCurrentServer()
|
||||
{
|
||||
//Unload current session on game thread
|
||||
if (MyMultiplayer.Static == null)
|
||||
throw new Exception("MyMultiplayer.Static is null on unloading? dafuq?");
|
||||
|
||||
|
||||
RemoveOldEntities();
|
||||
|
||||
//Try and close the quest log
|
||||
MySessionComponentIngameHelp component = MySession.Static.GetComponent<MySessionComponentIngameHelp>();
|
||||
component?.TryCancelObjective();
|
||||
|
||||
//Clear all old players and clients.
|
||||
Sync.Clients.Clear();
|
||||
Sync.Players.ClearPlayers();
|
||||
|
||||
|
||||
MyHud.Chat.UnregisterChat(MyMultiplayer.Static);
|
||||
|
||||
|
||||
|
||||
|
||||
MySession.Static.Gpss.RemovePlayerGpss(MySession.Static.LocalPlayerId);
|
||||
MyHud.GpsMarkers.Clear();
|
||||
MyMultiplayer.Static.ReplicationLayer.Disconnect();
|
||||
MyMultiplayer.Static.ReplicationLayer.Dispose();
|
||||
MyMultiplayer.Static.Dispose();
|
||||
MyMultiplayer.Static = null;
|
||||
|
||||
//Close any respawn screens that are open
|
||||
MyGuiScreenMedicals.Close();
|
||||
|
||||
//MySession.Static.UnloadDataComponents();
|
||||
|
||||
}
|
||||
|
||||
private void RemoveOldEntities()
|
||||
{
|
||||
foreach (var ent in MyEntities.GetEntities())
|
||||
{
|
||||
if (ent is MyPlanet)
|
||||
continue;
|
||||
|
||||
ent.Close();
|
||||
}
|
||||
}
|
||||
this.TargetServer = targetServer;
|
||||
this.TargetWorld = targetWorld;
|
||||
|
||||
//ModLoader.DownloadNewMods(TargetWorld.Checkpoint.Mods);
|
||||
}
|
||||
}
|
||||
|
||||
public MyGameServerItem TargetServer { get; }
|
||||
public MyObjectBuilder_World TargetWorld { get; }
|
||||
|
||||
private string OldArmorSkin { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public void BeginSwitch()
|
||||
{
|
||||
OldArmorSkin = MySession.Static.LocalHumanPlayer.BuildArmorSkin;
|
||||
|
||||
MySandboxGame.Static.Invoke(delegate
|
||||
{
|
||||
//Set camera controller to fixed spectator
|
||||
MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed);
|
||||
UnloadCurrentServer();
|
||||
SetNewMultiplayerClient();
|
||||
SeamlessClient.IsSwitching = false;
|
||||
}, "SeamlessClient");
|
||||
}
|
||||
|
||||
|
||||
private void SetNewMultiplayerClient()
|
||||
{
|
||||
// Following is called when the multiplayer is set successfully to target server
|
||||
Patches.OnJoinEvent += OnJoinEvent;
|
||||
|
||||
MySandboxGame.Static.SessionCompatHelper.FixSessionComponentObjectBuilders(TargetWorld.Checkpoint,
|
||||
TargetWorld.Sector);
|
||||
|
||||
// Create constructors
|
||||
var layerInstance = new MyTransportLayer(MyMultiplayer.GAME_EVENT_CHANNEL);
|
||||
var syncInstance = new MySyncLayer(layerInstance);
|
||||
var instance = new MyMultiplayerClient(TargetServer, syncInstance);
|
||||
|
||||
MyMultiplayer.Static = instance;
|
||||
MyMultiplayer.Static.ExperimentalMode = true;
|
||||
|
||||
// Set the new SyncLayer to the MySession.Static.SyncLayer
|
||||
MySession.Static.SyncLayer = MyMultiplayer.Static.SyncLayer;
|
||||
|
||||
SeamlessClient.TryShow("Successfully set MyMultiplayer.Static");
|
||||
|
||||
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
|
||||
Sync.Players.RegisterEvents();
|
||||
}
|
||||
|
||||
|
||||
private void OnJoinEvent(object sender, JoinResultMsg e)
|
||||
{
|
||||
ForceClientConnection();
|
||||
|
||||
// Un-register the event
|
||||
Patches.OnJoinEvent -= OnJoinEvent;
|
||||
}
|
||||
|
||||
|
||||
private void ForceClientConnection()
|
||||
{
|
||||
//Set World Settings
|
||||
SetWorldSettings();
|
||||
|
||||
//Load force load any connected players
|
||||
LoadConnectedClients();
|
||||
|
||||
|
||||
MySector.InitEnvironmentSettings(TargetWorld.Sector.Environment);
|
||||
|
||||
|
||||
var text = !string.IsNullOrEmpty(TargetWorld.Checkpoint.CustomSkybox)
|
||||
? TargetWorld.Checkpoint.CustomSkybox
|
||||
: MySector.EnvironmentDefinition.EnvironmentTexture;
|
||||
MyRenderProxy.PreloadTextures([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 });
|
||||
|
||||
|
||||
MyMultiplayer.Static.OnSessionReady();
|
||||
|
||||
|
||||
UpdateWorldGenerator();
|
||||
|
||||
StartEntitySync();
|
||||
|
||||
|
||||
MyHud.Chat.RegisterChat(MyMultiplayer.Static);
|
||||
MySession.Static.Gpss.RegisterChat(MyMultiplayer.Static);
|
||||
|
||||
|
||||
// Allow the game to start proccessing incoming messages in the buffer
|
||||
MyMultiplayer.Static.StartProcessingClientMessages();
|
||||
|
||||
//Recreate all controls... Will fix weird gui/paint/crap
|
||||
MyGuiScreenHudSpace.Static.RecreateControls(true);
|
||||
//MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin;
|
||||
}
|
||||
|
||||
|
||||
private void LoadOnlinePlayers()
|
||||
{
|
||||
//Get This players ID
|
||||
|
||||
MyPlayer.PlayerId? savingPlayerId = new MyPlayer.PlayerId(Sync.MyId);
|
||||
if (!savingPlayerId.HasValue)
|
||||
{
|
||||
SeamlessClient.TryShow("SavingPlayerID is null! Creating Default!");
|
||||
savingPlayerId = new MyPlayer.PlayerId(Sync.MyId);
|
||||
}
|
||||
|
||||
SeamlessClient.TryShow($"Saving PlayerID: {savingPlayerId}");
|
||||
|
||||
Sync.Players.LoadConnectedPlayers(TargetWorld.Checkpoint, savingPlayerId);
|
||||
Sync.Players.LoadControlledEntities(TargetWorld.Checkpoint.ControlledEntities,
|
||||
TargetWorld.Checkpoint.ControlledObject, savingPlayerId);
|
||||
/*
|
||||
|
||||
|
||||
SeamlessClient.TryShow("Saving PlayerID: " + savingPlayerId.ToString());
|
||||
|
||||
|
||||
|
||||
foreach (KeyValuePair<MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player> item3 in TargetWorld.Checkpoint.AllPlayersData.Dictionary)
|
||||
{
|
||||
MyPlayer.PlayerId playerId5 = new MyPlayer.PlayerId(item3.Key.GetClientId(), item3.Key.SerialId);
|
||||
|
||||
SeamlessClient.TryShow($"ConnectedPlayer: {playerId5.ToString()}");
|
||||
if (savingPlayerId.HasValue && playerId5.SteamId == savingPlayerId.Value.SteamId)
|
||||
{
|
||||
playerId5 = new MyPlayer.PlayerId(Sync.MyId, playerId5.SerialId);
|
||||
}
|
||||
|
||||
Patches.LoadPlayerInternal.Invoke(MySession.Static.Players, new object[] { playerId5, item3.Value, false });
|
||||
ConcurrentDictionary<MyPlayer.PlayerId, MyPlayer> Players = (ConcurrentDictionary<MyPlayer.PlayerId, MyPlayer>)Patches.MPlayerGPSCollection.GetValue(MySession.Static.Players);
|
||||
//LoadPlayerInternal(ref playerId5, item3.Value);
|
||||
if (Players.TryGetValue(playerId5, out MyPlayer myPlayer))
|
||||
{
|
||||
List<Vector3> value2 = null;
|
||||
if (TargetWorld.Checkpoint.AllPlayersColors != null && TargetWorld.Checkpoint.AllPlayersColors.Dictionary.TryGetValue(item3.Key, out value2))
|
||||
{
|
||||
myPlayer.SetBuildColorSlots(value2);
|
||||
}
|
||||
else if (TargetWorld.Checkpoint.CharacterToolbar != null && TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList != null && TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList.Count > 0)
|
||||
{
|
||||
myPlayer.SetBuildColorSlots(TargetWorld.Checkpoint.CharacterToolbar.ColorMaskHSVList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private void SetWorldSettings()
|
||||
{
|
||||
//MyEntities.MemoryLimitAddFailureReset();
|
||||
|
||||
//Clear old list
|
||||
MySession.Static.PromotedUsers.Clear();
|
||||
MySession.Static.CreativeTools.Clear();
|
||||
MySession.Static.RemoteAdminSettings.Clear();
|
||||
|
||||
|
||||
// Set new world settings
|
||||
MySession.Static.Name = MyStatControlText.SubstituteTexts(TargetWorld.Checkpoint.SessionName);
|
||||
MySession.Static.Description = TargetWorld.Checkpoint.Description;
|
||||
|
||||
MySession.Static.Mods = TargetWorld.Checkpoint.Mods;
|
||||
MySession.Static.Settings = TargetWorld.Checkpoint.Settings;
|
||||
MySession.Static.CurrentPath =
|
||||
MyLocalCache.GetSessionSavesPath(MyUtils.StripInvalidChars(TargetWorld.Checkpoint.SessionName), false,
|
||||
false);
|
||||
MySession.Static.WorldBoundaries = TargetWorld.Checkpoint.WorldBoundaries;
|
||||
MySession.Static.InGameTime = MyObjectBuilder_Checkpoint.DEFAULT_DATE;
|
||||
MySession.Static.ElapsedGameTime = new TimeSpan(TargetWorld.Checkpoint.ElapsedGameTime);
|
||||
MySession.Static.Settings.EnableSpectator = false;
|
||||
|
||||
MySession.Static.Password = TargetWorld.Checkpoint.Password;
|
||||
MySession.Static.PreviousEnvironmentHostility = TargetWorld.Checkpoint.PreviousEnvironmentHostility;
|
||||
MySession.Static.RequiresDX = TargetWorld.Checkpoint.RequiresDX;
|
||||
MySession.Static.CustomLoadingScreenImage = TargetWorld.Checkpoint.CustomLoadingScreenImage;
|
||||
MySession.Static.CustomLoadingScreenText = TargetWorld.Checkpoint.CustomLoadingScreenText;
|
||||
MySession.Static.CustomSkybox = TargetWorld.Checkpoint.CustomSkybox;
|
||||
|
||||
try
|
||||
{
|
||||
MySession.Static.Gpss = new MyGpsCollection();
|
||||
MySession.Static.Gpss.LoadGpss(TargetWorld.Checkpoint);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SeamlessClient.TryShow(
|
||||
$"An error occured while loading GPS points! You will have an empty gps list! \n {ex}");
|
||||
}
|
||||
|
||||
|
||||
MyRenderProxy.RebuildCullingStructure();
|
||||
//MySession.Static.Toolbars.LoadToolbars(checkpoint);
|
||||
|
||||
Sync.Players.RespawnComponent.InitFromCheckpoint(TargetWorld.Checkpoint);
|
||||
|
||||
|
||||
// Set new admin settings
|
||||
if (TargetWorld.Checkpoint.PromotedUsers != null)
|
||||
MySession.Static.PromotedUsers = TargetWorld.Checkpoint.PromotedUsers.Dictionary;
|
||||
else
|
||||
MySession.Static.PromotedUsers = new Dictionary<ulong, MyPromoteLevel>();
|
||||
|
||||
|
||||
foreach (var item in TargetWorld.Checkpoint.AllPlayersData.Dictionary)
|
||||
{
|
||||
var clientId = item.Key.GetClientId();
|
||||
var adminSettingsEnum = (AdminSettingsEnum)item.Value.RemoteAdminSettings;
|
||||
if (TargetWorld.Checkpoint.RemoteAdminSettings != null &&
|
||||
TargetWorld.Checkpoint.RemoteAdminSettings.Dictionary.TryGetValue(clientId, out var value))
|
||||
adminSettingsEnum = (AdminSettingsEnum)value;
|
||||
if (!MyPlatformGameSettings.IsIgnorePcuAllowed)
|
||||
{
|
||||
adminSettingsEnum &= ~AdminSettingsEnum.IgnorePcu;
|
||||
adminSettingsEnum &= ~AdminSettingsEnum.KeepOriginalOwnershipOnPaste;
|
||||
}
|
||||
|
||||
|
||||
MySession.Static.RemoteAdminSettings[clientId] = adminSettingsEnum;
|
||||
if (!Sync.IsDedicated && clientId == Sync.MyId)
|
||||
MySession.Static.AdminSettings = adminSettingsEnum;
|
||||
|
||||
var value2 = MySession.Static.PromotedUsers.GetValueOrDefault(clientId, MyPromoteLevel.None);
|
||||
if (item.Value.PromoteLevel > value2) MySession.Static.PromotedUsers[clientId] = item.Value.PromoteLevel;
|
||||
if (!MySession.Static.CreativeTools.Contains(clientId) && item.Value.CreativeToolsEnabled)
|
||||
MySession.Static.CreativeTools.Add(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadConnectedClients()
|
||||
{
|
||||
MySession.Static.LoadMembersFromWorld(TargetWorld, MyMultiplayer.Static);
|
||||
|
||||
//Re-Initilize Virtual clients
|
||||
MySession.Static.VirtualClients.Init();
|
||||
|
||||
//load online players
|
||||
LoadOnlinePlayers();
|
||||
}
|
||||
|
||||
private void StartEntitySync()
|
||||
{
|
||||
SeamlessClient.TryShow("Requesting Player From Server");
|
||||
Sync.Players.RequestNewPlayer(Sync.MyId, 0, MyGameService.UserName, null, true, true);
|
||||
if (MySession.Static.ControlledEntity == null && Sync.IsServer && !Game.IsDedicated)
|
||||
{
|
||||
MyLog.Default.WriteLine("ControlledObject was null, respawning character");
|
||||
//m_cameraAwaitingEntity = true;
|
||||
MyPlayerCollection.RequestLocalRespawn();
|
||||
}
|
||||
|
||||
//Request client state batch
|
||||
((MyMultiplayerClientBase)MyMultiplayer.Static).RequestBatchConfirmation();
|
||||
MyMultiplayer.Static.PendingReplicablesDone += MyMultiplayer_PendingReplicablesDone;
|
||||
//typeof(MyGuiScreenTerminal).GetMethod("CreateTabs")
|
||||
|
||||
MySession.Static.LoadDataComponents();
|
||||
//MyGuiSandbox.LoadData(false);
|
||||
//MyGuiSandbox.AddScreen(MyGuiSandbox.CreateScreen(MyPerGameSettings.GUI.HUDScreen));
|
||||
MyRenderProxy.RebuildCullingStructure();
|
||||
MyRenderProxy.CollectGarbage();
|
||||
|
||||
SeamlessClient.TryShow($"OnlinePlayers: {MySession.Static.Players.GetOnlinePlayers().Count}");
|
||||
SeamlessClient.TryShow("Loading Complete!");
|
||||
}
|
||||
|
||||
private void MyMultiplayer_PendingReplicablesDone()
|
||||
{
|
||||
if (MySession.Static.VoxelMaps.Instances.Count > 0) MySandboxGame.AreClipmapsReady = false;
|
||||
MyMultiplayer.Static.PendingReplicablesDone -= MyMultiplayer_PendingReplicablesDone;
|
||||
}
|
||||
|
||||
|
||||
private void UpdateWorldGenerator()
|
||||
{
|
||||
//This will re-init the MyProceduralWorldGenerator. (Not doing this will result in asteroids not rendering in properly)
|
||||
|
||||
|
||||
//This shoud never be null
|
||||
var generator = MySession.Static.GetComponent<MyProceduralWorldGenerator>();
|
||||
|
||||
//Force component to unload
|
||||
Patches.UnloadProceduralWorldGenerator.Invoke(generator, null);
|
||||
|
||||
//Re-call the generator init
|
||||
var generatorSettings = TargetWorld.Checkpoint.SessionComponents.OfType<MyObjectBuilder_WorldGenerator>().FirstOrDefault();
|
||||
if (generatorSettings != null)
|
||||
//Re-initilized this component (forces to update asteroid areas like not in planets etc)
|
||||
generator.Init(generatorSettings);
|
||||
|
||||
//Force component to reload, re-syncing settings and seeds to the destination server
|
||||
generator.LoadData();
|
||||
|
||||
//We need to go in and force planets to be empty areas in the generator. This is originially done on planet init.
|
||||
foreach (var planet in MyEntities.GetEntities().OfType<MyPlanet>())
|
||||
{
|
||||
generator.MarkEmptyArea(planet.PositionComp.GetPosition(), planet.m_planetInitValues.MaxRadius);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadCurrentServer()
|
||||
{
|
||||
//Unload current session on game thread
|
||||
if (MyMultiplayer.Static == null)
|
||||
throw new Exception("MyMultiplayer.Static is null on unloading? dafuq?");
|
||||
|
||||
|
||||
RemoveOldEntities();
|
||||
|
||||
//Try and close the quest log
|
||||
var component = MySession.Static.GetComponent<MySessionComponentIngameHelp>();
|
||||
component?.TryCancelObjective();
|
||||
|
||||
//Clear all old players and clients.
|
||||
Sync.Clients.Clear();
|
||||
Sync.Players.ClearPlayers();
|
||||
|
||||
|
||||
MyHud.Chat.UnregisterChat(MyMultiplayer.Static);
|
||||
|
||||
|
||||
MySession.Static.Gpss.RemovePlayerGpss(MySession.Static.LocalPlayerId);
|
||||
MyHud.GpsMarkers.Clear();
|
||||
MyMultiplayer.Static.ReplicationLayer.Disconnect();
|
||||
MyMultiplayer.Static.ReplicationLayer.Dispose();
|
||||
MyMultiplayer.Static.Dispose();
|
||||
MyMultiplayer.Static = null;
|
||||
|
||||
//Close any respawn screens that are open
|
||||
MyGuiScreenMedicals.Close();
|
||||
|
||||
//MySession.Static.UnloadDataComponents();
|
||||
}
|
||||
|
||||
private void RemoveOldEntities()
|
||||
{
|
||||
foreach (var ent in MyEntities.GetEntities())
|
||||
{
|
||||
if (ent is MyPlanet)
|
||||
continue;
|
||||
|
||||
ent.Close();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user