using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using EndGameStats.Core; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EndGameStats")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EndGameStats")] [assembly: AssemblyTitle("EndGameStats")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EndGameStats { [HarmonyPatch(typeof(ValuableObject), "Start")] internal static class ValuableRegistrationPatch { private static void Postfix(ValuableObject __instance) { Plugin.Instance.RegisterValuable(__instance); } } [HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerAddRPC")] internal static class GrabStartedPatch { private static void Postfix(PhysGrabObject __instance, int photonViewID) { Plugin.Instance.RecordGrab(__instance, photonViewID, released: false); } } [HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerRemoveRPC")] internal static class GrabEndedPatch { private static void Prefix(PhysGrabObject __instance, int photonViewID) { Plugin.Instance.RecordGrab(__instance, photonViewID, released: true); } } [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")] internal static class PlayerDeathPatch { private static void Postfix(PlayerAvatar __instance) { Plugin.Instance.RecordDeath(__instance); } } [HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")] internal static class PlayerRevivePatch { private static void Prefix(PlayerAvatar __instance, bool _revivedByTruck, out PlayerAvatar? __state) { __state = Plugin.Instance.CaptureRescuer(__instance, _revivedByTruck); } private static void Postfix(PlayerAvatar? __state) { Plugin.Instance.RecordRescue(__state); } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "BreakRPC")] internal static class ValuableDamagePatch { private static void Prefix(PhysGrabObjectImpactDetector __instance, float valueLost, bool _loseValue) { Plugin.Instance.RecordDamage(__instance, valueLost, _loseValue); } } [HarmonyPatch(typeof(ExtractionPoint), "ExtractionPointSurplus")] internal static class SuccessfulExtractionPatch { private static void Prefix() { Plugin.Instance.RecordSuccessfulExtraction(); } } [HarmonyPatch(typeof(HurtCollider), "EnemyHurt")] internal static class WeaponEnemyHitPatch { private static void Prefix(HurtCollider __instance, Enemy _enemy) { Plugin.Instance.RecordWeaponEnemyHit(__instance, _enemy); } } [HarmonyPatch(typeof(EnemyHealth), "DeathImpulseRPC")] internal static class EnemyDeathPatch { private static void Postfix(EnemyHealth __instance) { Plugin.Instance.RecordEnemyDeath(__instance); } } [BepInPlugin("chaun.repo.endgamestats", "End Game Stats", "0.4.0")] public sealed class Plugin : BaseUnityPlugin { private sealed class ValuableSample { public PlayerAvatar? LastCarrier; public float LastCarriedAt = float.NegativeInfinity; public ValuableObject Valuable { get; } public HashSet Participants { get; } = new HashSet(StringComparer.Ordinal); public ValuableSample(ValuableObject valuable) { Valuable = valuable; } } private sealed class EnemyAttribution { public PlayerAvatar Player { get; } public float At { get; } public EnemyAttribution(PlayerAvatar player, float at) { Player = player; At = at; } } public const string PluginGuid = "chaun.repo.endgamestats"; public const string PluginName = "End Game Stats"; public const string PluginVersion = "0.4.0"; private readonly Dictionary _valuables = new Dictionary(); private readonly HashSet _creditedExtractions = new HashSet(); private readonly HashSet _deadPlayers = new HashSet(StringComparer.Ordinal); private readonly Dictionary _enemyAttribution = new Dictionary(); private readonly HashSet _creditedEnemyKills = new HashSet(); private ConfigEntry _toggleKey; private ConfigEntry _cartSampleInterval; private ConfigEntry _releaseAttributionSeconds; private ConfigEntry _enemyKillAttributionSeconds; private ConfigEntry _language; private bool _visible; private bool _wasInLevel; private float _nextSample; private Rect _window = new Rect(40f, 60f, 1110f, 420f); private Texture2D _panelTexture; private Texture2D _screenTexture; private Texture2D _borderTexture; private Texture2D _rowTexture; private Texture2D _scanlineTexture; private GUIStyle _windowStyle; private Font? _terminalFont; internal static Plugin Instance { get; private set; } internal RunStatsBoard Board { get; private set; } = new RunStatsBoard(); private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Instance = this; _toggleKey = ((BaseUnityPlugin)this).Config.Bind("Display", "ToggleKey", new KeyboardShortcut((KeyCode)284, Array.Empty()), "Open or close the live stats board."); _language = ((BaseUnityPlugin)this).Config.Bind("Display", "Language", "Auto", "UI language: Auto, English, or SimplifiedChinese."); _cartSampleInterval = ((BaseUnityPlugin)this).Config.Bind("Tracking", "CartSampleIntervalSeconds", 1f, "Low-frequency fallback interval for valuables transported inside carts."); _releaseAttributionSeconds = ((BaseUnityPlugin)this).Config.Bind("Tracking", "DamageAttributionSeconds", 3f, "Attribute damage to the most recent carrier for this long after release."); _enemyKillAttributionSeconds = ((BaseUnityPlugin)this).Config.Bind("Tracking", "EnemyKillAttributionSeconds", 10f, "Credit an enemy kill to its most recent player interaction within this many seconds."); new Harmony("chaun.repo.endgamestats").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"End Game Stats 0.4.0 loaded"); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _visible = !_visible; } bool flag = SafeRunIsLevel(); if (flag && !_wasInLevel) { BeginLevel(); } else if (!flag && _wasInLevel) { _visible = true; } _wasInLevel = flag; if (flag && !(Time.unscaledTime < _nextSample)) { _nextSample = Time.unscaledTime + Mathf.Max(0.25f, _cartSampleInterval.Value); SampleCartParticipants(); } } private void BeginLevel() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Board = new RunStatsBoard(); _valuables.Clear(); _creditedExtractions.Clear(); _deadPlayers.Clear(); _enemyAttribution.Clear(); _creditedEnemyKills.Clear(); _visible = false; RegisterExistingValuables(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Started a new level stats snapshot"); } private void RegisterExistingValuables() { if (!Object.op_Implicit((Object)(object)ValuableDirector.instance)) { return; } foreach (ValuableObject valuable in ValuableDirector.instance.valuableList) { RegisterValuable(valuable); } } internal void RegisterValuable(ValuableObject? valuable) { if (valuable != null && Object.op_Implicit((Object)(object)valuable) && !_valuables.ContainsKey(((Object)valuable).GetInstanceID())) { _valuables.Add(((Object)valuable).GetInstanceID(), new ValuableSample(valuable)); } } private void SampleCartParticipants() { RegisterExistingValuables(); if (Object.op_Implicit((Object)(object)GameDirector.instance)) { foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { GetPlayer(player); } } KeyValuePair[] array = _valuables.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; ValuableObject valuable = keyValuePair.Value.Valuable; if (!Object.op_Implicit((Object)(object)valuable)) { _valuables.Remove(keyValuePair.Key); continue; } PhysGrabObjectImpactDetector component = ((Component)valuable).GetComponent(); if (Object.op_Implicit((Object)(object)component) && component.inCart) { PhysGrabCart value = Traverse.Create((object)component).Field("currentCart").GetValue(); if (Object.op_Implicit((Object)(object)value)) { AddParticipants(keyValuePair.Value, GetGrabbers(((Component)value).GetComponent())); } } } } internal void RecordGrab(PhysGrabObject grabObject, int grabberPhotonViewId, bool released) { PhotonView val = PhotonView.Find(grabberPhotonViewId); PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent() : null); if (val2 == null || !Object.op_Implicit((Object)(object)val2) || val2.playerAvatar == null || !Object.op_Implicit((Object)(object)val2.playerAvatar)) { return; } ValuableObject component = ((Component)grabObject).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { RegisterValuable(component); ValuableSample valuableSample = _valuables[((Object)component).GetInstanceID()]; PlayerRunStats player = GetPlayer(val2.playerAvatar); if (player != null) { valuableSample.Participants.Add(player.PlayerId); } valuableSample.LastCarrier = val2.playerAvatar; if (released) { valuableSample.LastCarriedAt = Time.unscaledTime; } return; } PhysGrabCart component2 = ((Component)grabObject).GetComponent(); if (!Object.op_Implicit((Object)(object)component2)) { EnemyRigidbody val3 = ((Component)grabObject).GetComponent() ?? ((Component)grabObject).GetComponentInParent(); EnemyHealth val4 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent() : null); if (Object.op_Implicit((Object)(object)val4)) { RememberEnemyInteractor(val4, val2.playerAvatar); } } else { if (released) { return; } foreach (KeyValuePair valuable2 in _valuables) { ValuableObject valuable = valuable2.Value.Valuable; if (Object.op_Implicit((Object)(object)valuable)) { PhysGrabObjectImpactDetector component3 = ((Component)valuable).GetComponent(); if ((Object)(object)(Object.op_Implicit((Object)(object)component3) ? Traverse.Create((object)component3).Field("currentCart").GetValue() : null) == (Object)(object)component2) { AddParticipants(valuable2.Value, (IEnumerable)(object)new PhysGrabber[1] { val2 }); } } } } } internal void RecordDeath(PlayerAvatar avatar) { PlayerRunStats player = GetPlayer(avatar); if (player != null && _deadPlayers.Add(player.PlayerId)) { player.RecordDeath(); } } internal PlayerAvatar? CaptureRescuer(PlayerAvatar revived, bool revivedByTruck) { PlayerRunStats player = GetPlayer(revived); if (player == null || !_deadPlayers.Remove(player.PlayerId)) { return null; } if (revivedByTruck) { return null; } PlayerDeathHead value = Traverse.Create((object)revived).Field("playerDeathHead").GetValue(); if (!Object.op_Implicit((Object)(object)value)) { return null; } return (from grabber in GetGrabbers(Traverse.Create((object)value).Field("physGrabObject").GetValue()) select grabber.playerAvatar).FirstOrDefault((Func)((PlayerAvatar val) => Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)revived)); } internal void RecordRescue(PlayerAvatar? rescuer) { if (Object.op_Implicit((Object)(object)rescuer)) { PlayerRunStats? player = GetPlayer(rescuer); if (player != null) { player.RecordRescue(); } } } internal void RecordDamage(PhysGrabObjectImpactDetector detector, float valueLost, bool loseValue) { if (!loseValue || valueLost <= 0f) { return; } ValuableObject component = ((Component)detector).GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return; } PlayerAvatar val = null; List grabbers = GetGrabbers(((Component)component).GetComponent()); ValuableSample value; if (grabbers.Count > 0) { val = grabbers[0].playerAvatar; } else if (_valuables.TryGetValue(((Object)component).GetInstanceID(), out value) && Time.unscaledTime - value.LastCarriedAt <= _releaseAttributionSeconds.Value) { val = value.LastCarrier; } if (Object.op_Implicit((Object)(object)val)) { PlayerRunStats? player = GetPlayer(val); if (player != null) { player.AddValuableDamage((double)valueLost); } } else { Board.AddUnattributedDamage((double)valueLost); } } internal void RecordSuccessfulExtraction() { if (!Object.op_Implicit((Object)(object)RoundDirector.instance)) { return; } GameObject[] array = RoundDirector.instance.dollarHaulList.ToArray(); foreach (GameObject val in array) { if (!Object.op_Implicit((Object)(object)val)) { continue; } ValuableObject component = val.GetComponent(); if (!Object.op_Implicit((Object)(object)component) || !_creditedExtractions.Add(((Object)component).GetInstanceID())) { continue; } float num = ReadFloat(component, "dollarValueCurrent"); if (!_valuables.TryGetValue(((Object)component).GetInstanceID(), out ValuableSample value) || value.Participants.Count == 0) { Board.AddUnattributedExtractedValue((double)num); continue; } float num2 = num / (float)value.Participants.Count; foreach (string playerId in value.Participants) { PlayerRunStats val2 = ((IEnumerable)Board.Players).FirstOrDefault((Func)((PlayerRunStats candidate) => candidate.PlayerId == playerId)); if (val2 != null) { val2.AddExtractedValue((double)num2); } else { Board.AddUnattributedExtractedValue((double)num2); } } } } internal void RecordWeaponEnemyHit(HurtCollider hurtCollider, Enemy enemy) { if (!Object.op_Implicit((Object)(object)enemy) || hurtCollider.deathPit) { return; } EnemyHealth component = ((Component)enemy).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { PhysGrabObject componentInParent = ((Component)hurtCollider).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent)) { PlayerAvatar value = Traverse.Create((object)componentInParent).Field("lastPlayerGrabbing").GetValue(); RememberEnemyInteractor(component, value); } } } internal void RecordEnemyDeath(EnemyHealth enemyHealth) { if (!Object.op_Implicit((Object)(object)enemyHealth) || !_creditedEnemyKills.Add(((Object)enemyHealth).GetInstanceID())) { return; } PlayerAvatar val = null; if (_enemyAttribution.TryGetValue(((Object)enemyHealth).GetInstanceID(), out EnemyAttribution value) && Time.unscaledTime - value.At <= Mathf.Max(0f, _enemyKillAttributionSeconds.Value)) { val = value.Player; } if (val == null) { val = Traverse.Create((object)enemyHealth).Field("onObjectHurtPlayer").GetValue(); } if (Object.op_Implicit((Object)(object)val)) { PlayerRunStats? player = GetPlayer(val); if (player != null) { player.RecordEnemyKill(); } } } private void RememberEnemyInteractor(EnemyHealth enemyHealth, PlayerAvatar? player) { if (Object.op_Implicit((Object)(object)enemyHealth) && Object.op_Implicit((Object)(object)player)) { _enemyAttribution[((Object)enemyHealth).GetInstanceID()] = new EnemyAttribution(player, Time.unscaledTime); } } private void AddParticipants(ValuableSample sample, IEnumerable grabbers) { foreach (PhysGrabber grabber in grabbers) { PlayerRunStats player = GetPlayer(grabber.playerAvatar); if (player != null) { sample.Participants.Add(player.PlayerId); } } } private PlayerRunStats? GetPlayer(PlayerAvatar? avatar) { if (!Object.op_Implicit((Object)(object)avatar)) { return null; } string value = Traverse.Create((object)avatar).Field("playerName").GetValue(); string text = (Object.op_Implicit((Object)(object)avatar.photonView) ? ("photon:" + avatar.photonView.OwnerActorNr.ToString(CultureInfo.InvariantCulture)) : "local"); return Board.GetOrAddPlayer(text, string.IsNullOrWhiteSpace(value) ? "Semibot" : value); } private static List GetGrabbers(PhysGrabObject? grabObject) { List list = new List(); if (!Object.op_Implicit((Object)(object)grabObject)) { return list; } if (!(Traverse.Create((object)grabObject).Field("playerGrabbing").GetValue() is IEnumerable enumerable)) { return list; } foreach (object item in enumerable) { PhysGrabber val = (PhysGrabber)((item is PhysGrabber) ? item : null); if (val != null && Object.op_Implicit((Object)(object)val)) { list.Add(val); } } return list; } private static float ReadFloat(object instance, string field) { return Traverse.Create(instance).Field(field).GetValue(); } private static bool SafeRunIsLevel() { try { return SemiFunc.RunIsLevel(); } catch { return false; } } private void OnGUI() { //IL_001d: 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_003e: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (_visible) { if (_windowStyle == null) { BuildVisualTheme(); } _window = GUI.Window(948210, _window, new WindowFunction(DrawWindow), string.Empty, _windowStyle); } } private void DrawWindow(int id) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_002f: 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_004f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Expected O, but got Unknown //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) DrawTerminalFrame(); GUIStyle val = new GUIStyle(GUI.skin.label) { font = _terminalFont, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val.normal.textColor = new Color(0.52f, 1f, 0.52f); GUIStyle val2 = val; GUI.Label(new Rect(20f, 5f, ((Rect)(ref _window)).width - 40f, 24f), T("[ CRT-03 // SALVAGE TELEMETRY ]", "[ CRT-03 // 回收作业终端 ]"), val2); GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, alignment = (TextAnchor)4, font = _terminalFont }; val3.normal.textColor = new Color(0.52f, 1f, 0.52f); GUIStyle val4 = val3; GUIStyle val5 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, font = _terminalFont }; val5.normal.textColor = new Color(0.38f, 0.86f, 0.42f); GUIStyle val6 = val5; GUIStyle style = new GUIStyle(val6); GUILayout.BeginVertical(Array.Empty()); GUILayout.Label(T("SYS.READOUT / STATUS: ONLINE", "系统读数 / 状态:在线"), val4, Array.Empty()); GUILayout.Space(3f); GUILayout.BeginHorizontal(Array.Empty()); Column(T("PLAYER", "玩家"), 190f, val4); Column(T("DEATHS", "死亡"), 70f, val4); Column(T("RESCUES", "救援"), 70f, val4); Column(T("KILLS", "击杀"), 70f, val4); Column(T("RECOVERED VALUE", "回收贡献"), 140f, val4); Column(T("GOODS DAMAGED", "物品损失"), 140f, val4); Column(T("TITLES", "称号"), 360f, val4); GUILayout.EndHorizontal(); GUILayout.Space(6f); foreach (PlayerRunStats item in Board.Players.OrderByDescending((PlayerRunStats p) => p.ExtractedValue)) { GUILayout.BeginHorizontal(Array.Empty()); Column(Truncate(item.DisplayName, 20), 190f, val6); Column(item.Deaths.ToString(CultureInfo.InvariantCulture), 70f, style); Column(item.TeammatesRescued.ToString(CultureInfo.InvariantCulture), 70f, style); Column(item.EnemyKills.ToString(CultureInfo.InvariantCulture), 70f, style); Column(Dollars(item.ExtractedValue), 140f, style); Column(Dollars(item.ValuableDamage), 140f, style); GUIStyle val7 = new GUIStyle(val6) { fontStyle = (FontStyle)1 }; val7.normal.textColor = new Color(0.7f, 1f, 0.5f); Column(GetTitles(item), 360f, val7); GUILayout.EndHorizontal(); } GUILayout.FlexibleSpace(); GUILayout.Label(T("Unattributed goods damage: " + Dollars(Board.UnattributedValuableDamage), "未归属的物品损失:" + Dollars(Board.UnattributedValuableDamage)), Array.Empty()); GUILayout.Label(T("Unattributed recovered value: " + Dollars(Board.UnattributedExtractedValue), "未归属的回收价值:" + Dollars(Board.UnattributedExtractedValue)), Array.Empty()); KeyboardShortcut value = _toggleKey.Value; string english = $"Press {((KeyboardShortcut)(ref value)).MainKey} to close"; value = _toggleKey.Value; GUILayout.Label(T(english, $"按 {((KeyboardShortcut)(ref value)).MainKey} 关闭"), Array.Empty()); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 28f)); } private static string Truncate(string value, int max) { if (value.Length > max) { return value.Substring(0, max - 1) + "…"; } return value; } private static string Dollars(double value) { return "$" + value.ToString("N0", CultureInfo.InvariantCulture); } private string GetTitles(PlayerRunStats player) { List list = new List(); AddTitle(list, player, "Defective Unit", "残次品", (PlayerRunStats p) => p.Deaths); AddTitle(list, player, "Guardian Angel", "再生父母", (PlayerRunStats p) => p.TeammatesRescued); AddTitle(list, player, "Physics Exorcist", "物理超度师", (PlayerRunStats p) => p.EnemyKills); AddTitle(list, player, "Born to Grind", "天生牛马", (PlayerRunStats p) => p.ExtractedValue); AddTitle(list, player, "Financial Liability", "负资产", (PlayerRunStats p) => p.ValuableDamage); return string.Join(" / ", list); } private void AddTitle(List titles, PlayerRunStats player, string englishTitle, string chineseTitle, Func value) { IReadOnlyList readOnlyList = Board.Leaders(value, false, (Func)null); if (readOnlyList.Count != 0 && !(value(readOnlyList[0]) <= 0.0) && readOnlyList.Any((PlayerRunStats leader) => leader.PlayerId == player.PlayerId)) { titles.Add(T(englishTitle, chineseTitle)); } } private static void Column(string text, float width, GUIStyle style) { GUILayout.Label(text, style, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(width) }); } private void BuildVisualTheme() { //IL_0068: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0147: 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) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0179: Expected O, but got Unknown _terminalFont = Font.CreateDynamicFontFromOSFont((!UseChinese()) ? new string[3] { "Consolas", "Courier New", "Arial" } : new string[3] { "SimSun", "Microsoft YaHei", "Arial" }, 16); _panelTexture = SolidTexture(new Color(0.025f, 0.027f, 0.023f, 0.99f)); _screenTexture = SolidTexture(new Color(0.005f, 0.055f, 0.018f, 0.98f)); _borderTexture = SolidTexture(new Color(0.12f, 0.16f, 0.11f, 1f)); _rowTexture = SolidTexture(new Color(0.1f, 0.3f, 0.12f, 0.18f)); _scanlineTexture = SolidTexture(new Color(0f, 0f, 0f, 0.24f)); GUIStyle val = new GUIStyle(GUI.skin.window); val.normal.background = _panelTexture; val.normal.textColor = new Color(0.52f, 1f, 0.52f); val.font = _terminalFont; val.fontStyle = (FontStyle)1; val.alignment = (TextAnchor)1; val.padding = new RectOffset(22, 22, 48, 22); _windowStyle = val; } private void DrawTerminalFrame() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(new Rect(10f, 27f, ((Rect)(ref _window)).width - 20f, ((Rect)(ref _window)).height - 37f), (Texture)(object)_borderTexture); GUI.DrawTexture(new Rect(17f, 34f, ((Rect)(ref _window)).width - 34f, ((Rect)(ref _window)).height - 51f), (Texture)(object)_screenTexture); GUI.DrawTexture(new Rect(17f, 34f, ((Rect)(ref _window)).width - 34f, 2f), (Texture)(object)_borderTexture); GUI.DrawTexture(new Rect(17f, ((Rect)(ref _window)).height - 19f, ((Rect)(ref _window)).width - 34f, 2f), (Texture)(object)_borderTexture); for (float num = 36f; num < ((Rect)(ref _window)).height - 20f; num += 3f) { GUI.DrawTexture(new Rect(18f, num, ((Rect)(ref _window)).width - 36f, 1f), (Texture)(object)_scanlineTexture); } } private static Texture2D SolidTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } private bool UseChinese() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (_language.Value.Equals("SimplifiedChinese", StringComparison.OrdinalIgnoreCase) || _language.Value.Equals("Chinese", StringComparison.OrdinalIgnoreCase) || _language.Value.Equals("简体中文", StringComparison.OrdinalIgnoreCase)) { return true; } if (_language.Value.Equals("English", StringComparison.OrdinalIgnoreCase)) { return false; } return ((object)Application.systemLanguage/*cast due to .constrained prefix*/).ToString().IndexOf("Chinese", StringComparison.OrdinalIgnoreCase) >= 0; } private string T(string english, string chinese) { if (!UseChinese()) { return english; } return chinese; } } }