using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; 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("MapFogCleaner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("MapFogCleaner")] [assembly: AssemblyTitle("MapFogCleaner")] [assembly: AssemblyVersion("1.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MapFogCleaner { public class CloudShadowToggleController : MonoBehaviour { private static readonly FieldRef MapLargeShaderRef = AccessTools.FieldRefAccess("m_mapLargeShader"); private static readonly FieldRef MapSmallShaderRef = AccessTools.FieldRefAccess("m_mapSmallShader"); private static Texture2D _transparentTex; private Material _large; private Material _small; private Texture _origLargeCloud; private Texture _origSmallCloud; private bool _hiddenApplied; private void Update() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_large == (Object)null || (Object)(object)_small == (Object)null) { Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return; } Material val = MapLargeShaderRef.Invoke(instance); Material val2 = MapSmallShaderRef.Invoke(instance); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } _large = val; _small = val2; _origLargeCloud = _large.GetTexture("_CloudTex"); _origSmallCloud = _small.GetTexture("_CloudTex"); MapFogCleanerPlugin.LogStatic("CloudShadowToggle: map materials captured."); } bool value = MapFogCleanerPlugin.HideCloudShadows.Value; if (value == _hiddenApplied) { return; } if (value) { if ((Object)(object)_transparentTex == (Object)null) { _transparentTex = new Texture2D(1, 1, (TextureFormat)4, false); _transparentTex.SetPixel(0, 0, new Color(0f, 0f, 0f, 0f)); _transparentTex.Apply(); } _large.SetTexture("_CloudTex", (Texture)(object)_transparentTex); _small.SetTexture("_CloudTex", (Texture)(object)_transparentTex); } else { _large.SetTexture("_CloudTex", _origLargeCloud); _small.SetTexture("_CloudTex", _origSmallCloud); } _hiddenApplied = value; MapFogCleanerPlugin.LogStatic($"CloudShadowToggle: hidden={value}"); } } [HarmonyPatch(typeof(Minimap), "Awake")] internal static class Minimap_Awake_AddCloudToggle { private static void Postfix(Minimap __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } public class FogCleanerController : MonoBehaviour { private static readonly FieldRef ExploredRef = AccessTools.FieldRefAccess("m_explored"); private static readonly FieldRef FogTextureRef = AccessTools.FieldRefAccess("m_fogTexture"); private const int StepsPerFrame = 20000; private bool[] _explored; private Texture2D _fogTexture; private int _textureSize; private float _pixelSize; private bool _ready; private float _timer; private Coroutine _scanCoroutine; private void Update() { if (!MapFogCleanerPlugin.Enabled.Value || (!_ready && !TryCapture())) { return; } _timer -= Time.deltaTime; if (!(_timer > 0f)) { _timer = MapFogCleanerPlugin.ScanInterval.Value; if (_scanCoroutine == null) { _scanCoroutine = ((MonoBehaviour)this).StartCoroutine(ScanAndFillRoutine()); } } } private bool TryCapture() { Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return false; } bool[] array = ExploredRef.Invoke(instance); Texture2D val = FogTextureRef.Invoke(instance); if (array == null || (Object)(object)val == (Object)null || instance.m_textureSize <= 0) { return false; } _explored = array; _fogTexture = val; _textureSize = instance.m_textureSize; _pixelSize = instance.m_pixelSize; _ready = true; int num = 0; bool[] array2 = array; for (int i = 0; i < array2.Length; i++) { if (array2[i]) { num++; } } MapFogCleanerPlugin.LogStatic($"Ready: explored.Length={array.Length}, textureSize={_textureSize}, pixelSize={_pixelSize}, exploredCount={num}"); return true; } private IEnumerator ScanAndFillRoutine() { int size = _textureSize; float num = MapFogCleanerPlugin.MaxIslandRadius.Value / _pixelSize; int maxIslandSize = Mathf.Max(1, Mathf.RoundToInt((float)Math.PI * num * num)); bool[] visited = new bool[size * size]; List pending = new List(64); Queue queue = new Queue(); bool changed = false; int componentsChecked = 0; int islandsFilled = 0; int cellsFilled = 0; int largestSkipped = 0; int steps = 0; for (int start = 0; start < size * size; start++) { int num2 = steps + 1; steps = num2; if (num2 >= 20000) { steps = 0; yield return null; } if (visited[start] || _explored[start]) { continue; } pending.Clear(); queue.Clear(); queue.Enqueue(start); visited[start] = true; int componentSize = 0; while (queue.Count > 0) { num2 = steps + 1; steps = num2; if (num2 >= 20000) { steps = 0; yield return null; } int num3 = queue.Dequeue(); componentSize++; if (pending.Count <= maxIslandSize) { pending.Add(num3); } int num4 = num3 % size; int num5 = num3 / size; TryEnqueue(num4 - 1, num5, size, visited, queue, _explored); TryEnqueue(num4 + 1, num5, size, visited, queue, _explored); TryEnqueue(num4, num5 - 1, size, visited, queue, _explored); TryEnqueue(num4, num5 + 1, size, visited, queue, _explored); } componentsChecked++; if (componentSize <= maxIslandSize) { islandsFilled++; foreach (int item in pending) { if (Explore(item % size, item / size, size)) { changed = true; cellsFilled++; } } } else if (componentSize > largestSkipped) { largestSkipped = componentSize; } } if (changed) { _fogTexture.Apply(); } MapFogCleanerPlugin.LogStatic($"ScanAndFill: maxIslandCells={maxIslandSize}, componentsChecked={componentsChecked}, islandsFilled={islandsFilled}, cellsFilled={cellsFilled}, largestSkipped={largestSkipped}, changed={changed}"); _scanCoroutine = null; } private static void TryEnqueue(int x, int y, int size, bool[] visited, Queue queue, bool[] explored) { if (x >= 0 && x < size && y >= 0 && y < size) { int num = y * size + x; if (!visited[num] && !explored[num]) { visited[num] = true; queue.Enqueue(num); } } } private bool Explore(int x, int y, int size) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) int num = y * size + x; if (_explored[num]) { return false; } Color pixel = _fogTexture.GetPixel(x, y); pixel.r = 0f; _fogTexture.SetPixel(x, y, pixel); _explored[num] = true; return true; } } [HarmonyPatch(typeof(Minimap), "Awake")] internal static class Minimap_Awake_AddFogCleaner { private static void Postfix(Minimap __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } [BepInPlugin("sopmehua.valheim.mapfogcleaner", "MapFogCleaner", "1.1.1")] public class MapFogCleanerPlugin : BaseUnityPlugin { public const string PluginGuid = "sopmehua.valheim.mapfogcleaner"; public const string PluginName = "MapFogCleaner"; public const string PluginVersion = "1.1.1"; public static ConfigEntry Enabled; public static ConfigEntry MaxIslandRadius; public static ConfigEntry ScanInterval; public static ConfigEntry HideCloudShadows; private static ManualLogSource _log; private Harmony _harmony; internal static void LogStatic(string message) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)message); } } private void Awake() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown _log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Включить/выключить мод."); MaxIslandRadius = ((BaseUnityPlugin)this).Config.Bind("General", "MaxIslandRadius", 100f, new ConfigDescription("Максимальный размер (примерный радиус в игровых метрах, не в клетках текстуры — разные миры могут использовать разное разрешение сетки тумана) неоткрытого 'островка', окружённого исследованной территорией, который будет автоматически закрашен. Больше значение — закрашиваются более крупные пятна тумана.", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 2000f), Array.Empty())); ScanInterval = ((BaseUnityPlugin)this).Config.Bind("General", "ScanInterval", 4f, new ConfigDescription("Как часто (в секундах) проверять карту на маленькие пятна тумана.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); HideCloudShadows = ((BaseUnityPlugin)this).Config.Bind("Map", "HideCloudShadows", false, "Убрать плывущие тени облаков на большой карте и на миникарте. Только визуально, на туман войны/исследование не влияет."); _harmony = new Harmony("sopmehua.valheim.mapfogcleaner"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"MapFogCleaner 1.1.1 загружен."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }