Decompiled source of DamageMeter v3.7.0

DamageMeter.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace DamageMeter;

internal class MHPlayer
{
	public string name = "";

	public string weapon = "";

	public float dealt;

	public float taken;

	public float dps;

	public float maxHit;

	public int kills;

	public int deaths;

	public int parries;

	public int blocks;
}
internal class MFight
{
	public string time = "";

	public string boss = "";

	public int stars;

	public int seconds;

	public bool killed;

	public float dealt;

	public List<MHPlayer> players = new List<MHPlayer>();
}
internal class MTrip
{
	public string kind = "";

	public string time = "";

	public string title = "";

	public string mobs = "";

	public string bosses = "";

	public int seconds;

	public int kills;

	public float dealt;

	public List<MHPlayer> players = new List<MHPlayer>();
}
internal static class HJson
{
	public static object Parse(string s)
	{
		int i = 0;
		try
		{
			return Val(s, ref i);
		}
		catch (Exception)
		{
			return null;
		}
	}

	private static void Ws(string s, ref int i)
	{
		while (i < s.Length && char.IsWhiteSpace(s[i]))
		{
			i++;
		}
	}

	private static object Val(string s, ref int i)
	{
		Ws(s, ref i);
		switch (s[i])
		{
		case '{':
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			i++;
			Ws(s, ref i);
			if (s[i] == '}')
			{
				i++;
				return dictionary;
			}
			while (true)
			{
				Ws(s, ref i);
				string key = Str(s, ref i);
				Ws(s, ref i);
				if (s[i] != ':')
				{
					throw new FormatException();
				}
				i++;
				dictionary[key] = Val(s, ref i);
				Ws(s, ref i);
				if (s[i] != ',')
				{
					break;
				}
				i++;
			}
			if (s[i] == '}')
			{
				i++;
				return dictionary;
			}
			throw new FormatException();
		}
		case '[':
		{
			List<object> list = new List<object>();
			i++;
			Ws(s, ref i);
			if (s[i] == ']')
			{
				i++;
				return list;
			}
			while (true)
			{
				list.Add(Val(s, ref i));
				Ws(s, ref i);
				if (s[i] != ',')
				{
					break;
				}
				i++;
			}
			if (s[i] == ']')
			{
				i++;
				return list;
			}
			throw new FormatException();
		}
		case '"':
			return Str(s, ref i);
		default:
		{
			if (string.CompareOrdinal(s, i, "true", 0, 4) == 0)
			{
				i += 4;
				return true;
			}
			if (string.CompareOrdinal(s, i, "false", 0, 5) == 0)
			{
				i += 5;
				return false;
			}
			if (string.CompareOrdinal(s, i, "null", 0, 4) == 0)
			{
				i += 4;
				return null;
			}
			int num = i;
			while (i < s.Length && (char.IsDigit(s[i]) || s[i] == '-' || s[i] == '+' || s[i] == '.' || s[i] == 'e' || s[i] == 'E'))
			{
				i++;
			}
			return double.Parse(s.Substring(num, i - num), CultureInfo.InvariantCulture);
		}
		}
	}

	private static string Str(string s, ref int i)
	{
		if (s[i] != '"')
		{
			throw new FormatException();
		}
		i++;
		StringBuilder stringBuilder = new StringBuilder();
		while (s[i] != '"')
		{
			if (s[i] == '\\')
			{
				i++;
				char c = s[i];
				switch (c)
				{
				case 'n':
					stringBuilder.Append('\n');
					break;
				case 't':
					stringBuilder.Append('\t');
					break;
				case 'u':
					stringBuilder.Append((char)Convert.ToInt32(s.Substring(i + 1, 4), 16));
					i += 4;
					break;
				default:
					stringBuilder.Append(c);
					break;
				}
			}
			else
			{
				stringBuilder.Append(s[i]);
			}
			i++;
		}
		i++;
		return stringBuilder.ToString();
	}

	public static string S(object o, string k)
	{
		if (!(o is Dictionary<string, object> dictionary) || !dictionary.TryGetValue(k, out var value) || value == null)
		{
			return "";
		}
		return Convert.ToString(value, CultureInfo.InvariantCulture);
	}

	public static double N(object o, string k)
	{
		if (o is Dictionary<string, object> dictionary && dictionary.TryGetValue(k, out var value) && value is double)
		{
			return (double)value;
		}
		return 0.0;
	}

	public static bool B(object o, string k)
	{
		if (o is Dictionary<string, object> dictionary && dictionary.TryGetValue(k, out var value) && value is bool)
		{
			return (bool)value;
		}
		return false;
	}

	public static List<object> L(object o, string k)
	{
		if (!(o is Dictionary<string, object> dictionary) || !dictionary.TryGetValue(k, out var value) || !(value is List<object>))
		{
			return new List<object>();
		}
		return (List<object>)value;
	}

	public static Dictionary<string, object> D(object o, string k)
	{
		if (!(o is Dictionary<string, object> dictionary) || !dictionary.TryGetValue(k, out var value) || !(value is Dictionary<string, object>))
		{
			return new Dictionary<string, object>();
		}
		return (Dictionary<string, object>)value;
	}
}
internal static class HHist
{
	private static List<string> Last(string path, int max)
	{
		List<string> list = new List<string>();
		try
		{
			if (!File.Exists(path))
			{
				return list;
			}
			string[] array = File.ReadAllLines(path);
			for (int i = Math.Max(0, array.Length - max); i < array.Length; i++)
			{
				if (array[i].Trim().Length > 2)
				{
					list.Add(array[i]);
				}
			}
		}
		catch (Exception)
		{
		}
		return list;
	}

	private static void Players(object o, List<MHPlayer> into)
	{
		foreach (object item in HJson.L(o, "players"))
		{
			if (into.Count >= 8)
			{
				break;
			}
			MHPlayer mHPlayer = new MHPlayer();
			mHPlayer.name = HJson.S(item, "name");
			mHPlayer.dealt = (float)HJson.N(item, "dealt");
			mHPlayer.taken = (float)(HJson.N(item, "taken") + HJson.N(item, "dot"));
			mHPlayer.kills = (int)HJson.N(item, "kills");
			mHPlayer.deaths = (int)HJson.N(item, "deaths");
			mHPlayer.parries = (int)HJson.N(item, "parries");
			mHPlayer.blocks = (int)HJson.N(item, "blocks");
			mHPlayer.dps = (float)HJson.N(item, "dps");
			mHPlayer.maxHit = (float)HJson.N(item, "maxHit");
			mHPlayer.weapon = HJson.S(item, "weapon");
			if (mHPlayer.name.Length > 0 && (mHPlayer.dealt > 0f || mHPlayer.deaths > 0 || mHPlayer.kills > 0))
			{
				into.Add(mHPlayer);
			}
		}
		into.Sort((MHPlayer a, MHPlayer b) => b.dealt.CompareTo(a.dealt));
	}

	public static List<MFight> Fights(string path, int max)
	{
		List<MFight> list = new List<MFight>();
		foreach (string item in Last(path, 120))
		{
			object obj = HJson.Parse(item);
			if (obj != null)
			{
				MFight mFight = new MFight();
				mFight.time = HJson.S(obj, "time");
				mFight.boss = HJson.S(obj, "boss");
				mFight.stars = (int)HJson.N(obj, "stars");
				mFight.killed = HJson.B(obj, "killed");
				mFight.seconds = (int)HJson.N(obj, "seconds");
				mFight.dealt = (float)HJson.N(obj, "dealt");
				Players(obj, mFight.players);
				if (mFight.boss.Length > 0)
				{
					list.Add(mFight);
				}
			}
		}
		list.Reverse();
		if (list.Count > max)
		{
			list.RemoveRange(max, list.Count - max);
		}
		return list;
	}

	private static string MobText(object o)
	{
		List<KeyValuePair<string, double>> list = new List<KeyValuePair<string, double>>();
		foreach (KeyValuePair<string, object> item in HJson.D(o, "mobs"))
		{
			if (item.Value is double)
			{
				list.Add(new KeyValuePair<string, double>(item.Key, (double)item.Value));
			}
		}
		list.Sort((KeyValuePair<string, double> a, KeyValuePair<string, double> b) => b.Value.CompareTo(a.Value));
		StringBuilder stringBuilder = new StringBuilder();
		for (int num = 0; num < list.Count && num < 14; num++)
		{
			if (num > 0)
			{
				stringBuilder.Append(", ");
			}
			stringBuilder.Append(list[num].Key).Append(" x").Append((int)list[num].Value);
		}
		return stringBuilder.ToString();
	}

	public static List<MTrip> Trips(string expPath, string sessPath, int max)
	{
		List<MTrip> list = new List<MTrip>();
		foreach (string item in Last(expPath, 60))
		{
			object obj = HJson.Parse(item);
			if (obj == null)
			{
				continue;
			}
			MTrip mTrip = new MTrip();
			mTrip.kind = "E";
			mTrip.time = HJson.S(obj, "start");
			string text = HJson.S(obj, "name");
			string text2 = HJson.S(obj, "leader");
			mTrip.title = ((text.Length > 0) ? (text + " (" + text2 + ")") : text2);
			mTrip.seconds = (int)HJson.N(obj, "seconds");
			mTrip.kills = (int)HJson.N(obj, "kills");
			mTrip.dealt = (float)HJson.N(obj, "dealt");
			mTrip.mobs = MobText(obj);
			Players(obj, mTrip.players);
			StringBuilder stringBuilder = new StringBuilder();
			foreach (object item2 in HJson.L(obj, "bosses"))
			{
				string text3 = Convert.ToString(item2, CultureInfo.InvariantCulture);
				if (text3.Length > 0 && stringBuilder.ToString().IndexOf(text3, StringComparison.Ordinal) < 0)
				{
					if (stringBuilder.Length > 0)
					{
						stringBuilder.Append(", ");
					}
					stringBuilder.Append(text3);
				}
			}
			mTrip.bosses = stringBuilder.ToString();
			list.Add(mTrip);
		}
		foreach (string item3 in Last(sessPath, 200))
		{
			object obj2 = HJson.Parse(item3);
			if (obj2 != null)
			{
				int num = (int)HJson.N(obj2, "kills");
				if (num >= 8 || !(HJson.N(obj2, "dealt") < 6000.0))
				{
					MTrip mTrip2 = new MTrip();
					mTrip2.kind = "S";
					mTrip2.time = HJson.S(obj2, "time");
					mTrip2.title = HJson.S(obj2, "biome");
					mTrip2.seconds = (int)HJson.N(obj2, "seconds");
					mTrip2.kills = num;
					mTrip2.dealt = (float)HJson.N(obj2, "dealt");
					mTrip2.mobs = MobText(obj2);
					Players(obj2, mTrip2.players);
					list.Add(mTrip2);
				}
			}
		}
		list.Sort((MTrip a, MTrip b) => string.CompareOrdinal(b.time, a.time));
		if (list.Count > max)
		{
			list.RemoveRange(max, list.Count - max);
		}
		return list;
	}
}
internal class MenuDrag : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
	internal RectTransform target;

	internal Canvas canvas;

	internal Action<Vector2> moved;

	internal Action reset;

	internal bool dragging;

	public void OnBeginDrag(PointerEventData e)
	{
		dragging = true;
	}

	public void OnDrag(PointerEventData e)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && !((Object)(object)canvas == (Object)null))
		{
			Vector2 val = target.anchoredPosition + e.delta / Mathf.Max(0.01f, canvas.scaleFactor);
			Rect rect = ((RectTransform)((Component)canvas).transform).rect;
			Vector2 val2 = ((Rect)(ref rect)).size * 0.5f;
			val.x = Mathf.Clamp(val.x, 0f - val2.x, val2.x);
			val.y = Mathf.Clamp(val.y, 0f - val2.y, val2.y);
			target.anchoredPosition = val;
		}
	}

	public void OnEndDrag(PointerEventData e)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		dragging = false;
		if (moved != null)
		{
			moved(target.anchoredPosition);
		}
	}

	public void OnPointerClick(PointerEventData e)
	{
		if (e.clickCount >= 2 && reset != null)
		{
			reset();
		}
	}
}
[BepInPlugin("dukr.dmgmeter", "DamageMeter", "3.7.0")]
public class Plugin : BaseUnityPlugin
{
	internal class Ev
	{
		public byte type;

		public string attacker;

		public string victim;

		public string recap;

		public long vUser;

		public uint vId;

		public float amount;

		public float maxHp;

		public float vx;

		public float vz;

		public bool boss;

		public bool killed;

		public bool dot;

		public bool parry;

		public bool guardBreak;

		public int level;

		public float[] types;

		public float t;

		public float px;

		public float pz;
	}

	internal class Hit
	{
		public float t;

		public string src;

		public float amount;

		public string kind;

		public float hp;
	}

	private class PS
	{
		public float dealt;

		public float dotDealt;

		public float taken;

		public float dot;

		public float blocked;

		public float maxHit;

		public float firstT = -1f;

		public float lastT;

		public float activeT;

		public float lastActT = -100f;

		public int blocks;

		public int parries;

		public int breaks;

		public int deaths;

		public int kills;

		public float[] types = new float[8];

		public Dictionary<string, float> weapons = new Dictionary<string, float>();

		public List<KeyValuePair<float, float>> hits = new List<KeyValuePair<float, float>>();
	}

	private class Enc
	{
		public string key;

		public string name;

		public string baseName;

		public long user;

		public uint id;

		public float max;

		public int level;

		public Vector2 pos;

		public int count = 1;

		public float startT;

		public float lastT;

		public float endAt;

		public bool boss;

		public bool killed;

		public bool final;

		public Dictionary<string, PS> ps = new Dictionary<string, PS>();

		public List<string> recaps = new List<string>();
	}

	private class Sess
	{
		public Vector2 pos;

		public float startT;

		public float lastT;

		public float enemyHp;

		public int kills;

		public Dictionary<string, PS> ps = new Dictionary<string, PS>();

		public Dictionary<string, int> mobs = new Dictionary<string, int>();

		public HashSet<string> killed = new HashSet<string>();
	}

	private class Exp
	{
		public string leader;

		public string name = "";

		public DateTime wall;

		public float startT;

		public float enemyHp;

		public int kills;

		public Dictionary<string, PS> ps = new Dictionary<string, PS>();

		public Dictionary<string, int> mobs = new Dictionary<string, int>();

		public HashSet<string> killed = new HashSet<string>();

		public List<string> bosses = new List<string>();
	}

	private class LiveRow
	{
		public string name;

		public float dealt;

		public float dps;

		public float taken;

		public int deaths;

		public int parries;

		public int kills;

		public bool mod;
	}

	private class LiveData
	{
		public string title;

		public int stars;

		public int seconds;

		public bool boss;

		public bool exp;

		public List<LiveRow> rows = new List<LiveRow>();

		public float at;

		public float until;

		public float cx;

		public float cz;

		public float lastEvent;

		public int version;
	}

	private class LiveRowUi
	{
		public GameObject root;

		public Image bg;

		public Image fill;

		public Image sel;

		public Text name;

		public Text dealt;

		public Text pct;

		public Text dps;

		public Text taken;

		public Text parry;

		public Text kills;

		public Text died;
	}

	private class InvSnap
	{
		public DateTime time;

		public Dictionary<string, int> items = new Dictionary<string, int>();
	}

	private class Row
	{
		public string name;

		public float dealt;

		public float dps;

		public float maxHit;

		public float taken;

		public float dot;

		public float blocked;

		public int blocks;

		public int parries;

		public int breaks;

		public int deaths;

		public bool mod;

		public string weapon;
	}

	private class Summary
	{
		public string boss;

		public int stars;

		public int seconds;

		public bool killed;

		public float other;

		public float accounted;

		public float shownAt;

		public List<Row> rows = new List<Row>();

		public List<string> awards = new List<string>();

		public List<string> recaps = new List<string>();
	}

	private class SEv
	{
		public byte type;

		public string attacker;

		public string victim;

		public string aprefab;

		public string recap;

		public long vu;

		public long au;

		public uint vid;

		public uint aid;

		public float amount;

		public float max;

		public float vx;

		public float vz;

		public float lost;

		public float age;

		public float px;

		public float pz;

		public bool boss;

		public bool killed;

		public bool dot;

		public bool aboss;

		public bool parry;

		public bool brk;

		public bool hasPos;

		public int level;

		public float[] types;
	}

	private delegate float Sel(PS s);

	private class FightView
	{
		public string title;

		public int stars;

		public bool boss;

		public int secs;

		public Vector2 pos;

		public float lastT;

		public Dictionary<string, PS> ps;

		public Enc enc;

		public Sess sess;
	}

	private const string RpcHistReq = "dukr_histreq";

	private const string RpcHist = "dukr_hist";

	private ConfigEntry<KeyboardShortcut> menuKey;

	private ConfigEntry<Vector2> menuPos;

	private ConfigEntry<float> menuScale;

	private bool menuOpen;

	private bool menuOpenedInv;

	private bool menuNeedRender;

	private float menuOpenAt;

	private float menuHistReqAt;

	private int menuTab;

	private int menuScroll;

	private int menuDetail = -1;

	private string menuName = "";

	private GameObject menuRoot;

	private GameObject menuInputGo;

	private GameObject menuDragGo;

	private RectTransform menuPanel;

	private Font menuFont;

	private InputField menuInput;

	private MenuDrag menuDrag;

	private readonly List<GameObject> menuDyn = new List<GameObject>();

	private readonly List<MFight> menuFights = new List<MFight>();

	private readonly List<MTrip> menuTrips = new List<MTrip>();

	private bool menuHistOk;

	private LiveData menuExp;

	private float menuExpAt;

	private static readonly string[] MenuTabs = new string[4] { "Expedition", "Bosses", "Trips", "Settings" };

	private static readonly Color MParch = new Color(0.93f, 0.89f, 0.78f, 1f);

	private static readonly Color MGold = new Color(1f, 0.8f, 0.35f, 1f);

	private static readonly Color MGoldDim = new Color(0.86f, 0.7f, 0.4f, 1f);

	private static readonly Color MDim = new Color(0.62f, 0.58f, 0.48f, 1f);

	private readonly Dictionary<long, float> histAsk = new Dictionary<long, float>();

	private List<MFight> sFights = new List<MFight>();

	private List<MTrip> sTrips = new List<MTrip>();

	private float sHistAt = -100f;

	private RectTransform curPanel;

	private List<GameObject> curDyn;

	private static object locObj;

	private static MethodInfo locM;

	private static bool locTried;

	private const float MW = 940f;

	private const float MHead = 76f;

	private const float MRow = 26f;

	private GameObject sumRoot;

	private RectTransform sumPanel;

	private readonly List<GameObject> sumDyn = new List<GameObject>();

	private Summary sumData;

	private float sumAt;

	private Summary sumDrawn;

	internal static Plugin I;

	private const string RpcLegacy = "dukr_dmg";

	private const string RpcEv = "dukr_ev2";

	private const string RpcSummary = "dukr_dmg_summary";

	private const string RpcSum2 = "dukr_dmg_sum2";

	private const string RpcCmd = "dukr_cmd";

	private const string RpcReply = "dukr_reply";

	private static readonly string[] TypeNames = new string[8] { "blunt", "slash", "pierce", "fire", "frost", "lightning", "poison", "spirit" };

	private static readonly CultureInfo Inv = CultureInfo.InvariantCulture;

	private static readonly List<Ev> buf = new List<Ev>();

	private static float lastX;

	private static float lastZ;

	private static string lastName;

	private float flushAt;

	private bool helloSent;

	internal static readonly List<Hit> recent = new List<Hit>();

	internal static readonly Dictionary<string, KeyValuePair<string, float>> appliers = new Dictionary<string, KeyValuePair<string, float>>();

	private Exp exp;

	private float expSaveAt;

	private ConfigEntry<string> expStartPolicy;

	private readonly HashSet<string> caps5 = new HashSet<string>();

	private readonly List<Sess> sessions = new List<Sess>();

	private readonly Dictionary<string, int> killTotals = new Dictionary<string, int>();

	private const float SessionGap = 25f;

	private const float SessionRange = 120f;

	private const int MaxSessions = 20;

	private ConfigEntry<int> sessionChatKills;

	private ConfigEntry<bool> summaryRecaps;

	private readonly Dictionary<string, Enc> encs = new Dictionary<string, Enc>();

	private readonly HashSet<string> modPlayers = new HashSet<string>();

	private readonly HashSet<string> v3Players = new HashSet<string>();

	private readonly HashSet<string> caps3 = new HashSet<string>();

	private readonly Dictionary<string, int> protoOf = new Dictionary<string, int>();

	private readonly Dictionary<string, float> win = new Dictionary<string, float>();

	private readonly List<string> lastTables = new List<string>();

	private readonly Dictionary<string, float[]> life = new Dictionary<string, float[]>();

	private readonly Dictionary<string, string[]> records = new Dictionary<string, string[]>();

	private float sweepAt;

	private float winAt;

	private object registeredFor;

	private string dataDir;

	private readonly Dictionary<string, float> finished = new Dictionary<string, float>();

	private const int MaxLiveFights = 60;

	private const int MaxPlayersPerFight = 24;

	private const int MaxRecapsPerFight = 12;

	private float warnAt;

	private const string RpcLive = "dukr_live";

	private readonly List<LiveData> fights4 = new List<LiveData>();

	private bool haveV4;

	private float demoUntil;

	private static readonly string[] LiveModes = new string[5] { "Near me", "Bosses only", "Everything", "Expedition", "Off" };

	private ConfigEntry<KeyboardShortcut> expKey;

	private ConfigEntry<bool> showExp;

	internal static bool expRunningSeen;

	private static float expSeenAt;

	private ConfigEntry<string> liveMode;

	private ConfigEntry<float> liveRange;

	private ConfigEntry<float> liveBossRange;

	private ConfigEntry<float> liveMinDmg;

	private ConfigEntry<float> liveHoldCfg;

	private ConfigEntry<bool> liveOnlyMine;

	private ConfigEntry<bool> chatSummaries;

	private ConfigEntry<KeyboardShortcut> modeKey;

	private ConfigEntry<float> srvRange;

	private ConfigEntry<float> srvBossRange;

	private readonly HashSet<string> caps4 = new HashSet<string>();

	private readonly HashSet<long> liveHad = new HashSet<long>();

	private LiveData live;

	private static int liveVersion;

	private int liveShownVersion = -1;

	private bool liveUserHidden;

	private float liveAt;

	private bool liveSent;

	private ConfigEntry<bool> liveEnabled;

	private ConfigEntry<bool> liveBars;

	private ConfigEntry<bool> liveAuto;

	private ConfigEntry<KeyboardShortcut> liveKey;

	private ConfigEntry<int> liveVer;

	private ConfigEntry<float> liveMinDamage;

	private ConfigEntry<float> liveHold;

	private Enc holdEnc;

	private float holdUntil;

	private ConfigEntry<float> liveX;

	private ConfigEntry<float> liveY;

	private ConfigEntry<float> liveScale;

	private ConfigEntry<float> liveWidth;

	private ConfigEntry<float> liveOpacity;

	private ConfigEntry<float> liveBarOpacity;

	private GameObject liveRoot;

	private RectTransform liveCanvasRect;

	private RectTransform livePanelRect;

	private Image livePanelImage;

	private Font liveFont;

	private Text liveTitle;

	private Text liveState;

	private Text liveTime;

	private readonly List<Text> liveHeads = new List<Text>();

	private readonly List<LiveRowUi> liveRows = new List<LiveRowUi>();

	private float liveAutoW;

	private float liveW;

	private float liveS;

	private float liveO;

	private float liveAlpha;

	private CanvasGroup liveGroup;

	private Image liveHead;

	private Image liveBorder;

	private Image liveSep1;

	private Image liveSep2;

	private static readonly uint[] Palette = new uint[12]
	{
		5809919u, 16756060u, 6935196u, 13994726u, 15126370u, 15759496u, 6084053u, 11048959u, 11851371u, 15569340u,
		7912913u, 14067320u
	};

	private const string RpcInv = "dukr_inv";

	private ConfigEntry<bool> invLogOn;

	private readonly Dictionary<string, float> joinSeen = new Dictionary<string, float>();

	private readonly HashSet<string> invSession = new HashSet<string>();

	private readonly HashSet<string> invMissing = new HashSet<string>();

	private float spawnAt;

	private float invNext;

	private float invChangedAt;

	private string invSig;

	private string invSeen;

	private bool invLogin = true;

	private ZNetPeer invPeer;

	private static Type abApi;

	private static MethodInfo abIsBackpack;

	private static MethodInfo abTryGet;

	private static bool abInit;

	private readonly Dictionary<string, InvSnap> invLast = new Dictionary<string, InvSnap>();

	private readonly Dictionary<string, string> invLoginDiff = new Dictionary<string, string>();

	private Dictionary<int, string> itemNames = new Dictionary<int, string>();

	private Summary shown;

	private ConfigEntry<string> logFile;

	private ConfigEntry<float> reportSeconds;

	private ConfigEntry<float> showSeconds;

	private ConfigEntry<float> engageRange;

	private ConfigEntry<bool> showTable;

	private ConfigEntry<bool> jokeAwards;

	private const float GroupIdle = 200f;

	private readonly Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>();

	private static readonly Color Parchment = new Color(0.93f, 0.89f, 0.78f, 1f);

	private static readonly Color Gold = new Color(1f, 0.8f, 0.35f, 1f);

	private static readonly Color GoldDim = new Color(0.86f, 0.7f, 0.4f, 1f);

	private static readonly Color Blood = new Color(0.93f, 0.4f, 0.34f, 1f);

	private const float HeadH = 30f;

	private const float ColH = 18f;

	private const float RowH = 19f;

	private const float TopPad = 4f;

	private GUIStyle label;

	private GUIStyle head;

	private GUIStyle box;

	private GUIStyle small;

	private Texture2D bg;

	private void MenuAwake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Menu", "Menu key", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Opens the DamageMeter menu: start, stop and rename an expedition, history of expeditions and boss fights, live panel settings. Everything is clicked with the mouse.");
		menuPos = ((BaseUnityPlugin)this).Config.Bind<Vector2>("Menu", "Position", Vector2.zero, "Offset of the menu window from the middle of the screen (canvas pixels). Drag the window to move it, double-click an empty part to center it.");
		menuScale = ((BaseUnityPlugin)this).Config.Bind<float>("Menu", "Scale", 1f, new ConfigDescription("Size of the menu window.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2f), Array.Empty<object>()));
	}

	private void MenuRegister()
	{
		ZRoutedRpc.instance.Register<string>("dukr_histreq", (Action<long, string>)OnHistReq);
		ZRoutedRpc.instance.Register<ZPackage>("dukr_hist", (Action<long, ZPackage>)OnHist);
	}

	private static void WriteMP(ZPackage o, MHPlayer p)
	{
		o.Write(Clean(p.name, 48));
		o.Write(p.dealt);
		o.Write(p.taken);
		o.Write(p.kills);
		o.Write(p.deaths);
		o.Write(p.parries);
		o.Write(p.blocks);
		o.Write(p.dps);
		o.Write(p.maxHit);
		o.Write(Clean(p.weapon, 40));
	}

	private static MHPlayer ReadMP(ZPackage k)
	{
		return new MHPlayer
		{
			name = Clean(k.ReadString(), 48),
			dealt = k.ReadSingle(),
			taken = k.ReadSingle(),
			kills = k.ReadInt(),
			deaths = k.ReadInt(),
			parries = k.ReadInt(),
			blocks = k.ReadInt(),
			dps = k.ReadSingle(),
			maxHit = k.ReadSingle(),
			weapon = Clean(k.ReadString(), 40)
		};
	}

	private void OnHistReq(long sender, string req)
	{
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return;
		}
		try
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (histAsk.TryGetValue(sender, out var value) && realtimeSinceStartup - value < 2f)
			{
				return;
			}
			histAsk[sender] = realtimeSinceStartup;
			if (realtimeSinceStartup - sHistAt > 10f)
			{
				sHistAt = realtimeSinceStartup;
				sFights = HHist.Fights(Path.Combine(dataDir, "encounters.jsonl"), 14);
				sTrips = HHist.Trips(Path.Combine(dataDir, "expeditions.jsonl"), Path.Combine(dataDir, "sessions.jsonl"), 14);
			}
			ZPackage val = new ZPackage();
			val.Write((byte)1);
			val.Write(sFights.Count);
			foreach (MFight sFight in sFights)
			{
				val.Write(Clean(sFight.time, 20));
				val.Write(Clean(sFight.boss, 40));
				val.Write(sFight.stars);
				val.Write(sFight.killed);
				val.Write(sFight.seconds);
				val.Write(sFight.dealt);
				int num = Math.Min(8, sFight.players.Count);
				val.Write(num);
				for (int i = 0; i < num; i++)
				{
					WriteMP(val, sFight.players[i]);
				}
			}
			val.Write(sTrips.Count);
			foreach (MTrip sTrip in sTrips)
			{
				val.Write(sTrip.kind);
				val.Write(Clean(sTrip.time, 20));
				val.Write(Clean(sTrip.title, 60));
				val.Write(sTrip.seconds);
				val.Write(sTrip.kills);
				val.Write(sTrip.dealt);
				val.Write(Clean(sTrip.mobs, 300));
				val.Write(Clean(sTrip.bosses, 100));
				int num2 = Math.Min(8, sTrip.players.Count);
				val.Write(num2);
				for (int j = 0; j < num2; j++)
				{
					WriteMP(val, sTrip.players[j]);
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "dukr_hist", new object[1] { val });
		}
		catch (Exception ex)
		{
			Warn("DamageMeter history request: " + ex.Message);
		}
	}

	private void OnHist(long sender, ZPackage pkg)
	{
		if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || !FromServer(sender))
		{
			return;
		}
		try
		{
			if (pkg.ReadByte() != 1)
			{
				return;
			}
			List<MFight> list = new List<MFight>();
			List<MTrip> list2 = new List<MTrip>();
			int num = pkg.ReadInt();
			if (num < 0 || num > 30)
			{
				return;
			}
			for (int i = 0; i < num; i++)
			{
				MFight mFight = new MFight();
				mFight.time = Clean(pkg.ReadString(), 20);
				mFight.boss = Clean(pkg.ReadString(), 40);
				mFight.stars = pkg.ReadInt();
				mFight.killed = pkg.ReadBool();
				mFight.seconds = pkg.ReadInt();
				mFight.dealt = pkg.ReadSingle();
				int num2 = pkg.ReadInt();
				if (num2 < 0 || num2 > 12)
				{
					return;
				}
				for (int j = 0; j < num2; j++)
				{
					mFight.players.Add(ReadMP(pkg));
				}
				list.Add(mFight);
			}
			int num3 = pkg.ReadInt();
			if (num3 < 0 || num3 > 30)
			{
				return;
			}
			for (int k = 0; k < num3; k++)
			{
				MTrip mTrip = new MTrip();
				mTrip.kind = Clean(pkg.ReadString(), 2);
				mTrip.time = Clean(pkg.ReadString(), 20);
				mTrip.title = Clean(pkg.ReadString(), 60);
				mTrip.seconds = pkg.ReadInt();
				mTrip.kills = pkg.ReadInt();
				mTrip.dealt = pkg.ReadSingle();
				mTrip.mobs = Clean(pkg.ReadString(), 300);
				mTrip.bosses = Clean(pkg.ReadString(), 100);
				int num4 = pkg.ReadInt();
				if (num4 < 0 || num4 > 12)
				{
					return;
				}
				for (int l = 0; l < num4; l++)
				{
					mTrip.players.Add(ReadMP(pkg));
				}
				list2.Add(mTrip);
			}
			menuFights.Clear();
			menuFights.AddRange(list);
			menuTrips.Clear();
			menuTrips.AddRange(list2);
			menuHistOk = true;
			menuNeedRender = true;
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter history parse: " + ex.Message));
		}
	}

	internal void MenuToggle()
	{
		if (menuOpen)
		{
			MenuClose();
			return;
		}
		menuOpen = true;
		menuOpenAt = Time.realtimeSinceStartup;
		menuNeedRender = true;
		menuDetail = -1;
		menuScroll = 0;
		MenuAskHistory(force: true);
		try
		{
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance != (Object)null && !InventoryGui.IsVisible())
			{
				instance.Show((Container)null, 1);
				menuOpenedInv = true;
			}
		}
		catch (Exception)
		{
		}
	}

	private void MenuClose()
	{
		menuOpen = false;
		if ((Object)(object)menuRoot != (Object)null && menuRoot.activeSelf)
		{
			menuRoot.SetActive(false);
		}
		try
		{
			if (menuOpenedInv && (Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible())
			{
				InventoryGui.instance.Hide();
			}
		}
		catch (Exception)
		{
		}
		menuOpenedInv = false;
	}

	private void MenuAskHistory(bool force)
	{
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		if (!force && realtimeSinceStartup - menuHistReqAt < 10f)
		{
			return;
		}
		menuHistReqAt = realtimeSinceStartup;
		try
		{
			ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null);
			if (val != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "dukr_histreq", new object[1] { "h" });
			}
		}
		catch (Exception)
		{
		}
	}

	private void MenuTick(float now)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		bool flag = ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || ((Object)(object)menuInput != (Object)null && menuInput.isFocused);
		KeyboardShortcut value = menuKey.Value;
		KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
		if ((int)mainKey != 0 && !flag && Input.GetKeyDown(mainKey))
		{
			MenuToggle();
		}
		if (menuOpen && now - menuOpenAt > 0.5f && !InventoryGui.IsVisible())
		{
			menuOpen = false;
			menuOpenedInv = false;
		}
		if (!menuOpen || Menu.IsVisible() || Minimap.IsOpen() || TextInput.IsVisible())
		{
			if ((Object)(object)menuRoot != (Object)null && menuRoot.activeSelf)
			{
				menuRoot.SetActive(false);
			}
			return;
		}
		if (menuTab == 1 || menuTab == 2)
		{
			MenuAskHistory(force: false);
		}
		float y = Input.mouseScrollDelta.y;
		if (y != 0f && (menuTab == 1 || menuTab == 2) && menuDetail < 0)
		{
			menuScroll -= (int)Mathf.Sign(y);
			menuNeedRender = true;
		}
		if (!((Object)(object)menuRoot == (Object)null) || MenuCreate())
		{
			if (!menuRoot.activeSelf)
			{
				menuRoot.SetActive(true);
				menuNeedRender = true;
			}
			MenuSyncSorting();
			if (menuNeedRender)
			{
				menuNeedRender = false;
				MenuRender();
			}
		}
	}

	private bool MenuCreate()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Expected O, but got Unknown
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			menuFont = ResolveLiveFont();
			if ((Object)(object)menuFont == (Object)null)
			{
				return false;
			}
			menuRoot = new GameObject("DamageMeterMenu", new Type[4]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Object.DontDestroyOnLoad((Object)(object)menuRoot);
			Canvas component = menuRoot.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 42;
			CanvasScaler component2 = menuRoot.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			component2.matchWidthOrHeight = 0.5f;
			GameObject val = new GameObject("Panel", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(menuRoot.transform, false);
			menuPanel = (RectTransform)val.transform;
			RectTransform obj = menuPanel;
			Vector2 anchorMin = (menuPanel.anchorMax = new Vector2(0.5f, 0.5f));
			obj.anchorMin = anchorMin;
			menuPanel.pivot = new Vector2(0.5f, 0.5f);
			menuPanel.anchoredPosition = menuPos.Value;
			return true;
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter menu creation failed: " + ex.Message));
			if ((Object)(object)menuRoot != (Object)null)
			{
				Object.Destroy((Object)(object)menuRoot);
			}
			menuRoot = null;
			return false;
		}
	}

	private void MenuSyncSorting()
	{
		try
		{
			int num = 42;
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_player != (Object)null)
			{
				Canvas componentInParent = ((Component)instance.m_player).GetComponentInParent<Canvas>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					num = Math.Max(num, componentInParent.rootCanvas.sortingOrder + 10);
				}
			}
			Canvas val = (((Object)(object)menuRoot != (Object)null) ? menuRoot.GetComponent<Canvas>() : null);
			if ((Object)(object)val != (Object)null && val.sortingOrder != num)
			{
				val.sortingOrder = num;
			}
		}
		catch (Exception)
		{
		}
	}

	private static void MRect(RectTransform r, float x, float y, float w, float h)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		r.anchorMin = new Vector2(0f, 1f);
		r.anchorMax = new Vector2(0f, 1f);
		r.pivot = new Vector2(0f, 1f);
		r.anchoredPosition = new Vector2(x, y);
		r.sizeDelta = new Vector2(w, h);
	}

	private Image MImg(string name, string sprite, Color col, bool sliced, bool fill)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[2]
		{
			typeof(RectTransform),
			typeof(Image)
		});
		val.transform.SetParent((Transform)(object)curPanel, false);
		RectTransform val2 = (RectTransform)val.transform;
		val2.anchorMin = Vector2.zero;
		val2.anchorMax = Vector2.one;
		val2.offsetMin = Vector2.zero;
		val2.offsetMax = Vector2.zero;
		Image component = val.GetComponent<Image>();
		((Graphic)component).raycastTarget = false;
		((Graphic)component).color = col;
		Sprite val3 = ((sprite != null) ? FindSprite(sprite) : null);
		if ((Object)(object)val3 != (Object)null)
		{
			component.sprite = val3;
			if (sliced)
			{
				component.type = (Type)1;
				component.pixelsPerUnitMultiplier = 2.5f;
			}
		}
		curDyn.Add(val);
		return component;
	}

	private Text MText(string text, float x, float y, float w, float h, int size, TextAnchor al, FontStyle st, Color col)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("T", new Type[2]
		{
			typeof(RectTransform),
			typeof(Text)
		});
		val.transform.SetParent((Transform)(object)curPanel, false);
		MRect((RectTransform)val.transform, x, y, w, h);
		Text component = val.GetComponent<Text>();
		component.font = menuFont;
		component.fontSize = size;
		component.fontStyle = st;
		component.alignment = al;
		((Graphic)component).color = col;
		((Graphic)component).raycastTarget = false;
		component.text = text;
		component.horizontalOverflow = (HorizontalWrapMode)1;
		component.verticalOverflow = (VerticalWrapMode)0;
		Outline obj = val.AddComponent<Outline>();
		((Shadow)obj).effectColor = new Color(0f, 0f, 0f, 0.8f);
		((Shadow)obj).effectDistance = new Vector2(1f, -1f);
		curDyn.Add(val);
		return component;
	}

	private void MClick(float x, float y, float w, float h, UnityAction act)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Click", new Type[3]
		{
			typeof(RectTransform),
			typeof(Image),
			typeof(Button)
		});
		val.transform.SetParent((Transform)(object)curPanel, false);
		MRect((RectTransform)val.transform, x, y, w, h);
		Image component = val.GetComponent<Image>();
		((Graphic)component).color = new Color(1f, 1f, 1f, 0.004f);
		((Graphic)component).raycastTarget = true;
		((UnityEvent)val.GetComponent<Button>().onClick).AddListener(act);
		curDyn.Add(val);
	}

	private void MButton(string label, float x, float y, float w, float h, bool on, UnityAction act)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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_005f: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		MRect((RectTransform)((Component)MImg("BtnFill", "panel_interior_bkg_128", on ? new Color(0.55f, 0.36f, 0.18f, 0.95f) : new Color(0.26f, 0.19f, 0.13f, 0.95f), sliced: true, fill: false)).transform, x, y, w, h);
		MRect((RectTransform)((Component)MImg("BtnBorder", "panel_border_128", new Color(1f, 1f, 1f, on ? 0.95f : 0.6f), sliced: true, fill: false)).transform, x, y, w, h);
		MText(label, x, y, w, h, 14, (TextAnchor)4, (FontStyle)1, on ? MGold : MParch);
		MClick(x, y, w, h, act);
	}

	private static string Nf(double v)
	{
		return ((long)Math.Round(v)).ToString("#,0", Inv).Replace(',', ' ');
	}

	private static string LocOrNull(string token)
	{
		try
		{
			if (!locTried || locObj == null)
			{
				locTried = true;
				Type type = AccessTools.TypeByName("Localization");
				if (type != null)
				{
					PropertyInfo propertyInfo = AccessTools.Property(type, "instance");
					FieldInfo fieldInfo = AccessTools.Field(type, "m_instance");
					locObj = ((propertyInfo != null) ? propertyInfo.GetValue(null, null) : ((fieldInfo != null) ? fieldInfo.GetValue(null) : null));
					locM = AccessTools.Method(type, "Localize", new Type[1] { typeof(string) }, (Type[])null);
				}
			}
			if (locObj != null && locM != null)
			{
				string text = locM.Invoke(locObj, new object[1] { token }) as string;
				if (!string.IsNullOrEmpty(text) && text != token && text.IndexOf('$') < 0)
				{
					return text;
				}
			}
		}
		catch (Exception)
		{
		}
		return null;
	}

	private static string Humanize(string v)
	{
		if (string.IsNullOrEmpty(v))
		{
			return "?";
		}
		v = v.Replace("_TW", "").Replace('_', ' ');
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < v.Length; i++)
		{
			if (i > 0 && char.IsUpper(v[i]) && char.IsLower(v[i - 1]))
			{
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(v[i]);
		}
		return stringBuilder.ToString();
	}

	private static string BossLabel(string prefab)
	{
		return LocOrNull("$enemy_" + (prefab ?? "").ToLowerInvariant()) ?? Humanize(prefab);
	}

	private static string When(string t)
	{
		string text;
		if (!DateTime.TryParse(t, Inv, DateTimeStyles.None, out var result))
		{
			text = t;
			if (text == null)
			{
				return "";
			}
		}
		else
		{
			text = result.ToString("dd.MM. HH:mm", Inv);
		}
		return text;
	}

	private static Color PColor(string name)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		uint num = Palette[(uint)Hash(name) % (uint)Palette.Length];
		return new Color((float)((num >> 16) & 0xFF) / 255f, (float)((num >> 8) & 0xFF) / 255f, (float)(num & 0xFF) / 255f, 1f);
	}

	private void MenuRender()
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_033e: Expected O, but got Unknown
		//IL_035d: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Expected O, but got Unknown
		//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0503: Expected O, but got Unknown
		//IL_0468: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0494: Expected O, but got Unknown
		curPanel = menuPanel;
		curDyn = menuDyn;
		foreach (GameObject item in menuDyn)
		{
			if ((Object)(object)item != (Object)null)
			{
				Object.Destroy((Object)(object)item);
			}
		}
		menuDyn.Clear();
		foreach (Transform item2 in (Transform)menuPanel)
		{
			Transform val = item2;
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)(object)menuInputGo && (Object)(object)((Component)val).gameObject != (Object)(object)menuDragGo)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		bool flag = expRunningSeen && realtimeSinceStartup - expSeenAt < 5f && menuExp != null;
		int num = ((menuTab == 1) ? menuFights.Count : ((menuTab == 2) ? menuTrips.Count : 0));
		int num2 = ((menuTab == 2) ? 3 : 2);
		int num3 = ((menuTab == 2) ? 5 : 6);
		int num4 = Math.Min(num, num3);
		menuScroll = Mathf.Clamp(menuScroll, 0, Math.Max(0, num - num3));
		float num5 = ((menuTab == 0) ? (116f + (flag ? (26f * (float)(4 + Math.Min(8, menuExp.rows.Count) + 4)) : 208f)) : ((menuTab == 3) ? 454f : ((menuDetail < 0 || menuDetail >= num) ? (106f + 26f * ((float)num4 * ((float)num2 + 0.3f) + ((num4 == 0) ? 1.5f : 0.5f)) + 20f) : (106f + 26f * (float)(6 + Math.Min(8, (menuTab == 1) ? menuFights[menuDetail].players.Count : menuTrips[menuDetail].players.Count) + 4)))));
		menuPanel.sizeDelta = new Vector2(940f, num5);
		((Transform)menuPanel).localScale = Vector3.one * Mathf.Clamp(menuScale.Value, 0.6f, 2f);
		MImg("Solid", null, new Color(0.075f, 0.085f, 0.065f, 1f), sliced: false, fill: true);
		MImg("Interior", "panel_interior_bkg_128", Color.white, sliced: true, fill: false);
		MRect((RectTransform)((Component)MImg("Band", "panel_interior_bkg_128", new Color(0.55f, 0.36f, 0.18f, 0.55f), sliced: true, fill: false)).transform, 4f, -4f, 932f, 34f);
		MImg("Border", "panel_border_128", new Color(1f, 1f, 1f, 0.95f), sliced: true, fill: false);
		MenuEnsureDrag(num5);
		MenuSearchBox(menuTab == 0, num5);
		MText("DamageMeter", 14f, -4f, 260f, 34f, 20, (TextAnchor)3, (FontStyle)1, MGold);
		MText("X", 900f, -4f, 32f, 34f, 20, (TextAnchor)4, (FontStyle)1, MParch);
		MClick(900f, -4f, 32f, 34f, (UnityAction)delegate
		{
			MenuClose();
		});
		float num6 = 14f;
		for (int num7 = 0; num7 < MenuTabs.Length; num7++)
		{
			float num8 = 28f + (float)MenuTabs[num7].Length * 9f;
			int ti = num7;
			MText(MenuTabs[num7], num6, -42f, num8, 26f, 15, (TextAnchor)4, (FontStyle)1, (num7 == menuTab) ? MGold : MDim);
			MClick(num6, -42f, num8, 26f, (UnityAction)delegate
			{
				menuTab = ti;
				menuScroll = 0;
				menuDetail = -1;
				menuNeedRender = true;
				if (ti == 1 || ti == 2)
				{
					MenuAskHistory(force: true);
				}
			});
			num6 += num8 + 8f;
		}
		MRect((RectTransform)((Component)MImg("Sep", "panel_separator", new Color(1f, 1f, 1f, 0.7f), sliced: false, fill: false)).transform, 12f, -70f, 916f, 4f);
		float y = -86f;
		if (menuTab == 0)
		{
			MenuExpedition(y, flag);
		}
		else if (menuTab == 3)
		{
			MenuSettings(y);
		}
		else if (menuDetail >= 0 && menuDetail < num)
		{
			MenuDetail(y, menuDetail);
		}
		else
		{
			MenuList(y, num4, num2, num3, num);
		}
	}

	private void MenuEnsureDrag(float h)
	{
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)menuDragGo == (Object)null)
		{
			menuDragGo = new GameObject("Drag", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			menuDragGo.transform.SetParent((Transform)(object)menuPanel, false);
			Image component = menuDragGo.GetComponent<Image>();
			((Graphic)component).color = new Color(1f, 1f, 1f, 0.004f);
			((Graphic)component).raycastTarget = true;
			menuDrag = menuDragGo.AddComponent<MenuDrag>();
			menuDrag.target = menuPanel;
			menuDrag.canvas = menuRoot.GetComponent<Canvas>();
			menuDrag.moved = delegate(Vector2 pos)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				menuPos.Value = pos;
			};
			menuDrag.reset = delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				menuPos.Value = Vector2.zero;
				menuPanel.anchoredPosition = Vector2.zero;
			};
		}
		MRect((RectTransform)menuDragGo.transform, 0f, 0f, 940f, h);
		menuDragGo.transform.SetAsLastSibling();
		if (!menuDrag.dragging)
		{
			menuPanel.anchoredPosition = menuPos.Value;
		}
	}

	private void MenuSearchBox(bool show, float h)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: 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_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)menuInputGo == (Object)null)
		{
			menuInputGo = new GameObject("NameInput", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(InputField)
			});
			menuInputGo.transform.SetParent((Transform)(object)menuPanel, false);
			((Graphic)menuInputGo.GetComponent<Image>()).color = new Color(0.03f, 0.04f, 0.03f, 0.95f);
			GameObject val = new GameObject("Text", new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val.transform.SetParent(menuInputGo.transform, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(8f, 2f);
			val2.offsetMax = new Vector2(-8f, -2f);
			Text component = val.GetComponent<Text>();
			component.font = menuFont;
			component.fontSize = 15;
			component.alignment = (TextAnchor)3;
			((Graphic)component).color = MParch;
			component.supportRichText = false;
			GameObject val3 = new GameObject("Placeholder", new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val3.transform.SetParent(menuInputGo.transform, false);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(8f, 2f);
			val4.offsetMax = new Vector2(-8f, -2f);
			Text component2 = val3.GetComponent<Text>();
			component2.font = menuFont;
			component2.fontSize = 15;
			component2.fontStyle = (FontStyle)2;
			component2.alignment = (TextAnchor)3;
			((Graphic)component2).color = MDim;
			component2.text = "Name (optional), e.g. Mistlands run";
			menuInput = menuInputGo.GetComponent<InputField>();
			menuInput.textComponent = component;
			menuInput.placeholder = (Graphic)(object)component2;
			menuInput.lineType = (LineType)0;
			menuInput.characterLimit = 40;
			((UnityEvent<string>)(object)menuInput.onValueChanged).AddListener((UnityAction<string>)delegate(string v)
			{
				menuName = v ?? "";
			});
		}
		menuInputGo.SetActive(show);
		if (show)
		{
			menuInputGo.transform.SetAsLastSibling();
		}
	}

	private void MenuExpedition(float y, bool running)
	{
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Expected O, but got Unknown
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Expected O, but got Unknown
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0495: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c5: Expected O, but got Unknown
		//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Expected O, but got Unknown
		//IL_050b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0515: Expected O, but got Unknown
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Expected O, but got Unknown
		//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_042c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0433: Unknown result type (might be due to invalid IL or missing references)
		if (!running)
		{
			MText("No expedition is running.", 18f, y, 904f, 26f, 17, (TextAnchor)3, (FontStyle)1, MGold);
			y -= 33.8f;
			MText("An expedition measures everything the party deals, takes, blocks and kills, bosses included, until somebody stops it.", 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
			y -= 26f;
			MText("The totals appear on the live panel for everybody who has DamageMeter 3.4+, and a summary goes to the chat at the end.", 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
			y -= 41.600002f;
			MText("Name", 18f, y, 60f, 30f, 14, (TextAnchor)3, (FontStyle)1, MDim);
			MRect((RectTransform)menuInputGo.transform, 80f, y, 440f, 30f);
			MButton("Start expedition", 540f, y, 200f, 30f, on: true, (UnityAction)delegate
			{
				SendCommand(("exp start " + menuName).Trim());
				menuName = "";
				if ((Object)(object)menuInput != (Object)null)
				{
					menuInput.text = "";
				}
			});
			return;
		}
		LiveData liveData = menuExp;
		MText(liveData.title, 18f, y, 904f, 32f, 19, (TextAnchor)3, (FontStyle)1, MGold);
		y -= 32f;
		float num = 0f;
		int num2 = 0;
		foreach (LiveRow row in liveData.rows)
		{
			num += row.dealt;
			num2 += row.kills;
		}
		MText("running for " + Clock(liveData.seconds) + "     " + num2 + " kills     dealt " + Nf(num), 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
		y -= 33.8f;
		float[] array = new float[8] { 18f, 340f, 420f, 500f, 590f, 680f, 760f, 840f };
		string[] array2 = new string[8] { "Player", "Damage", "Share", "DPS", "Taken", "Kills", "Deaths", "Parries" };
		for (int num3 = 0; num3 < array2.Length; num3++)
		{
			MText(array2[num3], array[num3], y, (num3 == 0) ? 200f : 70f, 26f, 12, (TextAnchor)((num3 == 0) ? 3 : 5), (FontStyle)1, MDim);
		}
		y -= 26f;
		int num4 = 0;
		while (num4 < liveData.rows.Count && num4 < 8)
		{
			LiveRow liveRow = liveData.rows[num4];
			if (num4 % 2 == 1)
			{
				MRect((RectTransform)((Component)MImg("Row", null, new Color(1f, 0.95f, 0.8f, 0.05f), sliced: false, fill: true)).transform, 10f, y, 920f, 26f);
			}
			string[] array3 = new string[7]
			{
				Nf(liveRow.dealt),
				(num > 0f) ? (((int)Math.Round(100f * liveRow.dealt / num)).ToString(Inv) + "%") : "-",
				(liveRow.dps > 0f) ? Nf(liveRow.dps) : "-",
				Nf(liveRow.taken),
				liveRow.kills.ToString(Inv),
				liveRow.deaths.ToString(Inv),
				liveRow.parries.ToString(Inv)
			};
			MText(liveRow.name, array[0], y, 300f, 26f, 14, (TextAnchor)3, (FontStyle)1, PColor(liveRow.name));
			for (int num5 = 0; num5 < array3.Length; num5++)
			{
				MText(array3[num5], array[num5 + 1], y, 70f, 26f, 14, (TextAnchor)5, (FontStyle)((num4 == 0 && num5 == 0) ? 1 : 0), (num4 == 0 && num5 == 0) ? MGold : MParch);
			}
			num4++;
			y -= 26f;
		}
		y -= 15.6f;
		MText("Name", 18f, y, 60f, 30f, 14, (TextAnchor)3, (FontStyle)1, MDim);
		MRect((RectTransform)menuInputGo.transform, 80f, y, 300f, 30f);
		MButton("Rename", 396f, y, 110f, 30f, on: false, (UnityAction)delegate
		{
			SendCommand(("exp name " + menuName).Trim());
			menuName = "";
			if ((Object)(object)menuInput != (Object)null)
			{
				menuInput.text = "";
			}
		});
		MButton("Stop expedition", 710f, y, 210f, 30f, on: true, (UnityAction)delegate
		{
			SendCommand("exp stop");
		});
	}

	private void MenuList(float y, int shown, int lines, int maxEntries, int count)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_057e: Unknown result type (might be due to invalid IL or missing references)
		//IL_058f: Unknown result type (might be due to invalid IL or missing references)
		//IL_05aa: Expected O, but got Unknown
		//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f5: Expected O, but got Unknown
		//IL_061d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: 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_01d7: 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_0145: 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_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Expected O, but got Unknown
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Expected O, but got Unknown
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_04de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		bool flag = menuTab == 1;
		if (!menuHistOk)
		{
			MText("Loading... (the server needs DamageMeter 3.6)", 18f, y, 904f, 26f, 14, (TextAnchor)3, (FontStyle)0, MDim);
		}
		else if (count == 0)
		{
			MText(flag ? "No boss fight recorded yet." : "No expedition or big fight recorded yet. Start an expedition on the first tab.", 18f, y, 904f, 26f, 14, (TextAnchor)3, (FontStyle)0, MDim);
		}
		for (int i = 0; i < shown; i++)
		{
			int num = i + menuScroll;
			string text = null;
			Color col = MGold;
			string text2;
			string text3;
			List<MHPlayer> players;
			string text4;
			if (flag)
			{
				MFight mFight = menuFights[num];
				text2 = When(mFight.time);
				text3 = BossLabel(mFight.boss) + ((mFight.stars > 0) ? ("  " + new string('*', mFight.stars)) : "");
				players = mFight.players;
				text4 = (mFight.killed ? "killed in " : "not killed, ") + Clock(mFight.seconds) + "    dealt " + Nf(mFight.dealt);
				if (!mFight.killed)
				{
					col = MDim;
				}
			}
			else
			{
				MTrip mTrip = menuTrips[num];
				text2 = When(mTrip.time);
				players = mTrip.players;
				text = mTrip.mobs;
				text3 = ((mTrip.kind == "E") ? ("Expedition - " + mTrip.title) : ("Fight in " + Humanize(mTrip.title)));
				col = ((mTrip.kind == "E") ? MGold : MParch);
				text4 = Clock(mTrip.seconds) + "    " + mTrip.kills + " kills    dealt " + Nf(mTrip.dealt);
			}
			MRect((RectTransform)((Component)MImg("Row", null, new Color(1f, 0.95f, 0.8f, (i % 2 == 0) ? 0.06f : 0.02f), sliced: false, fill: true)).transform, 10f, y, 906f, 26f * (float)lines + 2f);
			int di = num;
			MClick(10f, y, 906f, 26f * (float)lines, (UnityAction)delegate
			{
				menuDetail = di;
				menuNeedRender = true;
			});
			MText(text2, 18f, y, 110f, 26f, 13, (TextAnchor)3, (FontStyle)0, MDim);
			MText(text3, 130f, y, 517f, 26f, 15, (TextAnchor)3, (FontStyle)1, col);
			MText(text4, 560f, y, 350f, 26f, 13, (TextAnchor)5, (FontStyle)0, MParch);
			float num2 = 0f;
			foreach (MHPlayer item in players)
			{
				num2 += item.dealt;
			}
			float num3 = 18f;
			float y2 = y - 26f;
			for (int num4 = 0; num4 < players.Count && num4 < 5; num4++)
			{
				MHPlayer mHPlayer = players[num4];
				Text val = MText(mHPlayer.name, num3, y2, 200f, 26f, 13, (TextAnchor)3, (FontStyle)1, PColor(mHPlayer.name));
				num3 += val.preferredWidth + 6f;
				string text5 = Nf(mHPlayer.dealt) + ((num2 > 0f) ? (" (" + ((int)Math.Round(100f * mHPlayer.dealt / num2)).ToString(Inv) + "%)") : "") + ((!flag) ? ((mHPlayer.kills > 0) ? ("  " + mHPlayer.kills + " kills") : "") : ((mHPlayer.deaths > 0) ? ("  died " + mHPlayer.deaths) : ""));
				Text val2 = MText(text5, num3, y2, 260f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
				num3 += val2.preferredWidth + 22f;
				if (num3 > 800f)
				{
					break;
				}
			}
			if (!flag && !string.IsNullOrEmpty(text))
			{
				MText(text, 18f, y - 52f, 900f, 26f, 12, (TextAnchor)3, (FontStyle)0, MDim);
			}
			y -= 26f * ((float)lines + 0.3f);
		}
		if (count > maxEntries)
		{
			float num5 = 26f * ((float)lines + 0.3f) * (float)maxEntries;
			float num6 = Mathf.Max(24f, num5 * (float)maxEntries / (float)count);
			float num7 = count - maxEntries;
			float num8 = (num5 - num6) * ((num7 > 0f) ? ((float)menuScroll / num7) : 0f);
			MRect((RectTransform)((Component)MImg("Track", null, new Color(0f, 0f, 0f, 0.35f), sliced: false, fill: true)).transform, 924f, -86f, 6f, num5);
			MRect((RectTransform)((Component)MImg("Thumb", null, new Color(1f, 0.8f, 0.35f, 0.85f), sliced: false, fill: true)).transform, 924f, 0f - (86f + num8), 6f, num6);
			MText("mouse wheel scrolls", 710f, 0f - (86f + num5 + 4f), 200f, 20f, 11, (TextAnchor)5, (FontStyle)0, MDim);
		}
	}

	private void MenuDetail(float y, int idx)
	{
		//IL_01ee: 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_021b: Expected O, but got Unknown
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0615: Unknown result type (might be due to invalid IL or missing references)
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0365: Unknown result type (might be due to invalid IL or missing references)
		//IL_0376: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Expected O, but got Unknown
		//IL_071c: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
		bool flag = menuTab == 1;
		string text = null;
		string text2 = null;
		float num = 0f;
		List<MHPlayer> players;
		string text3;
		string text4;
		if (flag)
		{
			MFight mFight = menuFights[idx];
			players = mFight.players;
			text3 = BossLabel(mFight.boss) + ((mFight.stars > 0) ? ("  " + new string('*', mFight.stars)) : "");
			text4 = When(mFight.time) + "    " + (mFight.killed ? "killed in " : "not killed, ") + Clock(mFight.seconds) + "    dealt " + Nf(mFight.dealt);
		}
		else
		{
			MTrip mTrip = menuTrips[idx];
			players = mTrip.players;
			text = mTrip.mobs;
			text2 = mTrip.bosses;
			text3 = ((mTrip.kind == "E") ? ("Expedition - " + mTrip.title) : ("Fight in " + Humanize(mTrip.title)));
			text4 = When(mTrip.time) + "    " + Clock(mTrip.seconds) + "    " + mTrip.kills + " kills    dealt " + Nf(mTrip.dealt);
		}
		foreach (MHPlayer item in players)
		{
			num += item.dealt;
		}
		MText("< Back to the list", 18f, y, 220f, 26f, 14, (TextAnchor)3, (FontStyle)1, MGoldDim);
		MClick(10f, y, 230f, 26f, (UnityAction)delegate
		{
			menuDetail = -1;
			menuNeedRender = true;
		});
		y -= 28.6f;
		MText(text3, 18f, y, 904f, 32f, 19, (TextAnchor)3, (FontStyle)1, MGold);
		y -= 30f;
		MText(text4, 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
		y -= 33.8f;
		float[] array = new float[9] { 18f, 330f, 405f, 480f, 560f, 650f, 725f, 800f, 875f };
		string[] array2 = new string[9] { "Player", "Damage", "Share", "DPS", "Max hit", "Taken", "Blocks", "Parries", "Deaths" };
		for (int num2 = 0; num2 < array2.Length; num2++)
		{
			MText(array2[num2], array[num2], y, (num2 == 0) ? 200f : 70f, 26f, 12, (TextAnchor)((num2 == 0) ? 3 : 5), (FontStyle)1, MDim);
		}
		y -= 26f;
		int num3 = 0;
		while (num3 < players.Count && num3 < 8)
		{
			MHPlayer mHPlayer = players[num3];
			if (num3 % 2 == 1)
			{
				MRect((RectTransform)((Component)MImg("Row", null, new Color(1f, 0.95f, 0.8f, 0.05f), sliced: false, fill: true)).transform, 10f, y, 920f, 26f);
			}
			string[] array3 = new string[8]
			{
				Nf(mHPlayer.dealt),
				(num > 0f) ? (((int)Math.Round(100f * mHPlayer.dealt / num)).ToString(Inv) + "%") : "-",
				(mHPlayer.dps > 0f) ? Nf(mHPlayer.dps) : "-",
				(mHPlayer.maxHit > 0f) ? Nf(mHPlayer.maxHit) : "-",
				Nf(mHPlayer.taken),
				mHPlayer.blocks.ToString(Inv),
				mHPlayer.parries.ToString(Inv),
				mHPlayer.deaths.ToString(Inv)
			};
			MText(mHPlayer.name, array[0], y, 300f, 26f, 14, (TextAnchor)3, (FontStyle)1, PColor(mHPlayer.name));
			for (int num4 = 0; num4 < array3.Length; num4++)
			{
				MText(array3[num4], array[num4 + 1], y, 70f, 26f, 14, (TextAnchor)5, (FontStyle)((num3 == 0 && num4 == 0) ? 1 : 0), (num3 == 0 && num4 == 0) ? MGold : MParch);
			}
			num3++;
			y -= 26f;
		}
		y -= 13f;
		if (flag)
		{
			string text5 = "";
			foreach (MHPlayer item2 in players)
			{
				if (item2.weapon.Length > 0)
				{
					text5 = text5 + ((text5.Length > 0) ? ", " : "") + item2.name + ": " + Humanize(item2.weapon);
				}
			}
			if (text5.Length > 0)
			{
				MText("Weapons: " + text5, 18f, y, 904f, 26f, 12, (TextAnchor)3, (FontStyle)0, MDim);
			}
			return;
		}
		MText("Killed", 18f, y, 904f, 26f, 15, (TextAnchor)3, (FontStyle)1, MGold);
		y -= 26f;
		string text6 = (string.IsNullOrEmpty(text) ? "-" : text);
		int num5 = 130;
		int num6 = 0;
		while (num6 < text6.Length && num6 < num5 * 3)
		{
			int num7 = Math.Min(num5, text6.Length - num6);
			int num8 = ((num6 + num7 < text6.Length) ? text6.LastIndexOf(", ", num6 + num7, num7) : (-1));
			if (num8 > num6)
			{
				num7 = num8 - num6 + 1;
			}
			MText(text6.Substring(num6, num7).Trim(), 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)0, MParch);
			y -= 26f;
			num6 = num6 + num7 - num5;
			num6 += num5;
		}
		if (!string.IsNullOrEmpty(text2))
		{
			MText("Bosses: " + text2, 18f, y, 904f, 26f, 13, (TextAnchor)3, (FontStyle)1, MGold);
		}
	}

	private void SummaryShow(Summary s)
	{
		sumData = s;
		sumAt = Time.realtimeSinceStartup;
	}

	private void SummaryTick(float now)
	{
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Expected O, but got Unknown
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		if (sumData == null || !(now - sumAt <= Math.Max(8f, showSeconds.Value)) || !showTable.Value || !(liveMode.Value != "Off"))
		{
			sumData = null;
			if ((Object)(object)sumRoot != (Object)null && sumRoot.activeSelf)
			{
				sumRoot.SetActive(false);
			}
			return;
		}
		if ((Object)(object)menuFont == (Object)null)
		{
			menuFont = ResolveLiveFont();
		}
		if (!((Object)(object)menuFont == (Object)null))
		{
			if ((Object)(object)sumRoot == (Object)null)
			{
				sumRoot = new GameObject("DamageMeterSummary", new Type[4]
				{
					typeof(RectTransform),
					typeof(Canvas),
					typeof(CanvasScaler),
					typeof(CanvasGroup)
				});
				Object.DontDestroyOnLoad((Object)(object)sumRoot);
				Canvas component = sumRoot.GetComponent<Canvas>();
				component.renderMode = (RenderMode)0;
				component.sortingOrder = 40;
				CanvasScaler component2 = sumRoot.GetComponent<CanvasScaler>();
				component2.uiScaleMode = (ScaleMode)1;
				component2.referenceResolution = new Vector2(1920f, 1080f);
				component2.matchWidthOrHeight = 0.5f;
				CanvasGroup component3 = sumRoot.GetComponent<CanvasGroup>();
				component3.blocksRaycasts = false;
				component3.interactable = false;
				GameObject val = new GameObject("Panel", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(sumRoot.transform, false);
				sumPanel = (RectTransform)val.transform;
				RectTransform obj = sumPanel;
				RectTransform obj2 = sumPanel;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(1f, 1f);
				obj2.anchorMax = val2;
				obj.anchorMin = val2;
				sumPanel.pivot = new Vector2(1f, 1f);
				sumPanel.anchoredPosition = new Vector2(-20f, -110f);
			}
			if (!sumRoot.activeSelf)
			{
				sumRoot.SetActive(true);
				sumDrawn = null;
			}
			if (sumDrawn != sumData)
			{
				sumDrawn = sumData;
				SummaryRender(sumData);
			}
			float num = Math.Max(8f, showSeconds.Value) - (now - sumAt);
			sumRoot.GetComponent<CanvasGroup>().alpha = Mathf.Clamp01(num / 1.5f);
		}
	}

	private void SummaryRender(Summary s)
	{
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: 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_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Expected O, but got Unknown
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_031d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0504: Unknown result type (might be due to invalid IL or missing references)
		//IL_051f: Expected O, but got Unknown
		//IL_0742: Unknown result type (might be due to invalid IL or missing references)
		//IL_049c: Unknown result type (might be due to invalid IL or missing references)
		//IL_068c: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d3: Unknown result type (might be due to invalid IL or missing references)
		curPanel = sumPanel;
		curDyn = sumDyn;
		foreach (GameObject item in sumDyn)
		{
			if ((Object)(object)item != (Object)null)
			{
				Object.Destroy((Object)(object)item);
			}
		}
		sumDyn.Clear();
		float num = 0f;
		foreach (Row row2 in s.rows)
		{
			num += row2.dealt;
		}
		List<Row> list = new List<Row>();
		foreach (Row row3 in s.rows)
		{
			if (row3.dealt > 0f || row3.taken + row3.dot > 0f || row3.deaths > 0 || row3.blocks > 0)
			{
				list.Add(row3);
			}
		}
		if (list.Count > 8)
		{
			list.RemoveRange(8, list.Count - 8);
		}
		string text = "";
		foreach (string award in s.awards)
		{
			text = text + ((text.Length > 0) ? "     " : "") + award;
		}
		int num2 = ((text.Length != 0) ? ((text.Length <= 120) ? 1 : 2) : 0);
		float num3 = 112f + 26f * (float)(list.Count + 1) + ((s.other > 1f) ? 22f : 0f) + (float)num2 * 22f + 14f;
		sumPanel.sizeDelta = new Vector2(880f, num3);
		MImg("Solid", null, new Color(0.075f, 0.085f, 0.065f, 0.92f), sliced: false, fill: true);
		MImg("Interior", "panel_interior_bkg_128", new Color(1f, 1f, 1f, 0.95f), sliced: true, fill: false);
		MRect((RectTransform)((Component)MImg("Band", "panel_interior_bkg_128", new Color(0.55f, 0.36f, 0.18f, 0.55f), sliced: true, fill: false)).transform, 4f, -4f, 872f, 34f);
		MImg("Border", "panel_border_128", new Color(1f, 1f, 1f, 0.95f), sliced: true, fill: false);
		string text2 = BossLabel(s.boss) + ((s.stars > 0) ? ("  " + new string('*', s.stars)) : "");
		MText(text2, 14f, -4f, 528f, 34f, 20, (TextAnchor)3, (FontStyle)1, MGold);
		MText(s.killed ? ("killed in " + Clock(s.seconds)) : ("not killed (" + Clock(s.seconds) + ")"), 580f, -4f, 286f, 34f, 16, (TextAnchor)5, (FontStyle)1, s.killed ? MParch : MDim);
		float num4 = -44f;
		MText("dealt " + Nf(num) + ((s.accounted > 0f) ? ("  (" + F0(s.accounted) + "% of the boss HP accounted)") : ""), 14f, num4, 852f, 22f, 13, (TextAnchor)3, (FontStyle)0, MParch);
		num4 -= 28f;
		float[] array = new float[9] { 14f, 270f, 350f, 425f, 505f, 595f, 670f, 745f, 815f };
		string[] array2 = new string[9] { "Player", "Damage", "Share", "DPS", "Max hit", "Taken", "Blocks", "Parries", "Deaths" };
		for (int i = 0; i < array2.Length; i++)
		{
			MText(array2[i], array[i], num4, (i == 0) ? 200f : 62f, 24f, 12, (TextAnchor)((i == 0) ? 3 : 5), (FontStyle)1, MDim);
		}
		num4 -= 26f;
		int num5 = 0;
		while (num5 < list.Count)
		{
			Row row = list[num5];
			if (num5 % 2 == 1)
			{
				MRect((RectTransform)((Component)MImg("Row", null, new Color(1f, 0.95f, 0.8f, 0.05f), sliced: false, fill: true)).transform, 8f, num4, 864f, 26f);
			}
			string[] array3 = ((!row.mod) ? new string[8] { "n/a", "", "", "", "", "", "", "" } : new string[8]
			{
				Nf(row.dealt),
				(num > 0f) ? (((int)Math.Round(100f * row.dealt / num)).ToString(Inv) + "%") : "-",
				(row.dps > 0f) ? Nf(row.dps) : "-",
				(row.maxHit > 0f) ? Nf(row.maxHit) : "-",
				Nf(row.taken + row.dot),
				row.blocks.ToString(Inv),
				row.parries.ToString(Inv),
				row.deaths.ToString(Inv)
			});
			MText(row.name, array[0], num4, 240f, 26f, 14, (TextAnchor)3, (FontStyle)1, PColor(row.name));
			for (int j = 0; j < array3.Length; j++)
			{
				MText(array3[j], array[j + 1], num4, 62f, 26f, 14, (TextAnchor)5, (FontStyle)((num5 == 0 && j == 0) ? 1 : 0), (num5 == 0 && j == 0) ? MGold : MParch);
			}
			num5++;
			num4 -= 26f;
		}
		if (s.other > 1f)
		{
			MText("other / damage over time: " + Nf(s.other), 14f, num4, 852f, 22f, 12, (TextAnchor)3, (FontStyle)0, MDim);
			num4 -= 22f;
		}
		if (num2 > 0)
		{
			string text3 = text;
			string text4 = null;
			if (text.Length > 120)
			{
				int num6 = text.LastIndexOf("     ", 120, StringComparison.Ordinal);
				if (num6 < 40)
				{
					num6 = 120;
				}
				text3 = text.Substring(0, num6).Trim();
				text4 = text.Substring(num6).Trim();
			}
			MText(text3, 14f, num4, 852f, 22f, 12, (TextAnchor)3, (FontStyle)0, MGoldDim);
			num4 -= 22f;
			if (text4 != null)
			{
				MText(text4, 14f, num4, 852f, 22f, 12, (TextAnchor)3, (FontStyle)0, MGoldDim);
			}
		}
		curPanel = menuPanel;
		curDyn = menuDyn;
	}

	private void MenuSettings(float y)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Expected O, but got Unknown
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		MText("Live panel mode (what the panel shows for you)", 18f, y, 904f, 26f, 15, (TextAnchor)3, (FontStyle)1, MGold);
		y -= 31.2f;
		float num = 18f;
		string[] liveModes = LiveModes;
		foreach (string text in liveModes)
		{
			string mm = text;
			float num2 = 40f + (float)text.Length * 9f;
			MButton(text, num, y, num2, 30f, liveMode.Value == text, (UnityAction)delegate
			{
				liveMode.Value = mm;
				live = null;
				ChooseLive(Time.realtimeSinceStartup);
				menuNeedRender = true;
			});
			num += num2 + 10f;
		}
		y -= 46.8f;
		MCheck("Live panel enabled", liveEnabled, 18f, y);
		MCheck("Show the expedition totals when there is no fight", showExp, 440f, y);
		y -= 33.8f;
		MCheck("Only my fights (Near me mode)", liveOnlyMine, 18f, y);
		MCheck("Chat summaries after long fights", chatSummaries, 440f, y);
		y -= 33.8f;
		MCheck("Bars behind the names", liveBars, 18f, y);
		y -= 41.600002f;
		MStep("Range (Near me)", liveRange, 50f, 50f, 3000f, 18f, y);
		MStep("Boss range (0 = anywhere)", liveBossRange, 50f, 0f, 5000f, 480f, y);
		y -= 36.399998f;
		MStep("Minimum damage", liveMinDmg, 100f, 0f, 20000f, 18f, y);
		MStep("Keep after fight (s)", liveHoldCfg, 1f, 2f, 20f, 480f, y);
		y -= 36.399998f;
		MStep("Panel scale", liveScale, 0.1f, 0.5f, 2f, 18f, y);
		MStep("Panel opacity", liveOpacity, 0.05f, 0f, 1f, 480f, y);
		y -= 41.600002f;
		MButton("Reset panel position", 18f, y, 200f, 30f, on: false, (UnityAction)delegate
		{
			liveX.Value = 1500f;
			liveY.Value = -960f;
		});
		MText("Position and other details are also in the config (F1).", 236f, y, 680f, 30f, 12, (TextAnchor)3, (FontStyle)0, MDim);
	}

	private void MCheck(string label, ConfigEntry<bool> e, float x, float y)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		bool value = e.Value;
		MText(value ? "[x]" : "[  ]", x, y, 40f, 26f, 15, (TextAnchor)3, (FontStyle)1, value ? MGold : MDim);
		MText(label, x + 42f, y, 400f, 26f, 14, (TextAnchor)3, (FontStyle)0, MParch);
		ConfigEntry<bool> ce = e;
		MClick(x, y, 440f, 26f, (UnityAction)delegate
		{
			ce.Value = !ce.Value;
			menuNeedRender = true;
		});
	}

	private void MStep(string label, ConfigEntry<float> e, float step, float min, float max, float x, float y)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_00c1: 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_00fe: Expected O, but got Unknown
		MText(label, x, y, 230f, 26f, 14, (TextAnchor)3, (FontStyle)0, MParch);
		ConfigEntry<float> ce = e;
		float st = step;
		float lo = min;
		float hi = max;
		MButton("-", x + 236f, y - 1f, 30f, 28f, on: false, (UnityAction)delegate
		{
			ce.Value = Mathf.Clamp((float)Math.Round(ce.Value - st, 2), lo, hi);
			menuNeedRender = true;
		});
		MText(e.Value.ToString((st < 1f) ? "0.00" : "0", Inv), x + 270f, y, 70f, 26f, 14, (TextAnchor)4, (FontStyle)1, MGold);
		MButton("+", x + 344f, y - 1f, 30f, 28f, on: false, (UnityAction)delegate
		{
			ce.Value = Mathf.Clamp((float)Math.Round(ce.Value + st, 2), lo, hi);
			menuNeedRender = true;
		});
	}

	internal static void Add(Ev e)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		e.t = Time.realtimeSinceStartup;
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer != (Object)null)
		{
			Vector3 position = ((Component)localPlayer).transform.position;
			lastX = position.x;
			lastZ = position.z;
		}
		e.px = lastX;
		e.pz = lastZ;
		lock (buf)
		{
			if (buf.Count < 3000)
			{
				buf.Add(e);
			}
		}
	}

	private void Awake()
	{
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Expected O, but got Unknown
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Expected O, but got Unknown
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Expected O, but got Unknown
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Expected O, but got Unknown
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Expected O, but got Unknown
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Expected O, but got Unknown
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Expected O, but got Unknown
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Expected O, but got Unknown
		//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_045b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0465: Expected O, but got Unknown
		//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ab: Expected O, but got Unknown
		I = this;
		logFile = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "LogFile", Path.Combine(Paths.BepInExRootPath, "dmgmeter.log"), "Where the server writes the damage log.");
		engageRange = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "BossRangeMeters", 150f, "Reports from players closer than this to a boss count into its fight.");
		jokeAwards = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "Awards", true, "Add joke titles (most damage, most deaths...) under the table.");
		liveEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Live panel", "Enabled", true, "Show a live damage panel (damage, %, DPS, taken, deaths per player) during boss fights and big fights.");
		liveKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Live panel", "Toggle key", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Show or hide the live panel. Shift + this key resets its position.");
		liveX = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Position X", 1500f, "Distance from the left edge of the screen (canvas pixels, 1920x1080 reference).");
		liveY = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Position Y", -960f, "Distance from the top edge (negative = lower).");
		liveScale = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Scale", 1.2f, new ConfigDescription("Panel size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
		liveWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Width", 400f, new ConfigDescription("Panel width when Auto width is off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(340f, 800f), Array.Empty<object>()));
		liveOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Background opacity", 0.65f, new ConfigDescription("Panel background opacity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		liveAuto = ((BaseUnityPlugin)this).Config.Bind<bool>("Live panel", "Auto width", true, "Panel width follows the longest player name (the Width setting is used when this is off).");
		liveBars = ((BaseUnityPlugin)this).Config.Bind<bool>("Live panel", "Show bars", true, "Coloured bar behind each player proportional to damage share.");
		liveBarOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Bar opacity", 0.3f, new ConfigDescription("Opacity of the bars.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		liveMode = ((BaseUnityPlugin)this).Config.Bind<string>("Live panel", "Mode", "Near me", new ConfigDescription("What the live panel shows. Near me: fights around you or that you take part in. Bosses only: only boss fights. Everything: the latest fight anywhere on the server. Expedition: only the running expedition totals. Off: nothing.", (AcceptableValueBase)(object)new AcceptableValueList<string>(LiveModes), Array.Empty<object>()));
		liveRange = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Range", 250f, new ConfigDescription("Fights closer to you than this many meters count as 'near me'.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 3000f), Array.Empty<object>()));
		liveBossRange = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Boss range", 400f, new ConfigDescription("Boss fights closer than this are shown. 0 = show boss fights from anywhere (to watch friends from your base).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5000f), Array.Empty<object>()));
		liveMinDmg = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Minimum damage", 400f, new ConfigDescription("Fights against normal enemies are shown once the players dealt this much damage together.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20000f), Array.Empty<object>()));
		liveHoldCfg = ((BaseUnityPlugin)this).Config.Bind<float>("Live panel", "Keep after fight", 8f, new ConfigDescription("Seconds the result stays on screen after the last hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>()));
		liveOnlyMine = ((BaseUnityPlugin)this).Config.Bind<bool>("Live panel", "Only my fights", false, "Show only fights you took part in (in the Near me mode).");
		modeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Live panel", "Mode key", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Switches the mode: Near me, Bosses only, Everything, Expedition, Off.");
		expKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Live panel", "Expedition key", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Starts or stops an expedition: one long damage meter for the whole party (/dmeter exp start | stop | status).");
		showExp = ((BaseUnityPlugin)this).Config.Bind<bool>("Live panel", "Show expedition", true, "While an expedition is running, show its totals on the panel when there is no fight to show.");
		expStartPolicy = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "ExpeditionStart", "Anyone", new ConfigDescription("Who may start an expedition (the starter or an admin stops it).", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Anyone", "Admins" }), Array.Empty<object>()));
		chatSummaries = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "ChatSummaries", true, "Show the fight summary the server writes into the chat after a long fight.");
		srvRange = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "LivePanelRange", 250f, "For players with an older DamageMeter: fights closer than this many meters are shown to them (0 = fights anywhere).");
		srvBossRange = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "LivePanelBossRange", 400f, "For players with an older DamageMeter: boss fights closer than this are shown to them (0 = anywhere).");
		liveVer = ((BaseUnityPlugin)this).Config.Bind<int>("Live panel", "Settings version", 0, "Internal. Lets a new release apply its new default size and position once.");
		if (liveVer.Value < 1)
		{
			liveScale.Value = 1.2f;
			liveX.Value = 1500f;
			liveY.Value = -960f;
			liveVer.Value = 1;
			try
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			catch (Exception)
			{
			}
		}
		summaryRecaps = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "SummaryDeathRecaps", false, "Add the death recaps (what hit whom before a death) to the boss summary that is shown to everybody. They are always written to the server log.");
		sessionChatKills = ((BaseUnityPlugin)this).Config.Bind<int>("Server", "SessionChatMinKills", 8, "A combat session with at least this many kills is summed up in the chat for everybody (0 = never).");
		liveMinDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "LivePanelMinDamage", 400f, "Fights that are not bosses show the live panel once the players dealt this much damage in total (was 2000).");
		liveHold = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "LivePanelHoldSeconds", 8f, "The live panel stays on screen this long after a fight ended.");
		invLogOn = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "InventoryLog", true, "Server admin switch: store the inventory snapshots clients send and log what changed since a player was last seen. Clients always send them.");
		reportSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Client", "ReportSeconds", 1.5f, "How often a client sends its events to the server.");
		showTable = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "ShowTableAfterBoss", true, "Show the boss summary table on screen and in chat.");
		showSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Client", "TableSeconds", 25f, "How long the table stays on screen.");
		MenuAwake();
		dataDir = Path.Combine(Paths.BepInExRootPath, "dmgmeter-data");
		try
		{
			Directory.CreateDirectory(dataDir);
			LoadData();
		}
		catch (Exception)
		{
		}
		ExpLoad();
		Harmony val = new Harmony("dukr.dmgmeter");
		Type[] array = new Type[7]
		{
			typeof(RegisterRpc),
			typeof(RpcDamagePatch),
			typeof(ApplyDamagePatch),
			typeof(BlockPatch),
			typeof(PlayerDeathPatch),
			typeof(CharacterDeathPatch),
			typeof(CommandPatch)
		};
		foreach (Type type in array)
		{
			try
			{
				val.CreateClassProcessor(type).Patch();
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter patch " + type.Name + " failed: " + ex3.Message));
			}
		}
		PrepareAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"DamageMeter 3.7.0 loaded");
	}

	private static void PrepareAll()
	{
		try
		{
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.ContainsGenericParameters)
				{
					continue;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!methodInfo.IsAbstract && !methodInfo.ContainsGenericParameters)
					{
						try
						{
							RuntimeHelpers.PrepareMethod(methodInfo.MethodHandle);
						}
						catch (Exception)
						{
						}
					}
				}
				ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (ConstructorInfo constructorInfo in constructors)
				{
					try
					{
						RuntimeHelpers.PrepareMethod(constructorInfo.MethodHandle);
					}
					catch (Exception)
					{
					}
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private static string Clean(string s, int max)
	{
		if (string.IsNullOrEmpty(s))
		{
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder(Math.Min(s.Length, max));
		foreach (char c in s)
		{
			if (c >= ' ' && c != '\u007f')
			{
				stringBuilder.Append(c);
				if (stringBuilder.Length >= max)
				{
					break;
				}
			}
		}
		return stringBuilder.ToString().Trim();
	}

	private void Write(string kind, string who, string text)
	{
		try
		{
			who = Clean(who, 64);
			text = (text ?? "").Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
			File.AppendAllText(logFile.Value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + kind + " " + who + " " + text + Environment.NewLine);
		}
		catch (Exception)
		{
		}
	}

	private void Warn(string msg)
	{
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		if (!(realtimeSinceStartup < warnAt))
		{
			warnAt = realtimeSinceStartup + 30f;
			((BaseUnityPlugin)this).Logger.LogWarning((object)msg);
		}
	}

	internal void Register()
	{
		if (ZRoutedRpc.instance != null && registeredFor != ZRoutedRpc.instance)
		{
			registeredFor = ZRoutedRpc.instance;
			ZRoutedRpc.instance.Register<ZPackage>("dukr_dmg", (Action<long, ZPackage>)OnLegacy);
			ZRoutedRpc.instance.Register<ZPackage>("dukr_ev2", (Action<long, ZPackage>)OnEvents);
			ZRoutedRpc.instance.Register<ZPackage>("dukr_dmg_sum2", (Action<long, ZPackage>)OnSummary);
			ZRoutedRpc.instance.Register<string>("dukr_cmd", (Action<long, string>)OnCommand);
			ZRoutedRpc.instance.Register<string>("dukr_reply", (Action<long, string>)OnReply);
			ZRoutedRpc.instance.Register<ZPackage>("dukr_inv", (Action<long, ZPackage>)OnInventory);
			ZRoutedRpc.instance.Register<ZPackage>("dukr_live", (Action<long, ZPackage>)OnLive);
			MenuRegister();
		}
	}

	private static int Stars(int level)
	{
		return Math.Max(0, level - 1);
	}

	private static string F0(float v)
	{
		return v.ToString("0", Inv);
	}

	private void Update()
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null)
		{
			return;
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		if (ZNet.instance.IsServer())
		{
			try
			{
				ServerTick(realtimeSinceStartup);
				return;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter server tick: " + ex.Message));
				return;
			}
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			helloSent = false;
			spawnAt = 0f;
			DestroyLive();
			FlushEvents(realtimeSinceStartup, alive: false);
			return;
		}
		lastName = localPlayer.GetPlayerName();
		Vector3 position = ((Component)localPlayer).transform.position;
		lastX = position.x;
		lastZ = position.z;
		try
		{
			LiveTick(realtimeSinceStartup);
		}
		catch (Exception ex2)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter live panel: " + ex2.Message));
		}
		try
		{
			MenuTick(realtimeSinceStartup);
		}
		catch (Exception ex3)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("DamageMeter menu: " + ex3.Message));
		}
		try
		{
			SummaryTick(realtimeSinceStartup);
		}
		catch (Exception ex4)
		{
			((BaseUnityPlugin)this)