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 MeadhallChronicles MumbleContextRepair v0.2.0
BepInEx/plugins/MeadhallContextRepair.dll
Decompiled 2 weeks agousing System; using System.IO.MemoryMappedFiles; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] [BepInPlugin("com.meadhall.mumblecontextrepair", "Meadhall Mumble Context Repair (Test)", "0.2.0")] public sealed class MeadhallContextRepair : BaseUnityPlugin { private const long NameOffset = 44L; private const long ContextLengthOffset = 1104L; private const long ContextBytesOffset = 1108L; private const float SamplePeriod = 0.1f; private const float StableAfterRespawnSeconds = 6f; private const float StableAtInitialSpawnSeconds = 3f; private float elapsed; private float aliveSince = -1f; private bool everSawLivingPlayer; private bool recovering; private bool reportedFailure; private uint lastTick; private bool loggedRecovery; private void FixedUpdate() { elapsed += Time.fixedDeltaTime; if (elapsed < 0.1f) { return; } elapsed = 0f; bool flag = (Object)(object)ZNet.instance != (Object)null; Player localPlayer = Player.m_localPlayer; bool flag2 = flag && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead(); float realtimeSinceStartup = Time.realtimeSinceStartup; if (!flag2) { aliveSince = -1f; if (everSawLivingPlayer && !recovering) { recovering = true; loggedRecovery = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Player absent/dead: withholding positional context until stable respawn."); } } else { if (aliveSince < 0f) { aliveSince = realtimeSinceStartup; } everSawLivingPlayer = true; } try { using MemoryMappedFile memoryMappedFile = MemoryMappedFile.OpenExisting("MumbleLink", MemoryMappedFileRights.ReadWrite); using MemoryMappedViewAccessor memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor(0L, 0L, MemoryMappedFileAccess.ReadWrite); if (memoryMappedViewAccessor.ReadUInt32(0L) != 2) { return; } uint num = memoryMappedViewAccessor.ReadUInt32(4L); if (num == lastTick) { return; } lastTick = num; byte[] array = new byte[512]; memoryMappedViewAccessor.ReadArray(44L, array, 0, array.Length); string text = Encoding.Unicode.GetString(array); char[] trimChars = new char[1]; string text2 = text.TrimEnd(trimChars); if (text2 != "Valheim") { return; } uint num2 = memoryMappedViewAccessor.ReadUInt32(1104L); if (!flag2 || (recovering && realtimeSinceStartup - aliveSince < 6f)) { if (num2 != 0) { memoryMappedViewAccessor.Write(1104L, 0u); memoryMappedViewAccessor.WriteArray(1108L, new byte[256], 0, 256); } return; } if (recovering) { recovering = false; if (!loggedRecovery) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Player stable after respawn; context repair allowed."); loggedRecovery = true; } } if (realtimeSinceStartup - aliveSince < 3f || num2 != 0) { return; } string worldName = ZNet.instance.GetWorldName(); if (!string.IsNullOrEmpty(worldName)) { byte[] bytes = Encoding.UTF8.GetBytes("Valheim\0" + worldName); if (bytes.Length <= 256) { byte[] array2 = new byte[256]; Array.Copy(bytes, array2, bytes.Length); memoryMappedViewAccessor.WriteArray(1108L, array2, 0, array2.Length); memoryMappedViewAccessor.Write(1104L, (uint)bytes.Length); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Restored missing context after stable live-player check: " + worldName)); reportedFailure = false; } } } catch (Exception ex) { if (!reportedFailure) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not inspect Mumble shared memory: " + ex.Message)); reportedFailure = true; } } } }