Update for latest version of seamless
Notable feature: V3 support (allegedly)
This commit is contained in:
@@ -39,6 +39,10 @@ namespace SeamlessClient.Components
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
MyGuiControlTable myGuiControlTable = (MyGuiControlTable)typeof(MyGuiScreenMedicals).GetField("m_respawnsTable", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(__instance);
|
MyGuiControlTable myGuiControlTable = (MyGuiControlTable)typeof(MyGuiScreenMedicals).GetField("m_respawnsTable", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(__instance);
|
||||||
|
if (myGuiControlTable == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
string s = MyTexts.GetString(MySpaceTexts.SpawnInSpaceSuit);
|
string s = MyTexts.GetString(MySpaceTexts.SpawnInSpaceSuit);
|
||||||
foreach (var item in myGuiControlTable.Rows)
|
foreach (var item in myGuiControlTable.Rows)
|
||||||
{
|
{
|
||||||
|
@@ -180,13 +180,14 @@ namespace SeamlessClient.ServerSwitching
|
|||||||
}
|
}
|
||||||
|
|
||||||
SendPlayerData.Invoke(MyMultiplayer.Static, new object[] { MyGameService.OnlineName });
|
SendPlayerData.Invoke(MyMultiplayer.Static, new object[] { MyGameService.OnlineName });
|
||||||
|
isSwitch = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool LoadClientsFromWorld(ref List<MyObjectBuilder_Client> clients)
|
public static bool LoadClientsFromWorld(ref List<MyObjectBuilder_Client> clients)
|
||||||
{
|
{
|
||||||
if(clients == null || clients.Count == 0)
|
if(!isSwitch || clients == null || clients.Count == 0)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
//Dictionary<ulong, MyConnectedClientData>
|
//Dictionary<ulong, MyConnectedClientData>
|
||||||
@@ -209,13 +210,16 @@ namespace SeamlessClient.ServerSwitching
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static bool ProcessAllMembersData(ref AllMembersDataMsg msg)
|
private static bool ProcessAllMembersData(ref AllMembersDataMsg msg)
|
||||||
{
|
{
|
||||||
|
if(!isSwitch)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
Sync.Players.ClearIdentities();
|
Sync.Players.ClearIdentities();
|
||||||
if (msg.Identities != null)
|
if (msg.Identities != null)
|
||||||
@@ -610,11 +614,6 @@ namespace SeamlessClient.ServerSwitching
|
|||||||
PauseClient.Invoke(MyMultiplayer.Static, new object[] { false });
|
PauseClient.Invoke(MyMultiplayer.Static, new object[] { false });
|
||||||
MySandboxGame.PausePop();
|
MySandboxGame.PausePop();
|
||||||
MyHud.Notifications.Remove(MyNotificationSingletons.ConnectionProblem);
|
MyHud.Notifications.Remove(MyNotificationSingletons.ConnectionProblem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isSwitch = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -27,12 +27,19 @@ using Sandbox.Game;
|
|||||||
using VRage.Game.ModAPI;
|
using VRage.Game.ModAPI;
|
||||||
using VRage.Utils;
|
using VRage.Utils;
|
||||||
using SeamlessClient.ServerSwitching;
|
using SeamlessClient.ServerSwitching;
|
||||||
|
using Sandbox.Game.Entities.Character;
|
||||||
|
using VRage.Game.Utils;
|
||||||
|
using VRage;
|
||||||
|
using Sandbox.Game.GameSystems.CoordinateSystem;
|
||||||
|
|
||||||
namespace SeamlessClient.Components
|
namespace SeamlessClient.Components
|
||||||
{
|
{
|
||||||
public class ServerSwitcherComponentOLD : ComponentBase
|
public class ServerSwitcherComponentOLD : ComponentBase
|
||||||
{
|
{
|
||||||
private static bool isSeamlessSwitching = false;
|
private static bool isSeamlessSwitching { get; set; } = false;
|
||||||
|
private static bool WaitingForClientCheck { get; set; } = false;
|
||||||
|
|
||||||
|
|
||||||
private static ConstructorInfo TransportLayerConstructor;
|
private static ConstructorInfo TransportLayerConstructor;
|
||||||
private static ConstructorInfo SyncLayerConstructor;
|
private static ConstructorInfo SyncLayerConstructor;
|
||||||
private static ConstructorInfo ClientConstructor;
|
private static ConstructorInfo ClientConstructor;
|
||||||
@@ -53,9 +60,28 @@ namespace SeamlessClient.Components
|
|||||||
private string OldArmorSkin { get; set; } = string.Empty;
|
private string OldArmorSkin { get; set; } = string.Empty;
|
||||||
|
|
||||||
public ServerSwitcherComponentOLD() { Instance = this; }
|
public ServerSwitcherComponentOLD() { Instance = this; }
|
||||||
|
public static string SwitchingText = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
//Toggle waiting for client check
|
||||||
|
if (WaitingForClientCheck == false && isSeamlessSwitching)
|
||||||
|
WaitingForClientCheck = true;
|
||||||
|
|
||||||
|
if(WaitingForClientCheck && MySession.Static.LocalHumanPlayer != null)
|
||||||
|
WaitingForClientCheck = false;
|
||||||
|
|
||||||
|
if (isSeamlessSwitching || WaitingForClientCheck)
|
||||||
|
{
|
||||||
|
//SeamlessClient.TryShow("Switching Servers!");
|
||||||
|
MyRenderProxy.DebugDrawText2D(new VRageMath.Vector2(MySandboxGame.ScreenViewport.Width/2, MySandboxGame.ScreenViewport.Height - 150), SwitchingText, VRageMath.Color.AliceBlue, 1f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER);
|
||||||
|
MyRenderProxy.DebugDrawText2D(new VRageMath.Vector2(MySandboxGame.ScreenViewport.Width / 2, MySandboxGame.ScreenViewport.Height - 200), $"Transferring to {TargetServer.Name}", VRageMath.Color.Yellow, 1.5f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER);
|
||||||
|
|
||||||
|
|
||||||
|
MyRenderProxy.DebugDrawLine2D(new VRageMath.Vector2((MySandboxGame.ScreenViewport.Width / 2) - 250, MySandboxGame.ScreenViewport.Height - 170), new VRageMath.Vector2((MySandboxGame.ScreenViewport.Width / 2)+250, MySandboxGame.ScreenViewport.Height - 170), VRageMath.Color.Blue, VRageMath.Color.Green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Patch(Harmony patcher)
|
public override void Patch(Harmony patcher)
|
||||||
@@ -85,13 +111,28 @@ namespace SeamlessClient.Components
|
|||||||
//SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString());
|
//SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString());
|
||||||
|
|
||||||
//Invoke the switch event
|
//Invoke the switch event
|
||||||
|
SwitchingText = "Server Responded! Removing Old Entities and forcing client connection!";
|
||||||
|
RemoveOldEntities();
|
||||||
ForceClientConnection();
|
ForceClientConnection();
|
||||||
|
|
||||||
|
//Fix any character issues
|
||||||
|
if (MySession.Static.LocalCharacter != null)
|
||||||
|
MySession.Static.LocalHumanPlayer.SpawnIntoCharacter(MySession.Static.LocalCharacter);
|
||||||
|
|
||||||
isSeamlessSwitching = false;
|
isSeamlessSwitching = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartBackendSwitch(MyGameServerItem _TargetServer, MyObjectBuilder_World _TargetWorld)
|
public void StartBackendSwitch(MyGameServerItem _TargetServer, MyObjectBuilder_World _TargetWorld)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(MySession.Static.LocalCharacter != null)
|
||||||
|
{
|
||||||
|
var viewMatrix = MySession.Static.LocalCharacter.GetViewMatrix();
|
||||||
|
MySpectator.Static.SetViewMatrix(viewMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
SwitchingText = "Starting Seamless Switch... Please wait!";
|
||||||
isSeamlessSwitching = true;
|
isSeamlessSwitching = true;
|
||||||
OldArmorSkin = MySession.Static.LocalHumanPlayer.BuildArmorSkin;
|
OldArmorSkin = MySession.Static.LocalHumanPlayer.BuildArmorSkin;
|
||||||
TargetServer = _TargetServer;
|
TargetServer = _TargetServer;
|
||||||
@@ -105,7 +146,7 @@ namespace SeamlessClient.Components
|
|||||||
SetNewMultiplayerClient();
|
SetNewMultiplayerClient();
|
||||||
//SeamlessClient.IsSwitching = false;
|
//SeamlessClient.IsSwitching = false;
|
||||||
|
|
||||||
|
SwitchingText = "Waiting for server response...";
|
||||||
}, "SeamlessClient");
|
}, "SeamlessClient");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -129,12 +170,13 @@ namespace SeamlessClient.Components
|
|||||||
// Set the new SyncLayer to the MySession.Static.SyncLayer
|
// Set the new SyncLayer to the MySession.Static.SyncLayer
|
||||||
MySessionLayer.SetValue(MySession.Static, MyMultiplayer.Static.SyncLayer);
|
MySessionLayer.SetValue(MySession.Static, MyMultiplayer.Static.SyncLayer);
|
||||||
|
|
||||||
|
SwitchingText = "New Multiplayer Session Set";
|
||||||
Seamless.TryShow("Successfully set MyMultiplayer.Static");
|
Seamless.TryShow("Successfully set MyMultiplayer.Static");
|
||||||
|
|
||||||
|
|
||||||
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
|
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
|
||||||
Sync.Players.RegisterEvents();
|
Sync.Players.RegisterEvents();
|
||||||
|
SwitchingText = "Registering Player Events";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,7 +189,7 @@ namespace SeamlessClient.Components
|
|||||||
|
|
||||||
//Load force load any connected players
|
//Load force load any connected players
|
||||||
LoadConnectedClients();
|
LoadConnectedClients();
|
||||||
|
SwitchingText = "Loaded Connected Clients";
|
||||||
|
|
||||||
|
|
||||||
MySector.InitEnvironmentSettings(TargetWorld.Sector.Environment);
|
MySector.InitEnvironmentSettings(TargetWorld.Sector.Environment);
|
||||||
@@ -159,10 +201,8 @@ namespace SeamlessClient.Components
|
|||||||
|
|
||||||
MyModAPIHelper.Initialize();
|
MyModAPIHelper.Initialize();
|
||||||
MySession.Static.LoadDataComponents();
|
MySession.Static.LoadDataComponents();
|
||||||
|
|
||||||
//MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents);
|
|
||||||
MyModAPIHelper.Initialize();
|
MyModAPIHelper.Initialize();
|
||||||
// MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents);
|
|
||||||
|
|
||||||
|
|
||||||
//MethodInfo A = typeof(MySession).GetMethod("LoadGameDefinition", BindingFlags.Instance | BindingFlags.NonPublic);
|
//MethodInfo A = typeof(MySession).GetMethod("LoadGameDefinition", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
@@ -171,7 +211,7 @@ namespace SeamlessClient.Components
|
|||||||
|
|
||||||
|
|
||||||
MyMultiplayer.Static.OnSessionReady();
|
MyMultiplayer.Static.OnSessionReady();
|
||||||
|
SwitchingText = "Session Ready";
|
||||||
|
|
||||||
UpdateWorldGenerator();
|
UpdateWorldGenerator();
|
||||||
|
|
||||||
@@ -180,13 +220,14 @@ namespace SeamlessClient.Components
|
|||||||
|
|
||||||
MyHud.Chat.RegisterChat(MyMultiplayer.Static);
|
MyHud.Chat.RegisterChat(MyMultiplayer.Static);
|
||||||
GpsRegisterChat.Invoke(MySession.Static.Gpss, new object[] { MyMultiplayer.Static });
|
GpsRegisterChat.Invoke(MySession.Static.Gpss, new object[] { MyMultiplayer.Static });
|
||||||
|
SwitchingText = "Registered Chat";
|
||||||
|
|
||||||
// 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);
|
||||||
|
SwitchingText = "Client Registered. Waiting for entities from server...";
|
||||||
//MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin;
|
//MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,8 +482,7 @@ namespace SeamlessClient.Components
|
|||||||
throw new Exception("MyMultiplayer.Static is null on unloading? dafuq?");
|
throw new Exception("MyMultiplayer.Static is null on unloading? dafuq?");
|
||||||
|
|
||||||
|
|
||||||
RemoveOldEntities();
|
SwitchingText = "Unloading Local Server Components";
|
||||||
|
|
||||||
//Try and close the quest log
|
//Try and close the quest log
|
||||||
MySessionComponentIngameHelp component = MySession.Static.GetComponent<MySessionComponentIngameHelp>();
|
MySessionComponentIngameHelp component = MySession.Static.GetComponent<MySessionComponentIngameHelp>();
|
||||||
component?.TryCancelObjective();
|
component?.TryCancelObjective();
|
||||||
@@ -463,6 +503,10 @@ namespace SeamlessClient.Components
|
|||||||
MyMultiplayer.Static.ReplicationLayer.Dispose();
|
MyMultiplayer.Static.ReplicationLayer.Dispose();
|
||||||
MyMultiplayer.Static.Dispose();
|
MyMultiplayer.Static.Dispose();
|
||||||
MyMultiplayer.Static = null;
|
MyMultiplayer.Static = null;
|
||||||
|
SwitchingText = "Local Multiplayer Disposed";
|
||||||
|
|
||||||
|
//Clear grid coord systems
|
||||||
|
ResetCoordinateSystems();
|
||||||
|
|
||||||
//Close any respawn screens that are open
|
//Close any respawn screens that are open
|
||||||
MyGuiScreenMedicals.Close();
|
MyGuiScreenMedicals.Close();
|
||||||
@@ -471,7 +515,7 @@ namespace SeamlessClient.Components
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveOldEntities()
|
private static void RemoveOldEntities()
|
||||||
{
|
{
|
||||||
foreach (var ent in MyEntities.GetEntities())
|
foreach (var ent in MyEntities.GetEntities())
|
||||||
{
|
{
|
||||||
@@ -482,6 +526,11 @@ namespace SeamlessClient.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ResetCoordinateSystems()
|
||||||
|
{
|
||||||
|
AccessTools.Field(typeof(MyCoordinateSystem), "m_lastCoordSysId").SetValue(MyCoordinateSystem.Static, 1L);
|
||||||
|
AccessTools.Field(typeof(MyCoordinateSystem), "m_localCoordSystems").SetValue(MyCoordinateSystem.Static, new Dictionary<long, MyLocalCoordSys>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ namespace SeamlessClient.Messages
|
|||||||
[ProtoMember(3)] public string PlayerName;
|
[ProtoMember(3)] public string PlayerName;
|
||||||
[ProtoMember(4)] public byte[] WorldData;
|
[ProtoMember(4)] public byte[] WorldData;
|
||||||
|
|
||||||
[ProtoMember(5)] public MyObjectBuilder_Gps GpsCollection;
|
[ProtoMember(5)] public MyObjectBuilder_Gps GpsCollection { get; set; }
|
||||||
|
|
||||||
public WorldRequest()
|
public WorldRequest()
|
||||||
{
|
{
|
||||||
|
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
|
|||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion("2.0.0.6")] //Set these both to the same
|
[assembly: AssemblyVersion("3.0.0.6")] //Set these both to the same
|
||||||
[assembly: AssemblyFileVersion("2.0.0.6")]
|
[assembly: AssemblyFileVersion("3.0.0.6")]
|
||||||
|
16
Seamless.cs
16
Seamless.cs
@@ -34,6 +34,7 @@ namespace SeamlessClient
|
|||||||
public static ushort SeamlessClientNetId = 2936;
|
public static ushort SeamlessClientNetId = 2936;
|
||||||
|
|
||||||
private List<ComponentBase> allComps = new List<ComponentBase>();
|
private List<ComponentBase> allComps = new List<ComponentBase>();
|
||||||
|
private Assembly thisAssembly => typeof(Seamless).Assembly;
|
||||||
private bool Initilized = false;
|
private bool Initilized = false;
|
||||||
public static bool isSeamlessServer { get; private set; } = false;
|
public static bool isSeamlessServer { get; private set; } = false;
|
||||||
public static bool isDebug = false;
|
public static bool isDebug = false;
|
||||||
@@ -41,25 +42,24 @@ namespace SeamlessClient
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Init(object gameInstance)
|
public void Init(object gameInstance)
|
||||||
{
|
{
|
||||||
TryShow($"Running Seamless Client Plugin v[{SeamlessVersion}]");
|
TryShow($"Running Seamless Client Plugin v[{SeamlessVersion}]");
|
||||||
SeamlessPatcher = new Harmony("SeamlessClientPatcher");
|
SeamlessPatcher = new Harmony("SeamlessClientPatcher");
|
||||||
GetComponents();
|
GetComponents();
|
||||||
|
|
||||||
|
|
||||||
PatchComponents(SeamlessPatcher);
|
PatchComponents(SeamlessPatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void GetComponents()
|
private void GetComponents()
|
||||||
{
|
{
|
||||||
int failedCount = 0;
|
int failedCount = 0;
|
||||||
foreach (Type type in IntrospectionContext.Global.CollectDerivedTypes<ComponentBase>(typeof(Seamless).Module))
|
foreach (Type type in IntrospectionContext.Global.CollectDerivedTypes<ComponentBase>(typeof(Seamless).Module))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ComponentBase s = (ComponentBase)Activator.CreateInstance(type);
|
ComponentBase s = (ComponentBase)Activator.CreateInstance(type);
|
||||||
@@ -109,7 +109,6 @@ namespace SeamlessClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void MessageHandler(ushort packetID, byte[] data, ulong sender, bool fromServer)
|
private static void MessageHandler(ushort packetID, byte[] data, ulong sender, bool fromServer)
|
||||||
{
|
{
|
||||||
//Ignore anything except dedicated server
|
//Ignore anything except dedicated server
|
||||||
@@ -144,6 +143,9 @@ namespace SeamlessClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void SendSeamlessVersion()
|
public static void SendSeamlessVersion()
|
||||||
{
|
{
|
||||||
ClientMessage response = new ClientMessage(SeamlessVersion.ToString());
|
ClientMessage response = new ClientMessage(SeamlessVersion.ToString());
|
||||||
@@ -159,6 +161,10 @@ namespace SeamlessClient
|
|||||||
}
|
}
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
allComps.ForEach(x => x.Update());
|
allComps.ForEach(x => x.Update());
|
||||||
|
|
||||||
if (MyAPIGateway.Multiplayer == null)
|
if (MyAPIGateway.Multiplayer == null)
|
||||||
@@ -214,8 +220,6 @@ namespace SeamlessClient
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void TryShow(string message)
|
public static void TryShow(string message)
|
||||||
{
|
{
|
||||||
if (MySession.Static?.LocalHumanPlayer != null && isDebug)
|
if (MySession.Static?.LocalHumanPlayer != null && isDebug)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net9.0-windows</TargetFramework>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<Nullable>disable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.0",
|
"version": "9.0.0",
|
||||||
"rollForward": "latestFeature",
|
"rollForward": "latestFeature",
|
||||||
"allowPrerelease": false
|
"allowPrerelease": false
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user