using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[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 CastleStructures.HammerCompat
{
[BepInPlugin("codex.CastleStructures.HammerCompat", "CastleStructures Hammer Compat", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <RetryInjectionRoutine>d__14 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Plugin <>4__this;
private int <i>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <RetryInjectionRoutine>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
int num = <>1__state;
Plugin plugin = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<i>5__2 = 0;
break;
case 1:
<>1__state = -1;
<i>5__2++;
break;
}
if (<i>5__2 < 60)
{
if (plugin.TryInjectPieces("Retry"))
{
return false;
}
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
}
if (!plugin._sawCastlePieces)
{
((BaseUnityPlugin)plugin).Logger.LogWarning((object)"Timed out waiting for CastleStructures pieces (rkc_*) to appear. Original CastleStructures may not be loaded.");
}
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();
}
}
public const string PluginGuid = "codex.CastleStructures.HammerCompat";
public const string PluginName = "CastleStructures Hammer Compat";
public const string PluginVersion = "1.0.0";
private const string CastlePrefix = "rkc_";
private const string CastleCategory = "Castle";
private const string BuildItTable = "_RKCustomTable";
private ConfigEntry<bool> _showInVanillaHammer;
private ConfigEntry<bool> _showInImprovedHammer;
private bool _vanillaInjected;
private bool _improvedInjected;
private bool _sawCastlePieces;
private void Awake()
{
_showInVanillaHammer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInVanillaHammer", true, "If true, inject CastleStructures pieces into vanilla Hammer. Requires restart to apply.");
_showInImprovedHammer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInImprovedHammer", true, "If true and BuildIt is installed, inject CastleStructures pieces into BuildIt's Improved Hammer (_RKCustomTable). Requires restart to apply.");
((BaseUnityPlugin)this).Config.Save();
if (!_showInVanillaHammer.Value && !_showInImprovedHammer.Value)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Both CastleStructures hammer compat toggles are disabled. Nothing will be injected.");
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"CastleStructures Hammer Compat loaded. Config changes require restart (not applied live).");
PrefabManager.OnPrefabsRegistered += TryInjectFromEvent;
((MonoBehaviour)this).StartCoroutine(RetryInjectionRoutine());
}
private void OnDestroy()
{
PrefabManager.OnPrefabsRegistered -= TryInjectFromEvent;
}
private void TryInjectFromEvent()
{
TryInjectPieces("OnPrefabsRegistered");
}
[IteratorStateMachine(typeof(<RetryInjectionRoutine>d__14))]
private IEnumerator RetryInjectionRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <RetryInjectionRoutine>d__14(0)
{
<>4__this = this
};
}
private bool TryInjectPieces(string source)
{
List<GameObject> list = FindCastlePieces();
if (list.Count == 0)
{
return false;
}
_sawCastlePieces = true;
bool flag = !_showInVanillaHammer.Value;
bool flag2 = !_showInImprovedHammer.Value;
if (_showInVanillaHammer.Value)
{
EnsureCategory("Hammer", "Castle");
PieceTable val = ResolvePieceTable("Hammer");
if ((Object)(object)val != (Object)null)
{
int num = InjectIntoTable("Hammer", val, list, "Castle", ((BaseUnityPlugin)this).Logger);
if (num > 0 || _vanillaInjected)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[{source}] CastleStructures -> Hammer injected {num} new pieces.");
}
_vanillaInjected = true;
flag = true;
}
}
if (_showInImprovedHammer.Value)
{
PieceTable val2 = ResolvePieceTable("_RKCustomTable");
if ((Object)(object)val2 != (Object)null)
{
EnsureCategory("_RKCustomTable", "Castle");
int num2 = InjectIntoTable("_RKCustomTable", val2, list, "Castle", ((BaseUnityPlugin)this).Logger);
if (num2 > 0 || _improvedInjected)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] CastleStructures -> {1} injected {2} new pieces.", source, "_RKCustomTable", num2));
}
_improvedInjected = true;
flag2 = true;
}
else if (IsBuildItLoaded())
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + source + "] BuildIt detected but _RKCustomTable not available yet. Will retry."));
}
}
if (flag && flag2)
{
PrefabManager.OnPrefabsRegistered -= TryInjectFromEvent;
return true;
}
return false;
}
private List<GameObject> FindCastlePieces()
{
List<GameObject> list = new List<GameObject>();
if ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.m_prefabs == null)
{
return list;
}
foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
{
if (!((Object)(object)prefab == (Object)null) && (((Object)prefab).name ?? string.Empty).StartsWith("rkc_", StringComparison.OrdinalIgnoreCase) && !((Object)(object)prefab.GetComponent<Piece>() == (Object)null))
{
list.Add(prefab);
}
}
return list;
}
private static int InjectIntoTable(string tableName, PieceTable table, List<GameObject> prefabs, string categoryName, ManualLogSource logger)
{
if (table.m_pieces == null)
{
table.m_pieces = new List<GameObject>();
}
int num = 0;
PieceManager instance = PieceManager.Instance;
MethodInfo[] array = ((instance != null) ? (from m in ((object)instance).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)
where m.Name == "RegisterPieceInPieceTable"
select m).ToArray() : Array.Empty<MethodInfo>());
foreach (GameObject prefab in prefabs)
{
if (!table.m_pieces.Any((GameObject p) => (Object)(object)p != (Object)null && string.Equals(((Object)p).name, ((Object)prefab).name, StringComparison.Ordinal)))
{
bool flag = false;
if (instance != null && array.Length != 0)
{
flag = TryRegisterViaPieceManager(instance, array, tableName, table, prefab, categoryName);
}
if (!flag)
{
table.m_pieces.Add(prefab);
logger.LogDebug((object)("Fallback injected piece '" + ((Object)prefab).name + "' into '" + tableName + "' by direct table list add."));
}
num++;
}
}
return num;
}
private static bool TryRegisterViaPieceManager(object pieceManager, MethodInfo[] registerMethods, string tableName, PieceTable table, GameObject prefab, string categoryName)
{
foreach (MethodInfo methodInfo in registerMethods)
{
ParameterInfo[] parameters = methodInfo.GetParameters();
object[] array = new object[parameters.Length];
bool flag = true;
for (int j = 0; j < parameters.Length; j++)
{
Type parameterType = parameters[j].ParameterType;
string text = parameters[j].Name ?? string.Empty;
if (parameterType == typeof(string))
{
if (text.IndexOf("table", StringComparison.OrdinalIgnoreCase) >= 0)
{
array[j] = tableName;
}
else if (text.IndexOf("piece", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("prefab", StringComparison.OrdinalIgnoreCase) >= 0)
{
array[j] = ((Object)prefab).name;
}
else if (text.IndexOf("categor", StringComparison.OrdinalIgnoreCase) >= 0)
{
array[j] = categoryName;
}
else
{
array[j] = categoryName;
}
}
else if (typeof(GameObject).IsAssignableFrom(parameterType))
{
array[j] = prefab;
}
else if (typeof(PieceTable).IsAssignableFrom(parameterType))
{
array[j] = table;
}
else
{
if (!(parameterType == typeof(bool)))
{
flag = false;
break;
}
array[j] = false;
}
}
if (flag)
{
try
{
methodInfo.Invoke(pieceManager, array);
return true;
}
catch
{
}
}
}
return false;
}
private PieceTable ResolvePieceTable(string tableName)
{
try
{
if (tableName == "Hammer")
{
GameObject prefab = PrefabManager.Instance.GetPrefab("Hammer");
return (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildPieces;
}
GameObject prefab2 = PrefabManager.Instance.GetPrefab(tableName);
return ((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<PieceTable>() : null;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to resolve piece table '" + tableName + "': " + ex.Message));
return null;
}
}
private void EnsureCategory(string tableName, string categoryName)
{
try
{
object instance = PieceManager.Instance;
if (instance == null)
{
return;
}
MethodInfo[] source = (from m in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)
where m.Name == "AddPieceCategory"
select m).ToArray();
MethodInfo methodInfo = source.FirstOrDefault(delegate(MethodInfo m)
{
ParameterInfo[] parameters3 = m.GetParameters();
return parameters3.Length == 2 && parameters3[0].ParameterType == typeof(string) && parameters3[1].ParameterType == typeof(string);
});
if (methodInfo != null)
{
methodInfo.Invoke(instance, new object[2] { tableName, categoryName });
((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered piece category '" + categoryName + "' for table '" + tableName + "' via AddPieceCategory(string,string)."));
return;
}
PieceTable val = ResolvePieceTable(tableName);
if ((Object)(object)val != (Object)null)
{
MethodInfo methodInfo2 = source.FirstOrDefault(delegate(MethodInfo m)
{
ParameterInfo[] parameters2 = m.GetParameters();
return parameters2.Length == 2 && typeof(PieceTable).IsAssignableFrom(parameters2[0].ParameterType) && parameters2[1].ParameterType == typeof(string);
});
if (methodInfo2 != null)
{
methodInfo2.Invoke(instance, new object[2] { val, categoryName });
((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered piece category '" + categoryName + "' for table '" + tableName + "' via AddPieceCategory(PieceTable,string)."));
return;
}
}
MethodInfo methodInfo3 = source.FirstOrDefault(delegate(MethodInfo m)
{
ParameterInfo[] parameters = m.GetParameters();
return parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
});
if (methodInfo3 != null)
{
methodInfo3.Invoke(instance, new object[1] { categoryName });
((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered global piece category '" + categoryName + "' (table-specific overload unavailable for '" + tableName + "')."));
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("No supported AddPieceCategory overload found while adding '" + categoryName + "' to '" + tableName + "'."));
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to add category '" + categoryName + "' to '" + tableName + "': " + ex.Message));
}
}
private static bool IsBuildItLoaded()
{
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
if ((pluginInfo.Key ?? string.Empty).IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
PluginInfo value = pluginInfo.Value;
if (((value != null) ? value.Metadata : null) != null)
{
string obj = pluginInfo.Value.Metadata.GUID ?? string.Empty;
string text = pluginInfo.Value.Metadata.Name ?? string.Empty;
if (obj.IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
}
return false;
}
}
}