Decompiled source of SpeedMeter v1.0.0

SpeedMeter.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SpeedMeter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SpeedMeter")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("72565671-a90f-4bc8-9e66-3421e9e58a29")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SpeedMeterMod;

[BepInPlugin("com.yourname.jp.maezou.gladiomori.speedmeter", "Speed Meter", "1.0.0")]
public class SpeedMeter : BaseUnityPlugin
{
	private enum Lang
	{
		JP,
		EN,
		ZH
	}

	[CompilerGenerated]
	private sealed class <SpawnRetryRoutine>d__29 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public SpeedMeter <>4__this;

		private int <i>5__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <SpawnRetryRoutine>d__29(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if ((Object)(object)<>4__this._target != (Object)null)
				{
					<>4__this._speedMax = 0f;
					return false;
				}
				<i>5__1 = 0;
				break;
			case 1:
				<>1__state = -1;
				if (<>4__this.TryAcquireTarget(force: false))
				{
					<>4__this._speedMax = 0f;
					<>4__this._hasLastVel = false;
					return false;
				}
				<i>5__1++;
				break;
			}
			if (<i>5__1 < 6)
			{
				<>2__current = (object)new WaitForSeconds(5f);
				<>1__state = 1;
				return true;
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private const string FIXED_PATH = "SpawnPoints/GameObject/PlayerCharacter*/PlayerModelPhysics/HIP";

	private ConfigEntry<bool> _show;

	private ConfigEntry<float> _uiX;

	private ConfigEntry<float> _uiY;

	private ConfigEntry<KeyCode> _toggleUiKey;

	private ConfigEntry<bool> _use3D;

	private ConfigEntry<bool> _useLocalFrame;

	private ConfigEntry<bool> _kmh;

	private ConfigEntry<float> _sparkSeconds;

	private ConfigEntry<float> _accelSmoothing;

	private ConfigEntry<string> _language;

	private Lang _lang = Lang.JP;

	private Rect _panelRect;

	private Transform _target;

	private Vector3 _lastPos;

	private float _speedSmoothed;

	private float _speedMax;

	private readonly Queue<(float t, float v)> _hist = new Queue<(float, float)>();

	private Vector3 _lastVelBasis;

	private bool _hasLastVel;

	private float _accelNow;

	private float _accelSmoothed;

	private float _accelMax;

	private float _nextAutoScan;

	private void Awake()
	{
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		_show = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show", true, "UIを表示するか / Show the UI / 显示UI");
		_uiX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "X", 60f, "UI位置X / UI X position / UI X 坐标");
		_uiY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "Y", 60f, "UI位置Y / UI Y position / UI Y 坐标");
		_toggleUiKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("UI", "ToggleKey", (KeyCode)288, "UI表示切替キー / UI toggle key / UI开关按键");
		_language = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "Language", "JP", "UI言語 (JP/EN/ZH) / UI language (JP/EN/ZH) / 界面语言 (JP/EN/ZH)");
		_lang = ToLang(_language.Value);
		_use3D = ((BaseUnityPlugin)this).Config.Bind<bool>("Measure", "Use3D", false, "3D速度か水平速度か / 3D or horizontal / 三维速度或水平速度");
		_useLocalFrame = ((BaseUnityPlugin)this).Config.Bind<bool>("Measure", "UseLocalFrame", false, "ローカル基準かワールド基準か / Local or World frame / 本地坐标或世界坐标");
		_kmh = ((BaseUnityPlugin)this).Config.Bind<bool>("Measure", "UseKmH", false, "速度を km/h 表示 / Show speed in km/h / 速度以 km/h 显示");
		_sparkSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SparklineSeconds", 5f, "スパークライン秒 / Sparkline seconds / 迷你曲线秒数");
		_accelSmoothing = ((BaseUnityPlugin)this).Config.Bind<float>("Compute", "AccelSmoothing", 0.7f, "加速度平滑化(0–0.99) / Accel smoothing(0–0.99) / 加速度平滑(0–0.99)");
		_panelRect = new Rect(_uiX.Value, _uiY.Value, 320f, 230f);
		SceneManager.sceneLoaded += OnSceneLoaded;
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
	}

	private void Start()
	{
		TryAcquireTarget(force: true);
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		((MonoBehaviour)this).StartCoroutine(SpawnRetryRoutine());
	}

	[IteratorStateMachine(typeof(<SpawnRetryRoutine>d__29))]
	private IEnumerator SpawnRetryRoutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SpawnRetryRoutine>d__29(0)
		{
			<>4__this = this
		};
	}

	private void Update()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: 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_02a7: 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_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: 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_0218: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(_toggleUiKey.Value))
		{
			_show.Value = !_show.Value;
		}
		if (Input.GetKeyDown((KeyCode)289))
		{
			_show.Value = true;
			_uiX.Value = 60f;
			_uiY.Value = 60f;
			((Rect)(ref _panelRect)).position = new Vector2(60f, 60f);
			_hasLastVel = false;
		}
		if ((Object)(object)_target == (Object)null && Time.unscaledTime >= _nextAutoScan)
		{
			TryAcquireTarget(force: false);
			_nextAutoScan = Time.unscaledTime + 1f;
		}
		if ((Object)(object)_target == (Object)null)
		{
			return;
		}
		Vector3 val = (_useLocalFrame.Value ? _target.localPosition : _target.position);
		float deltaTime = Time.deltaTime;
		if (deltaTime > 0f)
		{
			Vector3 val2 = (val - _lastPos) / deltaTime;
			if (!_use3D.Value)
			{
				val2.y = 0f;
			}
			float magnitude = ((Vector3)(ref val2)).magnitude;
			_speedSmoothed = Mathf.Lerp(_speedSmoothed, magnitude, 0.5f);
			if (_speedSmoothed > _speedMax)
			{
				_speedMax = _speedSmoothed;
			}
			float unscaledTime = Time.unscaledTime;
			_hist.Enqueue((unscaledTime, _speedSmoothed));
			while (_hist.Count > 0 && unscaledTime - _hist.Peek().t > _sparkSeconds.Value)
			{
				_hist.Dequeue();
			}
			Vector3 val3 = val2;
			if (!_hasLastVel)
			{
				_lastVelBasis = val3;
				_hasLastVel = true;
			}
			else
			{
				Vector3 val4 = (val3 - _lastVelBasis) / deltaTime;
				_lastVelBasis = val3;
				_accelNow = ((Vector3)(ref val4)).magnitude;
				float num = 1f - Mathf.Clamp01(_accelSmoothing.Value);
				_accelSmoothed = Mathf.Lerp(_accelSmoothed, _accelNow, num);
				if (_accelSmoothed > _accelMax)
				{
					_accelMax = _accelSmoothed;
				}
			}
		}
		_lastPos = val;
	}

	private void OnGUI()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (_show.Value)
		{
			_panelRect = GUILayout.Window(2025, _panelRect, new WindowFunction(DrawWindow), WindowTitle(), Array.Empty<GUILayoutOption>());
			_uiX.Value = ((Rect)(ref _panelRect)).x;
			_uiY.Value = ((Rect)(ref _panelRect)).y;
		}
	}

	private void DrawWindow(int id)
	{
		//IL_047c: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
		string text = (_useLocalFrame.Value ? T("LocalFrame") : T("WorldFrame"));
		string text2 = (_use3D.Value ? T("Speed3D") : T("SpeedHorizontal"));
		float num = _speedSmoothed;
		float num2 = _speedMax;
		string text3 = (_kmh.Value ? "km/h" : "m/s");
		if (_kmh.Value)
		{
			num *= 3.6f;
			num2 *= 3.6f;
		}
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(LanguageButtonText(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
		{
			_lang = NextLang(_lang);
			_language.Value = LangToString(_lang);
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndHorizontal();
		GUILayout.Label(T("Target") + ": " + (Object.op_Implicit((Object)(object)_target) ? GetHierarchyPath(_target) : T("NotFound")), Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("Frame") + ": " + text + "   " + T("Mode") + ": " + text2, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("SpeedCurrent") + ": " + num.ToString("0.00") + " " + text3, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("SpeedMax") + ": " + num2.ToString("0.00") + " " + text3, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("AccelCurrent") + ": " + _accelSmoothed.ToString("0.00") + " m/s²", Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("AccelMax") + ": " + _accelMax.ToString("0.00") + " m/s²", Array.Empty<GUILayoutOption>());
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(T("ResetMaxSpeedAccel"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
		{
			_speedMax = 0f;
			_accelMax = 0f;
		}
		if (GUILayout.Button(_kmh.Value ? T("UnitMS") : T("UnitKMH"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
		{
			_kmh.Value = !_kmh.Value;
		}
		if (GUILayout.Button(_use3D.Value ? T("ModeHorizontal") : T("Mode3D"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
		{
			_use3D.Value = !_use3D.Value;
			_speedMax = 0f;
		}
		if (GUILayout.Button(_useLocalFrame.Value ? T("FrameWorld") : T("FrameLocal"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
		{
			_useLocalFrame.Value = !_useLocalFrame.Value;
			_speedMax = 0f;
			_hasLastVel = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(T("ReacquireFixedPath"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
		{
			TryAcquireTarget(force: true);
			_hasLastVel = false;
		}
		GUILayout.EndHorizontal();
		DrawSparkline(GUILayoutUtility.GetRect(300f, 48f));
		GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _panelRect)).width, 20f));
	}

	private void DrawSparkline(Rect r)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: 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_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		if (_hist.Count < 2)
		{
			return;
		}
		float item = _hist.Peek().t;
		float num = 0.001f;
		foreach (var item2 in _hist)
		{
			if (item2.v > num)
			{
				num = item2.v;
			}
		}
		Vector3 a = Vector3.zero;
		bool flag = true;
		Vector3 val = default(Vector3);
		foreach (var item3 in _hist)
		{
			float num2 = Mathf.InverseLerp(0f, _sparkSeconds.Value, item3.t - item);
			float num3 = Mathf.Lerp(((Rect)(ref r)).xMin, ((Rect)(ref r)).xMax, num2);
			float num4 = Mathf.Lerp(((Rect)(ref r)).yMax, ((Rect)(ref r)).yMin, item3.v / num);
			((Vector3)(ref val))..ctor(num3, num4, 0f);
			if (!flag)
			{
				Drawing.DrawLine(a, val, Color.white, 1f);
			}
			a = val;
			flag = false;
		}
		Drawing.DrawLine(new Vector3(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMin, 0f), new Vector3(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMin, 0f), new Color(1f, 1f, 1f, 0.15f), 1f);
		Drawing.DrawLine(new Vector3(((Rect)(ref r)).xMin, (((Rect)(ref r)).yMin + ((Rect)(ref r)).yMax) * 0.5f, 0f), new Vector3(((Rect)(ref r)).xMax, (((Rect)(ref r)).yMin + ((Rect)(ref r)).yMax) * 0.5f, 0f), new Color(1f, 1f, 1f, 0.12f), 1f);
		Drawing.DrawLine(new Vector3(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMax, 0f), new Vector3(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMax, 0f), new Color(1f, 1f, 1f, 0.15f), 1f);
	}

	private bool TryAcquireTarget(bool force)
	{
		//IL_005b: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		if (!force && (Object)(object)_target != (Object)null)
		{
			return true;
		}
		Transform val = FindByPathWildcard("SpawnPoints/GameObject/PlayerCharacter*/PlayerModelPhysics/HIP");
		if ((Object)(object)val != (Object)null)
		{
			_target = val;
			_lastPos = (_useLocalFrame.Value ? _target.localPosition : _target.position);
			_hasLastVel = false;
			return true;
		}
		return false;
	}

	private Transform FindByPathWildcard(string path)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(path))
		{
			return null;
		}
		string[] array = path.Split(new char[1] { '/' }, StringSplitOptions.RemoveEmptyEntries);
		if (array.Length == 0)
		{
			return null;
		}
		Scene activeScene = SceneManager.GetActiveScene();
		GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
		for (int i = 0; i < rootGameObjects.Length; i++)
		{
			if (!NameMatches(((Object)rootGameObjects[i]).name, array[0]))
			{
				continue;
			}
			Transform val = rootGameObjects[i].transform;
			bool flag = true;
			for (int j = 1; j < array.Length; j++)
			{
				Transform val2 = null;
				string pattern = array[j];
				for (int k = 0; k < val.childCount; k++)
				{
					Transform child = val.GetChild(k);
					if (NameMatches(((Object)child).name, pattern))
					{
						val2 = child;
						break;
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					flag = false;
					break;
				}
				val = val2;
			}
			if (flag)
			{
				return val;
			}
		}
		GameObject[] array2 = rootGameObjects;
		foreach (GameObject val3 in array2)
		{
			Transform val4 = FindChildRecursiveWildcard(val3.transform, array, 0);
			if ((Object)(object)val4 != (Object)null)
			{
				return val4;
			}
		}
		return null;
	}

	private Transform FindChildRecursiveWildcard(Transform parent, string[] parts, int index)
	{
		if (index >= parts.Length)
		{
			return parent;
		}
		string pattern = parts[index];
		for (int i = 0; i < parent.childCount; i++)
		{
			Transform child = parent.GetChild(i);
			if (NameMatches(((Object)child).name, pattern))
			{
				Transform val = FindChildRecursiveWildcard(child, parts, index + 1);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
		}
		return null;
	}

	private static bool NameMatches(string name, string pattern)
	{
		if (string.Equals(name, pattern, StringComparison.OrdinalIgnoreCase))
		{
			return true;
		}
		string pattern2 = "^" + Regex.Escape(pattern).Replace("\\*", ".*") + "$";
		return Regex.IsMatch(name, pattern2, RegexOptions.IgnoreCase);
	}

	private static string GetHierarchyPath(Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "<null>";
		}
		List<string> list = new List<string>();
		Transform val = t;
		while ((Object)(object)val != (Object)null)
		{
			list.Add(((Object)val).name);
			val = val.parent;
		}
		list.Reverse();
		return string.Join("/", list.ToArray());
	}

	private string WindowTitle()
	{
		return _lang switch
		{
			Lang.EN => "Speed Meter", 
			Lang.ZH => "速度计", 
			_ => "スピードメーター", 
		};
	}

	private string LanguageButtonText()
	{
		return _lang switch
		{
			Lang.EN => "Language: English (切换到中文/日文)", 
			Lang.ZH => "语言: 中文 (切换到日文/英文)", 
			_ => "言語: 日本語(英語/中文)", 
		};
	}

	private static string LangToString(Lang l)
	{
		return l switch
		{
			Lang.ZH => "ZH", 
			Lang.EN => "EN", 
			_ => "JP", 
		};
	}

	private static Lang NextLang(Lang l)
	{
		return l switch
		{
			Lang.EN => Lang.ZH, 
			Lang.JP => Lang.EN, 
			_ => Lang.JP, 
		};
	}

	private string T(string key)
	{
		if (_lang == Lang.EN)
		{
			switch (key)
			{
			case "Target":
				return "Target";
			case "NotFound":
				return "(Not found)";
			case "Frame":
				return "Frame";
			case "WorldFrame":
				return "World";
			case "LocalFrame":
				return "Local";
			case "Mode":
				return "Mode";
			case "Speed3D":
				return "3D";
			case "SpeedHorizontal":
				return "Horizontal";
			case "SpeedCurrent":
				return "Speed (Current)";
			case "SpeedMax":
				return "Speed (Max)";
			case "AccelCurrent":
				return "Accel (Current)";
			case "AccelMax":
				return "Accel (Max)";
			case "ResetMaxSpeedAccel":
				return "Reset Max (Speed/Accel)";
			case "UnitMS":
				return "Unit: m/s";
			case "UnitKMH":
				return "Unit: km/h";
			case "ModeHorizontal":
				return "Mode: Horizontal";
			case "Mode3D":
				return "Mode: 3D";
			case "FrameWorld":
				return "Frame: World";
			case "FrameLocal":
				return "Frame: Local";
			case "ReacquireFixedPath":
				return "Reacquire (fixed path)";
			}
		}
		else if (_lang == Lang.ZH)
		{
			switch (key)
			{
			case "Target":
				return "目标";
			case "NotFound":
				return "(未检测到)";
			case "Frame":
				return "参考系";
			case "WorldFrame":
				return "世界坐标";
			case "LocalFrame":
				return "本地坐标";
			case "Mode":
				return "模式";
			case "Speed3D":
				return "三维速度";
			case "SpeedHorizontal":
				return "水平速度";
			case "SpeedCurrent":
				return "速度(当前)";
			case "SpeedMax":
				return "速度(最大)";
			case "AccelCurrent":
				return "加速度(当前)";
			case "AccelMax":
				return "加速度(最大)";
			case "ResetMaxSpeedAccel":
				return "清零最大值(速度/加速度)";
			case "UnitMS":
				return "单位:m/s";
			case "UnitKMH":
				return "单位:km/h";
			case "ModeHorizontal":
				return "模式:水平";
			case "Mode3D":
				return "模式:三维";
			case "FrameWorld":
				return "参考系:世界";
			case "FrameLocal":
				return "参考系:本地";
			case "ReacquireFixedPath":
				return "重新获取(固定路径)";
			}
		}
		else
		{
			switch (key)
			{
			case "Target":
				return "対象";
			case "NotFound":
				return "(未検出)";
			case "Frame":
				return "基準";
			case "WorldFrame":
				return "ワールド座標";
			case "LocalFrame":
				return "ローカル座標";
			case "Mode":
				return "モード";
			case "Speed3D":
				return "3D速度";
			case "SpeedHorizontal":
				return "水平速度";
			case "SpeedCurrent":
				return "速度(現在)";
			case "SpeedMax":
				return "速度(最高)";
			case "AccelCurrent":
				return "加速度(現在)";
			case "AccelMax":
				return "加速度(最高)";
			case "ResetMaxSpeedAccel":
				return "最高リセット(速度/加速度)";
			case "UnitMS":
				return "単位: m/s";
			case "UnitKMH":
				return "単位: km/h";
			case "ModeHorizontal":
				return "モード: 水平";
			case "Mode3D":
				return "モード: 3D";
			case "FrameWorld":
				return "基準: ワールド";
			case "FrameLocal":
				return "基準: ローカル";
			case "ReacquireFixedPath":
				return "再検出(固定パス)";
			}
		}
		return key;
	}

	private static Lang ToLang(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return Lang.JP;
		}
		string text = s.Trim().ToUpperInvariant();
		switch (text)
		{
		case "EN":
			return Lang.EN;
		default:
			if (!(text == "CHS"))
			{
				return Lang.JP;
			}
			goto case "ZH";
		case "ZH":
		case "CN":
		case "ZH-CN":
			return Lang.ZH;
		}
	}
}
public static class Drawing
{
	private static Texture2D _lineTex;

	public static void DrawLine(Vector3 a, Vector3 b, Color color, float width)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_007f: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_lineTex == (Object)null)
		{
			_lineTex = new Texture2D(1, 1, (TextureFormat)4, false);
			_lineTex.SetPixel(0, 0, Color.white);
			_lineTex.Apply(false, false);
		}
		Matrix4x4 matrix = GUI.matrix;
		Color color2 = GUI.color;
		GUI.color = color;
		Vector3 val = b - a;
		float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
		float magnitude = ((Vector3)(ref val)).magnitude;
		GUIUtility.RotateAroundPivot(num, Vector2.op_Implicit(a));
		GUI.DrawTexture(new Rect(a.x, a.y, magnitude, width), (Texture)(object)_lineTex);
		GUI.matrix = matrix;
		GUI.color = color2;
	}
}