Decompiled source of Puttler Full Body Tracking v2.0.1

PuttlerFullBodyTracking.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PuttlerFullBodyTracking;
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(PuttlerFullBodyTrackingPlugin), "Full Body Tracking", "2.0", "Squidforge Productions", null)]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PuttlerFullBodyTracking")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PuttlerFullBodyTracking")]
[assembly: AssemblyTitle("PuttlerFullBodyTracking")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace PuttlerFullBodyTracking
{
	public class PuttlerFullBodyTrackingPlugin : MelonMod
	{
		private float BoneThickness = 7f;

		private StreamReader reader;

		private Thread pipeThread;

		private string json = null;

		private GameObject parentObject;

		private NamedPipeServerStream server = new NamedPipeServerStream("PuttlerFBTPipe", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

		private Process trackerProcess;

		private Dictionary<string, Rigidbody2D> boneBodies = new Dictionary<string, Rigidbody2D>();

		private Dictionary<string, Vector2> previousPositions = new Dictionary<string, Vector2>();

		private Dictionary<string, Vector2> smoothedVelocities = new Dictionary<string, Vector2>();

		private string basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		public override void OnInitializeMelon()
		{
			MelonLogger.Msg("==================================");
			MelonLogger.Msg("       Full Body Tracking         ");
			MelonLogger.Msg("     By Squidforge productions    ");
			MelonLogger.Msg("==================================");
			MelonLogger.Msg("Starting tracker application...");
			string text = Path.Combine(basePath, "FullBodyTracking", "Tracker", "FullBodyTracker.exe");
			trackerProcess = new Process
			{
				StartInfo = new ProcessStartInfo
				{
					FileName = text,
					WorkingDirectory = Path.GetDirectoryName(text),
					UseShellExecute = true
				}
			};
			trackerProcess.Start();
			MelonLogger.Msg("Awaiting pipe connection...");
			Thread thread = new Thread((ThreadStart)delegate
			{
				try
				{
					server.WaitForConnection();
					MelonLogger.Msg("Pipe connected!");
					reader = new StreamReader(server, Encoding.UTF8);
					pipeThread = new Thread(ReadPipe);
					pipeThread.IsBackground = true;
					pipeThread.Start();
				}
				catch (Exception value)
				{
					MelonLogger.Error($"Pipe connection failed: {value}");
				}
			});
			thread.IsBackground = true;
			thread.Start();
		}

		private void ReadPipe()
		{
			while (true)
			{
				try
				{
					json = reader.ReadLine();
				}
				catch
				{
				}
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			((MelonBase)this).LoggerInstance.Msg("Scene Loaded: " + sceneName);
			parentObject = new GameObject("Skeleton Parent");
			parentObject.transform.position = new Vector3(-12f, 7f, 0f);
		}

		public override void OnFixedUpdate()
		{
			Dictionary<string, Dictionary<string, float>> jointData;
			if (!string.IsNullOrEmpty(json))
			{
				Dictionary<string, object> dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
				if (!(dictionary["command"]?.ToString() != "BoneUpdate"))
				{
					jointData = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, float>>>(dictionary["data"].ToString());
					Draw("ShoulderLeft", "ElbowLeft");
					Draw("ElbowLeft", "WristLeft");
					Draw("ShoulderRight", "ElbowRight");
					Draw("ElbowRight", "WristRight");
					Draw("ShoulderLeft", "ShoulderRight");
					Draw("ShoulderLeft", "HipLeft");
					Draw("ShoulderRight", "HipRight");
					Draw("HipLeft", "HipRight");
					Draw("HipLeft", "KneeLeft");
					Draw("KneeLeft", "AnkleLeft");
					Draw("HipRight", "KneeRight");
					Draw("KneeRight", "AnkleRight");
				}
			}
			void Draw(string a, string b)
			{
				if (jointData.ContainsKey(a) && jointData.ContainsKey(b))
				{
					Dictionary<string, float> dictionary2 = jointData[a];
					Dictionary<string, float> dictionary3 = jointData[b];
					DrawBone(a + "_" + b, dictionary2["x"], dictionary2["y"], dictionary2["z"], dictionary3["x"], dictionary3["y"], dictionary3["z"]);
				}
			}
		}

		private void DrawBone(string boneKey, float joint0x, float joint0y, float joint0z, float joint1x, float joint1y, float joint1z)
		{
			//IL_00c3: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(joint0x, joint0y * -1f, joint0z);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(joint1x, joint1y * -1f, joint1z);
			string text = "Bone_" + boneKey;
			GameObject val3 = GameObject.Find(text);
			Rigidbody2D val4;
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = LoadCustomImage("FullBodyTracking/solidWhite.png");
				((Object)val3).name = text;
				val3.AddComponent<BoxCollider2D>();
				val4 = val3.AddComponent<Rigidbody2D>();
				val4.bodyType = (RigidbodyType2D)1;
				val4.gravityScale = 0f;
				val4.interpolation = (RigidbodyInterpolation2D)1;
				val4.collisionDetectionMode = (CollisionDetectionMode2D)1;
				val3.transform.parent = parentObject.transform;
				boneBodies[boneKey] = val4;
				previousPositions[boneKey] = val4.position;
				smoothedVelocities[boneKey] = Vector2.zero;
			}
			else
			{
				val4 = boneBodies[boneKey];
			}
			Vector2 val5 = Vector2.op_Implicit((val + val2) / 2f / 100f * 3f + parentObject.transform.position);
			Vector2 val6 = Vector2.op_Implicit(val2 - val);
			float num = Mathf.Atan2(val6.y, val6.x) * 57.29578f;
			float magnitude = ((Vector2)(ref val6)).magnitude;
			if (!previousPositions.ContainsKey(boneKey))
			{
				previousPositions[boneKey] = val4.position;
			}
			if (!smoothedVelocities.ContainsKey(boneKey))
			{
				smoothedVelocities[boneKey] = Vector2.zero;
			}
			float num2 = 0.05f;
			float num3 = 0f;
			float num4 = 0.4f;
			Vector2 val7 = (val5 - previousPositions[boneKey]) / Time.fixedDeltaTime;
			Vector2 val8 = Vector2.Lerp(smoothedVelocities[boneKey], val7, num4);
			val8 *= num2;
			val8 = Vector2.ClampMagnitude(val8, num3);
			smoothedVelocities[boneKey] = val8;
			val4.MovePosition(val5);
			val4.MoveRotation(num);
			val4.velocity = val8;
			val3.transform.localScale = new Vector3(magnitude, BoneThickness, BoneThickness) * 3f;
			previousPositions[boneKey] = val5;
		}

		private GameObject LoadCustomImage(string imagePath)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(basePath, imagePath);
			if (!File.Exists(text))
			{
				MelonLogger.Error("Texture not found: " + text);
				return null;
			}
			GameObject val = new GameObject(imagePath);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			byte[] array = File.ReadAllBytes(text);
			Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val3, Il2CppStructArray<byte>.op_Implicit(array));
			val2.sprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f));
			val.transform.parent = parentObject.transform;
			return val;
		}

		public override void OnApplicationQuit()
		{
			try
			{
				if (trackerProcess != null && !trackerProcess.HasExited)
				{
					trackerProcess.CloseMainWindow();
					if (!trackerProcess.WaitForExit(2000))
					{
						trackerProcess.Kill(entireProcessTree: true);
					}
					trackerProcess.Dispose();
					trackerProcess = null;
				}
			}
			catch (Exception value)
			{
				MelonLogger.Error($"Failed to stop tracker process: {value}");
			}
		}
	}
}