Decompiled source of Stats My Game v1.0.4

StatsMyGameValheim.dll

Decompiled 4 months ago
using 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;
		}
	}
}