using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using LethalConfig;
using LethalConfig.ConfigItems;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RenameEnemy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RenameEnemy")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b76ec941-fdb2-4cca-a6a4-b9c22de27df9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.sidgdev.ScanNameConfig", "ScanNameConfig", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ScanNameConfig : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <WaitAndReplaceScanTexts>d__18 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public ScanNameConfig <>4__this;
private int <newCreatures>5__1;
private MonoBehaviour[] <>s__2;
private int <>s__3;
private MonoBehaviour <scanNode>5__4;
private FieldInfo <headerField>5__5;
private FieldInfo <subField>5__6;
private FieldInfo <idField>5__7;
private string <currentHeader>5__8;
private string <currentSub>5__9;
private int <id>5__10;
private string <sanitizedName>5__11;
private bool <isNewCreature>5__12;
private (ConfigEntry<string> header, ConfigEntry<string> sub) <configEntry>5__13;
private string <newHeader>5__14;
private string <newSub>5__15;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitAndReplaceScanTexts>d__18(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>s__2 = null;
<scanNode>5__4 = null;
<headerField>5__5 = null;
<subField>5__6 = null;
<idField>5__7 = null;
<currentHeader>5__8 = null;
<currentSub>5__9 = null;
<sanitizedName>5__11 = null;
<configEntry>5__13 = default((ConfigEntry<string>, ConfigEntry<string>));
<newHeader>5__14 = null;
<newSub>5__15 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<newCreatures>5__1 = 0;
<>s__2 = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++)
{
<scanNode>5__4 = <>s__2[<>s__3];
<headerField>5__5 = ((object)<scanNode>5__4).GetType().GetField("headerText");
<subField>5__6 = ((object)<scanNode>5__4).GetType().GetField("subText");
<idField>5__7 = ((object)<scanNode>5__4).GetType().GetField("creatureScanID");
if (<headerField>5__5 != null && <subField>5__6 != null && <idField>5__7 != null)
{
<currentHeader>5__8 = (string)<headerField>5__5.GetValue(<scanNode>5__4);
<currentSub>5__9 = (string)<subField>5__6.GetValue(<scanNode>5__4);
<id>5__10 = (int)<idField>5__7.GetValue(<scanNode>5__4);
if (string.IsNullOrEmpty(<currentHeader>5__8) || !<>4__this.IsCreatureScanNode(<id>5__10, <currentHeader>5__8, <scanNode>5__4))
{
continue;
}
<sanitizedName>5__11 = <>4__this.SanitizeConfigKey(<currentHeader>5__8);
<isNewCreature>5__12 = !<>4__this.configEntries.ContainsKey(<sanitizedName>5__11);
<configEntry>5__13 = <>4__this.GetOrCreateConfigEntry(<currentHeader>5__8, <id>5__10, <currentHeader>5__8, <currentSub>5__9, <isNewCreature>5__12);
if (<isNewCreature>5__12)
{
<newCreatures>5__1++;
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Late-registered modded creature: " + <currentHeader>5__8));
}
<newHeader>5__14 = <configEntry>5__13.header.Value;
<newSub>5__15 = <configEntry>5__13.sub.Value;
if (<newHeader>5__14 != <currentHeader>5__8 || <newSub>5__15 != <currentSub>5__9)
{
<headerField>5__5.SetValue(<scanNode>5__4, <newHeader>5__14);
<subField>5__6.SetValue(<scanNode>5__4, <newSub>5__15);
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Renamed '" + <currentHeader>5__8 + "' → '" + <newHeader>5__14 + "' (" + <newSub>5__15 + ")"));
}
<currentHeader>5__8 = null;
<currentSub>5__9 = null;
<sanitizedName>5__11 = null;
<configEntry>5__13 = default((ConfigEntry<string>, ConfigEntry<string>));
<newHeader>5__14 = null;
<newSub>5__15 = null;
}
<headerField>5__5 = null;
<subField>5__6 = null;
<idField>5__7 = null;
<scanNode>5__4 = null;
}
<>s__2 = null;
((BaseUnityPlugin)<>4__this).Config.Save();
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"Applied renames for {<>4__this.configEntries.Count} creatures. ({<newCreatures>5__1} late-registered)");
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private Dictionary<string, (ConfigEntry<string> header, ConfigEntry<string> sub)> configEntries = new Dictionary<string, (ConfigEntry<string>, ConfigEntry<string>)>();
private Dictionary<string, (string header, string sub)> existingUserValues = new Dictionary<string, (string, string)>();
private readonly Dictionary<string, (string header, string sub)> defaultOverrides = new Dictionary<string, (string, string)>();
private readonly HashSet<string> knownCreatureHeaders = new HashSet<string>();
private readonly HashSet<int> baseGameCreatureIds = new HashSet<int>
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25
};
private readonly HashSet<string> baseGameCreatureNames = new HashSet<string>
{
"Bracken", "Bunker Spider", "Coil-Head", "Earth Leviathan", "Eyeless Dog", "Forest Keeper", "Ghost Girl", "Hoarding Bug", "Hygrodere", "Jester",
"Masked", "Nutcracker", "Snare Flea", "Spore Lizard", "Thumper", "Baboon Hawk", "Manticoil", "Circuit Bee", "Roaming Locust", "Tulip Snake",
"Old Bird", "Butler", "Barber", "Maneater", "Kidnapper Fox", "Giant Sapsucker", "Sapsucker"
};
private readonly HashSet<string> excludedScanNodes = new HashSet<string>
{
"Turret", "Landmine", "Spike Trap", "Steam Valve", "Big Door", "Door", "Entrance", "Exit", "Ship", "Terminal",
"Charging Station", "Teleporter", "Inverse Teleporter", "Loud Horn", "Storage Cabinet", "Cupboard"
};
private static bool LethalConfigEnabled => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
public void Awake()
{
LoadExistingConfigValues();
RegisterAllCreatures();
((MonoBehaviour)this).StartCoroutine(WaitAndReplaceScanTexts());
((BaseUnityPlugin)this).Logger.LogInfo((object)"ScanNameConfig loaded. LethalConfig will auto-detect config entries.");
}
private void RegisterAllCreatures()
{
foreach (string baseGameCreatureName in baseGameCreatureNames)
{
GetOrCreateConfigEntry(baseGameCreatureName, 0, baseGameCreatureName, "");
}
MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
foreach (MonoBehaviour val in array)
{
FieldInfo field = ((object)val).GetType().GetField("headerText");
FieldInfo field2 = ((object)val).GetType().GetField("subText");
FieldInfo field3 = ((object)val).GetType().GetField("creatureScanID");
if (field != null && field2 != null && field3 != null)
{
string text = (string)field.GetValue(val);
string defaultSub = (string)field2.GetValue(val);
int num = (int)field3.GetValue(val);
if (!string.IsNullOrEmpty(text) && IsCreatureScanNode(num, text, val))
{
GetOrCreateConfigEntry(text, num, text, defaultSub);
}
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered {configEntries.Count} creature config entries.");
}
private void LoadExistingConfigValues()
{
string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
if (!File.Exists(configFilePath))
{
return;
}
try
{
string[] array = File.ReadAllLines(configFilePath);
string[] array2 = array;
foreach (string text in array2)
{
string text2 = text.Trim();
if (text2.Contains(" Name") && text2.Contains("="))
{
int num = text2.IndexOf('=');
if (num > 0)
{
string text3 = text2.Substring(0, num).Trim();
text3 = text3.Replace(" Name", "");
string item = text2.Substring(num + 1).Trim();
if (!existingUserValues.ContainsKey(text3))
{
existingUserValues[text3] = (item, "");
}
else
{
existingUserValues[text3] = (item, existingUserValues[text3].sub);
}
}
}
else
{
if (!text2.Contains(" ScanInfo") || !text2.Contains("="))
{
continue;
}
int num2 = text2.IndexOf('=');
if (num2 > 0)
{
string key = text2.Substring(0, num2).Trim().Replace(" ScanInfo", "");
string item2 = text2.Substring(num2 + 1).Trim();
if (!existingUserValues.ContainsKey(key))
{
existingUserValues[key] = ("", item2);
}
else
{
existingUserValues[key] = (existingUserValues[key].header, item2);
}
}
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded {existingUserValues.Count} existing config entries.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to load existing config values: " + ex.Message));
}
}
private string SanitizeConfigKey(string key)
{
return key.Replace("=", "").Replace("\n", "").Replace("\t", "")
.Replace("\\", "")
.Replace("\"", "")
.Replace("'", "")
.Replace("[", "")
.Replace("]", "");
}
private bool IsBaseGameCreature(int id, string header)
{
if (baseGameCreatureIds.Contains(id))
{
return true;
}
if (baseGameCreatureNames.Contains(header))
{
return true;
}
return false;
}
private string GetCategoryForCreature(int id, string header)
{
return IsBaseGameCreature(id, header) ? "Base Game Enemies" : "Modded Enemies";
}
private bool IsCreatureScanNode(int id, string header, MonoBehaviour scanNode)
{
if (excludedScanNodes.Contains(header))
{
return false;
}
FieldInfo field = ((object)scanNode).GetType().GetField("creatureFileID");
if (field != null)
{
int num = (int)field.GetValue(scanNode);
if (num >= 0)
{
return true;
}
}
if (id > 0)
{
return true;
}
if (knownCreatureHeaders.Contains(header))
{
return true;
}
FieldInfo field2 = ((object)scanNode).GetType().GetField("nodeType");
if (field2 != null)
{
int num2 = (int)field2.GetValue(scanNode);
if (num2 == 1)
{
return true;
}
}
return false;
}
private (ConfigEntry<string> header, ConfigEntry<string> sub) GetOrCreateConfigEntry(string creatureName, int creatureId, string defaultHeader = null, string defaultSub = null, bool registerWithLethalConfig = false)
{
string text = SanitizeConfigKey(creatureName);
if (configEntries.TryGetValue(text, out (ConfigEntry<string>, ConfigEntry<string>) value))
{
return value;
}
string text2 = defaultHeader ?? creatureName;
string text3 = defaultSub ?? "";
if (defaultOverrides.TryGetValue(creatureName, out (string, string) value2))
{
(text2, text3) = value2;
}
if (existingUserValues.TryGetValue(text, out (string, string) value3))
{
if (!string.IsNullOrEmpty(value3.Item1))
{
(text2, _) = value3;
}
if (!string.IsNullOrEmpty(value3.Item2))
{
text3 = value3.Item2;
}
}
string categoryForCreature = GetCategoryForCreature(creatureId, creatureName);
ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>(categoryForCreature, text + " Name", text2, "Display name for " + creatureName);
ConfigEntry<string> val2 = ((BaseUnityPlugin)this).Config.Bind<string>(categoryForCreature, text + " ScanInfo", text3, "Sub-text info for " + creatureName);
configEntries[text] = (val, val2);
if (registerWithLethalConfig && LethalConfigEnabled)
{
RegisterEntryWithLethalConfig(val);
RegisterEntryWithLethalConfig(val2);
}
return (val, val2);
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private void RegisterEntryWithLethalConfig(ConfigEntry<string> entry)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
try
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(entry, false));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogDebug((object)("Failed to register entry with LethalConfig: " + ex.Message));
}
}
[IteratorStateMachine(typeof(<WaitAndReplaceScanTexts>d__18))]
private IEnumerator WaitAndReplaceScanTexts()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitAndReplaceScanTexts>d__18(0)
{
<>4__this = this
};
}
}