Decompiled source of ExpressionControl v1.0.1

Mods/ExpressionControl.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using ExpressionControl;
using ExpressionControl.Messages;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.VRMK;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "ExpressionControl", "1.0.0", "notnotnotswipez", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: ModuleInfo(typeof(ModuleMainClass), "ExpressionControlModule", "1.0.0", "notnotnotswipez", "expressioncontrollmodule", true, ConsoleColor.Yellow)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ExpressionControl")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExpressionControl")]
[assembly: AssemblyTitle("ExpressionControl")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 ExpressionControl
{
	[HarmonyPatch(typeof(ArtRig), "SetArtOutputAvatar")]
	public class AvatarPatches
	{
		public static void Postfix(ArtRig __instance, PhysicsRig inRig, Avatar avatar)
		{
			MelonCoroutines.Start(WaitForAvatar(((Rig)inRig).manager, avatar));
		}

		private static IEnumerator WaitForAvatar(RigManager instance, Avatar newAvatar)
		{
			for (int i = 0; i < 5; i++)
			{
				yield return null;
			}
			if (((Object)instance).GetInstanceID() == ((Object)Player.RigManager).GetInstanceID())
			{
				Core.ApplyBlendshapesToAvatar(newAvatar, Core.blendshapePairs);
				Core.Broadcast();
			}
		}
	}
	public class Core : MelonMod
	{
		public static string lastBlendshapeName;

		private static Page mainPage;

		private static bool deletionMode = false;

		public static Dictionary<string, bool> blendshapePairs = new Dictionary<string, bool>();

		public static Dictionary<int, Dictionary<string, bool>> rigmanagerBlendshapePairs = new Dictionary<int, Dictionary<string, bool>>();

		public static MelonPreferences_Category category;

		public static MelonPreferences_Entry<string> savedString;

		public override void OnInitializeMelon()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			category = MelonPreferences.CreateCategory("ExpressionControl");
			savedString = category.CreateEntry<string>("SavedString", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			blendshapePairs = GetDictionaryFromString(savedString.Value);
			mainPage = Page.Root.CreatePage("Expression Control", Color.yellow, 0, true);
			RemakeMenu();
			ModuleHandler.LoadModule(Assembly.GetExecutingAssembly());
		}

		private void RemakeMenu()
		{
			//IL_0016: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			mainPage.RemoveAll();
			mainPage.CreateString("Blendshape Name", Color.white, "", (Action<string>)delegate(string str)
			{
				lastBlendshapeName = str;
			});
			mainPage.CreateFunction("+", Color.green, (Action)delegate
			{
				blendshapePairs.Add(lastBlendshapeName, value: false);
				RemakeMenu();
				SaveDictToFile();
			});
			mainPage.CreateBool("Deletion Mode", Color.red, deletionMode, (Action<bool>)delegate(bool b)
			{
				deletionMode = b;
			});
			foreach (KeyValuePair<string, bool> keyPair in blendshapePairs)
			{
				mainPage.CreateBool(keyPair.Key, Color.white, keyPair.Value, (Action<bool>)delegate(bool b)
				{
					//IL_009c: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00be: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c8: 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_0116: Unknown result type (might be due to invalid IL or missing references)
					//IL_011b: Unknown result type (might be due to invalid IL or missing references)
					//IL_012b: Expected O, but got Unknown
					if (deletionMode)
					{
						blendshapePairs[keyPair.Key] = false;
						ApplyBlendshapesToLocalPlayer();
						blendshapePairs.Remove(keyPair.Key);
						RemakeMenu();
						SaveDictToFile();
						Broadcast();
					}
					else
					{
						blendshapePairs[keyPair.Key] = b;
						ApplyBlendshapesToLocalPlayer();
						SaveDictToFile();
						Broadcast();
						Notifier.Send(new Notification
						{
							ShowTitleOnPopup = true,
							Title = NotificationText.op_Implicit(keyPair.Key + " changed!"),
							Message = NotificationText.op_Implicit($"It is now {blendshapePairs[keyPair.Key]}!"),
							PopupLength = 3f
						});
					}
				});
			}
			mainPage.Remove((Element[])(object)new Element[0]);
		}

		public static void Broadcast()
		{
			if (!NetworkInfo.HasServer)
			{
				return;
			}
			ExpressionMessageData expressionMessageData = ExpressionMessageData.Create(blendshapePairs);
			FusionWriter val = FusionWriter.Create();
			try
			{
				ExpressionMessageData expressionMessageData2 = expressionMessageData;
				val.Write<ExpressionMessageData>(expressionMessageData2);
				FusionMessage val2 = FusionMessage.ModuleCreate<ExpressionMessage>(val);
				try
				{
					MessageSender.SendToServer((NetworkChannel)0, val2);
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private void SaveDictToFile()
		{
			savedString.Value = GetStringFromDictionary(blendshapePairs);
			category.SaveToFile(false);
		}

		public static string GetStringFromDictionary(Dictionary<string, bool> keyValuePairs)
		{
			string text = keyValuePairs.Count + ";";
			foreach (KeyValuePair<string, bool> keyValuePair in keyValuePairs)
			{
				text = text + keyValuePair.Key + ";";
				text = text + keyValuePair.Value + ";";
			}
			return text;
		}

		public static Dictionary<string, bool> GetDictionaryFromString(string targetString)
		{
			if (targetString == "")
			{
				return new Dictionary<string, bool>();
			}
			string[] array = targetString.Split(";");
			int num = int.Parse(array[0]);
			int num2 = 1;
			Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
			for (int i = num2; i < num * 2; i += 2)
			{
				dictionary.Add(array[i], bool.Parse(array[i + 1]));
			}
			return dictionary;
		}

		private void ApplyBlendshapesToLocalPlayer()
		{
			ApplyBlendshapesToRigmanager(Player.RigManager, blendshapePairs);
		}

		public static void ApplyBlendshapesToRigmanager(RigManager rigManager, Dictionary<string, bool> blendshapePairs)
		{
			if (rigmanagerBlendshapePairs.ContainsKey(((Object)rigManager).GetInstanceID()))
			{
				rigmanagerBlendshapePairs[((Object)rigManager).GetInstanceID()] = blendshapePairs;
			}
			else
			{
				rigmanagerBlendshapePairs.Add(((Object)rigManager).GetInstanceID(), blendshapePairs);
			}
			ApplyBlendshapesToAvatar(rigManager.avatar, blendshapePairs);
			MirrorPatches.skinnedMeshRendererPairs.Clear();
		}

		public static Dictionary<string, bool> TryGetBlendShapePairFromRigmanager(RigManager rigManager)
		{
			if (rigmanagerBlendshapePairs.ContainsKey(((Object)rigManager).GetInstanceID()))
			{
				return rigmanagerBlendshapePairs[((Object)rigManager).GetInstanceID()];
			}
			return null;
		}

		public static void ApplyBlendshapesToAvatar(Avatar avatar, Dictionary<string, bool> blendshapePairs)
		{
			ApplyBlendshapesToSkinnedMeshRenderers(((Component)avatar).GetComponentsInChildren<SkinnedMeshRenderer>(), blendshapePairs);
		}

		public static void ApplyBlendshapesToSkinnedMeshRenderers(Il2CppArrayBase<SkinnedMeshRenderer> skinnedMeshRenderers, Dictionary<string, bool> blendshapePairs)
		{
			foreach (SkinnedMeshRenderer skinnedMeshRenderer in skinnedMeshRenderers)
			{
				foreach (KeyValuePair<string, bool> blendshapePair in blendshapePairs)
				{
					int blendShapeIndex = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex(blendshapePair.Key);
					if (blendShapeIndex != -1)
					{
						float num = (blendshapePair.Value ? 100f : 0f);
						skinnedMeshRenderer.SetBlendShapeWeight(blendShapeIndex, num);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Mirror), "LateUpdate")]
	public class MirrorPatches
	{
		public static Dictionary<int, Il2CppArrayBase<SkinnedMeshRenderer>> skinnedMeshRendererPairs = new Dictionary<int, Il2CppArrayBase<SkinnedMeshRenderer>>();

		public static void Prefix(Mirror __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance.Reflection) || skinnedMeshRendererPairs.ContainsKey(((Object)__instance.Reflection).GetInstanceID()))
			{
				return;
			}
			skinnedMeshRendererPairs.Add(((Object)__instance.Reflection).GetInstanceID(), ((Component)__instance.Reflection).GetComponentsInChildren<SkinnedMeshRenderer>());
			Il2CppArrayBase<SkinnedMeshRenderer> skinnedMeshRenderers = skinnedMeshRendererPairs[((Object)__instance.Reflection).GetInstanceID()];
			RigManager rigManager = __instance.rigManager;
			if (Object.op_Implicit((Object)(object)rigManager))
			{
				Dictionary<string, bool> dictionary = Core.TryGetBlendShapePairFromRigmanager(rigManager);
				if (dictionary != null)
				{
					Core.ApplyBlendshapesToSkinnedMeshRenderers(skinnedMeshRenderers, dictionary);
				}
			}
		}
	}
	public class ModuleMainClass : Module
	{
	}
}
namespace ExpressionControl.Messages
{
	public class ExpressionMessageData : IFusionSerializable
	{
		public PlayerId playerId;

		public string dictString;

		public void Deserialize(FusionReader reader)
		{
			playerId = PlayerIdManager.GetPlayerId(reader.ReadByte());
			dictString = reader.ReadString();
		}

		public void Serialize(FusionWriter writer)
		{
			writer.Write(playerId.SmallId);
			writer.Write(dictString);
		}

		public static ExpressionMessageData Create(Dictionary<string, bool> dict)
		{
			return new ExpressionMessageData
			{
				playerId = PlayerIdManager.LocalId,
				dictString = Core.GetStringFromDictionary(dict)
			};
		}
	}
	public class ExpressionMessage : ModuleMessageHandler
	{
		public override void HandleMessage(byte[] bytes, bool isServerHandled = false)
		{
			FusionReader val = FusionReader.Create(bytes);
			try
			{
				ExpressionMessageData expressionMessageData = val.ReadFusionSerializable<ExpressionMessageData>();
				if (NetworkInfo.IsServer && isServerHandled)
				{
					FusionMessage val2 = FusionMessage.ModuleCreate<ExpressionMessage>(bytes);
					try
					{
						MessageSender.BroadcastMessageExcept(PlayerId.op_Implicit(expressionMessageData.playerId), (NetworkChannel)0, val2, true);
					}
					finally
					{
						((IDisposable)val2)?.Dispose();
					}
				}
				NetworkPlayer val3 = default(NetworkPlayer);
				if (!expressionMessageData.playerId.IsOwner && NetworkPlayerManager.TryGetPlayer(PlayerId.op_Implicit(expressionMessageData.playerId), ref val3))
				{
					Dictionary<string, bool> dictionaryFromString = Core.GetDictionaryFromString(expressionMessageData.dictString);
					if (dictionaryFromString != null)
					{
						Core.ApplyBlendshapesToRigmanager(val3.RigRefs.RigManager, dictionaryFromString);
					}
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
	}
}