Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimOptimizer v0.1.17
MagiCorp.ValheimOptimizer.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("MagiCorp.ValheimOptimizer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+2170dc9292f9eca3f6a5a042c19a5001720afa5c")] [assembly: AssemblyProduct("MagiCorp.ValheimOptimizer")] [assembly: AssemblyTitle("MagiCorp.ValheimOptimizer")] [assembly: AssemblyVersion("1.0.0.0")] namespace MagiCorp.ValheimOptimizer; [BepInPlugin("magicorp.valheim.optimizer", "MagiCorp Valheim Optimizer", "0.1.17")] public sealed class ValheimOptimizerPlugin : BaseUnityPlugin { public const string PluginGuid = "magicorp.valheim.optimizer"; public const string PluginName = "MagiCorp Valheim Optimizer"; public const string PluginVersion = "0.1.17"; internal const int ProtocolVersion = 4; internal static ManualLogSource Log; internal static ConfigEntry<bool> EnableNetworkScheduler; internal static ConfigEntry<int> OptimizedReplicationHz; internal static ConfigEntry<float> NetworkMainThreadBudgetMs; internal static ConfigEntry<int> ReplicationWindowKiB; internal static ConfigEntry<int> ReplicationMinRoomKiB; internal static ConfigEntry<bool> EnableZdoCompression; internal static ConfigEntry<int> CompressionThresholdBytes; internal static ConfigEntry<bool> EnableFastLoading; internal static ConfigEntry<int> LoadingObjectLimit; internal static ConfigEntry<bool> EnablePortalPrefetch; internal static ConfigEntry<int> PortalPrefetchMaxZdos; internal static ConfigEntry<int> PortalZonesPerFrame; internal static ConfigEntry<float> MinimumDistantTeleportSeconds; internal static ConfigEntry<float> InitialSpawnMinimumSeconds; internal static ConfigEntry<bool> EnableMinimapCache; internal static ConfigEntry<bool> ImmediateJoinLoadingScreen; internal static ConfigEntry<bool> AsyncJoinSceneLoad; internal static ConfigEntry<bool> MinimalMainMenu; internal static ConfigEntry<bool> UseCustomLoadingScreen; internal static ConfigEntry<bool> VerboseMetrics; internal static string PluginDirectory; private Harmony _harmony; private float _nextHello; private float _nextMetrics; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; EnableNetworkScheduler = ((BaseUnityPlugin)this).Config.Bind<bool>("Network", "AdaptiveReplicationScheduler", true, "Service all optimized peers within a bounded main-thread budget instead of one peer per frame."); OptimizedReplicationHz = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "ReplicationHz", 30, new ConfigDescription("ZDO replication rate for negotiated optimizer peers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 30), Array.Empty<object>())); NetworkMainThreadBudgetMs = ((BaseUnityPlugin)this).Config.Bind<float>("Network", "MainThreadBudgetMs", 1.75f, new ConfigDescription("Maximum scheduler CPU budget per update.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 8f), Array.Empty<object>())); ReplicationWindowKiB = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "ReplicationWindowKiB", 128, new ConfigDescription("Maximum ZDO send window when every peer supports the optimizer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 2048), Array.Empty<object>())); ReplicationMinRoomKiB = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "ReplicationMinRoomKiB", 8, new ConfigDescription("Minimum free ZDO send window before building another batch.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 256), Array.Empty<object>())); EnableZdoCompression = ((BaseUnityPlugin)this).Config.Bind<bool>("Network", "CompressZdoData", true, "Losslessly compress large ZDOData RPC payloads between optimizer peers."); CompressionThresholdBytes = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "CompressionThresholdBytes", 2048, new ConfigDescription("Do not compress smaller ZDO payloads.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(256, 65536), Array.Empty<object>())); EnableFastLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "AdaptiveObjectCreation", true, "Increase ZNet object creation throughput while the client is on a loading/teleport screen."); LoadingObjectLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Loading", "LoadingObjectsPerPass", 300, new ConfigDescription("Maximum object creation budget while loading. Vanilla is 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), Array.Empty<object>())); EnablePortalPrefetch = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "PortalPrefetch", true, "Prefetch destination terrain and ZDOs as soon as a distant teleport begins."); PortalPrefetchMaxZdos = ((BaseUnityPlugin)this).Config.Bind<int>("Loading", "PortalPrefetchMaxZDOs", 6000, new ConfigDescription("Maximum destination ZDOs to priority-send per teleport.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(500, 50000), Array.Empty<object>())); PortalZonesPerFrame = ((BaseUnityPlugin)this).Config.Bind<int>("Loading", "PortalZonesPerFrame", 2, new ConfigDescription("Destination terrain zones to poke per client frame.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); MinimumDistantTeleportSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Loading", "MinimumDistantTeleportSeconds", 2.5f, new ConfigDescription("Vanilla forces 8 seconds. Area readiness is still required.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2.05f, 8f), Array.Empty<object>())); InitialSpawnMinimumSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Loading", "InitialSpawnMinimumSeconds", 0.25f, new ConfigDescription("Minimum initial join respawn delay on negotiated servers. Area readiness and ground checks are still required. Death respawns are unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>())); EnableMinimapCache = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "PersistentMinimapCache", true, "Reuse Valheim minimap cache files on repeat joins to the same negotiated world with world-version validation."); ImmediateJoinLoadingScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "ImmediateJoinLoadingScreen", true, "Skip Valheim's cosmetic 1.5-second menu fade and show the loading screen immediately when starting or joining a world."); AsyncJoinSceneLoad = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "AsyncJoinSceneLoad", false, "Experimental asynchronous remote scene loading. Disabled by default because some clients could remain on the loading screen. Vanilla scene loading is used when false."); MinimalMainMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "MinimalMainMenu", true, "Use an UI-only black main menu: no 3D world rendering and no per-frame menu camera movement."); UseCustomLoadingScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "UseCustomLoadingScreen", true, "Use the packaged MagiCorp loading artwork for the pre-join loading overlay. Falls back to the black/text overlay if unavailable."); PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Paths.PluginPath; VerboseMetrics = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "PeriodicMetrics", true, "Log optimizer counters every 30 seconds."); NetworkOptimizations.Initialize(); LoadingOptimizations.Initialize(); PreJoinLoadingOverlay.PreloadArtwork(); PrivateAccess.LogResolution(); RunCompressionSelfTest(); _harmony = new Harmony("magicorp.valheim.optimizer"); _harmony.PatchAll(typeof(ValheimOptimizerPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded; protocol v{2}; SendZDOs window patches={3}, teleport patches={4}", "MagiCorp Valheim Optimizer", "0.1.17", 4, PatchDiagnostics.WindowConstantsPatched, PatchDiagnostics.TeleportConstantsPatched)); } private void Update() { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup >= _nextHello) { _nextHello = realtimeSinceStartup + 2f; NetworkOptimizations.SendPendingHellos(); } LoadingOptimizations.UpdateClientPrefetch(); if (VerboseMetrics.Value && realtimeSinceStartup >= _nextMetrics) { _nextMetrics = realtimeSinceStartup + 30f; Metrics.LogSummary(); } } private void OnDestroy() { LoadingOptimizations.RestoreLoadingPriority(); PreJoinLoadingOverlay.ReleaseResources(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void RunCompressionSelfTest() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) try { ZPackage val = new ZPackage(); for (int i = 0; i < 512; i++) { val.Write("MagiCorp-ValheimOptimizer-ZDO-ZDO-ZDO"); val.Write(i & 7); } ZPackage val2 = new ZPackage(); val2.WriteCompressed(val); ZPackage val3 = new ZPackage(); val3.Load(val2.GetArray()); ZPackage val4 = val3.ReadCompressedPackage(); if (!val.GetArray().SequenceEqual(val4.GetArray())) { throw new InvalidOperationException("ZPackage compression round-trip mismatch"); } Log.LogInfo((object)$"Compression self-test passed: {val.Size()} -> {val2.Size()} bytes ({100.0 * (double)val2.Size() / (double)val.Size():F1}% of original)"); } catch (Exception arg) { EnableZdoCompression.Value = false; Log.LogError((object)$"Compression self-test failed; compressed networking disabled: {arg}"); } } } internal static class MinimapOptimizations { private const int CacheSchema = 1; private static readonly FieldInfo MaskPathField = AccessTools.Field(typeof(Minimap), "m_cachedMinimapMaskTexturePath"); private static readonly FieldInfo BiomePathField = AccessTools.Field(typeof(Minimap), "m_cachedMinimapBiomeTexturePath"); private static readonly FieldInfo HeightPathField = AccessTools.Field(typeof(Minimap), "m_cachedMinimapHeightTexturePath"); private static readonly FieldInfo MetaPathField = AccessTools.Field(typeof(Minimap), "m_cachedMinimapMetaPath"); private static readonly FieldInfo SaveDirectoryField = AccessTools.Field(typeof(Minimap), "m_saveDirectory"); private static readonly FieldInfo MaskTextureField = AccessTools.Field(typeof(Minimap), "m_forestMaskTexture"); private static readonly FieldInfo MapTextureField = AccessTools.Field(typeof(Minimap), "m_mapTexture"); private static readonly FieldInfo HeightTextureField = AccessTools.Field(typeof(Minimap), "m_heightTexture"); private static readonly FieldInfo RespawnAfterDeathField = AccessTools.Field(typeof(Game), "m_respawnAfterDeath"); internal static bool IsAfterDeathRespawn(Game game) { try { return RespawnAfterDeathField != null && (bool)RespawnAfterDeathField.GetValue(game); } catch { return false; } } private static bool EnsurePaths(Minimap map) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected I4, but got Unknown if ((Object)(object)map == (Object)null || ZNet.World == null) { return false; } try { if (!string.IsNullOrEmpty(MetaPathField?.GetValue(map) as string)) { return true; } int stableHashCode = StringExtensionMethods.GetStableHashCode(ZNet.World.m_name ?? string.Empty); string text = Path.Combine(Paths.ConfigPath, "MagiCorp.ValheimOptimizer", "MinimapCache", $"{ZNet.World.m_seed:X8}_{stableHashCode:X8}_{(int)ZNet.World.m_worldVersion}"); Directory.CreateDirectory(text); SaveDirectoryField?.SetValue(map, text); MaskPathField?.SetValue(map, Path.Combine(text, "cacheMinimapMask")); BiomePathField?.SetValue(map, Path.Combine(text, "cacheMinimapBiome")); HeightPathField?.SetValue(map, Path.Combine(text, "cacheMinimapHeight")); MetaPathField?.SetValue(map, Path.Combine(text, "cacheMinimapMeta")); return true; } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Optimizer minimap cache path setup failed: " + ex.Message)); return false; } } private static string SidecarPath(Minimap map) { if (!EnsurePaths(map)) { return null; } string text = MetaPathField?.GetValue(map) as string; if (!string.IsNullOrEmpty(text)) { return text + ".magicorp"; } return null; } internal static bool TryLoad(Minimap map, int worldSeed) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between I4 and Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) if (!ValheimOptimizerPlugin.EnableMinimapCache.Value || !NetworkOptimizations.ClientServerNegotiated() || ZNet.World == null) { return false; } try { if (!EnsurePaths(map)) { return false; } string text = MaskPathField?.GetValue(map) as string; string text2 = BiomePathField?.GetValue(map) as string; string text3 = HeightPathField?.GetValue(map) as string; string text4 = MetaPathField?.GetValue(map) as string; string text5 = SidecarPath(map); if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2) || string.IsNullOrEmpty(text3) || string.IsNullOrEmpty(text4) || string.IsNullOrEmpty(text5)) { return false; } if (!File.Exists(text) || !File.Exists(text2) || !File.Exists(text3) || !File.Exists(text4) || !File.Exists(text5)) { return false; } byte[] array = File.ReadAllBytes(text4); if (array.Length < 8 || BitConverter.ToInt32(array, 0) != worldSeed || BitConverter.ToInt32(array, 4) != 1) { return false; } byte[] array2 = File.ReadAllBytes(text5); if (array2.Length < 20 || BitConverter.ToInt32(array2, 0) != 1 || BitConverter.ToInt32(array2, 4) != worldSeed || BitConverter.ToInt32(array2, 8) != (int)ZNet.World.m_worldVersion || BitConverter.ToInt32(array2, 12) != 2 || BitConverter.ToInt32(array2, 16) != 1) { return false; } Stopwatch stopwatch = Stopwatch.StartNew(); object? obj = MaskTextureField?.GetValue(map); Texture2D val = (Texture2D)((obj is Texture2D) ? obj : null); object? obj2 = MapTextureField?.GetValue(map); Texture2D val2 = (Texture2D)((obj2 is Texture2D) ? obj2 : null); object? obj3 = HeightTextureField?.GetValue(map); Texture2D val3 = (Texture2D)((obj3 is Texture2D) ? obj3 : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { return false; } val.SetPixels32(Utils.CompressedBufferToColors(File.ReadAllBytes(text))); val.Apply(); val2.SetPixels32(Utils.CompressedBufferToColors(File.ReadAllBytes(text2))); val2.Apply(); val3.SetPixels(Utils.CompressedHalfBufferToRedChannel(File.ReadAllBytes(text3))); val3.Apply(); ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH minimap-cache-hit load={stopwatch.ElapsedMilliseconds}ms worldVersion={ZNet.World.m_worldVersion}"); return true; } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Optimizer minimap cache load failed; regenerating normally: " + ex.Message)); return false; } } internal static void PrepareGeneration(Minimap map) { if (ValheimOptimizerPlugin.EnableMinimapCache.Value && NetworkOptimizations.ClientServerNegotiated() && ZNet.World != null) { EnsurePaths(map); } } internal static void MarkGenerated(Minimap map) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected I4, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!ValheimOptimizerPlugin.EnableMinimapCache.Value || !NetworkOptimizations.ClientServerNegotiated() || ZNet.World == null) { return; } try { string text = SidecarPath(map); if (!string.IsNullOrEmpty(text)) { List<byte> list = new List<byte>(20); list.AddRange(BitConverter.GetBytes(1)); list.AddRange(BitConverter.GetBytes(ZNet.World.m_seed)); list.AddRange(BitConverter.GetBytes((int)ZNet.World.m_worldVersion)); list.AddRange(BitConverter.GetBytes(2)); list.AddRange(BitConverter.GetBytes(1)); File.WriteAllBytes(text, list.ToArray()); ValheimOptimizerPlugin.Log.LogInfo((object)$"Optimizer minimap cache keyed for seed={ZNet.World.m_seed} worldVersion={ZNet.World.m_worldVersion}"); } } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Optimizer minimap cache metadata write failed: " + ex.Message)); } } } internal sealed class PeerState { public int RemoteProtocol; public bool Negotiated; public bool HelloSent; public int HelloAttempts; public float RegisteredAt; public bool CompatibilityLogged; public float SendAccumulator; public float LastPrefetchRequest; public bool InitialAreaRequested; public Vector3 InitialAreaTarget; public int InitialAreaStablePasses; public bool InitialAreaReadySent; } internal static class PrivateAccess { private static readonly FieldInfo PeerRpc = AccessTools.Field(typeof(ZNetPeer), "m_rpc"); private static readonly FieldInfo PeerUid = AccessTools.Field(typeof(ZNetPeer), "m_uid"); private static readonly FieldInfo ZdoUid = AccessTools.Field(typeof(ZDO), "m_uid"); private static readonly FieldInfo LocalPlayer = AccessTools.Field(typeof(Player), "m_localPlayer"); private static readonly FieldInfo PlayerTeleporting = AccessTools.Field(typeof(Player), "m_teleporting"); private static readonly FieldInfo Heightmaps = AccessTools.Field(typeof(Heightmap), "s_heightmaps"); private static readonly MethodInfo NetGetPeer = SafeMethod(typeof(ZNet), "GetPeer", typeof(ZRpc)); private static readonly MethodInfo HeightmapHaveQueuedRebuild = SafeMethod(typeof(Heightmap), "HaveQueuedRebuild", Type.EmptyTypes); private static readonly MethodInfo HeightmapRegenerate = SafeMethod(typeof(Heightmap), "Regenerate", Type.EmptyTypes); private static readonly MethodInfo ZdoFindPeer = SafeMethod(typeof(ZDOMan), "FindPeer", typeof(ZNetPeer)); private static readonly MethodInfo ZdoRpcZdoData = SafeMethod(typeof(ZDOMan), "RPC_ZDOData", typeof(ZRpc), typeof(ZPackage)); private static MethodInfo ZdoSendZdos; private static readonly MethodInfo SceneInLoadingScreen = SafeMethod(typeof(ZNetScene), "InLoadingScreen", Type.EmptyTypes); private static readonly MethodInfo SceneCreateObjectsSorted = SafeMethod(typeof(ZNetScene), "CreateObjectsSorted", typeof(List<ZDO>), typeof(int), typeof(int).MakeByRefType()); private static readonly MethodInfo SceneCreateDistantObjects = SafeMethod(typeof(ZNetScene), "CreateDistantObjects", typeof(List<ZDO>), typeof(int), typeof(int).MakeByRefType()); private static readonly MethodInfo ZoneCreateLocalZones = SafeMethod(typeof(ZoneSystem), "CreateLocalZones", typeof(Vector3)); private static MethodInfo SafeMethod(Type type, string name, params Type[] parameters) { try { return AccessTools.Method(type, name, parameters, (Type[])null); } catch { return null; } } internal static void LogResolution() { ValheimOptimizerPlugin.Log.LogInfo((object)$"Private access: GetPeer={NetGetPeer != null}, FindPeer={ZdoFindPeer != null}, RPC_ZDOData={ZdoRpcZdoData != null}, InLoadingScreen={SceneInLoadingScreen != null}, CreateObjectsSorted={SceneCreateObjectsSorted != null}, CreateDistantObjects={SceneCreateDistantObjects != null}, CreateLocalZones={ZoneCreateLocalZones != null}, HeightmapWarm={Heightmaps != null && HeightmapHaveQueuedRebuild != null && HeightmapRegenerate != null}"); } internal static ZRpc GetRpc(ZNetPeer peer) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (peer != null && !(PeerRpc == null)) { return (ZRpc)PeerRpc.GetValue(peer); } return null; } internal static long GetUid(ZNetPeer peer) { if (peer != null && !(PeerUid == null)) { return (long)PeerUid.GetValue(peer); } return 0L; } internal static ZDOID GetZdoUid(ZDO zdo) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && !(ZdoUid == null)) { return (ZDOID)ZdoUid.GetValue(zdo); } return ZDOID.None; } internal static Player GetLocalPlayer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!(LocalPlayer == null)) { return (Player)LocalPlayer.GetValue(null); } return null; } internal static bool IsTeleporting(Player player) { if ((Object)(object)player != (Object)null && PlayerTeleporting != null) { return (bool)PlayerTeleporting.GetValue(player); } return false; } internal static ZNetPeer GetNetPeer(ZNet net, ZRpc rpc) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if ((Object)(object)net == (Object)null || rpc == null || NetGetPeer == null) { return null; } try { return (ZNetPeer)NetGetPeer.Invoke(net, new object[1] { rpc }); } catch { return null; } } internal static List<Heightmap> GetHeightmaps() { if (Heightmaps == null) { return null; } try { return (List<Heightmap>)Heightmaps.GetValue(null); } catch { return null; } } internal static bool HeightmapNeedsRebuild(Heightmap h) { if ((Object)(object)h == (Object)null || HeightmapHaveQueuedRebuild == null) { return false; } try { return (bool)HeightmapHaveQueuedRebuild.Invoke(h, null); } catch { return false; } } internal static bool RegenerateHeightmap(Heightmap h) { if ((Object)(object)h == (Object)null || HeightmapRegenerate == null) { return false; } try { HeightmapRegenerate.Invoke(h, null); return true; } catch { return false; } } internal static bool IsInLoadingScreen(ZNetScene scene) { if ((Object)(object)scene == (Object)null || SceneInLoadingScreen == null) { return false; } return (bool)SceneInLoadingScreen.Invoke(scene, null); } internal static bool ReceiveZdoData(ZDOMan man, ZRpc rpc, ZPackage pkg) { if (man == null || rpc == null || pkg == null || ZdoRpcZdoData == null) { return false; } try { ZdoRpcZdoData.Invoke(man, new object[2] { rpc, pkg }); return true; } catch { return false; } } internal static bool TrySendZdosToPeer(ZDOMan man, ZNetPeer peer, bool flush, out bool sentData) { sentData = false; if (man == null || peer == null || ZdoFindPeer == null) { return false; } try { object obj = ZdoFindPeer.Invoke(man, new object[1] { peer }); if (obj == null) { return false; } if (ZdoSendZdos == null) { ZdoSendZdos = SafeMethod(typeof(ZDOMan), "SendZDOs", obj.GetType(), typeof(bool)); } if (ZdoSendZdos == null) { return false; } sentData = (bool)ZdoSendZdos.Invoke(man, new object[2] { obj, flush }); return true; } catch { return false; } } internal static void CreateObjectsFast(ZNetScene scene, List<ZDO> near, List<ZDO> distant, int maxCreated, out int created) { if (SceneCreateObjectsSorted == null || SceneCreateDistantObjects == null) { throw new MissingMethodException("ZNetScene object creation methods not found"); } created = 0; object[] array = new object[3] { near, maxCreated, created }; SceneCreateObjectsSorted.Invoke(scene, array); created = (int)array[2]; object[] array2 = new object[3] { distant, maxCreated, created }; SceneCreateDistantObjects.Invoke(scene, array2); created = (int)array2[2]; } internal static bool CreateLocalZones(ZoneSystem z, Vector3 target) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)z == (Object)null || ZoneCreateLocalZones == null) { return false; } return (bool)ZoneCreateLocalZones.Invoke(z, new object[1] { target }); } } internal static class NetworkOptimizations { internal const string HelloRpc = "MagiOpt_Hello_v1"; internal const string CompressedZdoRpc = "MagiOpt_ZDO_v1"; internal const string PortalPrefetchRpc = "MagiOpt_PortalPrefetch_v1"; internal const string InitialAreaRequestRpc = "MagiOpt_InitialAreaReq_v1"; internal const string InitialAreaReadyRpc = "MagiOpt_InitialAreaReady_v1"; private static readonly Dictionary<ZRpc, PeerState> Peers = new Dictionary<ZRpc, PeerState>(); private static readonly List<ZDO> PrefetchNear = new List<ZDO>(4096); private static readonly List<ZDO> PrefetchDistant = new List<ZDO>(1024); private static int _roundRobin; private static bool _clientInitialAreaReady; private static Vector3 _clientInitialAreaTarget; private static Vector3 _lastInitialAreaRequestTarget; private static float _lastInitialAreaRequestAt; internal static void Initialize() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Peers.Clear(); _roundRobin = 0; _clientInitialAreaReady = false; _clientInitialAreaTarget = Vector3.zero; _lastInitialAreaRequestTarget = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); _lastInitialAreaRequestAt = -100f; } internal static void RegisterPeer(ZNetPeer peer) { ZRpc rpc = PrivateAccess.GetRpc(peer); if (rpc == null) { return; } if (!Peers.ContainsKey(rpc)) { Peers[rpc] = new PeerState { RegisteredAt = Time.realtimeSinceStartup }; } if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { _clientInitialAreaReady = false; } try { rpc.Register<int>("MagiOpt_Hello_v1", (Action<ZRpc, int>)OnHello); rpc.Register<ZPackage>("MagiOpt_ZDO_v1", (Action<ZRpc, ZPackage>)OnCompressedZdo); rpc.Register<ZPackage>("MagiOpt_PortalPrefetch_v1", (Action<ZRpc, ZPackage>)OnPortalPrefetch); rpc.Register<ZPackage>("MagiOpt_InitialAreaReq_v1", (Action<ZRpc, ZPackage>)OnInitialAreaRequest); rpc.Register<ZPackage>("MagiOpt_InitialAreaReady_v1", (Action<ZRpc, ZPackage>)OnInitialAreaReady); } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Peer optimizer RPC registration failed: " + ex.Message)); } } internal static void RemovePeer(ZNetPeer peer) { ZRpc rpc = PrivateAccess.GetRpc(peer); if (rpc != null) { Peers.Remove(rpc); } if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { _clientInitialAreaReady = false; } } internal static bool IsNegotiated(ZRpc rpc) { if (rpc != null && Peers.TryGetValue(rpc, out var value)) { return value.Negotiated; } return false; } private static void OnHello(ZRpc rpc, int protocol) { if (!Peers.TryGetValue(rpc, out var value)) { value = new PeerState { RegisteredAt = Time.realtimeSinceStartup }; Peers[rpc] = value; } value.RemoteProtocol = protocol; bool negotiated = value.Negotiated; value.Negotiated = protocol == 4; if (value.Negotiated && !value.HelloSent) { try { rpc.Invoke("MagiOpt_Hello_v1", new object[1] { 4 }); value.HelloSent = true; value.HelloAttempts++; } catch { } } if (value.Negotiated && !negotiated) { Metrics.Handshakes++; ValheimOptimizerPlugin.Log.LogInfo((object)"Optimizer network protocol negotiated with peer"); Benchmarking.OnNegotiated(); } } internal static void SendPendingHellos() { try { if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null) { return; } List<ZNetPeer> peers = ZNet.instance.GetPeers(); bool flag = ZNet.instance.IsServer(); for (int i = 0; i < peers.Count; i++) { ZNetPeer peer = peers[i]; ZRpc rpc = PrivateAccess.GetRpc(peer); if (rpc == null) { continue; } if (!Peers.TryGetValue(rpc, out var value)) { RegisterPeer(peer); if (!Peers.TryGetValue(rpc, out value)) { continue; } } if (!flag) { if (!value.Negotiated && !value.CompatibilityLogged && Time.realtimeSinceStartup - value.RegisteredAt >= 6f) { value.CompatibilityLogged = true; ValheimOptimizerPlugin.Log.LogInfo((object)"Remote server did not advertise Valheim Optimizer; vanilla compatibility mode active"); } } else if (!value.Negotiated && value.HelloAttempts < 3) { rpc.Invoke("MagiOpt_Hello_v1", new object[1] { 4 }); value.HelloSent = true; value.HelloAttempts++; } } } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogDebug((object)("Hello pass skipped: " + ex.Message)); } } internal static bool ClientServerNegotiated() { try { if ((Object)(object)ZNet.instance == (Object)null) { return false; } if (ZNet.instance.IsServer()) { return true; } return IsNegotiated(ZNet.instance.GetServerRPC()); } catch { return false; } } internal static bool AllPeersNegotiated() { if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null) { return false; } List<ZNetPeer> peers = ZNet.instance.GetPeers(); if (peers == null || peers.Count == 0) { return false; } for (int i = 0; i < peers.Count; i++) { if (!IsNegotiated(PrivateAccess.GetRpc(peers[i]))) { return false; } } return true; } internal static int GetWindowBytes() { if (!AllPeersNegotiated()) { return 10240; } return ValheimOptimizerPlugin.ReplicationWindowKiB.Value * 1024; } internal static int GetMinRoomBytes() { if (!AllPeersNegotiated()) { return 2048; } return Math.Min(GetWindowBytes() / 2, ValheimOptimizerPlugin.ReplicationMinRoomKiB.Value * 1024); } internal static bool TryRunScheduler(ZDOMan man, float dt) { if (!ValheimOptimizerPlugin.EnableNetworkScheduler.Value || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !AllPeersNegotiated()) { return false; } List<ZNetPeer> peers = ZNet.instance.GetPeers(); int count = peers.Count; if (count == 0) { return true; } float num = 1f / (float)Math.Max(1, ValheimOptimizerPlugin.OptimizedReplicationHz.Value); for (int i = 0; i < count; i++) { ZRpc rpc = PrivateAccess.GetRpc(peers[i]); if (Peers.TryGetValue(rpc, out var value)) { value.SendAccumulator = Math.Min(0.5f, value.SendAccumulator + dt); } } long timestamp = Stopwatch.GetTimestamp(); double num2 = ValheimOptimizerPlugin.NetworkMainThreadBudgetMs.Value; int num3 = 0; for (int j = 0; j < count; j++) { int index = (_roundRobin + j) % count; ZNetPeer val = peers[index]; ZRpc rpc2 = PrivateAccess.GetRpc(val); if (Peers.TryGetValue(rpc2, out var value2) && !(value2.SendAccumulator + 0.0001f < num)) { if (!PrivateAccess.TrySendZdosToPeer(man, val, flush: false, out var sentData)) { return false; } UpdateInitialAreaReady(value2, rpc2, val, sentData); double num4 = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; if (num3 > 0 && num4 >= num2) { Metrics.SchedulerBudgetHits++; break; } value2.SendAccumulator = Math.Max(0f, value2.SendAccumulator - num); num3++; Metrics.SchedulerPeerServices++; } } _roundRobin = (_roundRobin + Math.Max(1, num3)) % Math.Max(1, count); Metrics.SchedulerPasses++; return true; } internal static void MarkUrgent(ZRpc rpc) { if (rpc != null && Peers.TryGetValue(rpc, out var value)) { value.SendAccumulator = 1f; } } internal static bool TryCompressZdoRpc(ZRpc rpc, ref string method, ref object[] parameters) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if (!ValheimOptimizerPlugin.EnableZdoCompression.Value || method != "ZDOData" || !IsNegotiated(rpc)) { return false; } if (parameters != null && parameters.Length == 1) { object obj = parameters[0]; ZPackage val = (ZPackage)((obj is ZPackage) ? obj : null); if (val != null) { int num = val.Size(); if (num < ValheimOptimizerPlugin.CompressionThresholdBytes.Value) { return false; } long timestamp = Stopwatch.GetTimestamp(); try { ZPackage val2 = new ZPackage(); val2.WriteCompressed(val); int num2 = val2.Size(); if (num2 + 16 >= num) { return false; } method = "MagiOpt_ZDO_v1"; parameters = new object[1] { val2 }; Interlocked.Increment(ref Metrics.CompressedPackets); Interlocked.Add(ref Metrics.ZdoBytesBeforeCompression, num); Interlocked.Add(ref Metrics.ZdoBytesAfterCompression, num2); return true; } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("ZDO compression failed; sending vanilla packet: " + ex.Message)); return false; } finally { Interlocked.Add(ref Metrics.CompressionStopwatchTicks, Stopwatch.GetTimestamp() - timestamp); } } } return false; } private static void OnCompressedZdo(ZRpc rpc, ZPackage packed) { try { ZPackage pkg = packed.ReadCompressedPackage(); Interlocked.Increment(ref Metrics.DecompressedPackets); if (!PrivateAccess.ReceiveZdoData(ZDOMan.instance, rpc, pkg)) { throw new MissingMethodException("RPC_ZDOData(ZRpc,ZPackage) unavailable"); } } catch (Exception arg) { ValheimOptimizerPlugin.Log.LogError((object)$"Compressed ZDO receive failed: {arg}"); } } internal static void RequestInitialArea(Vector3 target) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || !ClientServerNegotiated() || float.IsNaN(target.x) || float.IsNaN(target.y) || float.IsNaN(target.z)) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; bool flag = Vector3.SqrMagnitude(target - _lastInitialAreaRequestTarget) > 16f; if ((!flag && _clientInitialAreaReady) || (!flag && realtimeSinceStartup - _lastInitialAreaRequestAt < 1f)) { return; } _lastInitialAreaRequestTarget = target; _lastInitialAreaRequestAt = realtimeSinceStartup; if (flag) { _clientInitialAreaReady = false; } _clientInitialAreaTarget = target; ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (IsNegotiated(serverRPC)) { ZPackage val = new ZPackage(); val.Write(target); serverRPC.Invoke("MagiOpt_InitialAreaReq_v1", new object[1] { val }); ISocket socket = serverRPC.GetSocket(); if (socket != null) { socket.Flush(); } ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH initial-area-request target={target}"); } } internal static bool ClientInitialAreaReadyFor(Vector3 target) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (_clientInitialAreaReady) { return Vector3.SqrMagnitude(target - _clientInitialAreaTarget) <= 64f; } return false; } private static void OnInitialAreaRequest(ZRpc rpc, ZPackage pkg) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !IsNegotiated(rpc) || !Peers.TryGetValue(rpc, out var value)) { return; } try { Vector3 val = pkg.ReadVector3(); if (float.IsNaN(val.x) || float.IsNaN(val.y) || float.IsNaN(val.z) || float.IsInfinity(val.x) || float.IsInfinity(val.y) || float.IsInfinity(val.z) || (value.InitialAreaRequested && Vector3.SqrMagnitude(value.InitialAreaTarget - val) <= 16f)) { return; } value.InitialAreaRequested = true; value.InitialAreaTarget = val; value.InitialAreaStablePasses = 0; value.InitialAreaReadySent = false; ZNetPeer netPeer = PrivateAccess.GetNetPeer(ZNet.instance, rpc); if (netPeer != null) { PrefetchNear.Clear(); Vector2s zone = ZoneSystem.GetZone(val); ZDOMan.instance.FindSectorObjects(zone, new SimulationDistance(1, 0, false), PrefetchNear, (List<ZDO>)null); long uid = PrivateAccess.GetUid(netPeer); for (int i = 0; i < PrefetchNear.Count; i++) { ZDOMan.instance.ForceSendZDO(uid, PrivateAccess.GetZdoUid(PrefetchNear[i])); } MarkUrgent(rpc); ValheimOptimizerPlugin.Log.LogInfo((object)$"Initial area requested at {val}; prioritized {PrefetchNear.Count} near ZDOs"); } } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Initial area request failed: " + ex.Message)); } } private static void OnInitialAreaReady(ZRpc rpc, ZPackage pkg) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || !IsNegotiated(rpc)) { return; } try { Vector3 val = pkg.ReadVector3(); if (!(Vector3.SqrMagnitude(val - _clientInitialAreaTarget) > 64f)) { _clientInitialAreaReady = true; ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH initial-area-server-ready target={val}"); } } catch { } } private static void UpdateInitialAreaReady(PeerState state, ZRpc rpc, ZNetPeer netPeer, bool sentData) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (state == null || !state.InitialAreaRequested || state.InitialAreaReadySent || rpc == null || netPeer == null) { return; } if (sentData) { state.InitialAreaStablePasses = 0; return; } int num = ((netPeer.m_socket != null) ? netPeer.m_socket.GetSendQueueSize() : int.MaxValue); if (num > 4096) { state.InitialAreaStablePasses = 0; return; } state.InitialAreaStablePasses++; if (state.InitialAreaStablePasses >= 3) { ZPackage val = new ZPackage(); val.Write(state.InitialAreaTarget); rpc.Invoke("MagiOpt_InitialAreaReady_v1", new object[1] { val }); ISocket socket = rpc.GetSocket(); if (socket != null) { socket.Flush(); } state.InitialAreaReadySent = true; ValheimOptimizerPlugin.Log.LogInfo((object)$"Initial area replication complete target={state.InitialAreaTarget} queue={num}"); } } internal static void RequestPortalPrefetch(Vector3 target) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!ValheimOptimizerPlugin.EnablePortalPrefetch.Value || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { return; } ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (IsNegotiated(serverRPC)) { ZPackage val = new ZPackage(); val.Write(target); ISocket socket = serverRPC.GetSocket(); int num = ((socket != null) ? socket.GetSendQueueSize() : 0); serverRPC.Invoke("MagiOpt_PortalPrefetch_v1", new object[1] { val }); if (socket != null) { socket.Flush(); } ValheimOptimizerPlugin.Log.LogDebug((object)$"Portal prefetch request sent target={target} queueBefore={num} queueAfter={((socket != null) ? socket.GetSendQueueSize() : 0)}"); } } private static void OnPortalPrefetch(ZRpc rpc, ZPackage pkg) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) if (!ValheimOptimizerPlugin.EnablePortalPrefetch.Value || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !IsNegotiated(rpc)) { return; } try { if (!Peers.TryGetValue(rpc, out var value)) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - value.LastPrefetchRequest < 1.5f) { return; } value.LastPrefetchRequest = realtimeSinceStartup; Vector3 val = pkg.ReadVector3(); if (float.IsNaN(val.x) || float.IsNaN(val.y) || float.IsNaN(val.z) || float.IsInfinity(val.x) || float.IsInfinity(val.y) || float.IsInfinity(val.z)) { return; } ZNetPeer netPeer = PrivateAccess.GetNetPeer(ZNet.instance, rpc); if (netPeer == null) { return; } long uid = PrivateAccess.GetUid(netPeer); if (uid != 0L) { PrefetchNear.Clear(); PrefetchDistant.Clear(); Vector2s zone = ZoneSystem.GetZone(val); ZDOMan.instance.FindSectorObjects(zone, ZNet.instance.GetSyncedSimulationDistance(), PrefetchNear, PrefetchDistant); int value2 = ValheimOptimizerPlugin.PortalPrefetchMaxZdos.Value; int num = 0; int num2 = 0; while (num2 < PrefetchNear.Count && num < value2) { ZDOMan.instance.ForceSendZDO(uid, PrivateAccess.GetZdoUid(PrefetchNear[num2])); num2++; num++; } int num3 = 0; while (num3 < PrefetchDistant.Count && num < value2) { ZDOMan.instance.ForceSendZDO(uid, PrivateAccess.GetZdoUid(PrefetchDistant[num3])); num3++; num++; } MarkUrgent(rpc); Metrics.PortalPrefetchRequests++; Metrics.PortalZdosQueued += num; ValheimOptimizerPlugin.Log.LogInfo((object)$"Portal prefetch queued {num} destination ZDOs ({PrefetchNear.Count} near, {PrefetchDistant.Count} distant candidates)"); } } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Portal prefetch request failed: " + ex.Message)); } } } internal static class LoadingOptimizations { private static bool _clientPrefetch; private static Vector3 _prefetchTarget; private static float _prefetchStarted; private static int _terrainStableFrames; private static bool _baseTerrainLogged; private static bool _heightmapWarmLogged; private static bool _priorityChanged; private static ThreadPriority _oldPriority; internal static void Initialize() { _clientPrefetch = false; _terrainStableFrames = 0; _baseTerrainLogged = false; _heightmapWarmLogged = false; _priorityChanged = false; } internal static int GetAdaptiveLoadingObjectLimit() { int value = ValheimOptimizerPlugin.LoadingObjectLimit.Value; float unscaledDeltaTime = Time.unscaledDeltaTime; if (unscaledDeltaTime > 0.09f) { return 100; } if (unscaledDeltaTime > 0.06f) { return Math.Min(value, 140); } if (unscaledDeltaTime > 0.04f) { return Math.Min(value, 200); } return value; } internal static float GetMinimumDistantTeleportSeconds() { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && !NetworkOptimizations.ClientServerNegotiated()) { return 8f; } return ValheimOptimizerPlugin.MinimumDistantTeleportSeconds.Value; } internal static void BeginPortalPrefetch(Vector3 target) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (ValheimOptimizerPlugin.EnablePortalPrefetch.Value && NetworkOptimizations.ClientServerNegotiated()) { _prefetchTarget = target; _prefetchStarted = Time.realtimeSinceStartup; _clientPrefetch = true; _terrainStableFrames = 0; _baseTerrainLogged = false; _heightmapWarmLogged = false; NetworkOptimizations.RequestPortalPrefetch(target); SetHighLoadingPriority(); } } internal static void EndPortalPrefetch() { _clientPrefetch = false; RestoreLoadingPriority(); } internal static void UpdateClientPrefetch() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated()) { return; } if (!NetworkOptimizations.ClientServerNegotiated()) { _clientPrefetch = false; RestoreLoadingPriority(); return; } if (PrivateAccess.IsInLoadingScreen(ZNetScene.instance)) { SetHighLoadingPriority(); } else if (!_clientPrefetch) { RestoreLoadingPriority(); } if (!_clientPrefetch || (Object)(object)ZoneSystem.instance == (Object)null || WorldGenerator.instance == null || HeightmapBuilder.instance == null) { return; } if (Time.realtimeSinceStartup - _prefetchStarted > 12f) { EndPortalPrefetch(); ValheimOptimizerPlugin.Log.LogWarning((object)"Client portal terrain prefetch timed out after 12s"); return; } Vector2s zone = ZoneSystem.GetZone(_prefetchTarget); Vector3 zonePos = ZoneSystem.GetZonePos(zone); Heightmap val = (((Object)(object)ZoneSystem.instance.m_zonePrefab != (Object)null) ? ZoneSystem.instance.m_zonePrefab.GetComponentInChildren<Heightmap>() : null); if ((Object)(object)val == (Object)null || !HeightmapBuilder.instance.IsTerrainReady(zonePos, val.m_width, val.m_scale, val.IsDistantLod, WorldGenerator.instance)) { return; } if (!_baseTerrainLogged) { _baseTerrainLogged = true; Benchmarking.OnBaseTerrainReady(); } int value = ValheimOptimizerPlugin.PortalZonesPerFrame.Value; for (int i = 0; i < value; i++) { if (PrivateAccess.CreateLocalZones(ZoneSystem.instance, _prefetchTarget)) { Metrics.PortalZonesPoked++; } } if (!ZoneSystem.instance.IsZoneLoaded(_prefetchTarget)) { _terrainStableFrames = 0; return; } List<Heightmap> heightmaps = PrivateAccess.GetHeightmaps(); if (heightmaps == null || heightmaps.Count == 0) { return; } int num = 0; int num2 = 0; for (int j = 0; j < heightmaps.Count; j++) { Heightmap val2 = heightmaps[j]; if ((Object)(object)val2 == (Object)null) { continue; } Vector2s zone2 = ZoneSystem.GetZone(((Component)val2).transform.position); if (Math.Abs(zone2.x - zone.x) > 2 || Math.Abs(zone2.y - zone.y) > 2) { continue; } num++; if (num2 < 2 && PrivateAccess.HeightmapNeedsRebuild(val2) && PrivateAccess.RegenerateHeightmap(val2)) { num2++; Metrics.PortalHeightmapsWarmed++; if (!_heightmapWarmLogged) { _heightmapWarmLogged = true; Benchmarking.OnHeightmapWarm(); } } } if (num > 0) { _terrainStableFrames++; } } catch (Exception ex) { EndPortalPrefetch(); ValheimOptimizerPlugin.Log.LogWarning((object)("Client portal terrain prefetch stopped: " + ex.Message)); } } internal static void SetHighLoadingPriority() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!_priorityChanged) { _oldPriority = Application.backgroundLoadingPriority; Application.backgroundLoadingPriority = (ThreadPriority)4; _priorityChanged = true; } } internal static void RestoreLoadingPriority() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (_priorityChanged) { Application.backgroundLoadingPriority = _oldPriority; _priorityChanged = false; } } } internal static class Benchmarking { private static float _joinStart = -1f; private static float _negotiatedAt = -1f; private static float _teleportStart = -1f; private static bool _teleportActiveSeen; internal static void OnJoinStart() { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { _joinStart = Time.realtimeSinceStartup; _negotiatedAt = -1f; ValheimOptimizerPlugin.Log.LogInfo((object)"OPT BENCH join-start"); } } internal static void OnPeerAdded() { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && !(_joinStart >= 0f)) { _joinStart = Time.realtimeSinceStartup; ValheimOptimizerPlugin.Log.LogInfo((object)"OPT BENCH join-start"); } } internal static void OnNegotiated() { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { if (_joinStart < 0f) { _joinStart = Time.realtimeSinceStartup; } _negotiatedAt = Time.realtimeSinceStartup; ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH negotiated +{_negotiatedAt - _joinStart:F3}s"); } } internal static void OnSpawned(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)PrivateAccess.GetLocalPlayer() != (Object)(object)player) && !(_joinStart < 0f)) { float realtimeSinceStartup = Time.realtimeSinceStartup; string arg = ((_negotiatedAt >= 0f) ? $" negotiated={_negotiatedAt - _joinStart:F3}s" : ""); ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH join-spawned total={realtimeSinceStartup - _joinStart:F3}s{arg} loadCreated={Metrics.LoadingObjectsCreated}"); _joinStart = -1f; _negotiatedAt = -1f; } } internal static void BeginTeleport(Vector3 target, float distance, bool distantFlag) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) _teleportStart = Time.realtimeSinceStartup; _teleportActiveSeen = true; ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH teleport-start distance={distance:F1}m distantFlag={distantFlag} target={target}"); } internal static void OnBaseTerrainReady() { if (!(_teleportStart < 0f)) { ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH teleport-base-terrain-ready +{Time.realtimeSinceStartup - _teleportStart:F3}s"); } } internal static void OnHeightmapWarm() { if (!(_teleportStart < 0f)) { ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH teleport-heightmap-warm +{Time.realtimeSinceStartup - _teleportStart:F3}s"); } } internal static void OnTeleportUpdate(Player player) { if (!(_teleportStart < 0f) && !((Object)(object)player == (Object)null) && !((Object)(object)PrivateAccess.GetLocalPlayer() != (Object)(object)player)) { if (PrivateAccess.IsTeleporting(player)) { _teleportActiveSeen = true; } else if (_teleportActiveSeen) { LoadingOptimizations.EndPortalPrefetch(); Metrics.PortalTerrainPrefetchCompleted++; ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT BENCH teleport-complete total={Time.realtimeSinceStartup - _teleportStart:F3}s"); _teleportStart = -1f; _teleportActiveSeen = false; } } } } internal static class Metrics { internal static long Handshakes; internal static long CompressedPackets; internal static long DecompressedPackets; internal static long ZdoBytesBeforeCompression; internal static long ZdoBytesAfterCompression; internal static long CompressionStopwatchTicks; internal static long SchedulerPasses; internal static long SchedulerPeerServices; internal static long SchedulerBudgetHits; internal static long LoadingObjectsCreated; internal static long LoadingCreatePasses; internal static long PortalPrefetchRequests; internal static long PortalZdosQueued; internal static long PortalZonesPoked; internal static long PortalHeightmapsWarmed; internal static long PortalTerrainPrefetchCompleted; internal static void LogSummary() { long num = Interlocked.Read(in ZdoBytesBeforeCompression); long num2 = Interlocked.Read(in ZdoBytesAfterCompression); double num3 = ((num > 0) ? (100.0 * (double)(num - num2) / (double)num) : 0.0); double num4 = (double)Interlocked.Read(in CompressionStopwatchTicks) * 1000.0 / (double)Stopwatch.Frequency; ValheimOptimizerPlugin.Log.LogInfo((object)$"OPT METRICS peers={CountNegotiatedPeers()} zdoCompressed={CompressedPackets} rx={DecompressedPackets} bytes={num}->{num2} saved={num3:F1}% compCPU={num4:F1}ms schedulerServices={SchedulerPeerServices} budgetHits={SchedulerBudgetHits} loadCreated={LoadingObjectsCreated} portalReq={PortalPrefetchRequests} portalZDOs={PortalZdosQueued} zones={PortalZonesPoked} hmaps={PortalHeightmapsWarmed} terrainDone={PortalTerrainPrefetchCompleted}"); } private static int CountNegotiatedPeers() { try { if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null) { return 0; } int num = 0; List<ZNetPeer> peers = ZNet.instance.GetPeers(); for (int i = 0; i < peers.Count; i++) { if (NetworkOptimizations.IsNegotiated(PrivateAccess.GetRpc(peers[i]))) { num++; } } return num; } catch { return 0; } } } internal static class PatchDiagnostics { internal static int WindowConstantsPatched; internal static int TeleportConstantsPatched; } [HarmonyPatch(typeof(ZNet), "Start")] internal static class ZNetStartBenchmarkPatch { private static void Postfix() { Benchmarking.OnJoinStart(); } } [HarmonyPatch(typeof(ZDOMan), "AddPeer")] internal static class AddPeerPatch { private static void Postfix(ZNetPeer __0) { NetworkOptimizations.RegisterPeer(__0); Benchmarking.OnPeerAdded(); } } [HarmonyPatch(typeof(ZDOMan), "RemovePeer")] internal static class RemovePeerPatch { private static void Prefix(ZNetPeer __0) { NetworkOptimizations.RemovePeer(__0); } } [HarmonyPatch(typeof(ZRpc), "Invoke", new Type[] { typeof(string), typeof(object[]) })] internal static class ZRpcInvokePatch { private static void Prefix(ZRpc __instance, ref string __0, ref object[] __1) { NetworkOptimizations.TryCompressZdoRpc(__instance, ref __0, ref __1); } } [HarmonyPatch(typeof(ZDOMan), "SendZDOToPeers2")] internal static class ZdoSchedulerPatch { private static bool _failedOpen; private static bool Prefix(ZDOMan __instance, float __0) { if (_failedOpen) { return true; } try { return !NetworkOptimizations.TryRunScheduler(__instance, __0); } catch (Exception arg) { _failedOpen = true; ValheimOptimizerPlugin.Log.LogError((object)$"Replication scheduler failed; falling back to vanilla for this session: {arg}"); return true; } } } [HarmonyPatch(typeof(ZDOMan), "SendZDOs")] internal static class SendWindowPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo window = AccessTools.Method(typeof(NetworkOptimizations), "GetWindowBytes", (Type[])null, (Type[])null); MethodInfo minRoom = AccessTools.Method(typeof(NetworkOptimizations), "GetMinRoomBytes", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldc_I4 && instruction.operand is int num && num == 10240) { CodeInstruction val = new CodeInstruction(instruction) { opcode = OpCodes.Call, operand = window }; PatchDiagnostics.WindowConstantsPatched++; yield return val; } else if (instruction.opcode == OpCodes.Ldc_I4 && instruction.operand is int num2 && num2 == 2048) { CodeInstruction val2 = new CodeInstruction(instruction) { opcode = OpCodes.Call, operand = minRoom }; PatchDiagnostics.WindowConstantsPatched++; yield return val2; } else { yield return instruction; } } } } [HarmonyPatch(typeof(ZNetScene), "CreateObjects")] internal static class FastObjectCreationPatch { private static bool _failedOpen; private static bool Prefix(ZNetScene __instance, List<ZDO> __0, List<ZDO> __1) { if (_failedOpen || !ValheimOptimizerPlugin.EnableFastLoading.Value || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated() || !NetworkOptimizations.ClientServerNegotiated()) { return true; } try { if (!PrivateAccess.IsInLoadingScreen(__instance)) { return true; } int adaptiveLoadingObjectLimit = LoadingOptimizations.GetAdaptiveLoadingObjectLimit(); PrivateAccess.CreateObjectsFast(__instance, __0, __1, adaptiveLoadingObjectLimit, out var created); Metrics.LoadingCreatePasses++; Metrics.LoadingObjectsCreated += created; return false; } catch (Exception arg) { _failedOpen = true; ValheimOptimizerPlugin.Log.LogError((object)$"Adaptive object creation failed; falling back to vanilla for this session: {arg}"); return true; } } } [HarmonyPatch(typeof(Player), "TeleportTo")] internal static class PlayerTeleportPatch { private static void Postfix(Player __instance, Vector3 __0, Quaternion __1, bool __2, bool __result) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (__result && !((Object)(object)PrivateAccess.GetLocalPlayer() != (Object)(object)__instance)) { float num = Vector3.Distance(((Component)__instance).transform.position, __0); if (__2 || !(num < 32f)) { Benchmarking.BeginTeleport(__0, num, __2); LoadingOptimizations.BeginPortalPrefetch(__0); } } } } [HarmonyPatch(typeof(ZNet), "SetReferencePosition")] internal static class InitialAreaRequestPatch { private static void Postfix(Vector3 __0) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && !((Object)(object)PrivateAccess.GetLocalPlayer() != (Object)null)) { NetworkOptimizations.RequestInitialArea(__0); } } } [HarmonyPatch(typeof(Game), "FindSpawnPoint")] internal static class InitialSpawnDelayPatch { private static void Prefix(Game __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { Vector3 referencePosition = ZNet.instance.GetReferencePosition(); bool flag = NetworkOptimizations.ClientServerNegotiated() && !MinimapOptimizations.IsAfterDeathRespawn(__instance) && NetworkOptimizations.ClientInitialAreaReadyFor(referencePosition); __instance.m_respawnLoadDuration = (flag ? ValheimOptimizerPlugin.InitialSpawnMinimumSeconds.Value : 8f); } } } [HarmonyPatch(typeof(Minimap), "TryLoadMinimapTextureData")] internal static class MinimapCacheLoadPatch { private static bool Prefix(Minimap __instance, int worldSeed, ref bool __result) { if (!MinimapOptimizations.TryLoad(__instance, worldSeed)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Minimap), "GenerateWorldMap")] internal static class MinimapCacheGeneratePatch { private static void Prefix(Minimap __instance) { MinimapOptimizations.PrepareGeneration(__instance); } private static void Postfix(Minimap __instance) { MinimapOptimizations.MarkGenerated(__instance); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class PlayerSpawnBenchmarkPatch { private static void Postfix(Player __instance) { PreJoinLoadingOverlay.Hide(); Benchmarking.OnSpawned(__instance); } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] internal static class TeleportBenchmarkPatch { private static void Postfix(Player __instance) { Benchmarking.OnTeleportUpdate(__instance); } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] internal static class TeleportMinimumPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo getter = AccessTools.Method(typeof(LoadingOptimizations), "GetMinimumDistantTeleportSeconds", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldc_R4 && instruction.operand is float num && Math.Abs(num - 8f) < 0.0001f) { CodeInstruction val = new CodeInstruction(instruction) { opcode = OpCodes.Call, operand = getter }; PatchDiagnostics.TeleportConstantsPatched++; yield return val; } else { yield return instruction; } } } } internal sealed class PreJoinLoadingOverlay : MonoBehaviour { private static PreJoinLoadingOverlay _instance; private static Texture2D _artworkTexture; private static bool _artworkLoadAttempted; private static bool _artworkAvailable; private static readonly MethodInfo LoadImageMethod = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null); private string _tipKey; private GUIStyle _titleStyle; private GUIStyle _tipStyle; internal static void PreloadArtwork() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown if (_artworkLoadAttempted || !ValheimOptimizerPlugin.UseCustomLoadingScreen.Value) { return; } _artworkLoadAttempted = true; Texture2D val = null; try { string text = ValheimOptimizerPlugin.PluginDirectory; if (string.IsNullOrEmpty(text)) { text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } string text2 = Path.Combine(text ?? Paths.PluginPath, "loading_screen.png"); if (!File.Exists(text2)) { ValheimOptimizerPlugin.Log.LogWarning((object)("Custom loading artwork not found at " + text2 + "; using black/text fallback")); return; } byte[] array = File.ReadAllBytes(text2); val = new Texture2D(2, 2, (TextureFormat)4, false); if (LoadImageMethod == null) { throw new MissingMethodException("UnityEngine.ImageConversion.LoadImage was not found"); } if (!(bool)LoadImageMethod.Invoke(null, new object[3] { val, array, false }) || ((Texture)val).width < 2 || ((Texture)val).height < 2) { throw new InvalidDataException("Loading-screen image decode returned an invalid texture"); } ((Object)val).name = "MagiCorp.ValheimOptimizer.LoadingScreen"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; _artworkTexture = val; _artworkAvailable = true; ValheimOptimizerPlugin.Log.LogInfo((object)$"Custom loading artwork loaded once: {((Texture)val).width}x{((Texture)val).height} ({array.Length / 1024} KiB)"); } catch (Exception ex) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } _artworkTexture = null; _artworkAvailable = false; ValheimOptimizerPlugin.Log.LogWarning((object)("Custom loading artwork failed to load; using black/text fallback: " + ex.Message)); } } internal static void Show() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown try { if (ValheimOptimizerPlugin.UseCustomLoadingScreen.Value) { PreloadArtwork(); } if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("MagiCorp.PreJoinLoadingOverlay"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<PreJoinLoadingOverlay>(); } string[] array = new string[3] { "$loadscreen_tip06", "$loadscreen_tip17", "$loadscreen_tip24" }; _instance._tipKey = array[Random.Range(0, array.Length)]; ((Behaviour)_instance).enabled = true; ValheimOptimizerPlugin.Log.LogInfo((object)("Pre-join loading overlay shown artwork=" + (_artworkAvailable ? "custom" : "fallback") + " tip=" + _instance._tipKey)); } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Pre-join loading overlay failed: " + ex.Message)); } } internal static void Hide() { if ((Object)(object)_instance != (Object)null) { ((Behaviour)_instance).enabled = false; } } internal static void ReleaseResources() { if ((Object)(object)_artworkTexture != (Object)null) { Object.Destroy((Object)(object)_artworkTexture); _artworkTexture = null; } _artworkAvailable = false; _artworkLoadAttempted = false; if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } } private string Localize(string key) { try { return (Localization.instance != null) ? Localization.instance.Localize(key) : key; } catch { return key; } } private void EnsureStyles() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) int fontSize = Math.Max(24, Screen.height / 32); int fontSize2 = Math.Max(16, Screen.height / 54); if (_titleStyle == null) { _titleStyle = new GUIStyle(GUI.skin.label); _titleStyle.alignment = (TextAnchor)4; _titleStyle.fontStyle = (FontStyle)1; _titleStyle.normal.textColor = Color.white; } if (_tipStyle == null) { _tipStyle = new GUIStyle(GUI.skin.label); _tipStyle.alignment = (TextAnchor)4; _tipStyle.wordWrap = true; _tipStyle.normal.textColor = Color.white; } _titleStyle.fontSize = fontSize; _tipStyle.fontSize = fontSize2; } private void OnGUI() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) GUI.depth = -10000; GUI.color = Color.black; GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; EnsureStyles(); if (ValheimOptimizerPlugin.UseCustomLoadingScreen.Value && _artworkAvailable && (Object)(object)_artworkTexture != (Object)null) { GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_artworkTexture, (ScaleMode)1, true); return; } float num = (float)Screen.height * 0.43f; GUI.Label(new Rect((float)Screen.width * 0.15f, num, (float)Screen.width * 0.7f, 60f), "Loading...", _titleStyle); GUI.Label(new Rect((float)Screen.width * 0.18f, num + 72f, (float)Screen.width * 0.64f, 120f), Localize(_tipKey ?? "$loadscreen_tip06"), _tipStyle); } } [HarmonyPatch(typeof(Hud), "UpdateBlackScreen")] internal static class PreJoinLoadingOverlayHandoffPatch { private static void Postfix() { if ((Object)(object)Game.instance != (Object)null && Game.instance.WaitingForRespawn()) { PreJoinLoadingOverlay.Hide(); } } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] internal static class PreJoinLoadingOverlayErrorPatch { private static void Prefix() { PreJoinLoadingOverlay.Hide(); } } [HarmonyPatch(typeof(FejdStartup), "TransitionToMainScene")] internal static class ImmediateLoadingScreenPatch { private static readonly MethodInfo BackendCheck = AccessTools.Method(typeof(FejdStartup), "LoadMainSceneIfBackendSelected", (Type[])null, (Type[])null); private static IEnumerator ContinueAfterPresentedFrame(FejdStartup startup) { yield return null; try { BackendCheck?.Invoke(startup, null); } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Deferred backend check failed: " + ex.Message)); } } private static bool Prefix(FejdStartup __instance) { if (!ValheimOptimizerPlugin.ImmediateJoinLoadingScreen.Value || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_loading == (Object)null || BackendCheck == null) { return true; } try { PreJoinLoadingOverlay.Show(); __instance.m_loading.SetActive(true); ZCursor.Hide(); ((MonoBehaviour)__instance).StartCoroutine(ContinueAfterPresentedFrame(__instance)); ValheimOptimizerPlugin.Log.LogInfo((object)"Immediate loading screen activated; presenting a frame before scene load"); return false; } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Immediate loading transition failed; using vanilla fade: " + ex.Message)); return true; } } } [HarmonyPatch(typeof(FejdStartup), "LoadMainScene")] internal static class AsyncJoinScenePatch { private static readonly FieldInfo StartingWorldField = AccessTools.Field(typeof(FejdStartup), "m_startingWorld"); private static bool Prefix(FejdStartup __instance) { if (ValheimOptimizerPlugin.AsyncJoinSceneLoad.Value) { ValheimOptimizerPlugin.Log.LogWarning((object)"AsyncJoinSceneLoad is temporarily safety-disabled in 0.1.17; using Valheim's normal scene loader"); } return true; } } internal static class MinimalMainMenuOptimizations { internal static void InitializeMenuWorldIfNeeded(World world) { if (Application.isBatchMode) { WorldGenerator.Initialize(world); } else if (ValheimOptimizerPlugin.MinimalMainMenu.Value) { ValheimOptimizerPlugin.Log.LogInfo((object)"Minimal main menu: skipped WorldGenerator.Initialize(menu world); gameplay world initialization remains handled by ZNet"); } else { WorldGenerator.Initialize(world); } } private static bool IsUnderUiRoot(Transform transform, FejdStartup startup) { if ((Object)(object)transform == (Object)null || (Object)(object)startup == (Object)null) { return false; } GameObject[] array = (GameObject[])(object)new GameObject[6] { startup.m_mainMenu, startup.m_menuList, startup.m_loading, startup.m_characterSelectScreen, startup.m_startGamePanel, startup.m_creditsPanel }; foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && transform.IsChildOf(val.transform)) { return true; } } return false; } internal static void Apply(FejdStartup startup) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (Application.isBatchMode || !ValheimOptimizerPlugin.MinimalMainMenu.Value || (Object)(object)startup == (Object)null || (Object)(object)startup.m_mainCamera == (Object)null) { return; } try { Camera component = startup.m_mainCamera.GetComponent<Camera>(); int num = 0; if ((Object)(object)startup.m_mainMenu != (Object)null) { num |= 1 << startup.m_mainMenu.layer; } if ((Object)(object)startup.m_menuList != (Object)null) { num |= 1 << startup.m_menuList.layer; } if ((Object)(object)startup.m_loading != (Object)null) { num |= 1 << startup.m_loading.layer; } if ((Object)(object)startup.m_characterSelectScreen != (Object)null) { num |= 1 << startup.m_characterSelectScreen.layer; } if ((Object)(object)startup.m_startGamePanel != (Object)null) { num |= 1 << startup.m_startGamePanel.layer; } if ((Object)(object)startup.m_creditsPanel != (Object)null) { num |= 1 << startup.m_creditsPanel.layer; } if ((Object)(object)component != (Object)null) { component.clearFlags = (CameraClearFlags)2; component.backgroundColor = Color.black; component.cullingMask = num; } int num2 = 0; Camera[] array = Object.FindObjectsByType<Camera>((FindObjectsSortMode)0); foreach (Camera val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)component) && ((Behaviour)val).enabled && !((Object)(object)val.targetTexture != (Object)null) && (val.cullingMask & num) == 0) { ((Behaviour)val).enabled = false; num2++; } } int num3 = 0; ParticleSystem[] array2 = Object.FindObjectsByType<ParticleSystem>((FindObjectsSortMode)0); foreach (ParticleSystem val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !IsUnderUiRoot(((Component)val2).transform, startup)) { val2.Stop(true, (ParticleSystemStopBehavior)0); num3++; } } ValheimOptimizerPlugin.Log.LogInfo((object)$"Minimal main menu active: black UI-only main camera; disabled background cameras={num2}, stopped background particles={num3}"); } catch (Exception ex) { ValheimOptimizerPlugin.Log.LogWarning((object)("Minimal main menu setup failed: " + ex.Message)); } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] internal static class MinimalMainMenuWorldGeneratorPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo original = AccessTools.Method(typeof(WorldGenerator), "Initialize", new Type[1] { typeof(World) }, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(MinimalMainMenuOptimizations), "InitializeMenuWorldIfNeeded", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (original != null && replacement != null && CodeInstructionExtensions.Calls(instruction, original)) { yield return new CodeInstruction(instruction) { opcode = OpCodes.Call, operand = replacement }; } else { yield return instruction; } } } } [HarmonyPatch(typeof(FejdStartup), "Start")] internal static class MinimalMainMenuSetupPatch { private static void Postfix(FejdStartup __instance) { MinimalMainMenuOptimizations.Apply(__instance); } } [HarmonyPatch(typeof(FejdStartup), "UpdateCamera")] internal static class MinimalMainMenuCameraPatch { private static bool Prefix() { return !ValheimOptimizerPlugin.MinimalMainMenu.Value; } }