Decompiled source of MarkLoans v1.0.5
plugins/MarkLoans/MarkLoans.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Extensions; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("MarkLoans.Tests")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MarkLoans")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5")] [assembly: AssemblyProduct("MarkLoans")] [assembly: AssemblyTitle("MarkLoans")] [assembly: AssemblyVersion("1.0.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 MarkLoans { public static class AtomicFile { public static void Write(string path, string contents) { string text = path + ".markloans.tmp"; using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None)) { using StreamWriter streamWriter = new StreamWriter(fileStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); streamWriter.Write(contents); streamWriter.Flush(); fileStream.Flush(flushToDisk: true); } if (File.Exists(path)) { File.Replace(text, path, path + ".markloans.bak"); } else { File.Move(text, path); } } } internal sealed class LoanMenu : MonoBehaviour, IUIManager { internal View View; private GameObject canvasRoot; private GameObject panel; private GameObject toast; private GameObject voteBadge; private GameObject goldRule; private TMP_FontAsset font; private TextMeshProUGUI title; private TextMeshProUGUI summary; private TextMeshProUGUI amount; private TextMeshProUGUI terms; private TextMeshProUGUI debt; private TextMeshProUGUI voteText; private TextMeshProUGUI toastText; private TextMeshProUGUI badgeText; private Slider slider; private Button startVote; private Button approve; private Button reject; private Button repay; private Button close; private Quote quote; private string mode = "Loans"; private string shownVote; private string toastMessage; private string selectedLoan; private float toastUntil; private InputLayer oldLayer; private bool oldLocked; private bool oldHeadLocked; private CursorLockMode oldCursor; private bool oldVisible; private PlayerController lockedPlayer; private GameObject oldSelection; private bool registered; private float desiredPercent = 25f; private double serverNow; private float receivedAt; private bool pendingAuto; private float nextVoteRefresh; private float nextBadgeRefresh; private bool settingSlider; private bool requestingQuote; private float quoteRequestTime; private PlayerInteract lockedInteraction; private bool oldInteractionEnabled; private GameObject interactionPanel; private bool oldPanelActive; private static SFXGenericUIButtonComponent clickSound; private int lastClosedFrame = -1; private static readonly Color Gold = new Color(1f, 0.79f, 0.22f); private static readonly Color Ink = new Color(0.055f, 0.11f, 0.14f, 0.98f); public bool IsActive { get; private set; } public int Priority => 90; internal bool BlocksEscape { get { if (!IsActive) { return lastClosedFrame == Time.frameCount; } return true; } } private static string Cash(BigNumber value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return MoneyFormatter.FormatWithDollar(value, false); } internal void Receive(View view) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) View = view; serverNow = view.Now; receivedAt = Time.unscaledTime; if (!string.IsNullOrEmpty(view.Notice)) { ShowNotice(view.Notice); } bool flag = requestingQuote && IsActive; if (!string.IsNullOrEmpty(view.Notice) || view.Quote != null) { requestingQuote = false; } if (view.Quote != null && flag) { quote = view.Quote; mode = "Confirm"; if (!IsActive) { OpenUI(); } } if (view.Proposal != null && view.Proposal.Eligible.Contains(view.Session) && !view.Proposal.Approved.Contains(view.Session) && !view.Proposal.Rejected.Contains(view.Session) && shownVote != view.Proposal.Id) { shownVote = view.Proposal.Id; EnsureUI(); pendingAuto = true; if ((int)InputEvents.ActiveLayer == 0 || IsActive) { mode = "Vote"; OpenUI(); pendingAuto = false; } } if (view.Proposal == null && mode == "Vote") { CloseUI(); } Refresh(); } private void Update() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Invalid comparison between Unknown and I4 if (!registered && (Object)(object)UIManager.Instance != (Object)null) { UIManager.Instance.RegisterUI((IUIManager)(object)this); registered = true; } if ((Object)(object)canvasRoot == (Object)null) { return; } toast.SetActive(Time.unscaledTime < toastUntil); bool flag = View?.Proposal != null && View.Proposal.Eligible.Contains(View.Session) && !View.Proposal.Approved.Contains(View.Session) && !View.Proposal.Rejected.Contains(View.Session); if (flag && !IsActive && (int)InputEvents.ActiveLayer == 0) { if (!pendingAuto) { Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current.f6Key).wasPressedThisFrame) { goto IL_0117; } } mode = "Vote"; OpenUI(); pendingAuto = false; } goto IL_0117; IL_0117: voteBadge.SetActive(flag && !IsActive); if (flag && !IsActive && Time.unscaledTime >= nextBadgeRefresh) { nextBadgeRefresh = Time.unscaledTime + 0.2f; ((TMP_Text)badgeText).text = "MARK'S TEAM LOAN VOTE\n" + Remaining().ToString("0") + "s remaining • F6 to reopen"; } if (IsActive) { if (requestingQuote && Time.unscaledTime - quoteRequestTime > 10f) { requestingQuote = false; ShowNotice("Mark is taking his time. Try Start Vote again."); Refresh(); } if (!NetworkClient.isConnected || (Object)(object)lockedPlayer == (Object)null || (int)InputEvents.ActiveLayer != 3) { CloseUI(); } else if (mode == "Vote" && Time.unscaledTime >= nextVoteRefresh) { nextVoteRefresh = Time.unscaledTime + 0.2f; Refresh(); } } } private double Remaining() { if (View?.Proposal != null) { return Math.Max(0.0, View.Proposal.Deadline - (serverNow + (double)Time.unscaledTime - (double)receivedAt)); } return 0.0; } public void OpenUI() { //IL_001c: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) if (IsActive) { Refresh(); } else { if ((Object)(object)NetworkClient.localPlayer == (Object)null || (int)InputEvents.ActiveLayer != 0) { return; } EnsureUI(); lockedPlayer = ((Component)NetworkClient.localPlayer).GetComponent<PlayerController>(); if ((Object)(object)lockedPlayer == (Object)null) { return; } UIManager instance = UIManager.Instance; if (instance != null) { instance.SetActiveUI((IUIManager)(object)this); } oldLayer = InputEvents.ActiveLayer; oldLocked = lockedPlayer.IsLocked; oldHeadLocked = (Object)(object)lockedPlayer.head != (Object)null && lockedPlayer.head.isLocked; oldCursor = Cursor.lockState; oldVisible = Cursor.visible; EventSystem current = EventSystem.current; oldSelection = ((current != null) ? current.currentSelectedGameObject : null); lockedInteraction = ((Component)lockedPlayer).GetComponent<PlayerInteract>(); oldInteractionEnabled = (Object)(object)lockedInteraction != (Object)null && ((Behaviour)lockedInteraction).enabled; if ((Object)(object)lockedInteraction != (Object)null) { ((Behaviour)lockedInteraction).enabled = false; } LocalManager instance2 = MonoSingleton<LocalManager>.Instance; object obj; if (instance2 == null) { obj = null; } else { InteractionUIPanel interactionUIPanel = instance2.interactionUIPanel; obj = ((interactionUIPanel != null) ? ((Component)interactionUIPanel).gameObject : null); } interactionPanel = (GameObject)obj; oldPanelActive = (Object)(object)interactionPanel != (Object)null && interactionPanel.activeSelf; if ((Object)(object)interactionPanel != (Object)null) { interactionPanel.SetActive(false); } if ((Object)(object)Plugin.Instance.Visual.Mark != (Object)null) { TextMeshPro componentInChildren = Plugin.Instance.Visual.Mark.GetComponentInChildren<TextMeshPro>(true); if (componentInChildren != null) { ((Component)componentInChildren).gameObject.SetActive(false); } } InputEvents.OnMoveEvent?.Invoke(Vector2.zero); InputEvents.OnAimEvent?.Invoke(Vector2.zero); InputEvents.UpdateInteract(false); InputEvents.UpdateJump(false); InputEvents.UpdateCrouch(false); InputEvents.UpdateSprint(false); InputEvents.UpdateUseItem(false); InputEvents.UpdateThrowItem(false); InputEvents.ActiveLayer = (InputLayer)3; lockedPlayer.IsLocked = true; if ((Object)(object)lockedPlayer.head != (Object)null) { lockedPlayer.head.isLocked = true; } IsActive = true; panel.SetActive(true); UICursorSimple instance3 = UICursorSimple.Instance; if (instance3 != null) { instance3.ShowCursor(); } Refresh(); EventSystem current2 = EventSystem.current; if (current2 != null) { current2.SetSelectedGameObject((mode == "Vote") ? ((Component)approve).gameObject : ((Component)slider).gameObject); } PlayClick(); } } public void CloseUI() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_0040: 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_0131: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return; } lastClosedFrame = Time.frameCount; IsActive = false; GameObject obj = panel; if (obj != null) { obj.SetActive(false); } pendingAuto = false; bool num = (int)InputEvents.ActiveLayer == 3; if (num) { InputEvents.ActiveLayer = oldLayer; } if (num && (Object)(object)lockedPlayer != (Object)null) { lockedPlayer.IsLocked = oldLocked; if ((Object)(object)lockedPlayer.head != (Object)null) { lockedPlayer.head.isLocked = oldHeadLocked; } } if ((Object)(object)lockedInteraction != (Object)null) { ((Behaviour)lockedInteraction).enabled = oldInteractionEnabled; } if ((Object)(object)interactionPanel != (Object)null) { interactionPanel.SetActive(oldPanelActive); } if ((Object)(object)Plugin.Instance.Visual.Mark != (Object)null) { TextMeshPro componentInChildren = Plugin.Instance.Visual.Mark.GetComponentInChildren<TextMeshPro>(true); if (componentInChildren != null) { ((Component)componentInChildren).gameObject.SetActive(true); } } lockedInteraction = null; interactionPanel = null; if (num) { UICursorSimple instance = UICursorSimple.Instance; if (instance != null) { instance.HideCursor(); } Cursor.lockState = oldCursor; Cursor.visible = oldVisible; EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(oldSelection); } } UIManager instance2 = UIManager.Instance; if (instance2 != null) { instance2.ClearActiveUI((IUIManager)(object)this); } lockedPlayer = null; quote = null; mode = "Loans"; requestingQuote = false; } internal void ShowNotice(string text) { EnsureUI(); toastMessage = text; ((TMP_Text)toastText).text = text; toastUntil = Time.unscaledTime + 9f; PlayClick(); } private void EnsureUI() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0352: 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_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0584: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Expected O, but got Unknown if ((Object)(object)canvasRoot != (Object)null) { return; } font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null && ((Object)f).name.Contains("Liberation"))) ?? Resources.FindObjectsOfTypeAll<TMP_FontAsset>().FirstOrDefault(); canvasRoot = new GameObject("Mark Loans UI", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); canvasRoot.transform.SetParent(((Component)this).transform, false); canvasRoot.GetComponent<Canvas>().renderMode = (RenderMode)0; canvasRoot.GetComponent<Canvas>().sortingOrder = 500; CanvasScaler component = canvasRoot.GetComponent<CanvasScaler>(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.matchWidthOrHeight = 0.5f; panel = Box("Mark's desk", canvasRoot.transform, new Vector2(650f, 640f), Vector2.zero, Ink); goldRule = Box("Gold rule", panel.transform, new Vector2(650f, 5f), new Vector2(0f, 315f), Gold); title = Label(panel.transform, new Vector2(510f, 42f), new Vector2(-16f, 270f), 32f); ((TMP_Text)title).text = "MARK THE SHARK"; ((Graphic)title).color = Gold; summary = Label(panel.transform, new Vector2(580f, 42f), new Vector2(0f, 220f), 20f); slider = MakeSlider(panel.transform, new Vector2(0f, 174f)); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { if (!settingSlider) { desiredPercent = ((View == null) ? v : ((float)View.Rules.Snap(v))); Refresh(); } }); amount = Label(panel.transform, new Vector2(580f, 142f), new Vector2(0f, 74f), 58f); ((Graphic)amount).color = Gold; terms = Label(panel.transform, new Vector2(580f, 58f), new Vector2(0f, -33f), 22f); startVote = Button(panel.transform, "START VOTE", new Vector2(0f, -112f), (Action)StartLoan, (Vector2?)new Vector2(550f, 54f)); repay = Button(panel.transform, "REPAY", new Vector2(0f, -178f), (Action)delegate { if (selectedLoan != null) { Wire.Send("Repay", selectedLoan); ((Selectable)repay).interactable = false; } }, (Vector2?)new Vector2(550f, 48f)); close = Button(panel.transform, "X", new Vector2(280f, 270f), (Action)CloseUI, (Vector2?)new Vector2(38f, 38f)); debt = Label(panel.transform, new Vector2(580f, 88f), new Vector2(0f, -260f), 17f); voteText = Label(panel.transform, new Vector2(580f, 40f), new Vector2(0f, 117f), 22f); approve = Button(panel.transform, "APPROVE", new Vector2(-142f, -166f), (Action)delegate { Vote(yes: true); }, (Vector2?)new Vector2(265f, 54f)); reject = Button(panel.transform, "REJECT", new Vector2(142f, -166f), (Action)delegate { Vote(yes: false); }, (Vector2?)new Vector2(265f, 54f)); toast = Box("Team notification", canvasRoot.transform, new Vector2(760f, 105f), new Vector2(0f, 430f), Ink); toastText = Label(toast.transform, new Vector2(720f, 95f), Vector2.zero, 21f); voteBadge = Box("Vote notification", canvasRoot.transform, new Vector2(360f, 92f), new Vector2(710f, 390f), Ink); badgeText = Label(voteBadge.transform, new Vector2(330f, 80f), Vector2.zero, 20f); ((UnityEvent)voteBadge.AddComponent<Button>().onClick).AddListener((UnityAction)delegate { mode = "Vote"; OpenUI(); }); panel.SetActive(false); toast.SetActive(false); voteBadge.SetActive(false); } private void StartLoan() { if (View == null || requestingQuote) { return; } if (View.Proposal != null) { mode = "Vote"; Refresh(); return; } if (mode == "Confirm" && quote != null) { Wire.Send("Propose", quote.Id); quote = null; mode = "Loans"; } else { requestingQuote = true; quoteRequestTime = Time.unscaledTime; Wire.Send("Quote", null, desiredPercent); } Refresh(); } private void Vote(bool yes) { if (View?.Proposal != null) { Wire.Send("Vote", View.Proposal.Id, 0.0, yes); CloseUI(); } } private void Refresh() { //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_0673: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01df: Unknown result type (might be due to invalid IL or missing references) //IL_07d8: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_07e4: Unknown result type (might be due to invalid IL or missing references) //IL_076f: Unknown result type (might be due to invalid IL or missing references) //IL_0887: Unknown result type (might be due to invalid IL or missing references) //IL_088d: Unknown result type (might be due to invalid IL or missing references) //IL_0892: 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_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)canvasRoot == (Object)null || !IsActive) { return; } if (View == null) { ((TMP_Text)amount).text = "<size=26>WAITING FOR MARK</size>"; ((TMP_Text)terms).text = "Everyone needs Mark Loans 1.0.5"; Button obj = startVote; bool interactable = (((Selectable)repay).interactable = false); ((Selectable)obj).interactable = interactable; ((Component)approve).gameObject.SetActive(false); ((Component)reject).gameObject.SetActive(false); ((Component)voteText).gameObject.SetActive(false); return; } bool flag2 = mode == "Vote" && View.Proposal != null; bool flag3 = mode == "Confirm" && this.quote != null; ((RectTransform)panel.transform).sizeDelta = new Vector2(650f, (float)(flag2 ? 450 : 640)); ((RectTransform)goldRule.transform).anchoredPosition = new Vector2(0f, (float)(flag2 ? 220 : 315)); ((TMP_Text)title).rectTransform.anchoredPosition = new Vector2(-16f, (float)(flag2 ? 175 : 270)); ((Component)summary).gameObject.SetActive(!flag2); ((Component)debt).gameObject.SetActive(!flag2); ((Component)repay).gameObject.SetActive(!flag2); ((RectTransform)((Component)close).transform).anchoredPosition = new Vector2(280f, (float)(flag2 ? 175 : 270)); ((TMP_Text)amount).rectTransform.anchoredPosition = new Vector2(0f, (float)(flag2 ? 25 : 74)); ((TMP_Text)terms).rectTransform.anchoredPosition = new Vector2(0f, (float)(flag2 ? (-83) : (-33))); ((TMP_Text)title).text = (flag2 ? "MARK'S TEAM LOAN VOTE" : "MARK THE SHARK"); ((Component)slider).gameObject.SetActive(!flag2); ((Component)voteText).gameObject.SetActive(flag2); ((Component)startVote).gameObject.SetActive(!flag2); ((Component)approve).gameObject.SetActive(flag2); ((Component)reject).gameObject.SetActive(flag2); settingSlider = true; slider.minValue = (float)View.Rules.MinPercent; slider.maxValue = (float)View.Rules.MaxPercent; desiredPercent = (float)View.Rules.Snap(desiredPercent); slider.SetValueWithoutNotify(desiredPercent); settingSlider = false; ((Selectable)slider).interactable = !flag3 && View.Proposal == null && View.Ready; ((Selectable)startVote).interactable = !requestingQuote && (View.Ready || View.Proposal != null); ((TMP_Text)((Component)startVote).GetComponentInChildren<TextMeshProUGUI>()).text = (requestingQuote ? "GETTING TERMS..." : ((View.Proposal != null) ? "VIEW VOTE" : (View.Ledger.HasUnsettledDebt ? "REPAY EXISTING DEBT FIRST" : (flag3 ? "CONFIRM START VOTE" : "START VOTE")))); if (flag2) { Proposal proposal = View.Proposal; ShowTerms(proposal.Terms); ((TMP_Text)voteText).text = proposal.Approved.Count + "/" + proposal.Required + " approvals needed • " + Remaining().ToString("0") + "s"; bool flag4 = proposal.Eligible.Contains(View.Session) && !proposal.Approved.Contains(View.Session) && !proposal.Rejected.Contains(View.Session) && Remaining() > 0.0; Button obj2 = approve; bool interactable = (((Selectable)reject).interactable = flag4); ((Selectable)obj2).interactable = interactable; } else { try { Quote quote = (flag3 ? this.quote : Quote.Create(View.Day, View.BaseQuota, desiredPercent, View.Rules)); ShowTerms(quote); ((TMP_Text)summary).text = quote.Percent.ToString("0.##") + "% OF QUOTA " + Cash(View.BaseQuota) + " • DAY " + (View.Day + 1); } catch (Exception ex) { ((TMP_Text)amount).text = "<size=26>NO BORROWING QUOTE</size>"; ((TMP_Text)terms).text = ex.Message; ((Selectable)startVote).interactable = false; } } List<Loan> list = View.Ledger.Loans.Where((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)).ToList(); Loan loan = (from l in list where l.Status == "Outstanding" orderby l.Terms.DueDay select l).FirstOrDefault(); selectedLoan = loan?.Id; BigNumber val = BigNumber.Zero; foreach (Loan item in list) { val += ((item.Status == "Transferred") ? item.Transferred : (item.Terms.Total - item.Paid)); } ((TMP_Text)debt).text = (View.Ledger.HasUnsettledDebt ? "BORROWING LOCKED UNTIL DEBT IS SETTLED" : (View.Ledger.UsedDays.Contains(View.Day) ? "TODAY'S LOAN: USED" : (View.Ready ? "TODAY'S LOAN: AVAILABLE" : "BORROWING CLOSED"))) + " • TEAM DEBT " + Cash(val) + "\n"; foreach (Loan item2 in list) { TextMeshProUGUI obj3 = debt; ((TMP_Text)obj3).text = ((TMP_Text)obj3).text + ((item2.Status == "Defaulted") ? "UNPAID AT DEADLINE — LOSING PIT\n" : ((item2.Status == "Outstanding") ? ("Day " + (item2.Terms.Day + 1) + ": " + Cash(item2.Terms.Total - item2.Paid) + " due end of day " + (item2.Terms.DueDay + 1) + "\n") : (Cash(item2.Transferred) + " quota debt on day " + (item2.TransferDay + 1) + "\n"))); } if (list.Count == 0) { TextMeshProUGUI obj4 = debt; ((TMP_Text)obj4).text = ((TMP_Text)obj4).text + "No debt. Mark is trying to look happy for you."; } ((TMP_Text)((Component)repay).GetComponentInChildren<TextMeshProUGUI>()).text = ((loan == null) ? "REPAY" : ("REPAY " + Cash(loan.Terms.Total - loan.Paid))); ((Selectable)repay).interactable = loan?.Status == "Outstanding"; } private void ShowTerms(Quote q) { //IL_0017: 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_007c: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)amount).text = "<size=20>YOU BORROW</size>\n" + Cash(q.Principal) + "\n<size=28>INTEREST " + q.Rate.ToString("0.##") + "% • " + Cash(q.Interest) + "</size>"; ((TMP_Text)terms).text = "TOTAL REPAYMENT " + Cash(q.Total) + " • DUE END OF DAY " + (q.DueDay + 1) + "\nMISS THE DEADLINE: THE TEAM LOSES"; } private static GameObject Box(string name, Transform parent, Vector2 size, Vector2 pos, Color color) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //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) //IL_003f: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.sizeDelta = size; val2.anchoredPosition = pos; ((Graphic)val.GetComponent<Image>()).color = color; return val; } private TextMeshProUGUI Label(Transform parent, Vector2 size, Vector2 pos, float fontSize) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).rectTransform.sizeDelta = size; ((TMP_Text)component).rectTransform.anchoredPosition = pos; if ((Object)(object)font != (Object)null) { ((TMP_Text)component).font = font; } ((TMP_Text)component).fontSize = fontSize; ((Graphic)component).color = new Color(0.94f, 0.96f, 0.93f); ((TMP_Text)component).alignment = (TextAlignmentOptions)514; ((TMP_Text)component).textWrappingMode = (TextWrappingModes)1; ((Graphic)component).raycastTarget = false; return component; } private Button Button(Transform parent, string text, Vector2 pos, Action action, Vector2? size = null) { //IL_002e: 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) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_004a: 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_0061: 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_0087: 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_009f: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown Vector2 val = (Vector2)(((??)size) ?? new Vector2(275f, 42f)); GameObject val2 = Box(text, parent, val, pos, Gold); Button obj = val2.AddComponent<Button>(); ColorBlock colors = ((Selectable)obj).colors; ((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.92f, 0.6f); ((ColorBlock)(ref colors)).disabledColor = new Color(0.35f, 0.35f, 0.35f); ((Selectable)obj).colors = colors; TextMeshProUGUI obj2 = Label(val2.transform, val - new Vector2(16f, 4f), Vector2.zero, 23f); ((TMP_Text)obj2).text = text; ((Graphic)obj2).color = Ink; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { PlayClick(); action(); }); return obj; } private Slider MakeSlider(Transform parent, Vector2 pos) { //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_0025: 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_0055: Expected O, but got Unknown //IL_006d: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //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_0096: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_012d: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown GameObject val = Box("Hi Lo inspired percentage slider", parent, new Vector2(550f, 18f), pos, new Color(0.26f, 0.43f, 0.45f)); Slider val2 = val.AddComponent<Slider>(); GameObject val3 = new GameObject("Fill area", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val.transform, false); Stretch((RectTransform)val3.transform, Vector2.zero, Vector2.zero); GameObject val4 = Box("Fill", val3.transform, Vector2.zero, Vector2.zero, Gold); Stretch((RectTransform)val4.transform, Vector2.zero, Vector2.zero); val2.fillRect = (RectTransform)val4.transform; GameObject val5 = new GameObject("Handle area", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(val.transform, false); Stretch((RectTransform)val5.transform, new Vector2(12f, 0f), new Vector2(-12f, 0f)); GameObject val6 = Box("Knob", val5.transform, new Vector2(24f, 32f), Vector2.zero, new Color(1f, 0.94f, 0.72f)); val2.handleRect = (RectTransform)val6.transform; ((Selectable)val2).targetGraphic = (Graphic)(object)val6.GetComponent<Image>(); val2.direction = (Direction)0; return val2; } private static void Stretch(RectTransform rect, Vector2 min, Vector2 max) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001e: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = min; rect.offsetMax = max; } private static void PlayClick() { if ((Object)(object)clickSound == (Object)null) { clickSound = Object.FindAnyObjectByType<SFXGenericUIButtonComponent>((FindObjectsInactive)1); } if ((Object)(object)clickSound != (Object)null) { clickSound.PlayClick(); } } private void OnDestroy() { CloseUI(); if (registered) { UIManager instance = UIManager.Instance; if (instance != null) { instance.UnregisterUI((IUIManager)(object)this); } } if ((Object)(object)canvasRoot != (Object)null) { Object.Destroy((Object)(object)canvasRoot); } } } public sealed class LoanRules { public double MinPercent = 25.0; public double MaxPercent = 50.0; public double StepPercent = 5.0; public double MinInterest = 10.0; public double MaxInterest = 50.0; public double OverduePenalty; public double VoteSeconds = 30.0; public void Validate() { if (!new double[7] { MinPercent, MaxPercent, StepPercent, MinInterest, MaxInterest, OverduePenalty, VoteSeconds }.All((double x) => !double.IsNaN(x) && !double.IsInfinity(x)) || MinPercent <= 0.0 || MaxPercent <= MinPercent || MaxPercent > 10000.0 || StepPercent <= 0.0 || StepPercent > MaxPercent - MinPercent || MinInterest < 0.0 || MaxInterest < MinInterest || MaxInterest > 1000.0 || OverduePenalty < 0.0 || OverduePenalty > 1000.0 || VoteSeconds < 1.0 || VoteSeconds > 600.0) { throw new ArgumentException("Invalid loan configuration. See CONFIGURATION.md."); } } public double Snap(double percent) { if (double.IsNaN(percent) || double.IsInfinity(percent)) { throw new ArgumentException("Invalid percentage."); } percent = Math.Max(MinPercent, Math.Min(MaxPercent, percent)); if (percent >= MaxPercent) { return MaxPercent; } return Math.Min(MaxPercent, MinPercent + Math.Round((percent - MinPercent) / StepPercent, MidpointRounding.AwayFromZero) * StepPercent); } } public sealed class Quote { [JsonProperty(/*Could not decode attribute arguments.*/)] public string Id; [JsonProperty(/*Could not decode attribute arguments.*/)] public int Day; [JsonProperty(/*Could not decode attribute arguments.*/)] public int DueDay; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber BaseQuota; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber Principal; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber Interest; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber Total; [JsonProperty(/*Could not decode attribute arguments.*/)] public double Percent; [JsonProperty(/*Could not decode attribute arguments.*/)] public double Rate; [JsonProperty(/*Could not decode attribute arguments.*/)] public double Penalty; [JsonProperty(/*Could not decode attribute arguments.*/)] public double VoteSeconds; public static Quote Create(int day, BigNumber quota, double percent, LoanRules rules) { //IL_0006: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //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) //IL_006a: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0095: 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_00e8: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) rules.Validate(); if (quota <= BigNumber.Zero) { throw new InvalidOperationException("Mark needs a positive quota to lend against."); } percent = rules.Snap(percent); double num = rules.MinInterest + (percent - rules.MinPercent) / (rules.MaxPercent - rules.MinPercent) * (rules.MaxInterest - rules.MinInterest); BigNumber val = Whole(quota * (percent / 100.0)); BigNumber val2 = Whole(val * (num / 100.0)); if (val <= BigNumber.Zero || val + val2 > BigNumber.MaxValue) { throw new InvalidOperationException("This loan exceeds the game's money range."); } return new Quote { Id = Guid.NewGuid().ToString("N"), Day = day, DueDay = checked(day + 1), BaseQuota = quota, Percent = percent, Principal = val, Rate = num, Interest = val2, Total = val + val2, Penalty = rules.OverduePenalty, VoteSeconds = rules.VoteSeconds }; } public static BigNumber Whole(BigNumber value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) if (value.Exponent >= 15) { return value; } return BigNumber.FromDouble(Math.Round(((BigNumber)(ref value)).ToDouble(), MidpointRounding.AwayFromZero)); } } public sealed class Loan { [JsonProperty(/*Could not decode attribute arguments.*/)] public string Id; [JsonProperty(/*Could not decode attribute arguments.*/)] public Quote Terms; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber Paid; [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber Transferred; [JsonProperty(/*Could not decode attribute arguments.*/)] public string Status = "Outstanding"; [JsonProperty(/*Could not decode attribute arguments.*/)] public int TransferDay = -1; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool QuotaApplied; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool QuotaCleared; } public sealed class Ledger { [JsonProperty(/*Could not decode attribute arguments.*/)] public int Schema = 1; [JsonProperty(/*Could not decode attribute arguments.*/)] public string RunId = Guid.NewGuid().ToString("N"); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<int> UsedDays = new List<int>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<int> EndedDays = new List<int>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public List<Loan> Loans = new List<Loan>(); [JsonProperty(/*Could not decode attribute arguments.*/)] public BigNumber AppliedQuotaDebt; [JsonProperty(/*Could not decode attribute arguments.*/)] public int AppliedDay = -1; [JsonIgnore] public bool HasUnsettledDebt => Loans.Any((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)); [JsonIgnore] public bool HasDefaultedLoan => Loans.Any((Loan l) => l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)); public void Validate() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_01ff: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if (Schema != 1 || string.IsNullOrEmpty(RunId) || UsedDays == null || EndedDays == null || Loans == null || Loans.Any((Loan x) => x == null || x.Terms == null || string.IsNullOrEmpty(x.Id) || x.Terms.DueDay != x.Terms.Day + 1 || x.Terms.Principal <= BigNumber.Zero || x.Terms.Day < 0 || x.Terms.Interest < BigNumber.Zero || x.Terms.Total != x.Terms.Principal + x.Terms.Interest || x.Paid < BigNumber.Zero || x.Paid > x.Terms.Total || (x.Status != "Outstanding" && x.Status != "Repaid" && x.Status != "Transferred" && x.Status != "Defaulted")) || Loans.Select((Loan x) => x.Id).Distinct().Count() != Loans.Count) { throw new InvalidOperationException("Unsupported or damaged Mark Loans ledger. Restore the save backup."); } BigNumber val = BigNumber.Zero; foreach (Loan loan in Loans) { if ((loan.Status == "Repaid" && loan.Paid != loan.Terms.Total) || (loan.Status == "Transferred" && (loan.Paid >= loan.Terms.Total || loan.Transferred <= BigNumber.Zero || loan.TransferDay <= loan.Terms.DueDay)) || (loan.Status == "Defaulted" && (loan.Paid >= loan.Terms.Total || loan.Transferred != BigNumber.Zero || loan.QuotaApplied)) || (loan.QuotaCleared && !loan.QuotaApplied) || (loan.QuotaApplied && loan.Status != "Transferred")) { throw new InvalidOperationException("Inconsistent Mark Loans settlement record. Restore the save backup."); } if (loan.QuotaApplied && !loan.QuotaCleared) { val += loan.Transferred; } } if (val != AppliedQuotaDebt) { throw new InvalidOperationException("Inconsistent quota debt. Restore the save backup."); } } public bool Accept(string proposalId, Quote terms) { if (HasUnsettledDebt || UsedDays.Contains(terms.Day) || EndedDays.Contains(terms.Day) || Loans.Any((Loan x) => x.Id == proposalId)) { return false; } Loans.Add(new Loan { Id = proposalId, Terms = terms }); UsedDays.Add(terms.Day); return true; } public BigNumber Repay(string id, BigNumber balance) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_0065: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) Loan loan = Loans.FirstOrDefault((Loan x) => x.Id == id && x.Status == "Outstanding"); if (loan == null) { throw new InvalidOperationException("That loan has already been settled."); } BigNumber val = loan.Terms.Total - loan.Paid; if (balance < val) { throw new InvalidOperationException("Team funds cannot cover this repayment yet."); } loan.Paid += val; loan.Status = "Repaid"; return val; } public BigNumber EndDay(int day, BigNumber balance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e0: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (EndedDays.Contains(day)) { return BigNumber.Zero; } BigNumber val = BigNumber.Zero; foreach (Loan item in from x in Loans where x.Status == "Outstanding" && x.Terms.DueDay <= day orderby x.Terms.DueDay, x.Terms.Day select x) { BigNumber val2 = item.Terms.Total - item.Paid; BigNumber val3 = BigNumber.Min(val2, BigNumber.Max(BigNumber.Zero, balance - val)); item.Paid += val3; val += val3; if (val2 - val3 > BigNumber.Zero) { item.Status = "Defaulted"; } else { item.Status = "Repaid"; } } EndedDays.Add(day); return val; } public BigNumber ApplyQuota(int day) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0050: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0084: 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) BigNumber val = BigNumber.Zero; foreach (Loan item in Loans.Where((Loan x) => x.Status == "Transferred" && !x.QuotaApplied && x.TransferDay <= day)) { val += item.Transferred; item.QuotaApplied = true; } AppliedQuotaDebt += val; AppliedDay = day; return val; } public BigNumber ClearQuota() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) BigNumber appliedQuotaDebt = AppliedQuotaDebt; foreach (Loan item in Loans.Where((Loan x) => x.QuotaApplied)) { item.QuotaCleared = true; } AppliedQuotaDebt = BigNumber.Zero; return appliedQuotaDebt; } public Ledger Copy() { return Codec.Read<Ledger>(Codec.Write(this)); } public Ledger ViewForDay(int day) { //IL_00a5: 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) return new Ledger { RunId = RunId, Schema = Schema, UsedDays = UsedDays.Where((int d) => d == day).ToList(), EndedDays = EndedDays.Where((int d) => d == day).ToList(), Loans = Loans.Where((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)).ToList(), AppliedQuotaDebt = AppliedQuotaDebt, AppliedDay = AppliedDay }; } } public sealed class Proposal { public string Id = Guid.NewGuid().ToString("N"); public Quote Terms; public string Borrower; public List<string> Eligible; public List<string> Approved = new List<string>(); public List<string> Rejected = new List<string>(); public int Required; public double Deadline; public static Proposal Start(Quote quote, string borrower, IEnumerable<string> players, double now) { List<string> list = players.Distinct().ToList(); if (!list.Contains(borrower) || list.Count == 0) { throw new InvalidOperationException("Borrower is not connected."); } return new Proposal { Terms = quote, Borrower = borrower, Eligible = list, Required = (list.Count + 1) / 2, Approved = new List<string> { borrower }, Deadline = now + quote.VoteSeconds }; } public bool Vote(string player, bool approve, double now) { if (now >= Deadline || !Eligible.Contains(player) || Approved.Contains(player) || Rejected.Contains(player)) { return false; } (approve ? Approved : Rejected).Add(player); return true; } public bool Passed(double now) { if (now < Deadline) { return Approved.Count >= Required; } return false; } public bool Failed(double now) { if (!(now >= Deadline)) { return Eligible.Count - Rejected.Count < Required; } return true; } } internal sealed class MarkVisual : IDisposable { private readonly Plugin plugin; private readonly ConfigEntry<float> x; private readonly ConfigEntry<float> y; private readonly ConfigEntry<float> z; private readonly ConfigEntry<float> height; private GameObject cacheRoot; private GameObject template; private GameObject mark; private ElevatorManager elevator; private float nextScan; private bool warned; private readonly RaycastHit[] floorHits = (RaycastHit[])(object)new RaycastHit[16]; private Vector3 placedOffset; private float placedHeight; private static readonly FieldRef<ElevatorManager, Collider> ElevatorBounds = AccessTools.FieldRefAccess<ElevatorManager, Collider>("checkCollider"); internal GameObject Mark => mark; internal float[] Offset => new float[3] { x.Value, y.Value, z.Value }; internal float Height => height.Value; internal MarkVisual(Plugin owner, ConfigFile config) { plugin = owner; x = config.Bind<float>("Mark", "CornerOffsetX", -5.2f, "Local elevator X position. All peers should use the same values."); y = config.Bind<float>("Mark", "CornerOffsetY", 0f, "Local elevator floor height offset."); z = config.Bind<float>("Mark", "CornerOffsetZ", 3.4f, "Local elevator Z position."); height = config.Bind<float>("Mark", "ModelHeight", 2.4f, "Loan shark visual height, in Unity units."); } internal void Capture() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template != (Object)null) { return; } cacheRoot = new GameObject("Mark Loans Visual Cache"); Object.DontDestroyOnLoad((Object)(object)cacheRoot); cacheRoot.SetActive(false); string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "shark"); if (!File.Exists(Path.Combine(text, "model.json"))) { Object.Destroy((Object)(object)cacheRoot); cacheRoot = null; return; } try { template = SharkModel.Load(text, cacheRoot.transform); } catch (Exception ex) { plugin.Logger.LogError((object)("Cannot load extracted game's shark model: " + ex.Message)); Object.Destroy((Object)(object)cacheRoot); cacheRoot = null; return; } ((Object)template).name = "Mark LoanShark Template"; template.transform.localPosition = Vector3.zero; template.transform.localRotation = Quaternion.identity; plugin.Logger.LogInfo((object)"Cached original loan shark pose using static meshes."); } internal void Tick() { //IL_0107: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01e0: 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_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: 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_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0304: 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_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0497: 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_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) //IL_05fe: 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_061d: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_069e: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: 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_0509: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 1f; Capture(); ElevatorManager val = ((!NetworkClient.active) ? null : (((Object)(object)elevator != (Object)null) ? elevator : Object.FindAnyObjectByType<ElevatorManager>())); if ((Object)(object)val == (Object)null || !NetworkClient.active) { if ((Object)(object)mark != (Object)null) { Object.Destroy((Object)(object)mark); } mark = null; elevator = null; return; } float[] array = plugin.Menu.View?.MarkOffset ?? Offset; float num = Mathf.Clamp(plugin.Menu.View?.MarkHeight ?? Height, 0.5f, 5f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(array[0], array[1], array[2]); if ((Object)(object)mark != (Object)null && (Object)(object)val == (Object)(object)elevator && val2 == placedOffset && num == placedHeight) { return; } if ((Object)(object)template == (Object)null) { if (!warned) { plugin.Logger.LogWarning((object)"LoanShark_Body is unavailable. Install the shark folder next to MarkLoans.dll; no substitute model will be used."); warned = true; } return; } if ((Object)(object)mark != (Object)null) { Object.Destroy((Object)(object)mark); } elevator = val; placedOffset = val2; placedHeight = num; mark = new GameObject("Mark The Shark", new Type[2] { typeof(BoxCollider), typeof(MarkInteractable) }); mark.transform.SetParent(((Component)elevator).transform, false); mark.transform.localPosition = new Vector3(array[0], array[1], array[2]); BoxCollider component = mark.GetComponent<BoxCollider>(); GameObject val3 = Object.Instantiate<GameObject>(template, mark.transform); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.Euler(0f, 135f, 0f); val3.SetActive(true); Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length != 0) { Bounds val4 = VisibleBounds(componentsInChildren); if (((Bounds)(ref val4)).size.y > 0.01f) { Transform transform = val3.transform; transform.localScale *= num / ((Bounds)(ref val4)).size.y; val4 = VisibleBounds(componentsInChildren); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(mark.transform.position.x - ((Bounds)(ref val4)).center.x, mark.transform.position.y - ((Bounds)(ref val4)).min.y, mark.transform.position.z - ((Bounds)(ref val4)).center.z); Transform transform2 = val3.transform; transform2.position += val5; } } Vector3 position = mark.transform.position; position.y = (((Object)(object)elevator.playerSpawnPosition != (Object)null) ? (elevator.playerSpawnPosition.position.y + 1f) : (position.y + 4f)); int num2 = Physics.RaycastNonAlloc(position, Vector3.down, floorHits, 12f, -1, (QueryTriggerInteraction)1); float num3 = float.MaxValue; for (int i = 0; i < num2; i++) { RaycastHit val6 = floorHits[i]; if (!(((RaycastHit)(ref val6)).normal.y < 0.7f) && !(((RaycastHit)(ref val6)).distance >= num3) && !((Component)((RaycastHit)(ref val6)).collider).transform.IsChildOf(mark.transform) && !((Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<PlayerController>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<InteractableBase>() != (Object)null)) { num3 = ((RaycastHit)(ref val6)).distance; Vector3 position2 = mark.transform.position; position2.y = ((RaycastHit)(ref val6)).point.y + 0.03f + array[1]; mark.transform.position = position2; } } Bounds val7 = VisibleBounds(componentsInChildren); component.center = mark.transform.InverseTransformPoint(((Bounds)(ref val7)).center); Bounds val8 = default(Bounds); ((Bounds)(ref val8))..ctor(component.center, Vector3.zero); for (int j = 0; j < 8; j++) { ((Bounds)(ref val8)).Encapsulate(mark.transform.InverseTransformPoint(((Bounds)(ref val7)).center + Vector3.Scale(((Bounds)(ref val7)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))))); } component.center = ((Bounds)(ref val8)).center; component.size = ((Bounds)(ref val8)).size + Vector3.one * 0.2f; plugin.Logger.LogInfo((object)("Mark placed: visible bottom=" + ((Bounds)(ref val7)).min.y.ToString("0.00") + ", visible height=" + ((Bounds)(ref val7)).size.y.ToString("0.00") + ", full-body collider=" + ((object)component.size/*cast due to .constrained prefix*/).ToString())); GameObject val9 = new GameObject("Mark name", new Type[2] { typeof(TextMeshPro), typeof(MarkNameFacing) }); val9.transform.SetParent(mark.transform, false); val9.transform.position = new Vector3(((Bounds)(ref val7)).center.x, ((Bounds)(ref val7)).max.y + 0.35f, ((Bounds)(ref val7)).center.z); TextMeshPro component2 = val9.GetComponent<TextMeshPro>(); ((TMP_Text)component2).text = "MARK THE SHARK\n<size=65%>Loans • Debts • Questionable advice</size>"; ((TMP_Text)component2).fontSize = 2f; ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; ((Graphic)component2).color = new Color(1f, 0.81f, 0.25f); ((TMP_Text)component2).rectTransform.sizeDelta = new Vector2(5f, 1f); } private static Bounds VisibleBounds(Renderer[] renderers) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) bool flag = true; Bounds result = default(Bounds); for (int i = 0; i < renderers.Length; i++) { Bounds bounds = renderers[i].bounds; if (flag) { result = bounds; flag = false; } else { ((Bounds)(ref result)).Encapsulate(bounds); } } return result; } internal bool Near(Vector3 player) { //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_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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mark == (Object)null || (Object)(object)elevator == (Object)null || !mark.activeInHierarchy) { return false; } Collider val = ElevatorBounds.Invoke(elevator); if ((Object)(object)val != (Object)null) { Bounds bounds = val.bounds; if (((Bounds)(ref bounds)).Contains(player + Vector3.up * 0.5f)) { return Vector3.Distance(player, mark.transform.position) <= 4.5f; } } return false; } public void Dispose() { if ((Object)(object)mark != (Object)null) { Object.Destroy((Object)(object)mark); } if ((Object)(object)cacheRoot != (Object)null) { Object.Destroy((Object)(object)cacheRoot); } } } internal sealed class MarkNameFacing : MonoBehaviour { private void LateUpdate() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main != (Object)null) { ((Component)this).transform.rotation = ((Component)main).transform.rotation; } } } internal sealed class MarkInteractable : MonoBehaviour, IInteractable { public float HoldDuration { get; set; } = 0.25f; public bool HoldInteract { get; set; } public bool IsInteractable { get; set; } = true; public bool MeetRequirements { get; set; } = true; public bool IsBeingHovered { get; set; } public bool IsBeingHold { get; set; } public float HoldProgress { get; set; } public string TooltipMessage { get; set; } = "Press [E] to talk loans"; public string InteractableName { get; set; } = "Mark The Shark"; public CursorType CursorType { get; set; } = (CursorType)1; public event Action<IInteractable> OnInteractableChanged { add { } remove { } } public void OnHover(PlayerInteract p) { IsBeingHovered = true; } public void OnHoverExit(PlayerInteract p) { IsBeingHovered = false; } public void OnHold(PlayerInteract p) { } public void OnHoldExit(PlayerInteract p) { } public void OnInteract(PlayerInteract p) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)p).isLocalPlayer && (int)InputEvents.ActiveLayer == 0 && Plugin.Instance.Visual.Near(((Component)p).transform.position)) { Plugin.Instance.Menu.OpenUI(); } } public void ServerOnHover(PlayerInteract p) { } public void ServerOnHoverExit(PlayerInteract p) { } public void ServerOnHold(PlayerInteract p) { } public void ServerOnHoldExit(PlayerInteract p) { } public void ServerOnInteract(PlayerInteract p) { } public void RpcOnInteract(PlayerInteract p) { } } public struct MarkLoanRequest : NetworkMessage { public string Kind; public string Id; public string Version; public double Percent; public bool Approve; } public struct MarkLoanReply : NetworkMessage { public string Json; } public sealed class View { public string Session; public string Notice; public Ledger Ledger; public Proposal Proposal; public Quote Quote; public LoanRules Rules; public BigNumber BaseQuota; public int Day; public bool Ready; public double Now; public float[] MarkOffset; public float MarkHeight; } internal static class Wire { internal static void Init() { Writer<MarkLoanRequest>.write = delegate(NetworkWriter w, MarkLoanRequest m) { NetworkWriterExtensions.WriteString(w, m.Kind); NetworkWriterExtensions.WriteString(w, m.Id); NetworkWriterExtensions.WriteString(w, m.Version); NetworkWriterExtensions.WriteDouble(w, m.Percent); NetworkWriterExtensions.WriteBool(w, m.Approve); }; Reader<MarkLoanRequest>.read = (NetworkReader r) => new MarkLoanRequest { Kind = NetworkReaderExtensions.ReadString(r), Id = NetworkReaderExtensions.ReadString(r), Version = NetworkReaderExtensions.ReadString(r), Percent = NetworkReaderExtensions.ReadDouble(r), Approve = NetworkReaderExtensions.ReadBool(r) }; Writer<MarkLoanReply>.write = delegate(NetworkWriter w, MarkLoanReply m) { NetworkWriterExtensions.WriteString(w, m.Json); }; Reader<MarkLoanReply>.read = (NetworkReader r) => new MarkLoanReply { Json = NetworkReaderExtensions.ReadString(r) }; } internal static void RegisterServer() { NetworkServer.ReplaceHandler<MarkLoanRequest>((Action<NetworkConnectionToClient, MarkLoanRequest>)Plugin.Instance.Request, true); } internal static void RegisterClient() { NetworkClient.ReplaceHandler<MarkLoanReply>((Action<MarkLoanReply>)delegate(MarkLoanReply m) { try { Plugin.Instance.Receive(Codec.Read<View>(m.Json)); } catch (Exception ex) { Plugin.Instance.Logger.LogError((object)("Invalid Mark Loans host reply: " + ex.Message)); } }, true); } internal static void Send(string kind, string id = null, double percent = 0.0, bool approve = false) { if (NetworkClient.isConnected) { NetworkClient.Send<MarkLoanRequest>(new MarkLoanRequest { Kind = kind, Id = id, Percent = percent, Approve = approve, Version = "1.0.5" }, 0); } } } public static class Codec { private sealed class NumberConverter : JsonConverter { public override bool CanConvert(Type t) { return t == typeof(BigNumber); } public override void WriteJson(JsonWriter w, object value, JsonSerializer s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) BigNumber val = (BigNumber)value; w.WriteStartObject(); w.WritePropertyName("m"); w.WriteValue(val.Mantissa); w.WritePropertyName("e"); w.WriteValue(val.Exponent); w.WriteEndObject(); } public override object ReadJson(JsonReader r, Type t, object existing, JsonSerializer s) { //IL_0044: 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) JObject obj = JObject.Load(r); double num = ((JToken)obj).Value<double>((object)"m"); long num2 = ((JToken)obj).Value<long>((object)"e"); if (double.IsNaN(num) || double.IsInfinity(num) || num2 < -1000000000 || num2 > 1000000000) { throw new JsonSerializationException("Invalid money value."); } return (object)new BigNumber(num, num2); } } private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { (JsonConverter)(object)new NumberConverter() }, MaxDepth = 24, TypeNameHandling = (TypeNameHandling)0 }; public static string Write(object value) { return JsonConvert.SerializeObject(value, Settings); } public static T Read<T>(string json) { return JsonConvert.DeserializeObject<T>(json, Settings); } } internal static class Persistence { private sealed class Attached { public Ledger Ledger; public bool Invalid; } internal const string Key = "markLoans"; private static readonly ConditionalWeakTable<SaveData, Attached> Loaded = new ConditionalWeakTable<SaveData, Attached>(); internal static bool LastWriteSucceeded; internal static bool Resetting; internal static SaveData ResetOriginal; internal static readonly FieldRef<SaveManager, SaveData> Current = AccessTools.FieldRefAccess<SaveManager, SaveData>("currentSaveData"); internal static readonly FieldRef<SaveManager, bool> HasLoaded = AccessTools.FieldRefAccess<SaveManager, bool>("hasLoadedGame"); internal static void AttachRead(string json, object result) { SaveData val = (SaveData)((result is SaveData) ? result : null); if (val == null) { return; } Attached orCreateValue = Loaded.GetOrCreateValue(val); try { JToken val2 = JObject.Parse(json)["markLoans"]; orCreateValue.Ledger = ((val2 == null) ? new Ledger() : Codec.Read<Ledger>(((object)val2).ToString())); orCreateValue.Ledger.Validate(); } catch (Exception ex) { orCreateValue.Invalid = true; Plugin.Instance.Logger.LogError((object)("Mark Loans save data could not be read: " + ex.Message)); } } internal static void AttachWrite(object obj, ref string json) { SaveData val = (SaveData)((obj is SaveData) ? obj : null); if (val != null) { Attached orCreateValue = Loaded.GetOrCreateValue(val); if (NetworkServer.active && (Object)(object)NetworkSingleton<SaveManager>.Instance != (Object)null && val == Current.Invoke(NetworkSingleton<SaveManager>.Instance) && Plugin.Instance.Loaded) { orCreateValue.Ledger = Plugin.Instance.State; } if (orCreateValue.Invalid) { throw new InvalidOperationException("Refusing to overwrite an unreadable Mark Loans ledger."); } if (orCreateValue.Ledger != null) { JObject val2 = JObject.Parse(json); val2["markLoans"] = JToken.Parse(Codec.Write(orCreateValue.Ledger)); json = ((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>()); } } } internal static void OnLoad(SaveManager manager, bool wasLoaded) { if (!(!NetworkServer.active || wasLoaded) && HasLoaded.Invoke(manager) && Current.Invoke(manager) != null) { Attached orCreateValue = Loaded.GetOrCreateValue(Current.Invoke(manager)); Plugin.Instance.State = orCreateValue.Ledger ?? new Ledger(); Plugin.Instance.Loaded = !orCreateValue.Invalid; Plugin.Instance.Faulted = !Plugin.Instance.StartupHealthy || orCreateValue.Invalid; Plugin.Instance.CancelProposal(); Plugin.Instance.ResetLossRequest(); if (orCreateValue.Invalid) { Plugin.Instance.Logger.LogError((object)"Financial actions disabled because the save ledger is damaged."); } } } internal static void NewRun() { if (NetworkServer.active) { Plugin.Instance.State = new Ledger(); Plugin.Instance.ResetLossRequest(); Plugin.Instance.Loaded = true; Plugin.Instance.Faulted = !Plugin.Instance.StartupHealthy; Plugin.Instance.CancelProposal(); } } internal static void WriteAtomic(string path, string contents) { LastWriteSucceeded = false; AtomicFile.Write(path, contents); LastWriteSucceeded = true; } } [HarmonyPatch(typeof(JsonUtility), "FromJson", new Type[] { typeof(string), typeof(Type) })] internal static class ReadSavePatch { private static void Postfix(string json, object __result) { Persistence.AttachRead(json, __result); } } [HarmonyPatch(typeof(JsonUtility), "ToJson", new Type[] { typeof(object), typeof(bool) })] internal static class WriteSavePatch { private static void Postfix(object obj, ref string __result) { Persistence.AttachWrite(obj, ref __result); } } [HarmonyPatch(typeof(SaveManager), "LoadGame")] internal static class LoadPatch { private static void Prefix(SaveManager __instance, out bool __state) { __state = Persistence.HasLoaded.Invoke(__instance); } private static void Postfix(SaveManager __instance, bool __state) { Persistence.OnLoad(__instance, __state); } } [HarmonyPatch(typeof(SaveManager), "ResetCurrentSaveToDefaults")] internal static class ResetPatch { private static void Prefix(SaveManager __instance) { Persistence.Resetting = NetworkServer.active; Persistence.ResetOriginal = Persistence.Current.Invoke(__instance); } private static Exception Finalizer(Exception __exception) { Persistence.Resetting = false; Persistence.ResetOriginal = null; return __exception; } } [HarmonyPatch(typeof(SaveManager), "SaveGameDataToFile")] internal static class AtomicSavePatch { private static void Prefix(SaveData saveData) { if (Persistence.Resetting && saveData != Persistence.ResetOriginal && (Object)(object)NetworkSingleton<SaveManager>.Instance != (Object)null && saveData == Persistence.Current.Invoke(NetworkSingleton<SaveManager>.Instance)) { Persistence.NewRun(); Persistence.ResetOriginal = saveData; } } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo original = AccessTools.Method(typeof(File), "WriteAllText", new Type[2] { typeof(string), typeof(string) }, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(Persistence), "WriteAtomic", (Type[])null, (Type[])null); bool found = false; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, original)) { instruction.operand = replacement; found = true; } yield return instruction; } if (!found) { throw new MissingMethodException("The game's save writer changed; Mark Loans cannot ensure atomic saves."); } } } [HarmonyPatch(typeof(GameManager), "OnTimerEnd")] internal static class TimerEndPatch { private static bool Prefix(GameManager __instance, ref IEnumerator __result) { if (!Plugin.Instance.EndDay(__instance.daysPassed)) { return true; } Plugin.Instance.BeginLoanLoss(); __result = Enumerable.Empty<object>().GetEnumerator(); return false; } } [HarmonyPatch(typeof(GameManager), "ProgressGame")] internal static class ProgressLoanDeadlinePatch { private static bool Prefix(GameManager __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (!NetworkServer.active || !Plugin.Instance.Loaded || (int)__instance.state == 2) { return true; } bool flag = Plugin.Instance.State.HasDefaultedLoan; if ((int)__instance.state == 1) { flag = Plugin.Instance.EndDay(__instance.daysPassed); } if (!flag) { return true; } Plugin.Instance.BeginLoanLoss(); return false; } } [HarmonyPatch(typeof(NetworkManager), "ServerChangeScene")] internal static class DefaultLossRedirectPatch { private static void Prefix(ref string __0) { if (NetworkServer.active && Plugin.Instance.Loaded && Plugin.Instance.State.HasDefaultedLoan && (__0 == "HomeScene" || __0 == "CasinoScene")) { __0 = "LoseStateScene"; } } } [HarmonyPatch(typeof(GameManager), "ServerPayDebt")] internal static class FailedLoanQuotaRewardPatch { private static bool Prefix() { if (NetworkServer.active && Plugin.Instance.Loaded) { return !Plugin.Instance.State.HasDefaultedLoan; } return true; } } [HarmonyPatch(typeof(GameManager), "set_NetworkdaysPassed")] internal static class DayPatch { private static void Prefix(GameManager __instance, int value) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (NetworkServer.active && (int)__instance.state == 1 && value == __instance.daysPassed + 1) { Plugin.Instance.EndDay(__instance.daysPassed); } } } [HarmonyPatch(typeof(GameManager), "ProgressNextQuota")] internal static class QuotaPatch { private static void Prefix(GameManager __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Plugin.Instance.Loaded) { __instance.currentQuota = BigNumber.Max(BigNumber.Zero, __instance.currentQuota - Plugin.Instance.State.ClearQuota()); } } private static void Postfix(GameManager __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Plugin.Instance.Loaded) { __instance.currentQuota += Plugin.Instance.State.ApplyQuota(__instance.daysPassed); } } } [HarmonyPatch(typeof(CustomNetworkManager), "OnStartServer")] internal static class ServerStartPatch { private static void Postfix() { Wire.RegisterServer(); } } [HarmonyPatch(typeof(CustomNetworkManager), "OnClientConnect")] internal static class ClientStartPatch { private static void Prefix() { Wire.RegisterClient(); } } [HarmonyPatch(typeof(CustomNetworkManager), "OnStopClient")] internal static class ClientStopPatch { private static void Postfix() { Plugin.Instance.StopSession(); } } [HarmonyPatch(typeof(EscapeMenu), "ToggleEscapeMenu")] internal static class EscapePatch { private static bool Prefix() { return !Plugin.Instance.Menu.BlocksEscape; } } [BepInPlugin("local.markloans", "Mark Loans", "1.0.5")] public sealed class Plugin : BaseUnityPlugin { private sealed class Peer { public string Session = Guid.NewGuid().ToString("N"); public Quote Quote; public double QuoteExpiry; public double LastRequest; } public const string Version = "1.0.5"; internal static Plugin Instance; internal Ledger State = new Ledger(); internal bool Loaded; internal bool Faulted; internal bool StartupHealthy; internal LoanMenu Menu; internal MarkVisual Visual; private Harmony harmony; private Proposal proposal; private readonly Dictionary<NetworkConnectionToClient, Peer> peers = new Dictionary<NetworkConnectionToClient, Peer>(); private ConfigEntry<double> min; private ConfigEntry<double> max; private ConfigEntry<double> step; private ConfigEntry<double> minRate; private ConfigEntry<double> maxRate; private ConfigEntry<double> duration; private float nextHello; private float nextBroadcast; private bool busy; private bool snapshotSent; private bool lastReady; private int lastDay; private string lastRun; private BigNumber lastQuota; private bool lossRequested; private static readonly FieldRef<GameManager, bool> Transitioning = AccessTools.FieldRefAccess<GameManager, bool>("_isTransitioning"); internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; internal LoanRules Rules => new LoanRules { MinPercent = min.Value, MaxPercent = max.Value, StepPercent = step.Value, MinInterest = minRate.Value, MaxInterest = maxRate.Value, OverduePenalty = 0.0, VoteSeconds = duration.Value }; internal BigNumber BaseQuota { get { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null)) { return BigNumber.Max(BigNumber.Zero, NetworkSingleton<GameManager>.Instance.currentQuota - State.AppliedQuotaDebt); } return BigNumber.Zero; } } private bool CanBorrow { get { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 if (Loaded && !Faulted && (Object)(object)NetworkSingleton<GameManager>.Instance != (Object)null && (int)NetworkSingleton<GameManager>.Instance.state == 1 && !State.HasUnsettledDebt && !State.UsedDays.Contains(NetworkSingleton<GameManager>.Instance.daysPassed)) { return !State.EndedDays.Contains(NetworkSingleton<GameManager>.Instance.daysPassed); } return false; } } private void Awake() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown Instance = this; min = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "MinimumQuotaPercent", 25.0, "Minimum borrowing percentage of base quota."); max = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "MaximumQuotaPercent", 50.0, "Maximum borrowing percentage of base quota."); step = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "SliderStepPercent", 5.0, "Percentage point increment; maximum is always selectable."); minRate = ((BaseUnityPlugin)this).Config.Bind<double>("Interest", "MinimumPercent", 10.0, "One-time interest at minimum borrowing."); maxRate = ((BaseUnityPlugin)this).Config.Bind<double>("Interest", "MaximumPercent", 50.0, "One-time interest at maximum borrowing."); duration = ((BaseUnityPlugin)this).Config.Bind<double>("Voting", "DurationSeconds", 30.0, "Vote timeout in real seconds."); Visual = new MarkVisual(this, ((BaseUnityPlugin)this).Config); Menu = ((Component)this).gameObject.AddComponent<LoanMenu>(); Wire.Init(); harmony = new Harmony("local.markloans"); try { Rules.Validate(); harmony.PatchAll(typeof(Plugin).Assembly); StartupHealthy = true; } catch (Exception ex) { Faulted = true; Logger.LogError((object)("Mark Loans disabled: " + ex)); } SceneManager.sceneLoaded += SceneLoaded; Logger.LogInfo((object)"Mark Loans 1.0.5 loaded. All players must install this version. Multiplayer validation pending."); } private void SceneLoaded(Scene scene, LoadSceneMode mode) { Menu.CloseUI(); Visual.Capture(); if (NetworkServer.active) { CancelProposal(); } } private void Update() { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) if (Faulted) { return; } Visual.Tick(); if (NetworkClient.isConnected && Time.unscaledTime >= nextHello) { nextHello = Time.unscaledTime + 2f; if (Menu.View == null) { Wire.Send("Hello"); } } if (!NetworkServer.active) { return; } if (Loaded && State.HasDefaultedLoan) { BeginLoanLoss(); return; } foreach (NetworkConnectionToClient item in peers.Keys.Where((NetworkConnectionToClient x) => !NetworkServer.connections.Values.Contains(x)).ToList()) { peers.Remove(item); } if (proposal != null) { if ((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null || proposal.Terms.Day != NetworkSingleton<GameManager>.Instance.daysPassed || !CanBorrow || proposal.Failed(NetworkTime.time)) { CancelProposal("Vote expired or failed. Mark's patience has left the building."); } else if (proposal.Passed(NetworkTime.time)) { Accept(); } } if (Time.unscaledTime >= nextBroadcast) { nextBroadcast = Time.unscaledTime + 1f; if (proposal != null || !snapshotSent || lastQuota != BaseQuota || lastDay != (NetworkSingleton<GameManager>.Instance?.daysPassed ?? 0) || lastReady != CanBorrow || lastRun != State.RunId) { Broadcast(); } } } internal void Request(NetworkConnectionToClient conn, MarkLoanRequest request) { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Invalid comparison between Unknown and I4 //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_026c: 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_0323: Unknown result type (might be due to invalid IL or missing references) if (Faulted || !((NetworkConnection)conn).isAuthenticated || request.Version != "1.0.5") { return; } if (request.Kind == "Hello") { if (!peers.ContainsKey(conn)) { peers.Add(conn, new Peer()); } Reply(conn); } else { if (!peers.TryGetValue(conn, out var value) || (Object)(object)((NetworkConnection)conn).identity == (Object)null || NetworkTime.time - value.LastRequest < 0.15) { return; } value.LastRequest = NetworkTime.time; try { if (request.Kind == "Vote") { if (proposal != null && !(request.Id != proposal.Id) && proposal.Vote(value.Session, request.Approve, NetworkTime.time)) { if (proposal.Passed(NetworkTime.time)) { Accept(); } else if (proposal.Failed(NetworkTime.time)) { CancelProposal("The team said no. Mark will survive. Probably."); } else { Broadcast(); } } return; } if (!Loaded || busy) { throw new InvalidOperationException("The save is not ready for financial changes."); } if (request.Kind == "Repay") { if ((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null || (int)NetworkSingleton<GameManager>.Instance.state != 1) { throw new InvalidOperationException("Repayment is available during the casino day."); } Commit(() => -State.Repay(request.Id, NetworkSingleton<MoneyManager>.Instance.balance)); Broadcast("Loan repaid! Mark's accountant just did a little fin dance."); return; } if (State.HasUnsettledDebt) { throw new InvalidOperationException("Settle your existing loan or quota debt first. Mark remembers."); } if (!CanBorrow) { throw new InvalidOperationException("No more loans today. My wallet needs a nap. You can still repay me."); } if (!Visual.Near(((Component)((NetworkConnection)conn).identity).transform.position)) { throw new InvalidOperationException("Talk to Mark inside the elevator."); } if (proposal != null) { throw new InvalidOperationException("A team vote is already in progress."); } if (request.Kind == "Quote") { value.Quote = Quote.Create(NetworkSingleton<GameManager>.Instance.daysPassed, BaseQuota, request.Percent, Rules); value.QuoteExpiry = NetworkTime.time + 60.0; Reply(conn, null, value.Quote); } else { if (!(request.Kind == "Propose")) { return; } if (value.Quote == null || request.Id != value.Quote.Id || NetworkTime.time >= value.QuoteExpiry || value.Quote.Day != NetworkSingleton<GameManager>.Instance.daysPassed || value.Quote.BaseQuota != BaseQuota) { throw new InvalidOperationException("That quote has expired or the quota changed. Review a fresh quote."); } List<NetworkConnection