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 CommanderRadarZoom v1.0.0
CommanderRadarZoom.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CommanderRadarZoom.Config; using CommanderRadarZoom.Patches; using CommanderRadarZoom.Radar; using CommanderRadarZoom.UI; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CommanderRadarZoom")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3beb3e6d2f4e50cd6e70b31043883442a145e919")] [assembly: AssemblyProduct("CommanderRadarZoom")] [assembly: AssemblyTitle("CommanderRadarZoom")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 CommanderRadarZoom { [BepInPlugin("com.commanderradarzoom.client", "CommanderRadarZoom", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.commanderradarzoom.client"; public const string PluginName = "CommanderRadarZoom"; public const string PluginVersion = "1.0.0"; private Harmony? _harmony; private ModConfig? _modConfig; private LocalNotification? _notification; private RadarZoomController? _radarController; private bool _isShuttingDown; private bool _updateFailureLogged; private bool _guiFailureLogged; private void Awake() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown try { _modConfig = new ModConfig(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); _notification = new LocalNotification(); _radarController = new RadarZoomController(_modConfig, _notification, ((BaseUnityPlugin)this).Logger); _radarController.Initialize(); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Unable to initialize the local radar zoom controller. The mod will remain inactive.\n{arg}"); SafeShutdownController(); return; } try { _harmony = new Harmony("com.commanderradarzoom.client"); if (!ManualCameraRendererPatch.Install(_harmony, _radarController.OnManualCameraRendererStarted, ((BaseUnityPlugin)this).Logger)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"ManualCameraRenderer.Start could not be patched. The low-frequency camera discovery fallback will remain available."); } } catch (Exception arg2) { ManualCameraRendererPatch.Clear(); ((BaseUnityPlugin)this).Logger.LogError((object)("Harmony initialization failed. Radar zoom will continue only through the controller's " + $"safe discovery fallback.\n{arg2}")); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"CommanderRadarZoom 1.0.0 loaded. Only this client's radar camera rendering is modified."); } private void Update() { if (_isShuttingDown || _radarController == null) { return; } try { _radarController.Tick(); _updateFailureLogged = false; } catch (Exception arg) { if (!_updateFailureLogged) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Radar zoom update failed; later frames will retry safely.\n{arg}"); _updateFailureLogged = true; } } } private void OnGUI() { if (_isShuttingDown || _notification == null) { return; } try { _notification.Draw(); _guiFailureLogged = false; } catch (Exception arg) { if (!_guiFailureLogged) { ((BaseUnityPlugin)this).Logger.LogError((object)$"The local zoom notification could not be drawn.\n{arg}"); _guiFailureLogged = true; } } } private void OnDestroy() { if (_isShuttingDown) { return; } _isShuttingDown = true; ManualCameraRendererPatch.Clear(); SafeShutdownController(); try { _notification?.Clear(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to clear the local notification during shutdown: " + ex.Message)); } try { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to remove Harmony patches during shutdown: " + ex2.Message)); } try { _modConfig?.Dispose(); } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to detach configuration handlers during shutdown: " + ex3.Message)); } _radarController = null; _notification = null; _modConfig = null; _harmony = null; } private void SafeShutdownController() { try { _radarController?.Shutdown(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Radar zoom controller shutdown encountered an error: " + ex.Message)); } } } } namespace CommanderRadarZoom.UI { internal sealed class LocalNotification { private const float FadeDuration = 0.25f; private string? _message; private float _expiresAt; private GUIStyle? _boxStyle; private GUIStyle? _labelStyle; internal void Show(string message, float duration = 1.5f) { if (!string.IsNullOrWhiteSpace(message)) { _message = message; _expiresAt = Time.unscaledTime + Mathf.Max(0.1f, duration); } } internal void Clear() { _message = null; _expiresAt = 0f; } internal void Draw() { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0094: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(_message)) { return; } float num = _expiresAt - Time.unscaledTime; if (num <= 0f) { Clear(); return; } EnsureStyles(); float num2 = Mathf.Min(360f, Mathf.Max(160f, (float)Screen.width - 20f)); Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num2) * 0.5f, 48f, num2, 42f); float num3 = ((num < 0.25f) ? Mathf.Clamp01(num / 0.25f) : 1f); Color color = GUI.color; try { GUI.color = new Color(color.r, color.g, color.b, color.a * num3); GUI.Box(val, GUIContent.none, _boxStyle); GUI.Label(val, _message, _labelStyle); } finally { GUI.color = color; } } private void EnsureStyles() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0029: Expected O, but got Unknown //IL_002e: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (_boxStyle == null) { _boxStyle = new GUIStyle(GUI.skin.box) { padding = new RectOffset(12, 12, 8, 8) }; } if (_labelStyle == null) { _labelStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 18, clipping = (TextClipping)1, wordWrap = false }; _labelStyle.normal.textColor = new Color(0.62f, 1f, 0.42f, 1f); } } } } namespace CommanderRadarZoom.Radar { internal sealed class RadarZoomController { private const string EnhancedRadarBoosterGuid = "MrHydralisk.EnhancedRadarBooster"; private const float ReferenceCheckInterval = 1f; private const float ZoomEpsilon = 0.001f; private readonly ModConfig _config; private readonly LocalNotification _notification; private readonly ManualLogSource _logger; private readonly HashSet<string> _reportedPlugins = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private ManualCameraRenderer? _renderer; private Camera? _camera; private float _originalZoom; private float _lastObservedOrAppliedZoom; private float _nextReferenceCheck; private bool _initialized; private bool _lastEnabledState; private bool _compatibilityScanComplete; private bool _compatibilityBlocked; private bool _cameraBlocked; private bool _ownsCurrentValue; private bool _lastWriteWasUser; private bool _externalChangeLogged; private bool _sceneRefreshPending; private bool _enhancedRadarBoosterDetected; private bool _enhancedInspectionPending; private bool _enhancedRuntimeReadFailureLogged; private bool _canonicalCameraMismatchLogged; private PluginInfo? _enhancedRadarBoosterInfo; private FieldInfo? _enhancedRangeEnabledValueField; private FieldInfo? _enhancedRangeSyncValueField; internal RadarZoomController(ModConfig config, LocalNotification notification, ManualLogSource logger) { _config = config ?? throw new ArgumentNullException("config"); _notification = notification ?? throw new ArgumentNullException("notification"); _logger = logger ?? throw new ArgumentNullException("logger"); } internal void Initialize() { if (!_initialized) { SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; _initialized = true; _lastEnabledState = _config.Enabled; _nextReferenceCheck = 0f; _sceneRefreshPending = true; _logger.LogInfo((object)($"Configured radar zoom is {_config.CurrentZoom:0.##} " + $"(allowed {_config.MinimumZoom:0.##}-{_config.MaximumZoom:0.##}; larger values show more area).")); } } internal void Tick() { if (_initialized) { if (_config.ProcessPendingChanges()) { _sceneRefreshPending = true; _nextReferenceCheck = 0f; } EnsureCompatibilityScan(); HandleEnabledTransition(); float unscaledTime = Time.unscaledTime; if (unscaledTime >= _nextReferenceCheck) { _nextReferenceCheck = unscaledTime + 1f; RefreshCameraReference(); } if (_config.Enabled && !_compatibilityBlocked && !_cameraBlocked && HasCanonicalCamera() && CanHandleShortcuts()) { ProcessShortcuts(); } } } internal void OnManualCameraRendererStarted(ManualCameraRenderer renderer) { if (_initialized && !((Object)(object)renderer == (Object)null)) { EnsureCompatibilityScan(); TryRegisterCanonicalRenderer(renderer, "ManualCameraRenderer.Start"); } } internal void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (_initialized) { _sceneRefreshPending = true; _canonicalCameraMismatchLogged = false; _nextReferenceCheck = 0f; } } internal void OnSceneUnloaded(Scene scene) { if (_initialized) { _sceneRefreshPending = true; _canonicalCameraMismatchLogged = false; _nextReferenceCheck = 0f; } } internal void Shutdown() { if (_initialized) { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.sceneUnloaded -= OnSceneUnloaded; TryRestoreOriginalZoom("plugin shutdown"); ClearCameraReference(); _initialized = false; } } private void HandleEnabledTransition() { bool enabled = _config.Enabled; if (enabled != _lastEnabledState) { _lastEnabledState = enabled; if (!enabled) { TryRestoreOriginalZoom("the mod was disabled"); _notification.Clear(); _logger.LogInfo((object)"Radar zoom handling is disabled."); } else { _logger.LogInfo((object)"Radar zoom handling is enabled."); _sceneRefreshPending = true; _nextReferenceCheck = 0f; } } } private void RefreshCameraReference() { CheckEnhancedRadarBoosterRuntimeState(); if (!HasCanonicalCamera()) { ReleaseCameraReference(); TryAcquireCanonicalRenderer(); return; } if (_sceneRefreshPending) { _sceneRefreshPending = false; if (_config.Enabled && !_compatibilityBlocked && !_cameraBlocked) { ApplyZoom(_config.CurrentZoom, "scene, round, or configuration refresh", persist: false, notify: false, userInitiated: false); } } ObserveExternalChanges(); } private void TryAcquireCanonicalRenderer() { StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.mapScreen == (Object)null)) { TryRegisterCanonicalRenderer(instance.mapScreen, "low-frequency discovery"); } } private void TryRegisterCanonicalRenderer(ManualCameraRenderer renderer, string source) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.mapScreen == (Object)null || (Object)(object)renderer != (Object)(object)instance.mapScreen) { return; } Camera mapCamera = renderer.mapCamera; if ((Object)(object)mapCamera == (Object)null || (Object)(object)renderer.cam == (Object)null || (Object)(object)renderer.cam != (Object)(object)mapCamera) { if (!_canonicalCameraMismatchLogged) { _canonicalCameraMismatchLogged = true; _logger.LogWarning((object)("The canonical mapScreen found through " + source + " does not currently expose the same Camera through both cam and mapCamera. No camera value will be changed; discovery will retry at low frequency.")); } } else { if ((Object)(object)_renderer == (Object)(object)renderer && (Object)(object)_camera == (Object)(object)mapCamera) { return; } ReleaseCameraReference(); _renderer = renderer; _camera = mapCamera; _originalZoom = mapCamera.orthographicSize; _lastObservedOrAppliedZoom = _originalZoom; _cameraBlocked = false; _ownsCurrentValue = false; _lastWriteWasUser = false; _externalChangeLogged = false; _canonicalCameraMismatchLogged = false; _sceneRefreshPending = false; if (!mapCamera.orthographic) { _cameraBlocked = true; _logger.LogWarning((object)("The canonical radar camera found through " + source + " is not orthographic. CommanderRadarZoom will not force a projection change; zoom is disabled for this camera.")); return; } _logger.LogInfo((object)$"Cached the canonical local ship radar camera through {source}; native orthographicSize is {_originalZoom:0.##}."); if (_config.Enabled && !_compatibilityBlocked) { ApplyZoom(_config.CurrentZoom, "camera initialization", persist: false, notify: false, userInitiated: false); } } } private void ProcessShortcuts() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut val = _config.ResetZoom; if (((KeyboardShortcut)(ref val)).IsDown()) { ApplyZoom(_config.DefaultZoom, "reset", persist: true, notify: true, userInitiated: true); return; } val = _config.ZoomIn; if (((KeyboardShortcut)(ref val)).IsDown()) { float currentCameraZoomAsBaseline = GetCurrentCameraZoomAsBaseline(); ApplyZoom(currentCameraZoomAsBaseline - _config.ZoomStep, "zoom in", persist: true, notify: true, userInitiated: true); return; } val = _config.ZoomOut; if (((KeyboardShortcut)(ref val)).IsDown()) { float currentCameraZoomAsBaseline2 = GetCurrentCameraZoomAsBaseline(); ApplyZoom(currentCameraZoomAsBaseline2 + _config.ZoomStep, "zoom out", persist: true, notify: true, userInitiated: true); } } private float GetCurrentCameraZoomAsBaseline() { if ((Object)(object)_camera == (Object)null) { return _config.CurrentZoom; } float orthographicSize = _camera.orthographicSize; if (!Approximately(orthographicSize, _lastObservedOrAppliedZoom)) { ReconcileObservedZoom(orthographicSize); } return _config.ClampZoom(orthographicSize); } private void ApplyZoom(float requested, string reason, bool persist, bool notify, bool userInitiated) { if ((Object)(object)_camera == (Object)null || _cameraBlocked || _compatibilityBlocked) { return; } float orthographicSize = _camera.orthographicSize; if (!Approximately(orthographicSize, _lastObservedOrAppliedZoom) && !ReconcileObservedZoom(orthographicSize)) { return; } if (!_camera.orthographic) { TryRestoreOriginalZoom("the canonical radar camera changed to a perspective projection"); _cameraBlocked = true; _logger.LogWarning((object)"The canonical radar camera changed to a perspective projection. Zoom has been disabled for this camera."); return; } float num = _config.ClampZoom(requested); if (!Approximately(orthographicSize, num)) { _camera.orthographicSize = num; _ownsCurrentValue = true; _lastWriteWasUser = userInitiated; } else if (userInitiated && _ownsCurrentValue) { _lastWriteWasUser = true; } _lastObservedOrAppliedZoom = num; if (persist) { _config.SetCurrentZoom(num); } _logger.LogInfo((object)$"Radar zoom: {num:0.##} ({reason})."); if (notify && _config.ShowZoomNotification) { _notification.Show($"Radar zoom: {num:0.##}"); } } private void ObserveExternalChanges() { if ((Object)(object)_camera == (Object)null || !_config.Enabled || _compatibilityBlocked || _cameraBlocked) { return; } if (!_camera.orthographic) { TryRestoreOriginalZoom("the canonical radar camera changed to a perspective projection"); _cameraBlocked = true; _logger.LogWarning((object)"The canonical radar camera changed to a perspective projection. Zoom has been disabled for this camera."); return; } float orthographicSize = _camera.orthographicSize; if (!Approximately(orthographicSize, _lastObservedOrAppliedZoom)) { ReconcileObservedZoom(orthographicSize); } } private bool ReconcileObservedZoom(float actual) { if (_ownsCurrentValue && _lastWriteWasUser) { _ownsCurrentValue = false; _lastWriteWasUser = false; _cameraBlocked = true; _logger.LogWarning((object)("Another mod changed the radar orthographicSize from the requested " + $"{_lastObservedOrAppliedZoom:0.##} to {actual:0.##}. " + "CommanderRadarZoom has stopped writing to this camera to avoid a per-frame conflict.")); return false; } AdoptExternalBaseline(actual); return true; } private void AdoptExternalBaseline(float actual) { _lastObservedOrAppliedZoom = actual; _ownsCurrentValue = false; _lastWriteWasUser = false; if (!_externalChangeLogged) { _externalChangeLogged = true; _logger.LogWarning((object)($"Observed an external radar zoom value of {actual:0.##}. It will be respected; " + "CommanderRadarZoom will write again only after a user shortcut or lifecycle refresh.")); } } private bool CanHandleShortcuts() { if (!Application.isFocused) { return false; } GameNetworkManager instance = GameNetworkManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.localPlayerController == (Object)null) { return false; } PlayerControllerB localPlayerController = instance.localPlayerController; if (!localPlayerController.isPlayerControlled || localPlayerController.isTypingChat || localPlayerController.inTerminalMenu || localPlayerController.inSpecialMenu) { return false; } if (!((Object)(object)localPlayerController.quickMenuManager == (Object)null)) { return !localPlayerController.quickMenuManager.isMenuOpen; } return true; } private bool HasCanonicalCamera() { if ((Object)(object)_renderer == (Object)null || (Object)(object)_camera == (Object)null) { return false; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.mapScreen != (Object)null && (Object)(object)instance.mapScreen == (Object)(object)_renderer && (Object)(object)_renderer.mapCamera == (Object)(object)_camera) { return (Object)(object)_renderer.cam == (Object)(object)_camera; } return false; } private void ReleaseCameraReference() { bool flag = (Object)(object)_renderer != (Object)null || (Object)(object)_camera != (Object)null; TryRestoreOriginalZoom("the radar camera reference changed"); ClearCameraReference(); if (flag) { _canonicalCameraMismatchLogged = false; } } private void TryRestoreOriginalZoom(string reason) { if ((Object)(object)_camera == (Object)null || !_ownsCurrentValue) { _ownsCurrentValue = false; _lastWriteWasUser = false; return; } float orthographicSize = _camera.orthographicSize; if (!Approximately(orthographicSize, _lastObservedOrAppliedZoom)) { _logger.LogWarning((object)("The radar camera no longer contains CommanderRadarZoom's last value while " + reason + "; the external value was left unchanged.")); _ownsCurrentValue = false; _lastWriteWasUser = false; } else { _camera.orthographicSize = _originalZoom; _logger.LogInfo((object)$"Restored native radar zoom {_originalZoom:0.##} because {reason}."); _ownsCurrentValue = false; _lastWriteWasUser = false; _lastObservedOrAppliedZoom = _originalZoom; } } private void ClearCameraReference() { _renderer = null; _camera = null; _cameraBlocked = false; _ownsCurrentValue = false; _lastWriteWasUser = false; _externalChangeLogged = false; _originalZoom = 0f; _lastObservedOrAppliedZoom = 0f; } private void EnsureCompatibilityScan() { if (_compatibilityScanComplete) { return; } _compatibilityScanComplete = true; try { ScanInstalledPlugins(); } catch (Exception ex) { _logger.LogWarning((object)("Could not complete the one-time radar-mod compatibility scan. Runtime value observation remains active: " + ex.Message)); } } private void ScanInstalledPlugins() { foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { PluginInfo value = pluginInfo.Value; BepInPlugin metadata = value.Metadata; string text = ((metadata != null) ? metadata.GUID : null) ?? pluginInfo.Key; BepInPlugin metadata2 = value.Metadata; string name = ((metadata2 != null) ? metadata2.Name : null) ?? string.Empty; string fileName = (string.IsNullOrEmpty(value.Location) ? string.Empty : Path.GetFileNameWithoutExtension(value.Location)); if (string.Equals(text, "MrHydralisk.EnhancedRadarBooster", StringComparison.OrdinalIgnoreCase)) { InspectEnhancedRadarBooster(value); } else if (MatchesRadarModToken(text, name, fileName)) { ReportPotentialRadarMod(text, name); } } } private void InspectEnhancedRadarBooster(PluginInfo info) { _enhancedRadarBoosterDetected = true; _enhancedRadarBoosterInfo = info; BaseUnityPlugin instance = info.Instance; if ((Object)(object)instance == (Object)null) { _enhancedInspectionPending = true; _logger.LogWarning((object)"EnhancedRadarBooster was detected, but its configuration was unavailable. Its state will be checked again after plugin initialization; runtime overwrite detection also remains active."); return; } _enhancedInspectionPending = false; Type type = ((object)instance).GetType().Assembly.GetType("EnhancedRadarBooster.Config", throwOnError: false); if (type != null) { _enhancedRangeEnabledValueField = type.GetField("mapRangeRBEnabledValue", BindingFlags.Static | BindingFlags.Public); _enhancedRangeSyncValueField = type.GetField("mapRangeRBSyncValue", BindingFlags.Static | BindingFlags.Public); } ConfigEntry<bool> val = default(ConfigEntry<bool>); bool flag = instance.Config.TryGetEntry<bool>("Map", "MapRangeRBEnabled", ref val); ConfigEntry<bool> val2 = default(ConfigEntry<bool>); bool flag2 = instance.Config.TryGetEntry<bool>("Map", "MapRangeRBSync", ref val2); bool flag3 = flag && val.Value; bool flag4 = flag2 && val2.Value; bool conflictActive; bool flag5 = TryReadEnhancedRadarBoosterRuntimeState(out conflictActive); if (flag3 || flag4 || (flag5 && conflictActive)) { BlockForEnhancedRadarBooster(); } else if (!flag && !flag2) { _logger.LogWarning((object)"EnhancedRadarBooster was detected, but its map-range settings could not be read. Runtime overwrite detection will remain active."); } else { _logger.LogInfo((object)"EnhancedRadarBooster was detected with its conflicting map-range options disabled."); } } private void CheckEnhancedRadarBoosterRuntimeState() { if (!_enhancedRadarBoosterDetected || _compatibilityBlocked) { return; } if (_enhancedInspectionPending) { PluginInfo? enhancedRadarBoosterInfo = _enhancedRadarBoosterInfo; if ((Object)(object)((enhancedRadarBoosterInfo != null) ? enhancedRadarBoosterInfo.Instance : null) != (Object)null) { InspectEnhancedRadarBooster(_enhancedRadarBoosterInfo); if (_compatibilityBlocked) { return; } } } if (TryReadEnhancedRadarBoosterRuntimeState(out var conflictActive) && conflictActive) { BlockForEnhancedRadarBooster(); } } private bool TryReadEnhancedRadarBoosterRuntimeState(out bool conflictActive) { conflictActive = false; bool result = false; try { if (_enhancedRangeEnabledValueField?.GetValue(null) is bool flag) { result = true; conflictActive |= flag; } if (_enhancedRangeSyncValueField?.GetValue(null) is bool flag2) { result = true; conflictActive |= flag2; } return result; } catch (Exception ex) { if (!_enhancedRuntimeReadFailureLogged) { _enhancedRuntimeReadFailureLogged = true; _logger.LogWarning((object)("EnhancedRadarBooster runtime map-range state could not be read. Camera overwrite observation remains active: " + ex.Message)); } return false; } } private void BlockForEnhancedRadarBooster() { if (!_compatibilityBlocked) { _compatibilityBlocked = true; TryRestoreOriginalZoom("EnhancedRadarBooster controls the same property"); _notification.Clear(); _logger.LogWarning((object)"CommanderRadarZoom camera writes are disabled because EnhancedRadarBooster controls orthographicSize. Set [Map] MapRangeRBEnabled=false and MapRangeRBSync=false in that mod, then reconnect or restart. If those values are host-synchronized, the controlling host's EnhancedRadarBooster configuration must be changed."); } } private void ReportPotentialRadarMod(string guid, string name) { if (_reportedPlugins.Add(guid)) { _logger.LogInfo((object)("Detected radar/camera-related plugin '" + name + "' (" + guid + "). Only the canonical ship radar camera will be modified; runtime conflicts are observed without continuous overwrites.")); } } private static bool MatchesRadarModToken(string guid, string name, string fileName) { string text = guid + " " + name + " " + fileName; if (text.IndexOf("Minimap", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("TwoRadarMaps", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("GeneralImprovements", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("ShipWindows", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("OpenBodyCams", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool Approximately(float left, float right) { return Math.Abs(left - right) <= 0.001f; } } } namespace CommanderRadarZoom.Patches { internal static class ManualCameraRendererPatch { private static Action<ManualCameraRenderer>? _rendererStarted; private static ManualLogSource? _logger; internal static bool Install(Harmony harmony, Action<ManualCameraRenderer> rendererStarted, ManualLogSource logger) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown if (harmony == null) { throw new ArgumentNullException("harmony"); } if (rendererStarted == null) { throw new ArgumentNullException("rendererStarted"); } if (logger == null) { throw new ArgumentNullException("logger"); } MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ManualCameraRenderer), "Start", Type.EmptyTypes, (Type[])null); if (methodInfo == null) { logger.LogError((object)"ManualCameraRenderer.Start() was not found in the current game assembly; the initialization patch has been disabled."); Clear(); return false; } MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(ManualCameraRendererPatch), "StartPostfix", new Type[1] { typeof(ManualCameraRenderer) }, (Type[])null); if (methodInfo2 == null) { logger.LogError((object)"The internal ManualCameraRenderer postfix bridge could not be located."); Clear(); return false; } _rendererStarted = rendererStarted; _logger = logger; try { HarmonyMethod val = new HarmonyMethod(methodInfo2) { priority = 0 }; harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); logger.LogInfo((object)"Patched ManualCameraRenderer.Start() with a Priority.Last postfix for local radar camera discovery."); return true; } catch (Exception ex) { logger.LogError((object)("ManualCameraRenderer.Start() could not be patched; the patch path is disabled.\n" + ex)); Clear(); return false; } } internal static void Clear() { _rendererStarted = null; _logger = null; } [HarmonyPriority(0)] private static void StartPostfix(ManualCameraRenderer __instance) { Action<ManualCameraRenderer> rendererStarted = _rendererStarted; if (rendererStarted == null || (Object)(object)__instance == (Object)null) { return; } try { rendererStarted(__instance); } catch (Exception arg) { try { ManualLogSource? logger = _logger; if (logger != null) { logger.LogError((object)("An exception occurred while processing the local radar renderer initialization. " + $"The game will continue normally.\n{arg}")); } } catch { } } } } } namespace CommanderRadarZoom.Config { internal sealed class ModConfig : IDisposable { private const float DefaultDefaultZoom = 25f; private const float DefaultMinimumZoom = 10f; private const float DefaultMaximumZoom = 60f; private const float DefaultZoomStep = 2f; private readonly ConfigFile _configFile; private readonly ManualLogSource _logger; private readonly ConfigEntry<bool> _enabled; private readonly ConfigEntry<float> _defaultZoom; private readonly ConfigEntry<float> _minimumZoom; private readonly ConfigEntry<float> _maximumZoom; private readonly ConfigEntry<float> _zoomStep; private readonly ConfigEntry<KeyboardShortcut> _zoomIn; private readonly ConfigEntry<KeyboardShortcut> _zoomOut; private readonly ConfigEntry<KeyboardShortcut> _resetZoom; private readonly ConfigEntry<bool> _showZoomNotification; private readonly ConfigEntry<float> _currentZoom; private bool _handlingSettingChange; private bool _validationPending; private bool _shortcutWarningPending; private bool _savePending; private bool _disposed; internal bool Enabled => _enabled.Value; internal float DefaultZoom => _defaultZoom.Value; internal float MinimumZoom => _minimumZoom.Value; internal float MaximumZoom => _maximumZoom.Value; internal float ZoomStep => _zoomStep.Value; internal KeyboardShortcut ZoomIn => _zoomIn.Value; internal KeyboardShortcut ZoomOut => _zoomOut.Value; internal KeyboardShortcut ResetZoom => _resetZoom.Value; internal bool ShowZoomNotification => _showZoomNotification.Value; internal float CurrentZoom => _currentZoom.Value; internal ModConfig(ConfigFile configFile, ManualLogSource logger) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) _configFile = configFile ?? throw new ArgumentNullException("configFile"); _logger = logger ?? throw new ArgumentNullException("logger"); _configFile.SaveOnConfigSet = false; _enabled = _configFile.Bind<bool>("General", "Enabled", true, "Enable local ship-radar zoom controls."); _defaultZoom = _configFile.Bind<float>("Radar", "DefaultZoom", 25f, "orthographicSize restored by the reset shortcut. Smaller values appear closer; larger values show more area."); _minimumZoom = _configFile.Bind<float>("Radar", "MinimumZoom", 10f, "Smallest allowed radar-camera orthographicSize."); _maximumZoom = _configFile.Bind<float>("Radar", "MaximumZoom", 60f, "Largest allowed radar-camera orthographicSize."); _zoomStep = _configFile.Bind<float>("Radar", "ZoomStep", 2f, "Amount added or subtracted for each shortcut press."); _zoomIn = _configFile.Bind<KeyboardShortcut>("Keybinds", "ZoomIn", new KeyboardShortcut((KeyCode)61, Array.Empty<KeyCode>()), "Decrease orthographicSize so the radar appears closer."); _zoomOut = _configFile.Bind<KeyboardShortcut>("Keybinds", "ZoomOut", new KeyboardShortcut((KeyCode)45, Array.Empty<KeyCode>()), "Increase orthographicSize so the radar shows a wider area."); _resetZoom = _configFile.Bind<KeyboardShortcut>("Keybinds", "ResetZoom", new KeyboardShortcut((KeyCode)8, Array.Empty<KeyCode>()), "Restore Radar.DefaultZoom."); _showZoomNotification = _configFile.Bind<bool>("Display", "ShowZoomNotification", true, "Show a short notification drawn only on this client after a zoom shortcut is used."); _currentZoom = _configFile.Bind<float>("State", "CurrentZoom", 25f, "Last user-selected zoom. This value is maintained by the plugin and restored on the next launch."); ValidateAndSave(); WarnAboutShortcutCollisions(); SubscribeToSettingChanges(); } internal float ClampZoom(float value) { if (!IsFinite(value)) { value = DefaultZoom; } return Mathf.Clamp(value, MinimumZoom, MaximumZoom); } internal void SetCurrentZoom(float value) { float num = ClampZoom(value); if (!Approximately(_currentZoom.Value, num)) { _handlingSettingChange = true; try { _currentZoom.Value = num; } finally { _handlingSettingChange = false; } TrySave("current radar zoom"); } } internal bool ProcessPendingChanges() { if (_disposed || _handlingSettingChange) { return false; } bool validationPending = _validationPending; bool shortcutWarningPending = _shortcutWarningPending; bool savePending = _savePending; if (!validationPending && !shortcutWarningPending && !savePending) { return false; } _validationPending = false; _shortcutWarningPending = false; _savePending = false; _handlingSettingChange = true; bool flag = false; try { if (validationPending) { ValidateAndSave(); flag = true; } else if (savePending) { TrySave("configuration change"); } if (shortcutWarningPending) { WarnAboutShortcutCollisions(); } } catch (Exception arg) { _logger.LogError((object)$"Could not process a runtime configuration change safely: {arg}"); } finally { _handlingSettingChange = false; } return validationPending && flag; } public void Dispose() { if (!_disposed) { _disposed = true; _enabled.SettingChanged -= OnSimpleSettingChanged; _showZoomNotification.SettingChanged -= OnSimpleSettingChanged; _defaultZoom.SettingChanged -= OnValidatedSettingChanged; _minimumZoom.SettingChanged -= OnValidatedSettingChanged; _maximumZoom.SettingChanged -= OnValidatedSettingChanged; _zoomStep.SettingChanged -= OnValidatedSettingChanged; _currentZoom.SettingChanged -= OnValidatedSettingChanged; _zoomIn.SettingChanged -= OnShortcutSettingChanged; _zoomOut.SettingChanged -= OnShortcutSettingChanged; _resetZoom.SettingChanged -= OnShortcutSettingChanged; } } private void SubscribeToSettingChanges() { _enabled.SettingChanged += OnSimpleSettingChanged; _showZoomNotification.SettingChanged += OnSimpleSettingChanged; _defaultZoom.SettingChanged += OnValidatedSettingChanged; _minimumZoom.SettingChanged += OnValidatedSettingChanged; _maximumZoom.SettingChanged += OnValidatedSettingChanged; _zoomStep.SettingChanged += OnValidatedSettingChanged; _currentZoom.SettingChanged += OnValidatedSettingChanged; _zoomIn.SettingChanged += OnShortcutSettingChanged; _zoomOut.SettingChanged += OnShortcutSettingChanged; _resetZoom.SettingChanged += OnShortcutSettingChanged; } private void OnSimpleSettingChanged(object sender, EventArgs eventArgs) { if (!_disposed && !_handlingSettingChange) { _savePending = true; } } private void OnValidatedSettingChanged(object sender, EventArgs eventArgs) { if (!_disposed && !_handlingSettingChange) { _validationPending = true; _savePending = true; } } private void OnShortcutSettingChanged(object sender, EventArgs eventArgs) { if (!_disposed && !_handlingSettingChange) { _shortcutWarningPending = true; _savePending = true; } } private void ValidateAndSave() { float num = _minimumZoom.Value; if (!IsFinite(num) || num <= 0f) { WarnCorrection("Radar.MinimumZoom", num, 10f); num = 10f; } float num2 = _maximumZoom.Value; if (!IsFinite(num2) || num2 <= 0f) { WarnCorrection("Radar.MaximumZoom", num2, 60f); num2 = 60f; } if (num > num2) { _logger.LogWarning((object)$"Radar.MinimumZoom ({num}) was greater than Radar.MaximumZoom ({num2}); the values were swapped."); float num3 = num; num = num2; num2 = num3; } _minimumZoom.Value = num; _maximumZoom.Value = num2; float num4 = _defaultZoom.Value; if (!IsFinite(num4) || num4 <= 0f) { WarnCorrection("Radar.DefaultZoom", num4, 25f); num4 = 25f; } float num5 = Mathf.Clamp(num4, num, num2); if (!Approximately(num4, num5)) { WarnCorrection("Radar.DefaultZoom", num4, num5); } _defaultZoom.Value = num5; float num6 = _zoomStep.Value; if (!IsFinite(num6) || num6 <= 0f) { WarnCorrection("Radar.ZoomStep", num6, 2f); num6 = 2f; } _zoomStep.Value = num6; float num7 = _currentZoom.Value; if (!IsFinite(num7) || num7 <= 0f) { WarnCorrection("State.CurrentZoom", num7, num5); num7 = num5; } float num8 = Mathf.Clamp(num7, num, num2); if (!Approximately(num7, num8)) { WarnCorrection("State.CurrentZoom", num7, num8); } _currentZoom.Value = num8; TrySave("validated configuration"); } private void WarnAboutShortcutCollisions() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (((object)_resetZoom.Value/*cast due to .constrained prefix*/).Equals((object?)_zoomIn.Value)) { _logger.LogWarning((object)"Keybinds.ResetZoom and Keybinds.ZoomIn are identical. ResetZoom takes precedence."); } if (((object)_resetZoom.Value/*cast due to .constrained prefix*/).Equals((object?)_zoomOut.Value)) { _logger.LogWarning((object)"Keybinds.ResetZoom and Keybinds.ZoomOut are identical. ResetZoom takes precedence."); } if (((object)_zoomIn.Value/*cast due to .constrained prefix*/).Equals((object?)_zoomOut.Value)) { _logger.LogWarning((object)"Keybinds.ZoomIn and Keybinds.ZoomOut are identical. ZoomIn takes precedence."); } } private void WarnCorrection(string setting, float previous, float corrected) { _logger.LogWarning((object)$"Invalid {setting} value '{previous}' was corrected to '{corrected}'."); } private void TrySave(string reason) { try { _configFile.Save(); } catch (Exception arg) { _logger.LogError((object)$"Could not save {reason} to '{_configFile.ConfigFilePath}': {arg}"); } } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool Approximately(float left, float right) { return Math.Abs(left - right) <= 0.0001f; } } }