using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
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("ClassLibrary3")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClassLibrary3")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("22af9b72-d029-4805-9d13-0642bb61fc6f")]
[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("local.scp3166.rpcinit", "SCP3166 RPC Init Helper", "1.0.2")]
public class SCP3166RpcInitHelper : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <InitRoutine>d__3 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public SCP3166RpcInitHelper <>4__this;
private int <i>5__1;
private Assembly <asm>5__2;
private int <patched>5__3;
private int <invoked>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <InitRoutine>d__3(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<asm>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<i>5__1 = 0;
break;
case 1:
<>1__state = -1;
<asm>5__2 = null;
<i>5__1++;
break;
}
if (<i>5__1 < 600)
{
<asm>5__2 = <>4__this.FindScp3166Assembly();
if (<asm>5__2 != null)
{
<patched>5__3 = <>4__this.PatchInitializeRpcsMethods(<asm>5__2);
<>4__this.PatchInitializeNetworkBehavioursFinalizer(<asm>5__2);
<invoked>5__4 = <>4__this.InvokeInitializeRpcsOnce(<asm>5__2);
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"SCP3166 RPC helper: patched {<patched>5__3} InitializeRPCS methods; invoked {<invoked>5__4} InitializeRPCS methods.");
return false;
}
<>2__current = null;
<>1__state = 1;
return true;
}
((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)"SCP3166 RPC helper: SCP3166 assembly not found in time; did nothing.");
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 Harmony _harmony;
private static readonly HashSet<MethodBase> _initRpcsAlreadyRan = new HashSet<MethodBase>();
private void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
_harmony = new Harmony("local.scp3166.rpcinit");
((MonoBehaviour)this).StartCoroutine(InitRoutine());
}
[IteratorStateMachine(typeof(<InitRoutine>d__3))]
private IEnumerator InitRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InitRoutine>d__3(0)
{
<>4__this = this
};
}
private Assembly FindScp3166Assembly()
{
return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(delegate(Assembly a)
{
string text = a.GetName().Name ?? "";
return string.Equals(text, "ProjectSCP.SCP3166", StringComparison.OrdinalIgnoreCase) || text.IndexOf("SCP3166", StringComparison.OrdinalIgnoreCase) >= 0;
});
}
private int PatchInitializeRpcsMethods(Assembly asm)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
int num = 0;
foreach (Type item in SafeGetTypes(asm))
{
MethodInfo[] methods = item.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name.StartsWith("InitializeRPCS", StringComparison.OrdinalIgnoreCase))
{
HarmonyMethod val = new HarmonyMethod(typeof(SCP3166RpcInitHelper).GetMethod("InitializeRpcsPrefix", BindingFlags.Static | BindingFlags.NonPublic));
_harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
}
}
return num;
}
private void PatchInitializeNetworkBehavioursFinalizer(Assembly asm)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
Type type = asm.GetType("SCP3166.Plugin");
if (!(type == null))
{
MethodInfo method = type.GetMethod("InitializeNetworkBehaviours", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(method == null))
{
HarmonyMethod val = new HarmonyMethod(typeof(SCP3166RpcInitHelper).GetMethod("InitNetBehavioursFinalizer", BindingFlags.Static | BindingFlags.NonPublic));
_harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null);
}
}
}
private int InvokeInitializeRpcsOnce(Assembly asm)
{
int num = 0;
foreach (Type item in SafeGetTypes(asm))
{
MethodInfo[] methods = item.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!methodInfo.Name.StartsWith("InitializeRPCS", StringComparison.OrdinalIgnoreCase))
{
continue;
}
try
{
_initRpcsAlreadyRan.Add(methodInfo);
methodInfo.Invoke(null, null);
num++;
}
catch (TargetInvocationException ex)
{
if (IsDuplicateKeyException(ex.InnerException))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Duplicate key ignored in " + item.FullName + "." + methodInfo.Name));
num++;
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Invoke failed: {item.FullName}.{methodInfo.Name} -> {ex}");
}
}
catch (Exception ex2)
{
if (IsDuplicateKeyException(ex2))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Duplicate key ignored in " + item.FullName + "." + methodInfo.Name));
num++;
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Invoke failed: {item.FullName}.{methodInfo.Name} -> {ex2}");
}
}
}
}
return num;
}
private static bool InitializeRpcsPrefix(MethodBase __originalMethod)
{
if (__originalMethod == null)
{
return true;
}
if (_initRpcsAlreadyRan.Contains(__originalMethod))
{
return false;
}
_initRpcsAlreadyRan.Add(__originalMethod);
return true;
}
private static Exception InitNetBehavioursFinalizer(Exception __exception)
{
if (IsDuplicateKeyException(__exception))
{
return null;
}
if (__exception is TargetInvocationException ex && IsDuplicateKeyException(ex.InnerException))
{
return null;
}
return __exception;
}
private static bool IsDuplicateKeyException(Exception ex)
{
if (ex == null)
{
return false;
}
if (ex is ArgumentException ex2 && ex2.Message != null)
{
string text = ex2.Message.ToLowerInvariant();
if (text.Contains("same key") || text.Contains("already been added") || text.Contains("одинаков") || text.Contains("уже добав"))
{
return true;
}
}
return false;
}
private static IEnumerable<Type> SafeGetTypes(Assembly asm)
{
try
{
return asm.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
return ex.Types.Where((Type x) => x != null);
}
catch
{
return Array.Empty<Type>();
}
}
}