fixes for nexus v3
This commit is contained in:
@@ -1,439 +1,297 @@
|
||||
using HarmonyLib;
|
||||
using Sandbox.Engine.Analytics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using HarmonyLib;
|
||||
using Sandbox.Engine.Multiplayer;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Game;
|
||||
using Sandbox.Game.Entities;
|
||||
using Sandbox.Game.Gui;
|
||||
using Sandbox.Game.Multiplayer;
|
||||
using Sandbox.Game.World;
|
||||
using Sandbox.Game.World.Generator;
|
||||
using Sandbox.Graphics;
|
||||
using Sandbox.Graphics.GUI;
|
||||
using Sandbox.ModAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VRage;
|
||||
using VRage.Collections;
|
||||
using VRage.FileSystem;
|
||||
using VRage.Game;
|
||||
using VRage.Game.Entity;
|
||||
using VRage.GameServices;
|
||||
using VRage.Network;
|
||||
using VRage.Utils;
|
||||
using VRageMath;
|
||||
|
||||
namespace SeamlessClientPlugin.SeamlessTransfer
|
||||
namespace SeamlessClientPlugin.Utilities;
|
||||
|
||||
public static class Patches
|
||||
{
|
||||
public static class Patches
|
||||
/* Harmony Patcher */
|
||||
private static readonly Harmony Patcher = new("SeamlessClientPatcher");
|
||||
|
||||
/* WorldGenerator */
|
||||
public static MethodInfo UnloadProceduralWorldGenerator { get; private set; }
|
||||
|
||||
|
||||
public static event EventHandler<JoinResultMsg> OnJoinEvent;
|
||||
|
||||
public static void GetPatches()
|
||||
{
|
||||
/* All internal classes Types */
|
||||
public static readonly Type ClientType = Type.GetType("Sandbox.Engine.Multiplayer.MyMultiplayerClient, Sandbox.Game");
|
||||
public static readonly Type SyncLayerType = Type.GetType("Sandbox.Game.Multiplayer.MySyncLayer, Sandbox.Game");
|
||||
public static readonly Type MyTransportLayerType = Type.GetType("Sandbox.Engine.Multiplayer.MyTransportLayer, Sandbox.Game");
|
||||
public static readonly Type MySessionType = Type.GetType("Sandbox.Game.World.MySession, Sandbox.Game");
|
||||
public static readonly Type VirtualClientsType = Type.GetType("Sandbox.Engine.Multiplayer.MyVirtualClients, Sandbox.Game");
|
||||
public static readonly Type GUIScreenChat = Type.GetType("Sandbox.Game.Gui.MyGuiScreenChat, Sandbox.Game");
|
||||
public static readonly Type MyMultiplayerClientBase = Type.GetType("Sandbox.Engine.Multiplayer.MyMultiplayerClientBase, Sandbox.Game");
|
||||
public static readonly Type MySteamServerDiscovery = Type.GetType("VRage.Steam.MySteamServerDiscovery, Vrage.Steam");
|
||||
//Get reflected values and store them
|
||||
|
||||
/* Harmony Patcher */
|
||||
private static Harmony Patcher = new Harmony("SeamlessClientPatcher");
|
||||
/* Get Methods */
|
||||
var onJoin = GetMethod(typeof(MyMultiplayerClient), "OnUserJoined", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var loadingAction = GetMethod(typeof(MySessionLoader), "LoadMultiplayerSession",
|
||||
BindingFlags.Public | BindingFlags.Static);
|
||||
UnloadProceduralWorldGenerator = GetMethod(typeof(MyProceduralWorldGenerator), "UnloadData",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
|
||||
/* Static Contructors */
|
||||
public static ConstructorInfo ClientConstructor { get; private set; }
|
||||
public static ConstructorInfo SyncLayerConstructor { get; private set; }
|
||||
public static ConstructorInfo TransportLayerConstructor { get; private set; }
|
||||
public static ConstructorInfo MySessionConstructor { get; private set; }
|
||||
public static ConstructorInfo MyMultiplayerClientBaseConstructor { get; private set; }
|
||||
//MethodInfo ConnectToServer = GetMethod(typeof(MyGameService), "ConnectToServer", BindingFlags.Static | BindingFlags.Public);
|
||||
var loadingScreenDraw = GetMethod(typeof(MyGuiScreenLoading), "DrawInternal",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
|
||||
|
||||
/* Static FieldInfos and PropertyInfos */
|
||||
public static PropertyInfo MySessionLayer { get; private set; }
|
||||
public static FieldInfo VirtualClients { get; private set; }
|
||||
public static FieldInfo AdminSettings { get; private set; }
|
||||
public static FieldInfo RemoteAdminSettings { get; private set; }
|
||||
public static FieldInfo MPlayerGPSCollection { get; private set; }
|
||||
//Test patches
|
||||
//MethodInfo SetPlayerDed = GetMethod(typeof(MyPlayerCollection), "SetPlayerDeadInternal", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
|
||||
/* Static MethodInfos */
|
||||
public static MethodInfo InitVirtualClients { get; private set; }
|
||||
public static MethodInfo LoadPlayerInternal { get; private set; }
|
||||
public static MethodInfo LoadMembersFromWorld { get; private set; }
|
||||
public static MethodInfo LoadMultiplayer { get; private set; }
|
||||
public static MethodInfo GPSRegisterChat { get; private set; }
|
||||
|
||||
public static MethodInfo SendPlayerData;
|
||||
Patcher.Patch(loadingScreenDraw, new HarmonyMethod(GetPatchMethod(nameof(DrawInternal))));
|
||||
Patcher.Patch(onJoin, postfix: new HarmonyMethod(GetPatchMethod(nameof(OnUserJoined))));
|
||||
Patcher.Patch(loadingAction, new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession))));
|
||||
//Patcher.Patch(SetPlayerDed, prefix: new HarmonyMethod(GetPatchMethod(nameof(SetPlayerDeadInternal))));
|
||||
}
|
||||
|
||||
|
||||
public static event EventHandler<JoinResultMsg> OnJoinEvent;
|
||||
private static MethodInfo GetPatchMethod(string v)
|
||||
{
|
||||
return typeof(Patches).GetMethod(v, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* WorldGenerator */
|
||||
public static MethodInfo UnloadProceduralWorldGenerator;
|
||||
private static void OnUserJoined(ref JoinResultMsg msg)
|
||||
{
|
||||
if (msg.JoinResult == JoinResult.OK)
|
||||
//SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString());
|
||||
//Invoke the switch event
|
||||
OnJoinEvent?.Invoke(null, msg);
|
||||
}
|
||||
|
||||
|
||||
private static bool OnConnectToServer(MyGameServerItem server, Action<JoinResult> onDone)
|
||||
{
|
||||
if (SeamlessClient.IsSwitching)
|
||||
return false;
|
||||
|
||||
private static FieldInfo MBuffer;
|
||||
|
||||
public static void GetPatches()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Patch Utils */
|
||||
|
||||
private static MethodInfo GetMethod(Type type, string methodName, BindingFlags flags)
|
||||
{
|
||||
var foundMethod = type.GetMethod(methodName, flags);
|
||||
|
||||
if (foundMethod == null)
|
||||
throw new NullReferenceException($"Method for {methodName} is null!");
|
||||
|
||||
|
||||
return foundMethod;
|
||||
}
|
||||
|
||||
private static FieldInfo GetField(Type type, string fieldName, BindingFlags flags)
|
||||
{
|
||||
var foundField = type.GetField(fieldName, flags);
|
||||
|
||||
if (foundField == null)
|
||||
throw new NullReferenceException($"Field for {fieldName} is null!");
|
||||
|
||||
|
||||
return foundField;
|
||||
}
|
||||
|
||||
private static PropertyInfo GetProperty(Type type, string propertyName, BindingFlags flags)
|
||||
{
|
||||
var foundProperty = type.GetProperty(propertyName, flags);
|
||||
|
||||
if (foundProperty == null)
|
||||
throw new NullReferenceException($"Property for {propertyName} is null!");
|
||||
|
||||
|
||||
return foundProperty;
|
||||
}
|
||||
|
||||
private static ConstructorInfo GetConstructor(Type type, BindingFlags flags, Type[] types)
|
||||
{
|
||||
var foundConstructor = type.GetConstructor(flags, null, types, null);
|
||||
|
||||
if (foundConstructor == null)
|
||||
throw new NullReferenceException($"Contructor for {type.Name} is null!");
|
||||
|
||||
|
||||
return foundConstructor;
|
||||
}
|
||||
|
||||
|
||||
#region LoadingScreen
|
||||
|
||||
/* Loading Screen Stuff */
|
||||
|
||||
private static string _loadingScreenTexture;
|
||||
private static string _serverName;
|
||||
|
||||
private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
|
||||
{
|
||||
//
|
||||
|
||||
|
||||
MyLog.Default.WriteLine("LoadSession() - Start");
|
||||
if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, false))
|
||||
{
|
||||
//Get reflected values and store them
|
||||
|
||||
|
||||
|
||||
|
||||
/* Get Constructors */
|
||||
ClientConstructor = GetConstructor(ClientType, BindingFlags.Instance | BindingFlags.NonPublic, new Type[2] { typeof(MyGameServerItem), SyncLayerType });
|
||||
SyncLayerConstructor = GetConstructor(SyncLayerType, BindingFlags.Instance | BindingFlags.NonPublic, new Type[1] { MyTransportLayerType });
|
||||
TransportLayerConstructor = GetConstructor(MyTransportLayerType, BindingFlags.Instance | BindingFlags.Public, new Type[1] { typeof(int) });
|
||||
MySessionConstructor = GetConstructor(MySessionType, BindingFlags.Instance | BindingFlags.NonPublic, new Type[2] { typeof(MySyncLayer), typeof(bool) });
|
||||
MyMultiplayerClientBaseConstructor = GetConstructor(MyMultiplayerClientBase, BindingFlags.Instance | BindingFlags.NonPublic, new Type[] { typeof(MySyncLayer) });
|
||||
|
||||
|
||||
/* Get Fields and Properties */
|
||||
MySessionLayer = GetProperty(typeof(MySession), "SyncLayer", BindingFlags.Instance | BindingFlags.Public);
|
||||
VirtualClients = GetField(typeof(MySession), "VirtualClients", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
AdminSettings = GetField(typeof(MySession), "m_adminSettings", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
RemoteAdminSettings = GetField(typeof(MySession), "m_remoteAdminSettings", 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 */
|
||||
MethodInfo OnJoin = GetMethod(ClientType, "OnUserJoined", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
MethodInfo LoadingAction = GetMethod(typeof(MySessionLoader), "LoadMultiplayerSession", BindingFlags.Public | BindingFlags.Static);
|
||||
InitVirtualClients = GetMethod(VirtualClientsType, "Init", BindingFlags.Instance | BindingFlags.Public);
|
||||
LoadPlayerInternal = GetMethod(typeof(MyPlayerCollection), "LoadPlayerInternal", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
LoadMembersFromWorld = GetMethod(typeof(MySession), "LoadMembersFromWorld", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
LoadMultiplayer = GetMethod(typeof(MySession), "LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
SendPlayerData = GetMethod(ClientType, "SendPlayerData", 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 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(OnJoin, postfix: new HarmonyMethod(GetPatchMethod(nameof(OnUserJoined))));
|
||||
Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession))));
|
||||
//Patcher.Patch(SetPlayerDed, prefix: new HarmonyMethod(GetPatchMethod(nameof(SetPlayerDeadInternal))));
|
||||
|
||||
|
||||
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
|
||||
messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError),
|
||||
messageText: MyTexts.Get(MyCommonTexts.DialogTextLocalModsDisabledInMultiplayer)));
|
||||
MyLog.Default.WriteLine("LoadSession() - End");
|
||||
return false;
|
||||
}
|
||||
|
||||
MyLog.Default.WriteLine("Seamless Downloading mods!");
|
||||
|
||||
|
||||
|
||||
private static MethodInfo GetPatchMethod(string v)
|
||||
MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, result =>
|
||||
{
|
||||
return typeof(Patches).GetMethod(v, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region LoadingScreen
|
||||
|
||||
/* Loading Screen Stuff */
|
||||
|
||||
private static string LoadingScreenTexture = null;
|
||||
private static string ServerName;
|
||||
|
||||
private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
MyLog.Default.WriteLine("LoadSession() - Start");
|
||||
if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, allowLocalMods: false))
|
||||
if (result == MyGameServiceCallResult.OK)
|
||||
{
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: MyTexts.Get(MyCommonTexts.DialogTextLocalModsDisabledInMultiplayer)));
|
||||
MyLog.Default.WriteLine("LoadSession() - End");
|
||||
return false;
|
||||
MyScreenManager.CloseAllScreensNowExcept(null);
|
||||
MyGuiSandbox.Update(16);
|
||||
if (MySession.Static != null)
|
||||
{
|
||||
MySession.Static.Unload();
|
||||
MySession.Static = null;
|
||||
}
|
||||
|
||||
_serverName = multiplayerSession.HostName;
|
||||
GetCustomLoadingScreenPath(world.Checkpoint.Mods, out _loadingScreenTexture);
|
||||
|
||||
|
||||
MySessionLoader.StartLoading(delegate
|
||||
{
|
||||
MySession.LoadMultiplayer(world, multiplayerSession);
|
||||
});
|
||||
}
|
||||
|
||||
MyLog.Default.WriteLine("Seamless Downloading mods!");
|
||||
|
||||
|
||||
|
||||
MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, delegate (bool success)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
MyScreenManager.CloseAllScreensNowExcept(null);
|
||||
MyGuiSandbox.Update(16);
|
||||
if (MySession.Static != null)
|
||||
{
|
||||
MySession.Static.Unload();
|
||||
MySession.Static = null;
|
||||
}
|
||||
|
||||
ServerName = multiplayerSession.HostName;
|
||||
GetCustomLoadingScreenPath(world.Checkpoint.Mods, out LoadingScreenTexture);
|
||||
|
||||
|
||||
MySessionLoader.StartLoading(delegate
|
||||
{
|
||||
|
||||
LoadMultiplayer.Invoke(null, new object[] { world, multiplayerSession });
|
||||
//MySession.LoadMultiplayer(world, multiplayerSession);
|
||||
}, null, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
multiplayerSession.Dispose();
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
if (MyGameService.IsOnline)
|
||||
{
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: MyTexts.Get(MyCommonTexts.DialogTextDownloadModsFailed)));
|
||||
}
|
||||
else
|
||||
{
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: new StringBuilder(string.Format(MyTexts.GetString(MyCommonTexts.DialogTextDownloadModsFailedSteamOffline), MySession.GameServiceName))));
|
||||
}
|
||||
}
|
||||
MyLog.Default.WriteLine("LoadSession() - End");
|
||||
}, delegate
|
||||
else
|
||||
{
|
||||
multiplayerSession.Dispose();
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool DrawInternal(MyGuiScreenLoading __instance)
|
||||
{
|
||||
|
||||
//If we dont have a custom loading screen texture, do not do the special crap below
|
||||
if (string.IsNullOrEmpty(LoadingScreenTexture))
|
||||
return true;
|
||||
|
||||
|
||||
float m_transitionAlpha = (float)typeof(MyGuiScreenBase).GetField("m_transitionAlpha", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
|
||||
string m_font = "LoadingScreen";
|
||||
//MyGuiControlMultilineText m_multiTextControl = (MyGuiControlMultilineText)typeof(MyGuiScreenLoading).GetField("m_multiTextControl", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
|
||||
|
||||
|
||||
Color color = new Color(255, 255, 255, 250);
|
||||
color.A = (byte)((float)(int)color.A * m_transitionAlpha);
|
||||
Rectangle fullscreenRectangle = MyGuiManager.GetFullscreenRectangle();
|
||||
MyGuiManager.DrawSpriteBatch("Textures\\GUI\\Blank.dds", fullscreenRectangle, Color.Black, false, true);
|
||||
Rectangle outRect;
|
||||
MyGuiManager.GetSafeHeightFullScreenPictureSize(MyGuiConstants.LOADING_BACKGROUND_TEXTURE_REAL_SIZE, out outRect);
|
||||
MyGuiManager.DrawSpriteBatch(LoadingScreenTexture, outRect, new Color(new Vector4(1f, 1f, 1f, m_transitionAlpha)), true, true);
|
||||
MyGuiManager.DrawSpriteBatch("Textures\\Gui\\Screens\\screen_background_fade.dds", outRect, new Color(new Vector4(1f, 1f, 1f, m_transitionAlpha)), true, true);
|
||||
|
||||
//MyGuiSandbox.DrawGameLogoHandler(m_transitionAlpha, MyGuiManager.ComputeFullscreenGuiCoordinate(MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, 44, 68));
|
||||
|
||||
string LoadScreen = $"Loading into {ServerName}! Please wait!";
|
||||
|
||||
|
||||
MyGuiManager.DrawString(m_font, LoadScreen, new Vector2(0.5f, 0.95f), MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f, new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * m_transitionAlpha), MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
|
||||
|
||||
MyGuiManager.DrawString(m_font, "Nexus & SeamlessClient Made by: Casimir", new Vector2(0.95f, 0.95f), MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f, new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * m_transitionAlpha), MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
|
||||
|
||||
/*
|
||||
if (string.IsNullOrEmpty(m_customTextFromConstructor))
|
||||
{
|
||||
string font = m_font;
|
||||
Vector2 positionAbsoluteBottomLeft = m_multiTextControl.GetPositionAbsoluteBottomLeft();
|
||||
Vector2 textSize = m_multiTextControl.TextSize;
|
||||
Vector2 normalizedCoord = positionAbsoluteBottomLeft + new Vector2((m_multiTextControl.Size.X - textSize.X) * 0.5f + 0.025f, 0.025f);
|
||||
MyGuiManager.DrawString(font, m_authorWithDash.ToString(), normalizedCoord, MyGuiSandbox.GetDefaultTextScaleWithLanguage());
|
||||
if (MyGameService.IsOnline)
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
|
||||
messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError),
|
||||
messageText: MyTexts.Get(MyCommonTexts.DialogTextDownloadModsFailed)));
|
||||
else
|
||||
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
|
||||
messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError),
|
||||
messageText: new StringBuilder(string.Format(
|
||||
MyTexts.GetString(MyCommonTexts.DialogTextDownloadModsFailedSteamOffline),
|
||||
MySession.GameServiceName))));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//m_multiTextControl.Draw(1f, 1f);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static bool GetCustomLoadingScreenPath(List<MyObjectBuilder_Checkpoint.ModItem> Mods, out string File)
|
||||
MyLog.Default.WriteLine("LoadSession() - End");
|
||||
}, () =>
|
||||
{
|
||||
File = null;
|
||||
string WorkshopDir = MyFileSystem.ModsPath;
|
||||
List<string> backgrounds = new List<string>();
|
||||
Random r = new Random(DateTime.Now.Millisecond);
|
||||
SeamlessClient.TryShow(WorkshopDir);
|
||||
try
|
||||
multiplayerSession.Dispose();
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool DrawInternal(MyGuiScreenLoading __instance)
|
||||
{
|
||||
//If we dont have a custom loading screen texture, do not do the special crap below
|
||||
if (string.IsNullOrEmpty(_loadingScreenTexture))
|
||||
return true;
|
||||
//MyGuiControlMultilineText m_multiTextControl = (MyGuiControlMultilineText)typeof(MyGuiScreenLoading).GetField("m_multiTextControl", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
|
||||
|
||||
|
||||
var color = new Color(255, 255, 255, 250);
|
||||
color.A = (byte)(color.A * __instance.m_transitionAlpha);
|
||||
var fullscreenRectangle = MyGuiManager.GetFullscreenRectangle();
|
||||
MyGuiManager.DrawSpriteBatch(@"Textures\GUI\Blank.dds", fullscreenRectangle, Color.Black, false, true);
|
||||
MyGuiManager.GetSafeHeightFullScreenPictureSize(MyGuiConstants.LOADING_BACKGROUND_TEXTURE_REAL_SIZE,
|
||||
out var outRect);
|
||||
MyGuiManager.DrawSpriteBatch(_loadingScreenTexture, outRect,
|
||||
new Color(new Vector4(1f, 1f, 1f, __instance.m_transitionAlpha)), true, true);
|
||||
MyGuiManager.DrawSpriteBatch(@"Textures\Gui\Screens\screen_background_fade.dds", outRect,
|
||||
new Color(new Vector4(1f, 1f, 1f, __instance.m_transitionAlpha)), true, true);
|
||||
|
||||
//MyGuiSandbox.DrawGameLogoHandler(m_transitionAlpha, MyGuiManager.ComputeFullscreenGuiCoordinate(MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, 44, 68));
|
||||
|
||||
var loadScreen = $"Loading into {_serverName}! Please wait!";
|
||||
|
||||
|
||||
MyGuiManager.DrawString(MyFontEnum.LoadingScreen, loadScreen, new Vector2(0.5f, 0.95f),
|
||||
MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f,
|
||||
new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * __instance.m_transitionAlpha),
|
||||
MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
|
||||
|
||||
MyGuiManager.DrawString(MyFontEnum.LoadingScreen, "Nexus & SeamlessClient Made by: Casimir", new Vector2(0.95f, 0.95f),
|
||||
MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f,
|
||||
new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * __instance.m_transitionAlpha),
|
||||
MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
|
||||
|
||||
/*
|
||||
if (string.IsNullOrEmpty(m_customTextFromConstructor))
|
||||
{
|
||||
string font = m_font;
|
||||
Vector2 positionAbsoluteBottomLeft = m_multiTextControl.GetPositionAbsoluteBottomLeft();
|
||||
Vector2 textSize = m_multiTextControl.TextSize;
|
||||
Vector2 normalizedCoord = positionAbsoluteBottomLeft + new Vector2((m_multiTextControl.Size.X - textSize.X) * 0.5f + 0.025f, 0.025f);
|
||||
MyGuiManager.DrawString(font, m_authorWithDash.ToString(), normalizedCoord, MyGuiSandbox.GetDefaultTextScaleWithLanguage());
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//m_multiTextControl.Draw(1f, 1f);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static bool GetCustomLoadingScreenPath(List<MyObjectBuilder_Checkpoint.ModItem> mods, out string file)
|
||||
{
|
||||
file = null;
|
||||
var workshopDir = MyFileSystem.ModsPath;
|
||||
var backgrounds = new List<string>();
|
||||
SeamlessClient.TryShow(workshopDir);
|
||||
try
|
||||
{
|
||||
SeamlessClient.TryShow($"Installed Mods: ({mods.Count}) [{string.Join(", ", mods.Select(x => x.FriendlyName))}]");
|
||||
foreach (var mod in mods)
|
||||
{
|
||||
SeamlessClient.TryShow("Installed Mods: " + Mods);
|
||||
foreach (var Mod in Mods)
|
||||
var searchDir = mod.GetPath();
|
||||
|
||||
if (!Directory.Exists(searchDir))
|
||||
continue;
|
||||
|
||||
|
||||
var files = Directory.GetFiles(searchDir, "CustomLoadingBackground*.dds",
|
||||
SearchOption.TopDirectoryOnly);
|
||||
foreach (var filePath in files)
|
||||
{
|
||||
string SearchDir = Mod.GetPath();
|
||||
|
||||
if (!Directory.Exists(SearchDir))
|
||||
continue;
|
||||
|
||||
|
||||
var files = Directory.GetFiles(SearchDir, "CustomLoadingBackground*.dds", SearchOption.TopDirectoryOnly);
|
||||
foreach (var file in files)
|
||||
{
|
||||
// Adds all files containing CustomLoadingBackground to a list for later randomisation
|
||||
SeamlessClient.TryShow(Mod.FriendlyName + " contains a custom loading background!");
|
||||
backgrounds.Add(file);
|
||||
|
||||
}
|
||||
// Adds all files containing CustomLoadingBackground to a list for later randomisation
|
||||
SeamlessClient.TryShow($"{mod.FriendlyName} contains a custom loading background!");
|
||||
backgrounds.Add(filePath);
|
||||
}
|
||||
|
||||
// Randomly pick a loading screen from the available backgrounds
|
||||
var rInt = r.Next(0, backgrounds.Count() - 1);
|
||||
File = backgrounds[rInt];
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SeamlessClient.TryShow(ex.ToString());
|
||||
}
|
||||
|
||||
SeamlessClient.TryShow("No installed custom loading screen!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private static void OnUserJoined(ref JoinResultMsg msg)
|
||||
{
|
||||
if (msg.JoinResult == JoinResult.OK)
|
||||
{
|
||||
//SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString());
|
||||
|
||||
//Invoke the switch event
|
||||
OnJoinEvent?.Invoke(null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static bool OnConnectToServer(MyGameServerItem server, Action<JoinResult> onDone)
|
||||
{
|
||||
if (SeamlessClient.IsSwitching)
|
||||
return false;
|
||||
|
||||
|
||||
// Randomly pick a loading screen from the available backgrounds
|
||||
file = backgrounds[Random.Shared.Next(0, backgrounds.Count - 1)];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Patch Utils */
|
||||
|
||||
private static MethodInfo GetMethod(Type type, string MethodName, BindingFlags Flags)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodInfo FoundMethod = type.GetMethod(MethodName, Flags);
|
||||
|
||||
if (FoundMethod == null)
|
||||
throw new NullReferenceException($"Method for {MethodName} is null!");
|
||||
|
||||
|
||||
return FoundMethod;
|
||||
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
throw Ex;
|
||||
}
|
||||
|
||||
SeamlessClient.TryShow(ex.ToString());
|
||||
}
|
||||
|
||||
private static FieldInfo GetField(Type type, string FieldName, BindingFlags Flags)
|
||||
{
|
||||
try
|
||||
{
|
||||
FieldInfo FoundField = type.GetField(FieldName, Flags);
|
||||
|
||||
if (FoundField == null)
|
||||
throw new NullReferenceException($"Field for {FieldName} is null!");
|
||||
|
||||
|
||||
return FoundField;
|
||||
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
throw Ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static PropertyInfo GetProperty(Type type, string PropertyName, BindingFlags Flags)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo FoundProperty = type.GetProperty(PropertyName, Flags);
|
||||
|
||||
if (FoundProperty == null)
|
||||
throw new NullReferenceException($"Property for {PropertyName} is null!");
|
||||
|
||||
|
||||
return FoundProperty;
|
||||
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
throw Ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ConstructorInfo GetConstructor(Type type, BindingFlags Flags, Type[] Types)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
ConstructorInfo FoundConstructor = type.GetConstructor(Flags, null, Types, null);
|
||||
|
||||
if (FoundConstructor == null)
|
||||
throw new NullReferenceException($"Contructor for {type.Name} is null!");
|
||||
|
||||
|
||||
return FoundConstructor;
|
||||
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
throw Ex;
|
||||
}
|
||||
}
|
||||
SeamlessClient.TryShow("No installed custom loading screen!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
Reference in New Issue
Block a user