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 Stats My Game v1.0.4
StatsMyGameValheim.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("StatsMyGameValheim")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("StatsMyGameValheim")] [assembly: AssemblyTitle("StatsMyGameValheim")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 StatsMyGameValheim { internal class Lib { public static string getCurrentDay() { return typeof(EnvMan).GetMethod("GetCurrentDay", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(EnvMan.instance, new object[0]).ToString(); } } [BepInPlugin("com.stats-my-game.valheim", "stats-my-game.com/valheim", "1.0.4")] public class Mod : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.stats-my-game.valheim"); public static ConfigEntry<string> Key { get; private set; } private void Awake() { Key = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Key", "", "Enter the key you received at https://stats-my-game.com"); harmony.PatchAll(); } } internal class Patches { [HarmonyPatch(typeof(Game), "Start")] private class Game_Start_Patch { private static void Postfix(Game __instance) { Ws.doIt("gamestart"); } } [HarmonyPatch(typeof(Player), "Update")] private class Player_Update_Patch { private static DateTime lastUpdate = DateTime.Now; private static void Postfix() { if (!((Object)(object)Player.m_localPlayer == (Object)null) && (DateTime.Now - lastUpdate).TotalMinutes >= 1.0) { lastUpdate = DateTime.Now; Ws.doIt("update", Lib.getCurrentDay(), ((Character)Player.m_localPlayer).GetMaxHealth().ToString(), ((Character)Player.m_localPlayer).GetMaxStamina().ToString()); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private class Player_OnSpawned_Patch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { string currentDay = Lib.getCurrentDay(); if (!string.IsNullOrEmpty(currentDay)) { Ws.doIt("spawn", currentDay); } } } } [HarmonyPatch(typeof(Player), "OnDeath")] private class Player_OnDeath_Patch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { Ws.doIt("death", Lib.getCurrentDay()); } } } [HarmonyPatch(typeof(Character), "Damage")] public class Chracter_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { } public static void Postfix(Character __instance, HitData hit) { if (!((Object)(object)hit.GetAttacker() == (Object)null)) { hitsByPlayer.Remove(__instance); if ((Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer) { hitsByPlayer.Add(__instance, value: true); Ws.doIt("hit", Lib.getCurrentDay(), __instance.m_name, __instance.GetHoverName(), ((DamageTypes)(ref hit.m_damage)).GetTotalDamage().ToString()); } } } } [HarmonyPatch(typeof(Character), "OnDeath")] public class Chracter_OnDeath_Patch { public static void Prefix(Character __instance) { } public static void Postfix(Character __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!__instance.IsPlayer()) { if (hitsByPlayer.ContainsKey(__instance)) { string[] obj = new string[6] { "kill", null, null, null, null, null }; Faction faction = __instance.GetFaction(); obj[1] = ((object)(Faction)(ref faction)).ToString(); obj[2] = __instance.GetGroup().ToString(); obj[3] = ((Object)__instance).name; obj[4] = __instance.GetHoverName(); obj[5] = Lib.getCurrentDay(); Ws.doIt(obj); } hitsByPlayer.Remove(__instance); } } } [HarmonyPatch(typeof(Smelter), "QueueProcessed")] private class Smelter_QueueProcessed_Patch { private static void Postfix(string ore) { Ws.doIt("smelter", Lib.getCurrentDay(), ore); } } [HarmonyPatch(typeof(Player), "EatFood")] private class Player_EatFood_Patch { private static void Postfix(ItemData item) { Ws.doIt("eat", Lib.getCurrentDay(), item.m_shared.m_name, Localization.instance.Localize(item.m_shared.m_name), ((Character)Player.m_localPlayer).GetMaxHealth().ToString(), ((Character)Player.m_localPlayer).GetMaxStamina().ToString(), item.m_shared.m_food.ToString(), item.m_shared.m_foodStamina.ToString()); } } [HarmonyPatch(typeof(Player), "AddTrophy")] private class Player_AddTrophy_Patch { private static Dictionary<string, bool> trophies = new Dictionary<string, bool>(); private static void Postfix(ItemData item) { if (!trophies.ContainsKey(item.m_shared.m_name)) { trophies.Add(item.m_shared.m_name, value: true); Ws.doIt("trophy", Lib.getCurrentDay(), item.m_shared.m_name, Localization.instance.Localize(item.m_shared.m_name)); } } } [HarmonyPatch(typeof(Player), "SetMaxStamina")] private class Player_SetMaxStamina_Patch { private static float maxStamina; private static void Postfix(float stamina, bool flashBar) { if (stamina > maxStamina) { maxStamina = stamina; Ws.doIt("maxStamina", Lib.getCurrentDay(), stamina.ToString()); } } } [HarmonyPatch(typeof(Player), "SetMaxHealth")] private class Player_SetMaxHealth_Patch { private static float maxHealth; private static void Postfix(float health, bool flashBar) { if (health > maxHealth) { maxHealth = health; Ws.doIt("maxHealth", Lib.getCurrentDay(), health.ToString()); } } } [HarmonyPatch(typeof(Player), "OnDamaged")] private class Player_OnDamaged_Patch { private static void Postfix(HitData hit) { if (hit != null && !((Object)(object)hit.GetAttacker() == (Object)null)) { Ws.doIt("damage", Lib.getCurrentDay(), hit.GetAttacker().m_name, hit.GetAttacker().GetHoverName(), ((DamageTypes)(ref hit.m_damage)).GetTotalDamage().ToString()); } } } [HarmonyPatch(typeof(Player), "AddKnownItem")] private class Player_AddKnownItem_Patch { private static Dictionary<string, bool> items = new Dictionary<string, bool>(); private static void Postfix(ItemData item) { //IL_0076: 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) if (item.IsWeapon() && !items.ContainsKey(item.m_shared.m_name)) { items.Add(item.m_shared.m_name, value: true); Ws.doIt("itemWeapon", Lib.getCurrentDay(), item.m_shared.m_name, Localization.instance.Localize(item.m_shared.m_name), item.GetDamage().m_damage.ToString(), item.GetArmor().ToString(), item.GetBaseBlockPower().ToString(), item.GetDeflectionForce().ToString()); } } } [HarmonyPatch(typeof(Player), "AddKnownLocationName")] private class Player_AddKnownLocationName_Patch { private static void Postfix(string label) { Ws.doIt("knownLocation", Lib.getCurrentDay(), label); } } [HarmonyPatch(typeof(Player), "OnSkillLevelup")] private class Player_OnSkillLevelup_Patch { private static void Postfix(SkillType skill, float level) { Ws.doIt("OnSkillLevelup", Lib.getCurrentDay(), ((object)(SkillType)(ref skill)).ToString(), level.ToString()); } } [HarmonyPatch(typeof(Player), "SetSleeping")] private class Player_SetSleeping_Patch { private static void Postfix(bool sleep) { if (sleep) { Ws.doIt("sleep", Lib.getCurrentDay()); } } } [HarmonyPatch(typeof(Player), "AddKnownBiome")] private class Player_AddKnownBiome_Patch { private static void Postfix(Biome biome) { Ws.doIt("biome", Lib.getCurrentDay(), ((object)(Biome)(ref biome)).ToString()); } } [HarmonyPatch(typeof(CookingStation), "SpawnItem")] private class CookingStation_SpawnItem_Patch { private static void Postfix(string name, int slot, Vector3 userPoint) { Ws.doIt("cookItem", Lib.getCurrentDay(), name); } } [HarmonyPatch(typeof(Vegvisir), "Interact")] private class Vegvisir_Interact_Patch { private static void Postfix(Vegvisir __instance, Humanoid character, bool hold, bool alt) { if (character is Player) { Ws.doIt("vegvisir", Lib.getCurrentDay(), ((Object)__instance).name); } } } [HarmonyPatch(typeof(RandomEvent), "OnStart")] private class RandomEvent_OnStart_Patch { private static void Postfix(RandomEvent __instance) { if (__instance.m_nearBaseOnly) { Ws.doIt("invasion", Lib.getCurrentDay(), __instance.m_name); } } } private static Dictionary<Character, bool> hitsByPlayer = new Dictionary<Character, bool>(); } internal class Ws { private static List<Dictionary<string, string>> todo = new List<Dictionary<string, string>>(); private static readonly HttpClient client = new HttpClient(); public static async Task<bool> doIt(params string[] list) { if (ZNet.instance.GetNrOfPlayers() != 1) { return true; } Dictionary<string, string> values = new Dictionary<string, string> { { "k", Mod.Key.Value }, { "d", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") } }; int num = 0; foreach (string value in list) { num++; values.Add("p" + num, value); } string url = "stats-my-game.com"; List<Dictionary<string, string>> done = new List<Dictionary<string, string>>(); foreach (Dictionary<string, string> TheValues in todo) { try { FormUrlEncodedContent content = new FormUrlEncodedContent(TheValues); await (await client.PostAsync("https://" + url + "/api.php", content)).Content.ReadAsStringAsync(); done.Add(TheValues); } catch (Exception ex) { todo.Add(values); ex.ToString(); break; } } foreach (Dictionary<string, string> item in done) { todo.Remove(item); } if (todo.Count > 0) { return true; } try { FormUrlEncodedContent content2 = new FormUrlEncodedContent(values); await (await client.PostAsync("https://" + url + "/api.php", content2)).Content.ReadAsStringAsync(); } catch (Exception ex2) { todo.Add(values); ex2.ToString(); } return true; } } }