Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BoneMod v1.0.1
BepInEx/plugins/BoneMod/BoneMod.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyTitle("BoneMod")] [assembly: AssemblyDescription("Valheim BoneMod")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("an0nymooose")] [assembly: AssemblyProduct("BoneMod")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8f2e2083-d7bc-4426-802f-6cc9402029fc")] [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")] namespace BoneMod; public class Body { public Vector3 jaw { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 head { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 chest { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 neck { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 spine { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 hips { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 lefthand { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 righthand { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 leftfoot { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 rightfoot { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 leftleg { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 rightleg { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 leftarm { get; set; } = new Vector3(1f, 1f, 1f); public Vector3 rightarm { get; set; } = new Vector3(1f, 1f, 1f); } public class BodyManager { public static bool bodygroupUpdate(Player p, Vector3 Bodydata, string user, string group) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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) string[] array = new string[2] { "", "" }; HumanBodyBones[] array2; switch (group) { case "feet": array[0] = "leftfoot"; array[1] = "rightfoot"; array2 = (HumanBodyBones[])(object)new HumanBodyBones[2] { (HumanBodyBones)5, (HumanBodyBones)6 }; break; case "hands": array[0] = "lefthand"; array[1] = "righthand"; array2 = (HumanBodyBones[])(object)new HumanBodyBones[2] { (HumanBodyBones)17, (HumanBodyBones)18 }; break; case "legs": array[0] = "leftleg"; array[1] = "rightleg"; array2 = (HumanBodyBones[])(object)new HumanBodyBones[2] { (HumanBodyBones)2, (HumanBodyBones)1 }; break; case "arms": array[0] = "leftarm"; array[1] = "rightarm"; array2 = (HumanBodyBones[])(object)new HumanBodyBones[2] { (HumanBodyBones)13, (HumanBodyBones)14 }; break; default: return false; } ((Component)((Component)((Component)p).GetComponent<Character>()).GetComponentInChildren<Animator>().GetBoneTransform(array2[0])).transform.localScale = Bodydata; ((Component)((Component)((Component)p).GetComponent<Character>()).GetComponentInChildren<Animator>().GetBoneTransform(array2[1])).transform.localScale = Bodydata; updateBody(array[0], Bodydata, user); updateBody(array[1], Bodydata, user); return true; } public static HumanBodyBones nameToBodyPart(string name) { //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) return (HumanBodyBones)(name.ToLower() switch { "head" => 10, "chest" => 8, "neck" => 9, "spine" => 7, "hips" => 0, "lefthand" => 17, "righthand" => 18, "rightfoot" => 6, "leftfoot" => 5, "jaw" => 23, "leftleg" => 1, "rightleg" => 2, "leftarm" => 13, "rightarm" => 14, _ => 55, }); } public static void updateBody(string part, Vector3 data, string user) { //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) Main.allplayers.TryGetValue(user, out var value); switch (part) { case "head": value.head = data; break; case "chest": value.chest = data; break; case "neck": value.neck = data; break; case "spine": value.spine = data; break; case "hips": value.hips = data; break; case "lefthand": value.lefthand = data; break; case "righthand": value.righthand = data; break; case "rightfoot": value.rightfoot = data; break; case "leftfoot": value.leftfoot = data; break; case "jaw": value.jaw = data; break; case "leftleg": value.leftleg = data; break; case "rightleg": value.rightleg = data; break; case "leftarm": value.leftarm = data; break; case "rightarm": value.rightarm = data; break; } Main.allplayers[user] = value; } public static string vecStr(Vector3 str) { return str.x + " " + str.y + " " + str.z + " "; } public static string serializeBody(string user) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) Main.allplayers.TryGetValue(user, out var value); return vecStr(value.jaw) + vecStr(value.head) + vecStr(value.chest) + vecStr(value.neck) + vecStr(value.spine) + vecStr(value.hips) + vecStr(value.lefthand) + vecStr(value.righthand) + vecStr(value.leftfoot) + vecStr(value.rightfoot) + vecStr(value.leftleg) + vecStr(value.rightleg) + vecStr(value.leftarm) + vecStr(value.rightarm); } public static Player getPlayerObj(string name) { foreach (Player allPlayer in Player.GetAllPlayers()) { if (allPlayer.GetPlayerName().ToLower().Equals(name.ToLower())) { return allPlayer; } } return null; } public static void setBoneDataCmd(float[] scaleData, Player exePlayer, string user, string textBodyPart, HumanBodyBones part) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(scaleData[1], scaleData[2], scaleData[3]); if (!bodygroupUpdate(exePlayer, val, user, textBodyPart)) { ((Component)((Component)((Component)exePlayer).GetComponent<Character>()).GetComponentInChildren<Animator>().GetBoneTransform(part)).transform.localScale = val; updateBody(textBodyPart, val, user); } exePlayer.SetPrivateFieldValue(2, Main.properCase(textBodyPart) + " scale applied!", 0, null); } public static void resetPlayer(Player exePlayer, string playerName, string msg) { ZNetView component = ((Component)((Component)Player.m_localPlayer).GetComponent<Character>()).GetComponent<ZNetView>(); Main.allplayers.Remove(playerName); Main.allplayers.Add(playerName, new Body()); Main.RPC_applyScaleVectorsToPlayer(component, playerName, serializeBody(playerName)); exePlayer.SetPrivateFieldValue(2, msg, 5, null); } } [BepInPlugin("an0nymooose_BoneMod", "BoneMod", "1.0.0.0")] public class Main : BaseUnityPlugin { [HarmonyPatch(typeof(FejdStartup), "OnCharacterStart")] private class ResetBodyOnLog { private static bool Prefix() { updateSelfBones = true; return true; } } [HarmonyPatch(typeof(Game), "Logout")] private class SaveOnLogout { private static bool Prefix() { BoneSaveManager.saveData(); return true; } } [HarmonyPatch(typeof(Game), "OnApplicationQuit")] private class SaveOnExit { private static bool Prefix() { try { BoneSaveManager.saveData(); } catch { } return true; } } [HarmonyPatch(typeof(Player), "Awake")] public class registerApplyVectors { public static void Postfix(Player __instance) { Debug.Log((object)"[BoneMod] Registering new player object."); ((Component)((Component)__instance).GetComponent<Character>()).GetComponent<ZNetView>().Register<string, string>("applyScaleVectorsToPlayer", (Action<long, string, string>)applyScaleVectorsToPlayer); } public static void applyScaleVectorsToPlayer(long sender, string name, string vectors) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) Player playerObj = BodyManager.getPlayerObj(name); if (!Object.op_Implicit((Object)(object)playerObj)) { return; } try { string[] array = vectors.Split(new char[1] { ' ' }); string[] array2 = "jaw head chest neck spine hips lefthand righthand leftfoot rightfoot leftleg rightleg leftarm rightarm".Split(new char[1] { ' ' }); int num = 0; Animator componentInChildren = ((Component)((Component)playerObj).GetComponent<Character>()).GetComponentInChildren<Animator>(); Vector3 val2 = default(Vector3); for (int i = 0; i < array2.Length; i++) { HumanBodyBones val = BodyManager.nameToBodyPart(array2[i]); ((Vector3)(ref val2))..ctor(float.Parse(array[num]), float.Parse(array[num + 1]), float.Parse(array[num + 2])); ((Component)componentInChildren.GetBoneTransform(val)).transform.localScale = val2; if (updateSelfBones && Player.m_localPlayer.GetPlayerName().ToLower() == name) { BodyManager.updateBody(array2[i], val2, name); } num += 3; } } catch { Debug.Log((object)"[BoneMod] Failed to apply scaling to dead/loading player. It's normal, Continuing.."); } } } [HarmonyPatch(typeof(Chat), "OnNewChatMessage")] public class BoneMessageSystem : MonoBehaviour { private static bool Prefix(ref Type type, UserInfo sender, string text) { //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Invalid comparison between Unknown and I4 //IL_030e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { string text2 = text.ToLower(); string name = sender.Name; name = name.ToLower(); if (!allplayers.ContainsKey(name)) { allplayers.Add(name, new Body()); } if (text2.StartsWith("!bm")) { string playerName = Player.m_localPlayer.GetPlayerName(); Player playerObj = BodyManager.getPlayerObj(name.ToLower()); string[] array = text2.Split(new char[1] { ' ' }); string text3 = array[0]; if (text.StartsWith("\nBoneMod by an0nymooose") && name != playerName.ToLower()) { return false; } if (text3 == "!bmhelp" && name == playerName.ToLower()) { BoneSaveManager.saveData(); Chat.instance.SendText((Type)1, "\nBoneMod by an0nymooose\nCommands:\n1) !bm bodypart x y z (Ex: !bm head 2 1 2)\nTo equally scale, just provide X (!bm head 2)\n2) !bmreset Resets the player's bones.\nBones: jaw head chest neck spine hips lefthand righthand leftfoot rightfoot leftleg rightleg leftarm rightarm\n(Group parts \"arms, legs, hands, feet\" also valid)\n3) !bmstop/!bmstart controls your bone syncing between players\n4) !bmclearsave clears all saved local characters bones and resets your bones."); return false; } if (text3 == "!bmreset") { BodyManager.resetPlayer(playerObj, name, "Bones reset!"); return false; } if (text3 == "!bmclearsave" && name == playerName.ToLower()) { BoneSaveManager.clearSaveData(); BodyManager.resetPlayer(playerObj, name, "Bone save file cleared and bones reset!"); return false; } if (text3 == "!bmstop" && name == playerName.ToLower()) { playerObj.SetPrivateFieldValue(2, "Bone syncing stopped!", 5, null); broadcast = false; return false; } if (text3 == "!bmstart" && name == playerName.ToLower()) { playerObj.SetPrivateFieldValue(2, "Bone syncing started!", 5, null); broadcast = true; return false; } if (text3 == "!bm" && array.Length > 2) { array = text2.Trim().Split(new char[1] { ' ' }); string text4 = array[1]; float[] array2 = numCheck(array); if (array2[0] == 0f) { playerObj.SetPrivateFieldValue(2, "Invalid scale numbers / malformed command", 10, null); return false; } if (array2[0] == 2f) { array2[2] = array2[1]; array2[3] = array2[1]; } bool flag = true; type = (Type)2; HumanBodyBones val = BodyManager.nameToBodyPart(text4); if ((int)val == 55 && !"arms legs feet hands".Contains(text4)) { flag = false; } if (text3 == "!bm" && Math.Abs(array2[1]) <= (float)SIZE_LIMIT && Math.Abs(array2[2]) <= (float)SIZE_LIMIT && Math.Abs(array2[3]) <= (float)SIZE_LIMIT && flag) { BodyManager.setBoneDataCmd(array2, playerObj, name, text4, val); return false; } playerObj.SetPrivateFieldValue(2, "Invalid body part / size above " + SIZE_LIMIT, 5, null); return false; } } return true; } return false; } } public const string MODNAME = "BoneMod"; public const string AUTHOR = "an0nymooose"; public const string GUID = "an0nymooose_BoneMod"; public const string VERSION = "1.0.0.0"; internal readonly ManualLogSource log; internal readonly Harmony harmony; internal readonly Assembly assembly; private ConfigEntry<bool> configAutoStartBroadcast; private ConfigEntry<bool> configAlwaysLoadSavedBones; private ConfigEntry<int> configMAX_SIZE; public static Dictionary<string, Body> allplayers = new Dictionary<string, Body>(); public static bool updateSelfBones = false; public static bool CamUpdate = false; private static bool broadcast = true; private static int SIZE_LIMIT = 10; public const string bodylist = "jaw head chest neck spine hips lefthand righthand leftfoot rightfoot leftleg rightleg leftarm rightarm"; public const string bodygrouplist = "arms legs feet hands"; public const string HELP_TEXT = "\nBoneMod by an0nymooose\nCommands:\n1) !bm bodypart x y z (Ex: !bm head 2 1 2)\nTo equally scale, just provide X (!bm head 2)\n2) !bmreset Resets the player's bones.\nBones: jaw head chest neck spine hips lefthand righthand leftfoot rightfoot leftleg rightleg leftarm rightarm\n(Group parts \"arms, legs, hands, feet\" also valid)\n3) !bmstop/!bmstart controls your bone syncing between players\n4) !bmclearsave clears all saved local characters bones and resets your bones."; public Main() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("an0nymooose_BoneMod"); assembly = Assembly.GetExecutingAssembly(); } public void Start() { harmony.PatchAll(assembly); Debug.Log((object)"BoneMod Loaded!"); configAutoStartBroadcast = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "AutoStartBroadcast", true, "Whether or not to automatically start broadcasting your vectors in chat. Turn off if you are playing with others who do not have this mod."); configMAX_SIZE = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Size", 10, "The maximum transform size, 10 seems to be a good value without going crazy."); configAlwaysLoadSavedBones = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "Always load saved bones.", true, "Automatically load and apply saved bone profiles (bonemod.txt)."); SIZE_LIMIT = configMAX_SIZE.Value; if (!configAutoStartBroadcast.Value) { broadcast = false; } ((MonoBehaviour)this).InvokeRepeating("broadcastVectors", 2f, 10f); } private void broadcastVectors() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } string text = Player.m_localPlayer.GetPlayerName().ToLower(); if (Object.op_Implicit((Object)(object)Chat.instance) && broadcast) { if (updateSelfBones && configAlwaysLoadSavedBones.Value) { BoneSaveManager.loadSaveData(); updateSelfBones = false; } ZNetView component = ((Component)((Component)Player.m_localPlayer).GetComponent<Character>()).GetComponent<ZNetView>(); RPC_applyScaleVectorsToPlayer(component, text, BodyManager.serializeBody(text)); } } public static void RPC_applyScaleVectorsToPlayer(ZNetView bone_netview, string name, string vectors) { bone_netview.InvokeRPC(ZNetView.Everybody, "applyScaleVectorsToPlayer", new object[2] { name, vectors }); } private static float[] numCheck(string[] command) { float result4; if (command.Length == 5) { if (float.TryParse(command[2], out var result) && float.TryParse(command[3], out var result2) && float.TryParse(command[4], out var result3)) { return new float[4] { 1f, result, result2, result3 }; } } else if (command.Length == 3 && float.TryParse(command[2], out result4)) { return new float[4] { 2f, result4, 0f, 0f }; } return new float[4]; } public static string properCase(string x) { return (x.Length > 0) ? (x[0].ToString().ToUpper() + x.Substring(1, x.Length - 1)) : ""; } } public class BoneSaveManager { public static List<string> readSaveData() { try { Debug.Log((object)"READING BONEMOD.TXT"); using StreamReader streamReader = new StreamReader(Paths.ConfigPath + "\\boneData.txt"); List<string> list = new List<string>(); string text = ""; while ((text = streamReader.ReadLine()) != null) { list.Add(text); } streamReader.Close(); return list; } catch (IOException) { return null; } } public static void saveData() { Debug.Log((object)"WRITING BONEMOD.TXT"); string text = Player.m_localPlayer.GetPlayerName().ToLower(); List<string> list = readSaveData(); bool flag = false; StreamWriter streamWriter = new StreamWriter(Paths.ConfigPath + "\\boneData.txt", append: false); if (list != null) { string[] array = list.ToArray(); for (int i = 0; i < array.Length; i++) { if (array[i].StartsWith("[" + text + "]")) { flag = true; array[i] = "[" + text + "] " + BodyManager.serializeBody(text); streamWriter.WriteLine(array[i]); } else { streamWriter.WriteLine(array[i]); } } if (!flag) { streamWriter.WriteLine("[" + text + "] " + BodyManager.serializeBody(text)); } } else { streamWriter.WriteLine("[" + text + "] " + BodyManager.serializeBody(text)); } streamWriter.Flush(); streamWriter.Close(); } public static void clearSaveData() { Debug.Log((object)"CLEARING BONEMOD.TXT"); StreamWriter streamWriter = new StreamWriter(Paths.ConfigPath + "\\boneData.txt", append: false); streamWriter.Write(""); streamWriter.Flush(); streamWriter.Close(); Utility.GetUniqueFilesInDirectories((IEnumerable<string>)new List<string> { Paths.PluginPath }, "*"); } public static void loadSaveData() { string text = Player.m_localPlayer.GetPlayerName().ToLower(); List<string> list = readSaveData(); if (list == null) { return; } string[] array = list.ToArray(); for (int i = 0; i < array.Length; i++) { if (array[i].StartsWith("[" + text + "]")) { ZNetView component = ((Component)((Component)Player.m_localPlayer).GetComponent<Character>()).GetComponent<ZNetView>(); string text2 = "[" + text + "]"; string vectors = array[i].Substring(array[i].IndexOf(text2) + text2.Length).Trim(); Main.RPC_applyScaleVectorsToPlayer(component, text, vectors); } } } } public static class PrivateAccessor { public static void SetPrivateFieldValue(this object obj, int propName, string val, int P_3, object P_4) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown ((Character)obj).Message((MessageType)propName, val, P_3, (Sprite)P_4, false); } public static T GetPrivateFieldValue<T, T>(this object P_0, string P_1) { if (P_0 == null) { throw new ArgumentNullException("obj"); } Type type = P_0.GetType(); FieldInfo fieldInfo = null; while (fieldInfo == null && type != null) { fieldInfo = type.GetField(P_1, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); type = type.BaseType; } if (fieldInfo == null) { throw new ArgumentOutOfRangeException("propName", $"Field {P_1} was not found in Type {P_0.GetType().FullName}"); } return (T)fieldInfo.GetValue(P_0); } }