using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;
[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("PersistentTerminal")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyDescription("Terminal remembers your last screen")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("PersistentTerminal")]
[assembly: AssemblyTitle("PersistentTerminal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 PersistentTerminal
{
[BepInPlugin("mrbub.persistentterminal", "PersistentTerminal", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
public static ConfigEntry<string> TerminalTheme;
public static ConfigEntry<string> CustomTextColor;
public static ConfigEntry<string> CustomBackgroundColor;
public static ConfigEntry<string> CustomScreenLightColor;
public static ConfigEntry<bool> AlwaysOnScreen;
public static ConfigEntry<bool> AlwaysOnLight;
private void Awake()
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
TerminalTheme = ((BaseUnityPlugin)this).Config.Bind<string>("Theme", "Preset", "Default", new ConfigDescription("Terminal color theme preset.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[7] { "Default", "Green", "Amber", "Blue", "Red", "Purple", "Cyan" }), Array.Empty<object>()));
CustomTextColor = ((BaseUnityPlugin)this).Config.Bind<string>("Custom Colors", "TextColor", "", "Custom text color in RGB format (0-255). Overrides the theme preset if set.\nExample: 0,255,0 for green\nLeave empty to use theme preset.");
CustomBackgroundColor = ((BaseUnityPlugin)this).Config.Bind<string>("Custom Colors", "BackgroundColor", "", "Custom background color in RGB format (0-255). Overrides the theme preset if set.\nExample: 0,20,0 for dark green\nLeave empty to use theme preset.");
CustomScreenLightColor = ((BaseUnityPlugin)this).Config.Bind<string>("Custom Colors", "ScreenLightColor", "", "Custom screen light color in RGB format (0-255). Overrides the theme preset if set.\nExample: 0,255,0 for green\nLeave empty to use theme preset.");
AlwaysOnScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "AlwaysOnScreen", false, "Keep the terminal screen always on, even when not in use.");
AlwaysOnLight = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "AlwaysOnLight", false, "Keep the terminal light always on.");
new Harmony("mrbub.persistentterminal").PatchAll();
Logger.LogInfo((object)"PersistentTerminal v1.2.0 loaded!");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "mrbub.persistentterminal";
public const string PLUGIN_NAME = "PersistentTerminal";
public const string PLUGIN_VERSION = "1.2.0";
}
}
namespace PersistentTerminal.Patches
{
[HarmonyPatch(typeof(Terminal))]
internal class TerminalPatches
{
private static TerminalNode lastNode = null;
private static string lastScreenText = "";
private static int lastTextPosition = 0;
private static int lastSaveFileNum = -1;
private static bool isRestoring = false;
private static bool hasRestoredThisSession = false;
private static bool skipSoundPlayback = false;
private static List<string> commandHistory = new List<string>();
private static int historyIndex = -1;
private static string currentInput = "";
private static string savedInput = "";
private static bool themeApplied = false;
private static Light terminalLight = null;
private static Image terminalBackground = null;
[HarmonyPatch("BeginUsingTerminal")]
[HarmonyPrefix]
private static void BeginUsingTerminalPrefix(Terminal __instance)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance == (Object)null) && !hasRestoredThisSession)
{
int saveFileNum = GameNetworkManager.Instance.saveFileNum;
if (saveFileNum != lastSaveFileNum)
{
ClearSavedState();
lastSaveFileNum = saveFileNum;
}
else if ((Object)(object)lastNode != (Object)null && !string.IsNullOrEmpty(lastScreenText))
{
isRestoring = true;
}
}
}
[HarmonyPatch("BeginUsingTerminal")]
[HarmonyPostfix]
private static void BeginUsingTerminalPostfix(Terminal __instance)
{
if (!themeApplied)
{
ApplyTheme(__instance);
themeApplied = true;
}
if (!isRestoring)
{
if (!string.IsNullOrEmpty(savedInput) && (Object)(object)__instance.screenText != (Object)null)
{
Plugin.Logger.LogInfo((object)("[INPUT] Restoring saved input: '" + savedInput + "'"));
TMP_InputField screenText = __instance.screenText;
screenText.text += savedInput;
__instance.textAdded = savedInput.Length;
__instance.currentText = __instance.screenText.text;
Plugin.Logger.LogInfo((object)$"[INPUT] Input restored, textAdded: {__instance.textAdded}");
savedInput = "";
}
return;
}
try
{
if (!((Object)(object)lastNode == (Object)null))
{
Plugin.Logger.LogInfo((object)("[RESTORE] Starting restoration of node: " + ((Object)lastNode).name));
skipSoundPlayback = true;
__instance.LoadNewNode(lastNode);
skipSoundPlayback = false;
if (lastTextPosition > 0 && (Object)(object)__instance.screenText != (Object)null)
{
__instance.textAdded = lastTextPosition;
Plugin.Logger.LogInfo((object)$"[RESTORE] Restored scroll position: {lastTextPosition}");
}
if (!string.IsNullOrEmpty(savedInput) && (Object)(object)__instance.screenText != (Object)null)
{
Plugin.Logger.LogInfo((object)("[INPUT] Restoring saved input after node restore: '" + savedInput + "'"));
TMP_InputField screenText2 = __instance.screenText;
screenText2.text += savedInput;
__instance.textAdded = savedInput.Length;
__instance.currentText = __instance.screenText.text;
Plugin.Logger.LogInfo((object)$"[INPUT] Input restored, textAdded: {__instance.textAdded}");
savedInput = "";
}
Plugin.Logger.LogInfo((object)("[RESTORE] Successfully restored to: " + ((Object)lastNode).name));
hasRestoredThisSession = true;
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)("Error restoring terminal state: " + ex.Message));
skipSoundPlayback = false;
}
finally
{
isRestoring = false;
}
}
[HarmonyPatch("LoadNewNode")]
[HarmonyPrefix]
private static bool LoadNewNodePrefix(Terminal __instance, TerminalNode node)
{
if (isRestoring && (Object)(object)node != (Object)null && ((Object)node).name == "Start")
{
return false;
}
return true;
}
[HarmonyPatch("LoadNewNode")]
[HarmonyPostfix]
private static void LoadNewNodePostfix(Terminal __instance, TerminalNode node)
{
if (!isRestoring && !skipSoundPlayback && __instance.terminalInUse && (Object)(object)node != (Object)null && (Object)(object)__instance.currentNode == (Object)(object)node)
{
lastNode = node;
if ((Object)(object)__instance.screenText != (Object)null)
{
lastScreenText = __instance.screenText.text;
lastTextPosition = __instance.textAdded;
}
}
}
[HarmonyPatch("PlayTerminalAudioServerRpc")]
[HarmonyPrefix]
private static bool PlayTerminalAudioServerRpcPrefix(int clipIndex)
{
if (skipSoundPlayback)
{
return false;
}
return true;
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void UpdatePostfix(Terminal __instance)
{
if (!__instance.terminalInUse || (Object)(object)__instance.screenText == (Object)null)
{
return;
}
Keyboard current = Keyboard.current;
if (current == null)
{
return;
}
if (((ButtonControl)current.upArrowKey).wasPressedThisFrame && commandHistory.Count > 0)
{
if (historyIndex == -1)
{
currentInput = GetCurrentInput(__instance);
Plugin.Logger.LogInfo((object)("[HISTORY] Saved current input: '" + currentInput + "'"));
}
if (historyIndex < commandHistory.Count - 1)
{
historyIndex++;
string text = commandHistory[commandHistory.Count - 1 - historyIndex];
Plugin.Logger.LogInfo((object)$"[HISTORY] Up arrow - showing command {historyIndex + 1}/{commandHistory.Count}: '{text}'");
SetCurrentInput(__instance, text);
}
else
{
Plugin.Logger.LogInfo((object)"[HISTORY] Already at oldest command");
}
}
else if (((ButtonControl)current.downArrowKey).wasPressedThisFrame && commandHistory.Count > 0)
{
if (historyIndex > 0)
{
historyIndex--;
string text2 = commandHistory[commandHistory.Count - 1 - historyIndex];
Plugin.Logger.LogInfo((object)$"[HISTORY] Down arrow - showing command {historyIndex + 1}/{commandHistory.Count}: '{text2}'");
SetCurrentInput(__instance, text2);
}
else if (historyIndex == 0)
{
Plugin.Logger.LogInfo((object)("[HISTORY] Down arrow - restoring current input: '" + currentInput + "'"));
historyIndex = -1;
SetCurrentInput(__instance, currentInput);
}
else
{
Plugin.Logger.LogInfo((object)"[HISTORY] Already at newest input");
}
}
}
[HarmonyPatch("OnSubmit")]
[HarmonyPrefix]
private static void OnSubmitPrefix(Terminal __instance)
{
if ((Object)(object)__instance.screenText == (Object)null || __instance.textAdded <= 0)
{
return;
}
string text = GetCurrentInput(__instance);
if (!string.IsNullOrWhiteSpace(text))
{
if (commandHistory.Count == 0 || commandHistory[commandHistory.Count - 1] != text)
{
commandHistory.Add(text);
Plugin.Logger.LogInfo((object)$"[HISTORY] Added command to history: '{text}' (total: {commandHistory.Count})");
if (commandHistory.Count > 50)
{
string text2 = commandHistory[0];
commandHistory.RemoveAt(0);
Plugin.Logger.LogInfo((object)("[HISTORY] Removed oldest command: '" + text2 + "'"));
}
}
else
{
Plugin.Logger.LogInfo((object)("[HISTORY] Skipped duplicate command: '" + text + "'"));
}
}
historyIndex = -1;
currentInput = "";
}
private static string GetCurrentInput(Terminal terminal)
{
if ((Object)(object)terminal.screenText == (Object)null || terminal.textAdded <= 0)
{
return "";
}
int num = terminal.screenText.text.Length - terminal.textAdded;
if (num < 0 || num >= terminal.screenText.text.Length)
{
return "";
}
return terminal.screenText.text.Substring(num);
}
private static void SetCurrentInput(Terminal terminal, string input)
{
if (!((Object)(object)terminal.screenText == (Object)null))
{
if (terminal.textAdded > 0)
{
terminal.screenText.text = terminal.screenText.text.Substring(0, terminal.screenText.text.Length - terminal.textAdded);
}
TMP_InputField screenText = terminal.screenText;
screenText.text += input;
terminal.textAdded = input.Length;
terminal.currentText = terminal.screenText.text;
}
}
[HarmonyPatch("QuitTerminal")]
[HarmonyPrefix]
private static void QuitTerminalPrefix(Terminal __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.currentNode == (Object)null)
{
return;
}
try
{
lastNode = __instance.currentNode;
if ((Object)(object)__instance.screenText != (Object)null)
{
lastScreenText = __instance.screenText.text;
lastTextPosition = __instance.textAdded;
savedInput = GetCurrentInput(__instance);
if (!string.IsNullOrEmpty(savedInput))
{
Plugin.Logger.LogInfo((object)("[INPUT] Saved player input: '" + savedInput + "'"));
}
}
if ((Object)(object)GameNetworkManager.Instance != (Object)null)
{
lastSaveFileNum = GameNetworkManager.Instance.saveFileNum;
}
Plugin.Logger.LogInfo((object)$"[HISTORY] Command history size: {commandHistory.Count}");
hasRestoredThisSession = false;
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)("Error saving terminal state: " + ex.Message));
}
}
[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
[HarmonyPostfix]
private static void ResetShipPostfix()
{
ClearSavedState();
}
[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
[HarmonyPostfix]
private static void EndOfGamePostfix()
{
ClearSavedState();
}
[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
[HarmonyPostfix]
private static void DisconnectPostfix()
{
Plugin.Logger.LogInfo((object)"[STATE] Disconnected - clearing terminal state");
ClearSavedState();
}
private static void ClearSavedState()
{
Plugin.Logger.LogInfo((object)"[STATE] Clearing all saved state");
lastNode = null;
lastScreenText = "";
lastTextPosition = 0;
isRestoring = false;
hasRestoredThisSession = false;
skipSoundPlayback = false;
commandHistory.Clear();
historyIndex = -1;
currentInput = "";
savedInput = "";
themeApplied = false;
Plugin.Logger.LogInfo((object)"[STATE] State cleared");
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void StartPostfix(Terminal __instance)
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
//IL_030b: Unknown result type (might be due to invalid IL or missing references)
//IL_031f: Unknown result type (might be due to invalid IL or missing references)
//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
//IL_040a: Unknown result type (might be due to invalid IL or missing references)
//IL_041e: Unknown result type (might be due to invalid IL or missing references)
Plugin.Logger.LogInfo((object)"[INIT] ========== Terminal.Start - Full Object Discovery ==========");
Plugin.Logger.LogInfo((object)("[INIT] Terminal GameObject: " + ((Object)((Component)__instance).gameObject).name));
Plugin.Logger.LogInfo((object)("[INIT] Terminal transform: " + ((Object)((Component)__instance).transform).name));
if ((Object)(object)__instance.terminalLight != (Object)null)
{
terminalLight = __instance.terminalLight;
Plugin.Logger.LogInfo((object)$"[INIT] terminalLight: {((Object)((Component)__instance.terminalLight).gameObject).name} (enabled: {((Behaviour)__instance.terminalLight).enabled})");
Plugin.Logger.LogInfo((object)$"[INIT] terminalLight color: R:{__instance.terminalLight.color.r} G:{__instance.terminalLight.color.g} B:{__instance.terminalLight.color.b}");
if (Plugin.AlwaysOnLight.Value)
{
((Behaviour)terminalLight).enabled = true;
Plugin.Logger.LogInfo((object)"[ALWAYS-ON] Terminal light enabled");
}
}
else
{
Plugin.Logger.LogWarning((object)"[INIT] terminalLight is null");
}
if ((Object)(object)__instance.terminalUIScreen != (Object)null)
{
Plugin.Logger.LogInfo((object)("[INIT] terminalUIScreen: " + ((Object)__instance.terminalUIScreen).name));
LogGameObjectHierarchy(((Component)__instance.terminalUIScreen).gameObject, 0, 3);
}
else
{
Plugin.Logger.LogWarning((object)"[INIT] terminalUIScreen is null");
}
if ((Object)(object)__instance.screenText != (Object)null)
{
Plugin.Logger.LogInfo((object)("[INIT] screenText GameObject: " + ((Object)((Component)__instance.screenText).gameObject).name));
if ((Object)(object)__instance.screenText.textComponent != (Object)null)
{
Plugin.Logger.LogInfo((object)("[INIT] screenText.textComponent: " + ((object)__instance.screenText.textComponent).GetType().Name));
Plugin.Logger.LogInfo((object)$"[INIT] screenText color: R:{((Graphic)__instance.screenText.textComponent).color.r} G:{((Graphic)__instance.screenText.textComponent).color.g} B:{((Graphic)__instance.screenText.textComponent).color.b}");
}
}
else
{
Plugin.Logger.LogWarning((object)"[INIT] screenText is null");
}
Plugin.Logger.LogInfo((object)"[INIT] === Terminal GameObject Children ===");
LogGameObjectHierarchy(((Component)__instance).gameObject, 0, 3);
Plugin.Logger.LogInfo((object)"[INIT] === Searching for UI Image components ===");
Image[] componentsInChildren = ((Component)__instance.terminalUIScreen).GetComponentsInChildren<Image>(true);
Plugin.Logger.LogInfo((object)$"[INIT] Found {componentsInChildren.Length} Image components in Canvas");
Image[] array = componentsInChildren;
foreach (Image val in array)
{
Plugin.Logger.LogInfo((object)$"[INIT] Image: {((Object)((Component)val).gameObject).name} - Color: R:{((Graphic)val).color.r:F2} G:{((Graphic)val).color.g:F2} B:{((Graphic)val).color.b:F2} A:{((Graphic)val).color.a:F2}");
if (((Object)((Component)val).gameObject).name == "MainContainer" && (Object)(object)terminalBackground == (Object)null)
{
terminalBackground = val;
Plugin.Logger.LogInfo((object)"[INIT] *** Cached MainContainer as terminal background ***");
}
}
Plugin.Logger.LogInfo((object)"[INIT] === Searching for Light components ===");
Light[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<Light>(true);
Plugin.Logger.LogInfo((object)$"[INIT] Found {componentsInChildren2.Length} Light components in Terminal");
Light[] array2 = componentsInChildren2;
foreach (Light val2 in array2)
{
Plugin.Logger.LogInfo((object)$"[INIT] Light: {((Object)((Component)val2).gameObject).name} - Type: {val2.type} - Color: R:{val2.color.r:F2} G:{val2.color.g:F2} B:{val2.color.b:F2} - Enabled: {((Behaviour)val2).enabled}");
}
Plugin.Logger.LogInfo((object)"[INIT] ========== End Terminal Object Discovery ==========");
if (Plugin.AlwaysOnScreen.Value)
{
Plugin.Logger.LogInfo((object)"[INIT] Always-on enabled, applying theme immediately");
ApplyTheme(__instance);
themeApplied = true;
}
if (Plugin.AlwaysOnScreen.Value && (Object)(object)__instance.terminalNodes != (Object)null && __instance.terminalNodes.specialNodes != null && __instance.terminalNodes.specialNodes.Count > 1)
{
Plugin.Logger.LogInfo((object)"[ALWAYS-ON] Loading store node for always-on screen");
__instance.LoadNewNode(__instance.terminalNodes.specialNodes[1]);
}
}
private static void LogGameObjectHierarchy(GameObject obj, int depth, int maxDepth)
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)obj == (Object)null || depth > maxDepth)
{
return;
}
string text = new string(' ', depth * 2);
Plugin.Logger.LogInfo((object)("[HIERARCHY] " + text + "└─ " + ((Object)obj).name));
Component[] components = obj.GetComponents<Component>();
foreach (Component val in components)
{
if ((Object)(object)val != (Object)null && !(val is Transform))
{
Plugin.Logger.LogInfo((object)("[HIERARCHY] " + text + " ├─ Component: " + ((object)val).GetType().Name));
}
}
foreach (Transform item in obj.transform)
{
LogGameObjectHierarchy(((Component)item).gameObject, depth + 1, maxDepth);
}
}
[HarmonyPatch("waitUntilFrameEndToSetActive")]
[HarmonyPrefix]
private static void WaitUntilFrameEndToSetActivePrefix(Terminal __instance, ref bool active)
{
if (Plugin.AlwaysOnScreen.Value)
{
Plugin.Logger.LogInfo((object)$"[ALWAYS-ON] Forcing terminal canvas to stay active (was: {active})");
active = true;
}
}
[HarmonyPatch("SetTerminalInUseClientRpc")]
[HarmonyPostfix]
private static void SetTerminalInUseClientRpcPostfix(Terminal __instance, bool inUse)
{
if (Plugin.AlwaysOnLight.Value && (Object)(object)terminalLight != (Object)null)
{
((Behaviour)terminalLight).enabled = true;
Plugin.Logger.LogInfo((object)$"[ALWAYS-ON] Terminal light kept enabled (inUse: {inUse})");
}
}
private static void ApplyTheme(Terminal terminal)
{
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
//IL_03db: Unknown result type (might be due to invalid IL or missing references)
//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0401: Unknown result type (might be due to invalid IL or missing references)
//IL_0406: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: 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)
//IL_0414: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_052f: Unknown result type (might be due to invalid IL or missing references)
//IL_053f: Unknown result type (might be due to invalid IL or missing references)
//IL_054a: Unknown result type (might be due to invalid IL or missing references)
//IL_0555: Unknown result type (might be due to invalid IL or missing references)
//IL_048b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)terminal.screenText == (Object)null || (Object)(object)terminal.screenText.textComponent == (Object)null)
{
Plugin.Logger.LogWarning((object)"[THEME] Cannot apply theme - screenText or textComponent is null");
return;
}
bool flag = !string.IsNullOrWhiteSpace(Plugin.CustomTextColor.Value);
bool flag2 = !string.IsNullOrWhiteSpace(Plugin.CustomScreenLightColor.Value);
bool flag3 = !string.IsNullOrWhiteSpace(Plugin.CustomBackgroundColor.Value);
Color val = default(Color);
Color val2 = default(Color);
Color val3 = default(Color);
if (flag || flag2 || flag3)
{
Plugin.Logger.LogInfo((object)"[THEME] Using custom colors (overriding theme)");
val = (Color)(flag ? ParseCustomColor(Plugin.CustomTextColor.Value) : new Color(0f, 1f, 0f, 1f));
val2 = (Color)(flag2 ? ParseCustomColor(Plugin.CustomScreenLightColor.Value) : new Color(0f, 1f, 0f, 1f));
val3 = (Color)(flag3 ? ParseCustomColor(Plugin.CustomBackgroundColor.Value) : new Color(0f, 0.08f, 0f, 1f));
}
else
{
string text = Plugin.TerminalTheme.Value.ToLower();
switch (text)
{
case "green":
((Color)(ref val))..ctor(0f, 1f, 0f, 1f);
((Color)(ref val2))..ctor(0f, 1f, 0f, 1f);
((Color)(ref val3))..ctor(0f, 0.08f, 0f, 1f);
break;
case "amber":
((Color)(ref val))..ctor(1f, 0.75f, 0f, 1f);
((Color)(ref val2))..ctor(1f, 0.75f, 0f, 1f);
((Color)(ref val3))..ctor(0.08f, 0.06f, 0f, 1f);
break;
case "blue":
((Color)(ref val))..ctor(0.3f, 0.7f, 1f, 1f);
((Color)(ref val2))..ctor(0.3f, 0.7f, 1f, 1f);
((Color)(ref val3))..ctor(0f, 0.03f, 0.08f, 1f);
break;
case "red":
((Color)(ref val))..ctor(1f, 0.2f, 0.2f, 1f);
((Color)(ref val2))..ctor(1f, 0.2f, 0.2f, 1f);
((Color)(ref val3))..ctor(0.08f, 0f, 0f, 1f);
break;
case "purple":
((Color)(ref val))..ctor(0.8f, 0.4f, 1f, 1f);
((Color)(ref val2))..ctor(0.8f, 0.4f, 1f, 1f);
((Color)(ref val3))..ctor(0.06f, 0f, 0.08f, 1f);
break;
case "cyan":
((Color)(ref val))..ctor(0f, 1f, 1f, 1f);
((Color)(ref val2))..ctor(0f, 1f, 1f, 1f);
((Color)(ref val3))..ctor(0f, 0.08f, 0.08f, 1f);
break;
default:
Plugin.Logger.LogInfo((object)"[THEME] Using default terminal colors");
return;
}
Plugin.Logger.LogInfo((object)("[THEME] Using theme preset: " + text));
}
((Graphic)terminal.screenText.textComponent).color = val;
Plugin.Logger.LogInfo((object)$"[THEME] Applied text color: R:{val.r:F2} G:{val.g:F2} B:{val.b:F2}");
if (terminal.screenText.caretColor != val)
{
terminal.screenText.caretColor = val;
Plugin.Logger.LogInfo((object)"[THEME] Applied caret color");
}
if ((Object)(object)terminal.terminalUIScreen != (Object)null)
{
TextMeshProUGUI[] componentsInChildren = ((Component)terminal.terminalUIScreen).GetComponentsInChildren<TextMeshProUGUI>(true);
Plugin.Logger.LogInfo((object)$"[THEME] Found {componentsInChildren.Length} TextMeshProUGUI components");
TextMeshProUGUI[] array = componentsInChildren;
foreach (TextMeshProUGUI val4 in array)
{
if (!((Object)(object)val4 == (Object)(object)terminal.screenText.textComponent))
{
((Graphic)val4).color = val;
Plugin.Logger.LogInfo((object)("[THEME] Colored text component: " + ((Object)((Component)val4).gameObject).name));
}
}
}
if ((Object)(object)terminalLight != (Object)null)
{
terminalLight.color = val2;
Plugin.Logger.LogInfo((object)$"[THEME] Applied light color: R:{val2.r:F2} G:{val2.g:F2} B:{val2.b:F2}");
}
else
{
Plugin.Logger.LogInfo((object)"[THEME] No terminal light found to color");
}
if ((Object)(object)terminalBackground != (Object)null)
{
((Graphic)terminalBackground).color = val3;
Plugin.Logger.LogInfo((object)$"[THEME] Applied background color: R:{val3.r:F2} G:{val3.g:F2} B:{val3.b:F2}");
}
else
{
Plugin.Logger.LogInfo((object)"[THEME] No terminal background found to color");
}
}
private static Color ParseCustomColor(string colorString)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
try
{
string[] array = colorString.Split(',');
if (array.Length == 3)
{
float num = float.Parse(array[0].Trim()) / 255f;
float num2 = float.Parse(array[1].Trim()) / 255f;
float num3 = float.Parse(array[2].Trim()) / 255f;
return new Color(num, num2, num3, 1f);
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)("[THEME] Failed to parse custom color '" + colorString + "': " + ex.Message));
}
Plugin.Logger.LogWarning((object)"[THEME] Using default green color due to parse error");
return new Color(0f, 1f, 0f, 1f);
}
}
}