- Fixed duplicate component calls

- Removed loading screen items in SP
- Re-Added custom loading screens for servers
This commit is contained in:
Garrett
2023-12-19 22:37:03 -06:00
parent 04bbf37b12
commit 410ad52b59
6 changed files with 763 additions and 131 deletions

View File

@@ -18,171 +18,137 @@ using Sandbox.Engine.Networking;
using VRage;
using VRage.GameServices;
using VRageRender;
using Sandbox.Game.Multiplayer;
using Sandbox.Game;
using SeamlessClient.GUI.Screens;
using Sandbox.Engine.Analytics;
using System.IO;
using VRage.FileSystem;
namespace SeamlessClient.Components
{
public class LoadingScreenComponent : ComponentBase
{
private static MethodInfo LoadMultiplayer;
private static string _loadingScreenTexture = null;
private static string _serverName;
private bool ScannedMods = false;
public static string JoiningServerName { get; private set; }
public static List<string> CustomLoadingTextures { get; private set; } = new List<string>();
static Random random = new Random(Guid.NewGuid().GetHashCode());
delegate void MyDelegate(string text);
private static List<MyObjectBuilder_Checkpoint.ModItem> mods;
public override void Patch(Harmony patcher)
{
var startLoading = PatchUtils.GetMethod(typeof(MySessionLoader), "StartLoading");
var loadingAction = PatchUtils.GetMethod(typeof(MySessionLoader), "LoadMultiplayerSession");
var loadingScreenDraw = PatchUtils.GetMethod(typeof(MyGuiScreenLoading), "DrawInternal");
LoadMultiplayer = PatchUtils.GetMethod(typeof(MySession), "LoadMultiplayer");
patcher.Patch(startLoading, prefix: new HarmonyMethod(Get(typeof(LoadingScreenComponent), nameof(StartLoading))));
patcher.Patch(loadingAction, postfix: new HarmonyMethod(Get(typeof(LoadingScreenComponent), nameof(LoadMultiplayerSession))));
}
patcher.Patch(loadingAction, prefix: new HarmonyMethod(Get(typeof(LoadingScreenComponent), nameof(LoadMultiplayerSession))));
patcher.Patch(loadingScreenDraw, prefix: new HarmonyMethod(Get(typeof(LoadingScreenComponent), nameof(DrawInternal_PRE))));
patcher.Patch(loadingScreenDraw, postfix: new HarmonyMethod(Get(typeof(LoadingScreenComponent), nameof(DrawInternal_POST))));
base.Patch(patcher);
public static string getRandomLoadingScreen()
{
int randomIndex = random.Next(CustomLoadingTextures.Count);
return CustomLoadingTextures[randomIndex];
}
private static bool LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
private static void LoadMultiplayerSession(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
{
MyLog.Default.WriteLine("LoadSession() - Start");
if (!MyWorkshop.CheckLocalModsAllowed(world.Checkpoint.Mods, false))
{
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;
//This is the main enty point for the start loading system...
if (Sync.IsServer)
return;
JoiningServerName = multiplayerSession.HostName;
mods = world.Checkpoint.Mods;
//GetCustomLoadingScreenPath(world.Checkpoint.Mods);
//Search for any custom loading screens
return;
}
MyWorkshop.DownloadModsAsync(world.Checkpoint.Mods, delegate (MyGameServiceCallResult result)
private static bool StartLoading(Action loadingAction, Action loadingActionXMLAllowed = null, string customLoadingBackground = null, string customLoadingtext = null)
{
switch (result)
{
case MyGameServiceCallResult.NotEnoughSpace:
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), messageText: MyTexts.Get(MyCommonTexts.DialogTextDownloadModsFailed_NotEnoughSpace), okButtonText: null, cancelButtonText: null, yesButtonText: null, noButtonText: null, callback: delegate
{
MySessionLoader.UnloadAndExitToMenu();
}));
break;
case MyGameServiceCallResult.OK:
MyScreenManager.CloseAllScreensNowExcept(null);
MyGuiSandbox.Update(16);
if (MySession.Static != null)
{
MySession.Static.Unload();
MySession.Static = null;
}
MySessionLoader.StartLoading(delegate
{
LoadMultiplayer.Invoke(null, new object[] { world, multiplayerSession });
});
break;
default:
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.GameServiceDisplayName))));
}
break;
}
MyLog.Default.WriteLine("LoadSession() - End");
}, delegate
{
multiplayerSession.Dispose();
MySessionLoader.UnloadAndExitToMenu();
});
return false;
}
private void OnFinished(MyGameServiceCallResult result)
{
}
/* Control what screen is being loaded */
private static bool DrawInternal_PRE(MyGuiScreenLoading __instance)
{
//If we dont have a custom loading screen texture, do not do the special crap below
if (string.IsNullOrEmpty(_loadingScreenTexture))
//If we are loading into a single player enviroment, skip override
if (Sync.IsServer)
return true;
const string mFont = "LoadingScreen";
var mTransitionAlpha = (float)typeof(MyGuiScreenBase).GetField("m_transitionAlpha", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
var color = new Color(255, 255, 255, 250);
color.A = (byte)(color.A * mTransitionAlpha);
var 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, mTransitionAlpha)), true, true);
MyGuiManager.DrawSpriteBatch("Textures\\Gui\\Screens\\screen_background_fade.dds", outRect,
new Color(new Vector4(1f, 1f, 1f, mTransitionAlpha)), 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(mFont, loadScreen, new Vector2(0.5f, 0.95f),
MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f,
new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * mTransitionAlpha),
MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
/*
if (string.IsNullOrEmpty(m_customTextFromConstructor))
GetCustomLoadingScreenPath();
if (MySpaceAnalytics.Instance != null)
{
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());
MySpaceAnalytics.Instance.StoreWorldLoadingStartTime();
}
*/
//m_multiTextControl.Draw(1f, 1f);
MyGuiScreenGamePlay newGameplayScreen = new MyGuiScreenGamePlay();
MyGuiScreenGamePlay myGuiScreenGamePlay = newGameplayScreen;
myGuiScreenGamePlay.OnLoadingAction = (Action)Delegate.Combine(myGuiScreenGamePlay.OnLoadingAction, loadingAction);
//Use custom loading screen
GUILoadingScreen myGuiScreenLoading = new GUILoadingScreen(newGameplayScreen, MyGuiScreenGamePlay.Static, customLoadingBackground, customLoadingtext);
myGuiScreenLoading.OnScreenLoadingFinished += delegate
{
if (MySession.Static != null)
{
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateScreen(MyPerGameSettings.GUI.HUDScreen));
newGameplayScreen.LoadingDone = true;
}
};
myGuiScreenLoading.OnLoadingXMLAllowed = loadingActionXMLAllowed;
MyGuiSandbox.AddScreen(myGuiScreenLoading);
return false;
}
private static void DrawInternal_POST(MyGuiScreenLoading __instance)
public static void GetCustomLoadingScreenPath()
{
const string mFont = "LoadingScreen";
var mTransitionAlpha = (float)typeof(MyGuiScreenBase).GetField("m_transitionAlpha", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
MyGuiManager.DrawString(mFont, "Nexus & SeamlessClient Made by: Casimir", new Vector2(0.95f, 0.95f),
MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f,
new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * mTransitionAlpha),
MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
try
{
//var Mods = world.Checkpoint.Mods;
var Mods = mods;
Seamless.TryShow("Server 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 file in files)
{
// Adds all files containing CustomLoadingBackground to a list for later randomisation
Seamless.TryShow(mod.FriendlyName + " contains a custom loading background!");
CustomLoadingTextures.Add(file);
}
}
}
catch (Exception ex)
{
Seamless.TryShow(ex.ToString());
}
Seamless.TryShow("");
return;
}
}
}

View File

@@ -1,6 +1,7 @@
using HarmonyLib;
using Sandbox.Game;
using Sandbox.Game.Gui;
using Sandbox.Game.Multiplayer;
using Sandbox.Game.World;
using SeamlessClient.Messages;
using SeamlessClient.Utilities;
@@ -27,7 +28,7 @@ namespace SeamlessClient.OnlinePlayersWindow
public override void Update()
{
if (!Seamless.isSeamlessServer)
if (Sync.IsServer)
{
MyPerGameSettings.GUI.PlayersScreen = typeof(MyGuiScreenPlayers);
}

View File

@@ -0,0 +1,652 @@
using Sandbox.AppCode;
using Sandbox.Engine.Multiplayer;
using Sandbox.Engine.Networking;
using Sandbox.Engine.Utils;
using Sandbox.Game.Gui;
using Sandbox.Game.Screens;
using Sandbox.Game.World;
using Sandbox.Game;
using Sandbox.Graphics.GUI;
using Sandbox.Graphics;
using Sandbox;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VRage.Audio;
using VRage.Input;
using VRage.Library.Utils;
using VRage.Utils;
using VRage;
using VRageMath;
using VRageRender;
using VRage.Collections;
using Sandbox.Game.Multiplayer;
using Sandbox.Engine.Platform;
using SeamlessClient.Components;
using System.Security.AccessControl;
using System.Reflection;
using System.Timers;
namespace SeamlessClient.GUI.Screens
{
public class GUILoadingScreen : MyGuiScreenBase
{
public static readonly int STREAMING_TIMEOUT = 900;
public static GUILoadingScreen Static;
private MyGuiScreenBase m_screenToLoad;
private readonly MyGuiScreenGamePlay m_screenToUnload;
private string m_backgroundScreenTexture;
private string m_backgroundTextureFromConstructor;
private string m_customTextFromConstructor;
private string m_rotatingWheelTexture;
private object m_currentText;
private MyGuiControlMultilineText m_multiTextControl;
private StringBuilder m_authorWithDash;
private MyGuiControlRotatingWheel m_wheel;
private bool m_exceptionDuringLoad;
public static string LastBackgroundTexture;
public Action OnLoadingXMLAllowed;
public static int m_currentTextIdx = 0;
private volatile bool m_loadInDrawFinished;
private bool m_loadFinished;
private bool m_runLoadEnded;
private bool m_isStreamed;
private int m_streamingTimeout;
private float m_progress;
private int m_displayProgress;
private float m_localProgress;
private float m_localTotal;
private float m_localProgressDelta;
private float m_localProgressMin;
private string m_font = "LoadingScreen";
private bool m_closed;
private MyTimeSpan m_loadingTimeStart;
private static Dictionary<LoadingProgress, float> _progressMap;
private Timer backgroundTimer = new Timer(8000);
/// <summary>
/// Event created once the screen has been loaded and added to GUI manager.
/// </summary>
public event Action OnScreenLoadingFinished;
public GUILoadingScreen(MyGuiScreenBase screenToLoad, MyGuiScreenGamePlay screenToUnload, string textureFromConstructor, string customText = null)
: base(Vector2.Zero)
{
base.CanBeHidden = false;
m_isTopMostScreen = true;
object instance = PatchUtils.GetProperty(PatchUtils.MyLoadingPerformance, "Instance").GetValue(null);
if(instance != null)
PatchUtils.GetMethod(PatchUtils.MyLoadingPerformance, "StartTiming").Invoke(instance, null);
//MyLoadingPerformance.Instance.StartTiming();
Static = this;
m_screenToLoad = screenToLoad;
m_screenToUnload = screenToUnload;
m_closeOnEsc = false;
base.DrawMouseCursor = false;
m_loadInDrawFinished = false;
m_drawEvenWithoutFocus = true;
MethodInfo text = PatchUtils.GetMethod(PatchUtils.MyLoadingScreenText, "GetRandomText");
m_currentText = text.Invoke(null, null);
//m_currentText = MyLoadingScreenText.GetRandomText();
m_isFirstForUnload = true;
MyGuiSandbox.SetMouseCursorVisibility(false);
m_rotatingWheelTexture = "Textures\\GUI\\screens\\screen_loading_wheel_loading_screen.dds";
m_backgroundTextureFromConstructor = textureFromConstructor;
m_customTextFromConstructor = customText;
m_loadFinished = false;
if (m_screenToLoad != null)
{
MySandboxGame.IsUpdateReady = false;
MySandboxGame.AreClipmapsReady = !Sync.IsServer || Game.IsDedicated || MyExternalAppBase.Static != null;
MySandboxGame.RenderTasksFinished = Game.IsDedicated || MyExternalAppBase.Static != null;
}
m_authorWithDash = new StringBuilder();
RecreateControls(true);
MyInput.Static.EnableInput(false);
if (Sync.IsServer || Game.IsDedicated || MyMultiplayer.Static == null)
{
m_isStreamed = true;
}
else
{
MyMultiplayer.Static.LocalRespawnRequested += OnLocalRespawnRequested;
}
MySession.LoadingStep = (Action<LoadingProgress>)Delegate.Combine(MySession.LoadingStep, new Action<LoadingProgress>(SetProgress));
MySession.LoadingLocalAdd = (Action<float>)Delegate.Combine(MySession.LoadingLocalAdd, new Action<float>(AddLocalProgress));
MySession.LoadingLocalClear = (Action)Delegate.Combine(MySession.LoadingLocalClear, new Action(ClearLocalProgress));
MySession.LoadingLocalBoundSet = (Action<LoadingProgress, LoadingProgress>)Delegate.Combine(MySession.LoadingLocalBoundSet, new Action<LoadingProgress, LoadingProgress>(SetLocalBounds));
MySession.LoadingLocalTotalSet = (Action<float>)Delegate.Combine(MySession.LoadingLocalTotalSet, new Action<float>(SetLocalTotal));
}
private void OnLocalRespawnRequested()
{
(MyMultiplayer.Static as MyMultiplayerClientBase).RequestBatchConfirmation();
MyMultiplayer.Static.PendingReplicablesDone += MyMultiplayer_PendingReplicablesDone;
MyMultiplayer.Static.LocalRespawnRequested -= OnLocalRespawnRequested;
m_streamingTimeout = 0;
}
private void MyMultiplayer_PendingReplicablesDone()
{
m_isStreamed = true;
if (MySession.Static.VoxelMaps.Instances.Count > 0)
{
MySandboxGame.AreClipmapsReady = false;
}
MyMultiplayer.Static.PendingReplicablesDone -= MyMultiplayer_PendingReplicablesDone;
}
public GUILoadingScreen(MyGuiScreenBase screenToLoad, MyGuiScreenGamePlay screenToUnload)
: this(screenToLoad, screenToUnload, null)
{
}
public override void RecreateControls(bool constructor)
{
base.RecreateControls(constructor);
Vector2 vector = MyGuiManager.MeasureString(m_font, MyTexts.Get(MyCommonTexts.LoadingPleaseWaitUppercase), 1.1f);
m_wheel = new MyGuiControlRotatingWheel(MyGuiConstants.LOADING_PLEASE_WAIT_POSITION - new Vector2(0f, 0.09f + vector.Y), MyGuiConstants.ROTATING_WHEEL_COLOR, 0.36f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, m_rotatingWheelTexture, false, MyPerGameSettings.GUI.MultipleSpinningWheels);
m_multiTextControl = new MyGuiControlMultilineText(contents: string.IsNullOrEmpty(m_customTextFromConstructor) ? new StringBuilder(m_currentText.ToString()) : new StringBuilder(m_customTextFromConstructor), position: new Vector2(0.5f, 0.66f), size: new Vector2(0.9f, 0.2f), backgroundColor: Vector4.One, font: m_font, textScale: 1f, textAlign: MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_BOTTOM, drawScrollbarV: false, drawScrollbarH: false);
m_multiTextControl.BorderEnabled = false;
m_multiTextControl.OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM;
m_multiTextControl.TextBoxAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM;
Controls.Add(m_wheel);
RefreshText();
}
public override string GetFriendlyName()
{
return "GUILoadingScreen";
}
public override void LoadContent()
{
m_loadingTimeStart = new MyTimeSpan(Stopwatch.GetTimestamp());
MySandboxGame.Log.WriteLine("MyGuiScreenLoading.LoadContent - START");
MySandboxGame.Log.IncreaseIndent();
m_backgroundScreenTexture = m_backgroundTextureFromConstructor ?? GetRandomBackgroundTexture();
if (m_screenToUnload != null)
{
m_screenToUnload.IsLoaded = false;
m_screenToUnload.CloseScreenNow();
}
base.LoadContent();
MyRenderProxy.LimitMaxQueueSize = true;
if (m_screenToLoad != null && !m_loadInDrawFinished && m_loadFinished)
{
m_screenToLoad.State = MyGuiScreenState.OPENING;
m_screenToLoad.LoadContent();
}
else
{
m_loadFinished = false;
}
MySandboxGame.Log.DecreaseIndent();
MySandboxGame.Log.WriteLine("MyGuiScreenLoading.LoadContent - END");
}
public static string GetRandomBackgroundTexture()
{
string text = MyUtils.GetRandomInt(MyPerGameSettings.GUI.LoadingScreenIndexRange.X, MyPerGameSettings.GUI.LoadingScreenIndexRange.Y + 1).ToString().PadLeft(3, '0');
return "Textures\\GUI\\Screens\\loading_background_" + text + ".dds";
}
public override void UnloadContent()
{
if (m_backgroundScreenTexture != null)
{
MyRenderProxy.UnloadTexture(m_backgroundScreenTexture);
}
if (m_backgroundTextureFromConstructor != null)
{
MyRenderProxy.UnloadTexture(m_backgroundTextureFromConstructor);
}
if (m_backgroundScreenTexture != null)
{
MyRenderProxy.UnloadTexture(m_rotatingWheelTexture);
}
if (m_screenToLoad != null && !m_loadFinished && m_loadInDrawFinished)
{
m_screenToLoad.UnloadContent();
m_screenToLoad.UnloadData();
m_screenToLoad = null;
}
if (m_screenToLoad != null && !m_loadInDrawFinished)
{
m_screenToLoad.UnloadContent();
}
MyRenderProxy.LimitMaxQueueSize = false;
base.UnloadContent();
Static = null;
}
public override bool Update(bool hasFocus)
{
if (!base.Update(hasFocus))
{
return false;
}
if (base.State == MyGuiScreenState.OPENED && !m_loadFinished)
{
m_loadFinished = true;
MyHud.ScreenEffects.FadeScreen(0f);
MyAudio.Static.Mute = true;
MyAudio.Static.StopMusic();
MyAudio.Static.ChangeGlobalVolume(0f, 0f);
MyRenderProxy.DeferStateChanges(true);
DrawLoading();
if (m_screenToLoad != null)
{
MySandboxGame.Log.WriteLine("RunLoadingAction - START");
RunLoad();
Action<LoadingProgress> loadingStep = MySession.LoadingStep;
if (loadingStep != null)
{
loadingStep(LoadingProgress.PROGRESS_STEP10);
}
MySandboxGame.Log.WriteLine("RunLoadingAction - END");
}
if (m_screenToLoad != null)
{
MyScreenManager.AddScreenNow(m_screenToLoad);
m_screenToLoad.Update(false);
}
m_screenToLoad = null;
m_wheel.ManualRotationUpdate = true;
}
m_streamingTimeout++;
bool flag = Sync.IsServer || Game.IsDedicated || MyMultiplayer.Static == null || !MyFakes.ENABLE_WAIT_UNTIL_MULTIPLAYER_READY || m_isStreamed || (MyFakes.LOADING_STREAMING_TIMEOUT_ENABLED && m_streamingTimeout >= STREAMING_TIMEOUT);
if (m_runLoadEnded && m_loadFinished && ((MySandboxGame.IsGameReady && flag && MySandboxGame.AreClipmapsReady) || m_exceptionDuringLoad) && !m_closed)
{
MyRenderProxy.DeferStateChanges(false);
MyHud.ScreenEffects.FadeScreen(1f, (!MyFakes.TESTING_TOOL_PLUGIN) ? 5f : 0f);
if (MyHud.ScreenEffects.IsBlackscreenFadeInProgress())
{
MyHudScreenEffects screenEffects = MyHud.ScreenEffects;
screenEffects.OnBlackscreenFadeFinishedCallback = (Action)Delegate.Combine(screenEffects.OnBlackscreenFadeFinishedCallback, new Action(MyGameService.OnLoadingScreenCompleted));
}
else
{
MyGameService.OnLoadingScreenCompleted();
}
if (!m_exceptionDuringLoad && this.OnScreenLoadingFinished != null)
{
this.OnScreenLoadingFinished();
this.OnScreenLoadingFinished = null;
}
CloseScreenNow();
DrawLoading();
MyTimeSpan myTimeSpan = new MyTimeSpan(Stopwatch.GetTimestamp()) - m_loadingTimeStart;
MySandboxGame.Log.WriteLine("Loading duration: " + myTimeSpan.Seconds);
m_closed = true;
}
else if (m_loadFinished && !MySandboxGame.AreClipmapsReady && MySession.Static != null && MySession.Static.VoxelMaps.Instances.Count == 0)
{
MySandboxGame.AreClipmapsReady = true;
}
return true;
}
private void RunLoad()
{
m_exceptionDuringLoad = false;
try
{
m_screenToLoad.RunLoadingAction();
}
catch (MyLoadingNeedXMLException ex)
{
m_exceptionDuringLoad = true;
if (OnLoadingXMLAllowed != null)
{
UnloadOnException(false);
if (MySandboxGame.Static.SuppressLoadingDialogs)
{
OnLoadingXMLAllowed();
return;
}
MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, MyTexts.Get(MyCommonTexts.LoadingNeedsXML), MyTexts.Get(MyCommonTexts.MessageBoxCaptionInfo), null, null, null, null, delegate
{
OnLoadingXMLAllowed();
}));
}
else
{
OnLoadException(ex, new StringBuilder(ex.Message), 1.5f);
}
}
catch (MyLoadingException ex2)
{
OnLoadException(ex2, new StringBuilder(ex2.Message), 1.5f);
m_exceptionDuringLoad = true;
}
catch (OutOfMemoryException)
{
throw;
}
catch (Exception e)
{
OnLoadException(e, MyTexts.Get(MyCommonTexts.WorldFileIsCorruptedAndCouldNotBeLoaded));
m_exceptionDuringLoad = true;
}
finally
{
m_runLoadEnded = true;
}
}
protected override void OnClosed()
{
MyRenderProxy.DeferStateChanges(false);
base.OnClosed();
MyInput.Static.EnableInput(true);
MyAudio.Static.Mute = false;
MySession.LoadingStep = (Action<LoadingProgress>)Delegate.Remove(MySession.LoadingStep, new Action<LoadingProgress>(SetProgress));
MySession.LoadingLocalAdd = (Action<float>)Delegate.Remove(MySession.LoadingLocalAdd, new Action<float>(AddLocalProgress));
MySession.LoadingLocalClear = (Action)Delegate.Remove(MySession.LoadingLocalClear, new Action(ClearLocalProgress));
MySession.LoadingLocalBoundSet = (Action<LoadingProgress, LoadingProgress>)Delegate.Remove(MySession.LoadingLocalBoundSet, new Action<LoadingProgress, LoadingProgress>(SetLocalBounds));
MySession.LoadingLocalTotalSet = (Action<float>)Delegate.Remove(MySession.LoadingLocalTotalSet, new Action<float>(SetLocalTotal));
}
private void UnloadOnException(bool exitToMainMenu)
{
MyRenderProxy.DeferStateChanges(false);
DrawLoading();
m_screenToLoad = null;
if (MyGuiScreenGamePlay.Static != null)
{
MyGuiScreenGamePlay.Static.UnloadData();
MyGuiScreenGamePlay.Static.UnloadContent();
}
MySandboxGame.IsUpdateReady = true;
MySandboxGame.AreClipmapsReady = true;
MySandboxGame.RenderTasksFinished = true;
if (exitToMainMenu)
{
MySessionLoader.UnloadAndExitToMenu();
}
else
{
MySessionLoader.Unload();
}
}
private void OnLoadException(Exception e, StringBuilder errorText, float heightMultiplier = 1f)
{
MySandboxGame.Log.WriteLine("ERROR: Loading screen failed");
MySandboxGame.Log.WriteLine(e);
UnloadOnException(true);
MyLoadingNeedDLCException exception;
MyGuiScreenMessageBox myGuiScreenMessageBox;
if ((exception = e as MyLoadingNeedDLCException) != null)
{
myGuiScreenMessageBox = MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Info, MyMessageBoxButtonsType.YES_NO, messageCaption: MyTexts.Get(MyCommonTexts.RequiresAnyDlc), messageText: new StringBuilder().AppendFormat(MyTexts.GetString(MyPlatformGameSettings.LocalizationKeys.ScenarioRequiresDlc), MyTexts.GetString(exception.RequiredDLC.DisplayName)), okButtonText: null, cancelButtonText: null, yesButtonText: null, noButtonText: null, callback: delegate (MyGuiScreenMessageBox.ResultEnum result)
{
if (result == MyGuiScreenMessageBox.ResultEnum.YES)
{
MyGameService.OpenDlcInShop(exception.RequiredDLC.AppId);
}
});
}
else
{
myGuiScreenMessageBox = MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, errorText, MyTexts.Get(MyCommonTexts.MessageBoxCaptionError));
Vector2 value = myGuiScreenMessageBox.Size.Value;
value.Y *= heightMultiplier;
myGuiScreenMessageBox.Size = value;
myGuiScreenMessageBox.RecreateControls(false);
}
MyGuiSandbox.AddScreen(myGuiScreenMessageBox);
}
public override void HandleInput(bool receivedFocusInThisUpdate)
{
base.HandleInput(receivedFocusInThisUpdate);
}
public void SetLocalBounds(LoadingProgress start, LoadingProgress end)
{
m_localProgressDelta = _progressMap[end] - _progressMap[start];
m_localProgressMin = m_progress;
}
public void ClearLocalProgress()
{
m_localTotal = 1f;
m_localProgress = 0f;
m_localProgressDelta = 0f;
}
public void SetLocalTotal(float total)
{
m_localTotal = total;
m_localProgress = 0f;
}
public void AddLocalProgress(float amount = 1f)
{
SetLocalProgress(m_localProgress + amount);
}
public void SetLocalProgress(float progress)
{
m_localProgress = progress;
if (m_localTotal > 0f)
{
float num = MathHelper.Clamp(m_localProgress / m_localTotal, 0f, 1f);
SetProgress(m_localProgressMin + num * m_localProgressDelta);
}
}
public void SetProgress(LoadingProgress progress)
{
SetProgress(_progressMap[progress]);
}
private void SetProgress(float progress)
{
m_progress = progress;
int num = (int)(m_progress * 100f);
if (num != m_displayProgress)
{
m_displayProgress = num;
if (MyUtils.MainThread == System.Threading.Thread.CurrentThread)
{
DrawLoading();
}
}
}
public bool DrawLoading()
{
DrawInternal();
bool result = base.Draw();
MyRenderProxy.AfterUpdate(null, false);
MyRenderProxy.BeforeUpdate();
return result;
}
private void DrawInternal()
{
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);
bool isCustom = false;
if(LoadingScreenComponent.CustomLoadingTextures.Count != 0)
{
if(LoadingScreenComponent.CustomLoadingTextures.Count > 1)
{
if (!backgroundTimer.Enabled)
{
backgroundTimer.Elapsed += BackgroundTimer_Elapsed;
backgroundTimer.Start();
m_backgroundScreenTexture = LoadingScreenComponent.getRandomLoadingScreen();
}
}
else
{
m_backgroundScreenTexture = LoadingScreenComponent.CustomLoadingTextures.First();
}
isCustom = true;
}
MyGuiManager.DrawSpriteBatch(m_backgroundScreenTexture, 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), new Vector2(0.005f, 0.19f));
LastBackgroundTexture = m_backgroundScreenTexture;
string loading = MyTexts.GetString(MyCommonTexts.LoadingPleaseWaitUppercase);
//If our server name is not empty:
if (!string.IsNullOrEmpty(LoadingScreenComponent.JoiningServerName))
{
loading = $"Loading into {LoadingScreenComponent.JoiningServerName}...";
}
MyGuiManager.DrawString(m_font, loading, MyGuiConstants.LOADING_PLEASE_WAIT_POSITION, MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f, new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * m_transitionAlpha), MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
MyGuiManager.DrawString(m_font, string.Format("{0}%", m_displayProgress), MyGuiConstants.LOADING_PERCENTAGE_POSITION, MyGuiSandbox.GetDefaultTextScaleWithLanguage() * 1.1f, new Color(MyGuiConstants.LOADING_PLEASE_WAIT_COLOR * m_transitionAlpha), MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM);
if (!isCustom && string.IsNullOrEmpty(m_customTextFromConstructor))
{
string font = m_font;
Vector2 positionAbsoluteBottomLeft = m_multiTextControl.GetPositionAbsoluteBottomLeft();
Vector2 textSize = m_multiTextControl.TextSize;
MyGuiManager.DrawString(normalizedCoord: positionAbsoluteBottomLeft + new Vector2((m_multiTextControl.Size.X - textSize.X) * 0.5f + 0.025f, 0.025f), font: font, text: m_authorWithDash.ToString(), scale: MyGuiSandbox.GetDefaultTextScaleWithLanguage());
m_multiTextControl.Draw(1f, 1f);
}
/* Custom draws */
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);
}
private void BackgroundTimer_Elapsed(object sender, ElapsedEventArgs e)
{
m_backgroundScreenTexture = LoadingScreenComponent.getRandomLoadingScreen();
}
public override bool Draw()
{
DrawInternal();
return base.Draw();
}
private void RefreshText()
{
if (string.IsNullOrEmpty(m_customTextFromConstructor))
{
m_multiTextControl.TextEnum = MyStringId.GetOrCompute(m_currentText.ToString());
if (m_currentText.GetType() == PatchUtils.MyLoadingScreenQuote)
{
MyStringId author = (MyStringId)PatchUtils.GetField(PatchUtils.MyLoadingScreenQuote, "Author").GetValue(m_currentText);
m_authorWithDash.Clear().Append("- ").AppendStringBuilder(MyTexts.Get(author))
.Append(" -");
}
}
}
public override void OnRemoved()
{
base.OnRemoved();
}
static GUILoadingScreen()
{
Dictionary<LoadingProgress, float> dictionary = new Dictionary<LoadingProgress, float>();
dictionary[LoadingProgress.PROGRESS_STEP1] = 0.01f;
dictionary[LoadingProgress.PROGRESS_STEP2] = 0.05f;
dictionary[LoadingProgress.PROGRESS_STEP2_1_BEFORE_COMPILE_SCRIPTS] = 0.05f;
dictionary[LoadingProgress.PROGRESS_STEP2_2_AFTER_COMPILE_SCRIPTS] = 0.2f;
dictionary[LoadingProgress.PROGRESS_STEP2_3_LOAD_DEFINITIONS] = 0.26f;
dictionary[LoadingProgress.PROGRESS_STEP2_4_POST_LOAD_DEFINITIONS] = 0.26f;
dictionary[LoadingProgress.PROGRESS_STEP2_5_BEFORE_LOAD_VOXELS] = 0.3f;
dictionary[LoadingProgress.PROGRESS_STEP2_6_AFTER_LOAD_VOXELS] = 0.4f;
dictionary[LoadingProgress.PROGRESS_STEP2_6_AFTER_LOAD_GAME_DEFINITION] = 0.44f;
dictionary[LoadingProgress.PROGRESS_STEP3] = 0.45f;
dictionary[LoadingProgress.PROGRESS_STEP4] = 0.5f;
dictionary[LoadingProgress.PROGRESS_STEP5] = 0.9f;
dictionary[LoadingProgress.PROGRESS_STEP6] = 0.91f;
dictionary[LoadingProgress.PROGRESS_STEP7] = 0.92f;
dictionary[LoadingProgress.PROGRESS_STEP8] = 0.93f;
dictionary[LoadingProgress.PROGRESS_STEP9] = 0.99f;
dictionary[LoadingProgress.PROGRESS_STEP10] = 1f;
_progressMap = dictionary;
}
}
}

View File

@@ -33,7 +33,7 @@ namespace SeamlessClient
private Assembly thisAssembly => typeof(Seamless).Assembly;
private bool Initilized = false;
public static bool isSeamlessServer { get; private set; } = false;
public static bool isDebug = true;
public static bool isDebug = false;
@@ -155,11 +155,10 @@ namespace SeamlessClient
{
}
public void Update()
{
allComps.ForEach(x => x.Update());
if (MyAPIGateway.Multiplayer == null)
{
isSeamlessServer = false;
@@ -174,7 +173,7 @@ namespace SeamlessClient
Initilized = true;
}
allComps.ForEach(x => x.Update());
}

View File

@@ -99,6 +99,7 @@
<Compile Include="Components\LoadingScreenComponent.cs" />
<Compile Include="Components\MyGUIScreenMedicalsPatch.cs" />
<Compile Include="Components\MyHudTimeTracker.cs" />
<Compile Include="GUI\Screens\GUILoadingScreen.cs" />
<Compile Include="Messages\OnlinePlayerData.cs" />
<Compile Include="Utilities\UtilExtensions.cs" />
<Compile Include="Utilities\PatchUtils.cs" />

View File

@@ -45,6 +45,19 @@ namespace SeamlessClient.Components
public static readonly Type MySlimBlockType =
Type.GetType("Sandbox.Game.Entities.Cube.MySlimBlock, Sandbox.Game");
public static readonly Type MyLoadingScreenQuote =
Type.GetType("Sandbox.Game.Screens.Helpers.MyLoadingScreenQuote, Sandbox.Game");
public static readonly Type MyLoadingScreenHint =
Type.GetType("Sandbox.Game.Screens.Helpers.MyLoadingScreenHint, Sandbox.Game");
public static readonly Type MyLoadingPerformance =
Type.GetType("Sandbox.Engine.Utils.MyLoadingPerformance, Sandbox.Game");
public static readonly Type MyLoadingScreenText =
Type.GetType("Sandbox.Game.Screens.Helpers.MyLoadingScreenText, Sandbox.Game");
/* Harmony Patcher */
private static readonly Harmony Patcher = new Harmony("SeamlessClientPatcher");