using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
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: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SWP Team")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Lightweight receiver for SWP appearance sync - allows vanilla clients to see extended appearance values from mod users")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SWP_Receiver")]
[assembly: AssemblyTitle("SWP_Receiver")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SWPReceiver;
[BepInPlugin("com.swp.receiver", "SWP Receiver", "1.0.0")]
public class SWPReceiverPlugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(PlayerVisual), "Apply_NetworkedCharacterDisplay")]
public static class Patch_PlayerVisual_ApplyNetworkedCharacterDisplay
{
private static bool Prepare()
{
return !_mainModPresent;
}
private static void Postfix(PlayerVisual __instance)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!_mainModPresent && _initialized && !((Object)(object)__instance == (Object)null))
{
PlayerAppearanceStruct playerAppearanceStruct = __instance._playerAppearanceStruct;
int instanceID = ((Object)__instance).GetInstanceID();
int frameCount = Time.frameCount;
if (!_lastAppliedFrame.TryGetValue(instanceID, out var value) || frameCount - value >= 5)
{
_lastAppliedFrame[instanceID] = frameCount;
TryPurgeOldEntries(frameCount);
ApplyExtendedValues(__instance, playerAppearanceStruct);
}
}
}
catch (Exception ex)
{
LogDebug("Patch Postfix error: " + ex.Message);
}
}
}
[HarmonyPatch(typeof(PlayerVisual), "OnAppearanceStructChange")]
public static class Patch_PlayerVisual_OnAppearanceStructChange
{
private static int _lastRebuildFrame = -999999;
private const int REBUILD_DEBOUNCE_FRAMES = 30;
private static bool Prepare()
{
return !_mainModPresent;
}
private static void Postfix(PlayerVisual __instance, PlayerAppearanceStruct _old, PlayerAppearanceStruct _new)
{
//IL_0031: 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)
try
{
if (_mainModPresent || !_initialized || (Object)(object)__instance == (Object)null)
{
return;
}
string text = _old._setRaceTag ?? "";
string text2 = _new._setRaceTag ?? "";
if (string.IsNullOrEmpty(text2) || string.Equals(text, text2, StringComparison.OrdinalIgnoreCase))
{
return;
}
string raceName = "";
try
{
if ((Object)(object)__instance._playerRaceModel != (Object)null && (Object)(object)__instance._playerRaceModel._scriptablePlayerRace != (Object)null)
{
raceName = __instance._playerRaceModel._scriptablePlayerRace._raceName ?? "";
}
}
catch
{
raceName = "";
}
string text3 = NormalizeRaceName(text2);
string b = NormalizeRaceName(raceName);
if (!string.Equals(text3, b, StringComparison.OrdinalIgnoreCase))
{
int frameCount = Time.frameCount;
if (frameCount - _lastRebuildFrame >= 30)
{
_lastRebuildFrame = frameCount;
LogInfo("Cross-race change detected: '" + text + "' -> '" + text2 + "', triggering rebuild");
ForceRaceRebuild(__instance, text3);
}
}
}
catch (Exception ex)
{
LogDebug("OnAppearanceStructChange error: " + ex.Message);
}
}
}
[CompilerGenerated]
private sealed class <ForceRaceRebuildRoutine>d__23 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public PlayerVisual pv;
public string targetRaceTag;
private GameObject <rmo>5__1;
private IEnumerator <createRoutine>5__2;
private MethodInfo <method>5__3;
private Coroutine <co>5__4;
private RaceModelEquipDisplay <ed>5__5;
private PlayerAppearanceStruct <s>5__6;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ForceRaceRebuildRoutine>d__23(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
<rmo>5__1 = null;
<createRoutine>5__2 = null;
<method>5__3 = null;
<co>5__4 = null;
<ed>5__5 = null;
<s>5__6 = default(PlayerAppearanceStruct);
<>1__state = -2;
}
private bool MoveNext()
{
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if ((Object)(object)pv == (Object)null)
{
return false;
}
LogDebug("ForceRaceRebuildRoutine started for race '" + targetRaceTag + "'");
<rmo>5__1 = null;
try
{
<rmo>5__1 = pv._raceModelObject;
}
catch
{
<rmo>5__1 = null;
}
if ((Object)(object)<rmo>5__1 != (Object)null)
{
try
{
Object.Destroy((Object)(object)<rmo>5__1);
}
catch
{
}
LogDebug("Destroyed old _raceModelObject");
}
try
{
pv._playerRaceModel = null;
}
catch
{
}
try
{
pv._raceModelObject = null;
}
catch
{
}
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<createRoutine>5__2 = null;
try
{
<method>5__3 = typeof(PlayerVisual).GetMethod("Create_PlayerRaceModel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (<method>5__3 != null)
{
<createRoutine>5__2 = <method>5__3.Invoke(pv, null) as IEnumerator;
}
<method>5__3 = null;
}
catch
{
<createRoutine>5__2 = null;
}
if (<createRoutine>5__2 != null)
{
LogDebug("Starting Create_PlayerRaceModel coroutine");
<co>5__4 = null;
try
{
<co>5__4 = ((MonoBehaviour)pv).StartCoroutine(<createRoutine>5__2);
}
catch
{
<co>5__4 = null;
}
if (<co>5__4 != null)
{
<>2__current = <co>5__4;
<>1__state = 2;
return true;
}
goto IL_01f7;
}
LogDebug("Could not get Create_PlayerRaceModel method");
goto IL_020e;
case 2:
<>1__state = -1;
LogDebug("Create_PlayerRaceModel coroutine completed");
goto IL_01f7;
case 3:
<>1__state = -1;
<>2__current = null;
<>1__state = 4;
return true;
case 4:
{
<>1__state = -1;
try
{
<ed>5__5 = null;
try
{
<ed>5__5 = pv._raceModelED;
}
catch
{
<ed>5__5 = null;
}
if ((Object)(object)<ed>5__5 != (Object)null)
{
try
{
<ed>5__5.Apply_EquipmentVisualDisplay();
}
catch
{
}
}
<ed>5__5 = null;
}
catch
{
}
try
{
<s>5__6 = pv._playerAppearanceStruct;
ApplyExtendedValues(pv, <s>5__6);
<s>5__6 = default(PlayerAppearanceStruct);
}
catch
{
}
LogDebug("ForceRaceRebuildRoutine completed for '" + targetRaceTag + "'");
return false;
}
IL_01f7:
<co>5__4 = null;
goto IL_020e;
IL_020e:
<>2__current = null;
<>1__state = 3;
return true;
}
}
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 PLUGIN_GUID = "com.swp.receiver";
public const string PLUGIN_NAME = "SWP Receiver";
public const string PLUGIN_VERSION = "1.0.0";
private static ManualLogSource _logger;
private static Harmony _harmony;
private static bool _mainModPresent = false;
private static bool _initialized = false;
private static Dictionary<int, int> _lastAppliedFrame = new Dictionary<int, int>();
private static int _lastPurgeFrame = 0;
private const int PURGE_INTERVAL_FRAMES = 600;
private const int ENTRY_MAX_AGE_FRAMES = 300;
private void Awake()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
_logger = ((BaseUnityPlugin)this).Logger;
try
{
_mainModPresent = DetectMainMod();
if (_mainModPresent)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"SWP Receiver v1.0.0: Main SWP mod detected, staying dormant.");
return;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"SWP Receiver v1.0.0: Initializing receiver patches...");
_harmony = new Harmony("com.swp.receiver");
_harmony.PatchAll(typeof(SWPReceiverPlugin).Assembly);
_initialized = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"SWP Receiver: Successfully initialized.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("SWP Receiver: Failed to initialize: " + ex.Message));
}
}
private void OnDestroy()
{
try
{
if (_harmony != null && _initialized)
{
_harmony.UnpatchSelf();
_harmony = null;
}
}
catch
{
}
}
private static bool DetectMainMod()
{
try
{
Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
if (pluginInfos != null)
{
string[] array = new string[3] { "com.eleen.atlyss.sliderpreset", "com.swp.sliderpreset", "com.eyemod.sliders" };
string[] array2 = array;
foreach (string key in array2)
{
if (pluginInfos.ContainsKey(key))
{
return true;
}
}
}
}
catch
{
}
try
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Assembly[] array3 = assemblies;
foreach (Assembly assembly in array3)
{
try
{
if (assembly.GetType("SliderPreset.SliderPresetPlugin") != null)
{
return true;
}
}
catch
{
}
}
}
catch
{
}
return false;
}
internal static void ApplyExtendedValues(PlayerVisual pv, PlayerAppearanceStruct s)
{
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)pv == (Object)null || _mainModPresent || !_initialized)
{
return;
}
try
{
PlayerRaceModel playerRaceModel = pv._playerRaceModel;
if (!((Object)(object)playerRaceModel == (Object)null))
{
Transform armatureTransform = playerRaceModel._armatureTransform;
if ((Object)(object)armatureTransform != (Object)null)
{
armatureTransform.localScale = new Vector3(s._widthWeight, s._heightWeight, s._widthWeight);
}
Transform headBoneTransform = playerRaceModel._headBoneTransform;
if ((Object)(object)headBoneTransform != (Object)null)
{
headBoneTransform.localScale = new Vector3(s._headWidth, 1f, 1f);
}
playerRaceModel._bellyWeight = s._bellyWeight;
playerRaceModel._bottomWeight = s._bottomWeight;
playerRaceModel._boobWeight = s._boobWeight;
playerRaceModel._torsoWeight = s._torsoWeight;
playerRaceModel._muzzleWeight = s._muzzleWeight;
playerRaceModel._armWeight = s._armWeight;
ApplyBlendShapes(playerRaceModel, s);
}
}
catch (Exception ex)
{
LogDebug("ApplyExtendedValues error: " + ex.Message);
}
}
private static void ApplyBlendShapes(PlayerRaceModel raceModel, PlayerAppearanceStruct s)
{
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: 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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
try
{
SkinnedMeshRenderer baseBodyMesh = raceModel._baseBodyMesh;
if ((Object)(object)baseBodyMesh != (Object)null && (Object)(object)baseBodyMesh.sharedMesh != (Object)null)
{
int blendShapeCount = baseBodyMesh.sharedMesh.blendShapeCount;
if (blendShapeCount > 0)
{
baseBodyMesh.SetBlendShapeWeight(0, s._bellyWeight);
}
if (s._bottomWeight < 0f)
{
if (blendShapeCount > 1)
{
baseBodyMesh.SetBlendShapeWeight(1, 0f);
}
int num = 4;
try
{
RaceModelEquipDisplay equipDisplay = raceModel._equipDisplay;
if ((Object)(object)equipDisplay != (Object)null)
{
FieldInfo field = ((object)equipDisplay).GetType().GetField("_hasHeadBlendWeights", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && (bool)field.GetValue(equipDisplay))
{
num = 5;
}
}
}
catch
{
}
if (blendShapeCount > num)
{
baseBodyMesh.SetBlendShapeWeight(num, s._bottomWeight * -1f);
}
}
else if (blendShapeCount > 1)
{
baseBodyMesh.SetBlendShapeWeight(1, s._bottomWeight);
}
if (blendShapeCount > 2)
{
baseBodyMesh.SetBlendShapeWeight(2, s._torsoWeight);
}
if (blendShapeCount > 3)
{
baseBodyMesh.SetBlendShapeWeight(3, s._muzzleWeight);
}
}
SkinnedMeshRenderer baseBoobMesh = raceModel._baseBoobMesh;
if ((Object)(object)baseBoobMesh != (Object)null && (Object)(object)baseBoobMesh.sharedMesh != (Object)null && baseBoobMesh.sharedMesh.blendShapeCount > 0)
{
baseBoobMesh.SetBlendShapeWeight(0, s._boobWeight);
}
SkinnedMeshRenderer baseArmMesh = raceModel._baseArmMesh;
if ((Object)(object)baseArmMesh != (Object)null && (Object)(object)baseArmMesh.sharedMesh != (Object)null && baseArmMesh.sharedMesh.blendShapeCount > 0)
{
baseArmMesh.SetBlendShapeWeight(0, s._armWeight);
}
}
catch (Exception ex)
{
LogDebug("ApplyBlendShapes error: " + ex.Message);
}
}
private static void LogDebug(string msg)
{
try
{
ManualLogSource logger = _logger;
if (logger != null)
{
logger.LogDebug((object)("[SWP_Receiver] " + msg));
}
}
catch
{
}
}
private static void LogInfo(string msg)
{
try
{
ManualLogSource logger = _logger;
if (logger != null)
{
logger.LogInfo((object)("[SWP_Receiver] " + msg));
}
}
catch
{
}
}
private static string NormalizeRaceName(string raceName)
{
if (string.IsNullOrEmpty(raceName))
{
return "";
}
return raceName.Replace(" ", "").ToLowerInvariant();
}
private static void TryPurgeOldEntries(int currentFrame)
{
if (currentFrame - _lastPurgeFrame < 600)
{
return;
}
_lastPurgeFrame = currentFrame;
try
{
List<int> list = new List<int>();
foreach (KeyValuePair<int, int> item in _lastAppliedFrame)
{
if (currentFrame - item.Value > 300)
{
list.Add(item.Key);
}
}
foreach (int item2 in list)
{
_lastAppliedFrame.Remove(item2);
}
}
catch
{
}
}
private static void ForceRaceRebuild(PlayerVisual pv, string targetRaceTag)
{
try
{
if (!((Object)(object)pv == (Object)null))
{
((MonoBehaviour)pv).StartCoroutine(ForceRaceRebuildRoutine(pv, targetRaceTag));
}
}
catch (Exception ex)
{
LogDebug("ForceRaceRebuild error: " + ex.Message);
}
}
[IteratorStateMachine(typeof(<ForceRaceRebuildRoutine>d__23))]
private static IEnumerator ForceRaceRebuildRoutine(PlayerVisual pv, string targetRaceTag)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ForceRaceRebuildRoutine>d__23(0)
{
pv = pv,
targetRaceTag = targetRaceTag
};
}
}