Decompiled source of FXDSP v1.0.0
plugins/FXDSP/FXDSP.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using ABN; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using FXDSP.Configuration; using FXDSP.Core; using FXDSP.Persistence; using FXDSP.Runtime; using FXDSP.UI; using HarmonyLib; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using crecheng.DSPModSave; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("FXDSP")] [assembly: AssemblyProduct("FXDSP")] [assembly: AssemblyDescription("Item-backed trading, building exchange and logistics delivery for Dyson Sphere Program.")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: ComVisible(false)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace FXDSP { [BepInPlugin("dspfx.mod", "FXDSP", "1.0.0")] [BepInDependency("crecheng.DSPModSave", "1.2.2")] public sealed class Plugin : BaseUnityPlugin, IModCanSave { private const string RuntimeOwnerKey = "FXDSP.PluginRuntimeOwner.v1"; private readonly string _owner = Guid.NewGuid().ToString("N"); private Harmony _harmony; private ModSettings _settings; private MarketSession _session; private MarketWindow _window; private UIMessageBox _achievementPopup; private PositionHud _hud; private DeliveryService _delivery; private bool _useDelivery; private bool _registered; private bool _saveWarningShown; private string _notice = ""; private int _selectedLeverage = 5; private int _selectedItemId = 99000001; private int _exchangeItemId = 2001; private int _exchangeTier = 1; private readonly List<MarketOption> _marketOptions = new List<MarketOption>(); private readonly Dictionary<int, PositionSettlement> _shownSettlements = new Dictionary<int, PositionSettlement>(); internal static Plugin Active { get; private set; } internal bool BypassAbnormalityChecks { get { if (OwnsRuntime && _settings != null) { return _settings.BypassAbnormalityChecks.Value; } return false; } } private bool OwnsRuntime => object.Equals(AppDomain.CurrentDomain.GetData("FXDSP.PluginRuntimeOwner.v1"), _owner); private void Awake() { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown try { AppDomain.CurrentDomain.SetData("FXDSP.PluginRuntimeOwner.v1", _owner); Active = this; ModLocalization.Update(); _settings = new ModSettings(((BaseUnityPlugin)this).Config); _settings.VerboseLogging.SettingChanged += OnVerboseLoggingChanged; _session = new MarketSession(); _delivery = new DeliveryService(_session); _window = new MarketWindow(GetSnapshot, GetPortfolio, Execute, _session.AcknowledgeIntroduction, () => _session.Achievements); _hud = new PositionHud(GetPortfolio, Execute, _window.ShowAllPositions, _window.ShowExchange, () => _settings.PositionHudMode.Value, delegate(int mode) { _settings.PositionHudMode.Value = mode; }); _harmony = new Harmony("dspfx.mod.runtime." + Guid.NewGuid().ToString("N")); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Local abnormality bypass: " + BypassAbnormalityChecks + ". Existing records retained; sandbox/account eligibility unchanged.")); TryRegisterSaveHandler(); TradeResearchState tradeResearchState = ResearchProgression.Read(); _session.SetTradingFeeRate(tradeResearchState.TradingFee); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FXDSP 1.0.0 loaded. F8: copper-margin market; F6: ScriptEngine reload."); if (_settings.VerboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Harmony owner: " + _harmony.Id)); } } catch (Exception ex) { Cleanup(); ((BaseUnityPlugin)this).Logger.LogError((object)("FXDSP initialization failed: " + ex)); throw; } } private void Update() { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_00df: Unknown result type (might be due to invalid IL or missing references) if (!OwnsRuntime || _session == null) { return; } try { TryRegisterSaveHandler(); ModLocalization.Update(); TradeResearchState tradeResearchState = ResearchProgression.Read(); _session.SetTradingFeeRate(tradeResearchState.TradingFee); if (GameMain.isRunning && GameMain.data != null && (Object)(object)GameMain.instance != (Object)null && !GameMain.instance.isMenuDemo) { ResourceMarketCatalog.GetOptions(); } _session.Tick(); _delivery.Tick(); ShowNewSettlement(); try { if (!GameMain.isRunning || GameMain.mainPlayer == null || !((Object)(object)GameMain.instance != (Object)null) || GameMain.instance.isMenuDemo) { _window.Close(); _hud.Tick(visible: false); return; } KeyboardShortcut value; if (!tradeResearchState.Access) { value = _settings.WindowKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !VFInput.inputing) { UIRealtimeTip.Popup(TextLocalization.Translate("请先研究“交易系统”:10 铁矿、10 铜矿。"), true, 0); } _window.Close(); _hud.Tick(visible: false); return; } value = _settings.WindowKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !VFInput.inputing) { _window.Toggle(); } _window.Tick(); _hud.Tick(!_window.HasSettlement); ShowAchievements(); } catch (Exception ex) { _window.Close(); _hud.Tick(visible: false); _notice = "交易窗口暂时无法创建,请查看日志后重试 F8。"; ((BaseUnityPlugin)this).Logger.LogError((object)("FXDSP window failed: " + ex)); } } catch (Exception ex2) { _notice = "更新失败,请查看 BepInEx 日志。"; ((BaseUnityPlugin)this).Logger.LogError((object)("FXDSP update failed: " + ex2)); ((Behaviour)this).enabled = false; _window.Close(); if (_hud != null) { _hud.Tick(visible: false); } } } private void ShowAchievements() { if (_session.CanAccessDelivery && _session.Achievements.Pending.Count != 0 && (!((Object)(object)_achievementPopup != (Object)null) || !((Component)_achievementPopup).gameObject.activeInHierarchy)) { AchievementDefinition achievementDefinition = AchievementCatalog.Find(_session.Achievements.Pending[0]); _achievementPopup = UIMessageBox.Show(TextLocalization.Translate("成就达成 · " + achievementDefinition.Name), TextLocalization.Translate(achievementDefinition.Description), TextLocalization.Translate("知道了"), 0); _session.Achievements.AcknowledgeFirst(); _session.PreserveForReload(); } } private void TryRegisterSaveHandler() { if (!_registered && OwnsRuntime && DSPModSavePlugin.logger != null && Chainloader.PluginInfos.ContainsKey("crecheng.DSPModSave")) { DSPModSavePlugin.RemoveModSaveManually((BaseUnityPlugin)(object)this); DSPModSavePlugin.AddModSaveManually((BaseUnityPlugin)(object)this); _registered = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"FXDSP save handler registered."); } } private MarketSnapshot GetSnapshot(int quantity) { MarketSnapshot marketSnapshot = new MarketSnapshot(); if (_session == null) { return marketSnapshot; } if (MarketCatalog.IsSelectable(_selectedItemId) && !_session.IsMarketEnabled(_selectedItemId)) { MarginMarket marginMarket = _session.Markets.FirstOrDefault((MarginMarket candidate) => MarketCatalog.IsSelectable(candidate.State.ItemId) && MarketCatalog.Category(candidate.State.ItemId) == MarketCatalog.Category(_selectedItemId) && _session.IsMarketEnabled(candidate.State.ItemId)); if (marginMarket != null) { _selectedItemId = marginMarket.State.ItemId; } } MarginMarket market = _session.GetMarket(_selectedItemId); TradeResearchState tradeResearchState = ResearchProgression.Read(); marketSnapshot.Ready = ((Behaviour)this).enabled && OwnsRuntime && _registered && _session.CanTrade && !GameMain.isPaused && tradeResearchState.Access; marketSnapshot.ResourcesEditable = marketSnapshot.Ready; marketSnapshot.MarketEnabled = _session.IsMarketEnabled(_selectedItemId); marketSnapshot.Ready &= marketSnapshot.MarketEnabled; marketSnapshot.Status = (marketSnapshot.Ready ? _notice : _session.Status); if (marketSnapshot.ResourcesEditable && !marketSnapshot.MarketEnabled) { marketSnapshot.Status = (string.IsNullOrEmpty(_notice) ? "请选择品种" : _notice); } if (GameMain.isPaused) { marketSnapshot.Status = "游戏已暂停,交易与行情暂停。"; } marketSnapshot.PersistenceStatus = (marketSnapshot.Ready ? "" : _session.Status); if (market == null) { return marketSnapshot; } marketSnapshot.ItemId = market.State.ItemId; marketSnapshot.ItemName = MarketCatalog.Name(marketSnapshot.ItemId); bool flag = marketSnapshot.ItemId == 99000001; ItemProto val = (((Object)(object)LDB.items == (Object)null || flag) ? null : ((ProtoSet<ItemProto>)(object)LDB.items).Select(marketSnapshot.ItemId)); if (val != null) { marketSnapshot.ItemName = ((Proto)val).name; marketSnapshot.ItemIcon = val.iconSprite; } marketSnapshot.BackpackQuantity = ((!flag && marketSnapshot.MarketEnabled) ? PlayerInventory.Count(marketSnapshot.ItemId) : 0); marketSnapshot.CanUseDelivery = marketSnapshot.ItemId != 1099; marketSnapshot.UseDelivery = _useDelivery && marketSnapshot.CanUseDelivery; marketSnapshot.TransferAvailable = (marketSnapshot.UseDelivery ? _delivery.Available(marketSnapshot.ItemId).Count : ((flag || !marketSnapshot.MarketEnabled) ? ((BigInteger)0) : PlayerInventory.Available(marketSnapshot.ItemId))); marketSnapshot.DeliveryName = _delivery.BindingName(marketSnapshot.ItemId); marketSnapshot.DeliveryBound = _delivery.BoundPlatform(marketSnapshot.ItemId) != null; if (_marketOptions.Count == 0 && (Object)(object)LDB.items != (Object)null) { foreach (int itemId in MarketCatalog.ItemIds) { ItemProto val2 = ((itemId == 99000001) ? null : ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId)); _marketOptions.Add(new MarketOption { ItemId = itemId, Name = MarketCatalog.Name(itemId), Icon = ((val2 == null) ? null : val2.iconSprite) }); } } marketSnapshot.Markets = _marketOptions; marketSnapshot.ResourceOptions = ResourceMarketCatalog.GetOptions(); foreach (MarketOption resourceOption in marketSnapshot.ResourceOptions) { resourceOption.Enabled = _session.IsMarketEnabled(resourceOption.ItemId); MarginMarket marginMarket2 = _session.FindMarket(resourceOption.ItemId); resourceOption.HasPosition = marginMarket2 != null && marginMarket2.Position != null; } marketSnapshot.BuildingCoinBalance = _session.GetMarket(99000001).State.Balance; if (flag) { marketSnapshot.ExchangeOffers = (from offer in BuildingExchangeCatalog.GetOffers() where offer.Tier == _exchangeTier select offer).ToArray(); foreach (ExchangeOffer exchangeOffer in marketSnapshot.ExchangeOffers) { marketSnapshot.ExchangeInventory[exchangeOffer.ItemId] = PlayerInventory.Count(exchangeOffer.ItemId); } marketSnapshot.ExchangeTier = _exchangeTier; marketSnapshot.ExchangeUnlocked = tradeResearchState.CanExchange(_exchangeTier); marketSnapshot.ExchangeFeeRate = tradeResearchState.ExchangeFee; marketSnapshot.ExchangeItemId = _exchangeItemId; marketSnapshot.ExchangeBackpackQuantity = ((_exchangeItemId > 0) ? PlayerInventory.Count(_exchangeItemId) : 0); } marketSnapshot.AvailableBalance = market.State.Balance; marketSnapshot.Equity = market.Equity; marketSnapshot.UsedMargin = market.UsedMargin; marketSnapshot.UnrealizedPnL = market.UnrealizedPnL; marketSnapshot.RealizedPnL = market.State.RealizedPnL; marketSnapshot.NetPnL = market.NetPnL; marketSnapshot.SelectedLeverage = _selectedLeverage; marketSnapshot.Bid = (marketSnapshot.MarketEnabled ? market.Bid : 0m); marketSnapshot.Ask = (marketSnapshot.MarketEnabled ? market.Ask : 0m); marketSnapshot.FeeRate = market.FeeRate; marketSnapshot.Deposited = market.State.TotalDeposited; marketSnapshot.Withdrawn = market.State.TotalWithdrawn; marketSnapshot.ReturnRatio = AccountPerformance.ReturnRatio(marketSnapshot.RealizedPnL, marketSnapshot.Deposited, marketSnapshot.Withdrawn); if (marketSnapshot.MarketEnabled) { marketSnapshot.Candles = MarketCandles.Build(market.History); } marketSnapshot.RecentEvents = market.RecentLogs.Reverse().ToArray(); MarginPosition position = market.Position; marketSnapshot.HasPosition = position != null; if (position != null) { marketSnapshot.PositionDirection = ((position.Side == PositionSide.Long) ? "做多" : "做空"); marketSnapshot.PositionLeverage = position.Leverage; marketSnapshot.EntryPrice = position.EntryPrice; marketSnapshot.PositionMargin = position.Margin; marketSnapshot.PositionOpenTick = position.OpenTick; marketSnapshot.CurrentTick = GameMain.gameTick; marketSnapshot.LiquidationPrice = market.LiquidationPrice; } if (marketSnapshot.MarketEnabled && quantity >= 1 && quantity <= 100) { marketSnapshot.OrderMargin = market.MarginForAllocation(quantity, _selectedLeverage); if (marketSnapshot.OrderMargin > 0m) { marketSnapshot.OpenCost = market.OpenCost(marketSnapshot.OrderMargin, _selectedLeverage); marketSnapshot.OpenFee = market.OpenFee(marketSnapshot.OrderMargin, _selectedLeverage); } } return marketSnapshot; } private void Execute(MarketCommand command, int quantity) { switch (command) { case MarketCommand.UseBackpack: case MarketCommand.UseDelivery: _useDelivery = command == MarketCommand.UseDelivery; _notice = ""; return; case MarketCommand.SelectExchangeTier: if (quantity >= 1 && quantity <= 5) { _exchangeTier = quantity; ExchangeOffer[] array = (from offer in BuildingExchangeCatalog.GetOffers() where offer.Tier == quantity select offer).ToArray(); if (!array.Any((ExchangeOffer offer) => offer.ItemId == _exchangeItemId)) { _exchangeItemId = ((array.Length != 0) ? array[0].ItemId : 0); } _notice = ""; } return; case MarketCommand.SelectExchangeItem: BuildingExchangeCatalog.Find(quantity); _exchangeItemId = quantity; _notice = ""; return; case MarketCommand.SelectMarket: if (MarketCatalog.Contains(quantity)) { _selectedItemId = quantity; _notice = ""; return; } break; } if (!OwnsRuntime || !_registered || !_session.CanTrade || GameMain.isPaused || !((Behaviour)this).enabled) { _notice = "当前不能交易,请先进入存档并检查市场状态。"; return; } try { TradeResearchState tradeResearchState = ResearchProgression.Read(); tradeResearchState.RequireAccess(); _session.SetTradingFeeRate(tradeResearchState.TradingFee); MarginMarket market = _session.GetMarket(_selectedItemId); if ((command == MarketCommand.Deposit || command == MarketCommand.Withdraw || command == MarketCommand.OpenLong || command == MarketCommand.OpenShort) && !_session.IsMarketEnabled(_selectedItemId)) { throw new InvalidOperationException("请先启用该市场。"); } switch (command) { case MarketCommand.EnableResource: case MarketCommand.DisableResource: ResourceMarketCatalog.RequireResource(quantity); _session.SetResourceEnabled(quantity, command == MarketCommand.EnableResource); _notice = ""; break; case MarketCommand.Deposit: _notice = ((_useDelivery && _selectedItemId != 1099) ? _delivery.Transfer(market, quantity, deposit: true) : PlayerInventory.Deposit(market, quantity)); break; case MarketCommand.Withdraw: _notice = ((_useDelivery && _selectedItemId != 1099) ? _delivery.Transfer(market, quantity, deposit: false) : PlayerInventory.Withdraw(market, quantity)); break; case MarketCommand.OpenLong: _notice = market.Open(PositionSide.Long, market.MarginForAllocation(quantity, _selectedLeverage), _selectedLeverage, quantity); break; case MarketCommand.OpenShort: _notice = market.Open(PositionSide.Short, market.MarginForAllocation(quantity, _selectedLeverage), _selectedLeverage, quantity); break; case MarketCommand.ClosePosition: _notice = market.Close(); break; case MarketCommand.CloseMarketPosition: case MarketCommand.CloseHudPosition: _notice = (_session.ClosePosition(quantity) ? "持仓已平仓。" : "该市场当前空仓。"); if (command == MarketCommand.CloseHudPosition) { _shownSettlements[quantity] = _session.GetMarket(quantity).LastSettlement; } break; case MarketCommand.CloseAllPositions: _notice = "已平仓 " + _session.CloseAllPositions() + " 项持仓。"; break; case MarketCommand.BuyBuilding: case MarketCommand.SellBuilding: { ExchangeOffer exchangeOffer = BuildingExchangeCatalog.Find(_exchangeItemId); tradeResearchState.RequireExchange(exchangeOffer.Tier); MarginMarket market2 = _session.GetMarket(99000001); _notice = ((command == MarketCommand.BuyBuilding) ? PlayerInventory.BuyBuilding(market2, exchangeOffer.ItemId, quantity, exchangeOffer.UnitValue, tradeResearchState.ExchangeFee) : PlayerInventory.SellBuilding(market2, exchangeOffer.ItemId, quantity, exchangeOffer.UnitValue, tradeResearchState.ExchangeFee)); break; } case MarketCommand.ChangeLeverage: if (!MarginMarket.IsAllowedLeverage(quantity)) { throw new InvalidOperationException("不支持该杠杆。"); } _selectedLeverage = quantity; _notice = ""; break; default: throw new InvalidOperationException("未知交易指令。"); } _session.PreserveForReload(); ShowNewSettlement(); if (_settings.VerboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)_notice); } } catch (InvalidOperationException ex) { _notice = ex.Message; } catch (OverflowException) { _notice = "数量或金额超出安全数值范围,本次操作取消。"; } catch (Exception ex3) { _notice = "操作异常,交易已停用,请保留日志。"; ((BaseUnityPlugin)this).Logger.LogError((object)("FXDSP command failed: " + ex3)); ((Behaviour)this).enabled = false; } } private PortfolioSnapshot GetPortfolio() { PortfolioSnapshot portfolioSnapshot = new PortfolioSnapshot(); if (_session == null) { return portfolioSnapshot; } portfolioSnapshot.Ready = ((Behaviour)this).enabled && OwnsRuntime && _registered && _session.CanTrade; List<PositionSnapshot> list = new List<PositionSnapshot>(); foreach (MarginMarket market in _session.Markets) { MarginPosition position = market.Position; if (position != null) { int itemId = market.State.ItemId; ItemProto val = ((itemId == 99000001 || (Object)(object)LDB.items == (Object)null) ? null : ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId)); list.Add(new PositionSnapshot { ItemId = itemId, Name = MarketCatalog.Name(itemId), Icon = ((val == null) ? null : val.iconSprite), Direction = ((position.Side == PositionSide.Long) ? "做多" : "做空"), Leverage = position.Leverage, Margin = position.Margin, EntryPrice = position.EntryPrice, CurrentPrice = market.MidPrice, LiquidationPrice = market.LiquidationPrice, UnrealizedPnL = market.UnrealizedPnL, OpenTick = position.OpenTick, CurrentTick = GameMain.gameTick }); } } portfolioSnapshot.Positions = list; return portfolioSnapshot; } private void ShowNewSettlement() { if (!_session.CanTrade) { return; } foreach (MarginMarket market in _session.Markets) { PositionSettlement lastSettlement = market.LastSettlement; if (lastSettlement != null && (!_shownSettlements.TryGetValue(market.State.ItemId, out var value) || lastSettlement != value)) { _shownSettlements[market.State.ItemId] = lastSettlement; _notice = ""; _window.ShowSettlement(lastSettlement); } } } internal void ConsumeEscape() { if (!OwnsRuntime || _window == null) { return; } try { _window.ConsumeEscape(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("FXDSP input failed: " + ex)); } } internal bool AllowSave() { if (!OwnsRuntime || _session == null || GameMain.data == null || (Object)(object)GameMain.instance == (Object)null || GameMain.instance.isMenuDemo) { return true; } _session.Tick(); _delivery.Tick(); if (_session.CanSave) { return true; } if (!_saveWarningShown) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"FXDSP has not received this save's account state. Saving is blocked to preserve its sidecar. Return to the main menu and reload the save with FXDSP loaded."); _saveWarningShown = true; } _notice = "市场尚未接入当前存档,请返回主菜单重新读档后再保存。"; return false; } public void Export(BinaryWriter writer) { _session.Export(writer); } public void Import(BinaryReader reader) { _session.Import(reader); _shownSettlements.Clear(); _window.ResetNotifications(); _notice = ""; _saveWarningShown = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("FXDSP account import: " + _session.Status)); } public void IntoOtherSave() { _session.IntoOtherSave(); _shownSettlements.Clear(); _window.ResetNotifications(); _notice = ""; _saveWarningShown = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("FXDSP new account: " + _session.Status)); } private void OnVerboseLoggingChanged(object sender, EventArgs args) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("VerboseLogging = " + _settings.VerboseLogging.Value)); } private void OnDestroy() { Cleanup(); } private void Cleanup() { if (OwnsRuntime && _delivery != null) { _delivery.Tick(); } if (_session != null) { _session.PreserveForReload(); } if (OwnsRuntime && _registered) { DSPModSavePlugin.RemoveModSaveManually((BaseUnityPlugin)(object)this); } _registered = false; if (_window != null) { _window.Dispose(); _window = null; } if (_hud != null) { _hud.Dispose(); _hud = null; } if (_delivery != null) { _delivery.Deactivate(); _delivery = null; } if (_settings != null) { _settings.VerboseLogging.SettingChanged -= OnVerboseLoggingChanged; _settings = null; } if (_harmony != null) { _harmony.UnpatchSelf(); _harmony = null; } if ((Object)(object)Active == (Object)(object)this) { Active = null; } } } [HarmonyPatch(typeof(VFInput), "OnUpdate")] internal static class MarketInputPatch { private static void Postfix() { if ((Object)(object)Plugin.Active != (Object)null) { Plugin.Active.ConsumeEscape(); } } } [HarmonyPatch(typeof(GameSave), "SaveCurrentGame")] internal static class MarketSaveGuardPatch { private static bool Prefix(ref bool __result) { if ((Object)(object)Plugin.Active == (Object)null || Plugin.Active.AllowSave()) { return true; } __result = false; return false; } } public static class PluginInfo { public const string Guid = "dspfx.mod"; public const string Name = "FXDSP"; public const string Version = "1.0.0"; } } namespace FXDSP.UI { internal sealed class AchievementsView : IDisposable { private readonly Text _count; private readonly Text _pageText; private readonly Button _previous; private readonly Button _next; private readonly Text[] _names = (Text[])(object)new Text[6]; private readonly Text[] _descriptions = (Text[])(object)new Text[6]; private readonly Text[] _states = (Text[])(object)new Text[6]; private readonly Image[] _cards = (Image[])(object)new Image[6]; private TradingAchievementState _state; private int _page; internal AchievementsView(NativeUiFactory ui, Transform parent) { //IL_0065: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown ((Graphic)ui.Image("achievement-background", parent, 20f, 101f, 1100f, 627f, new Color(0.03f, 0.055f, 0.07f, 1f))).raycastTarget = true; _count = ui.Text("achievements-title", parent, 42f, 117f, 900f, 40f, "成就", 22, null, (TextAnchor)0); for (int i = 0; i < 6; i++) { float x = 42 + i % 2 * 542; float y = 176 + i / 2 * 160; Image val = ui.Image("achievement-card-" + i, parent, x, y, 514f, 140f, Color.white); _cards[i] = val; _names[i] = ui.Text("name", ((Component)val).transform, 20f, 14f, 370f, 32f, "", 20, null, (TextAnchor)0); _states[i] = ui.Text("state", ((Component)val).transform, 390f, 18f, 104f, 26f, "", 14, null, (TextAnchor)5); _descriptions[i] = ui.Text("description", ((Component)val).transform, 20f, 58f, 474f, 66f, "", 15, null, (TextAnchor)0); _descriptions[i].verticalOverflow = (VerticalWrapMode)0; } _previous = ui.Button("previous", parent, 42f, 680f, 104f, 32f, "上一页", (UnityAction)delegate { _page--; Refresh(_state); }); _next = ui.Button("next", parent, 994f, 680f, 104f, 32f, "下一页", (UnityAction)delegate { _page++; Refresh(_state); }); _pageText = ui.Text("page", parent, 470f, 680f, 200f, 32f, "", 14, null, (TextAnchor)4); } internal void Refresh(TradingAchievementState state) { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) _state = state; int num = (AchievementCatalog.All.Count + 5) / 6; _page = Math.Max(0, Math.Min(num - 1, _page)); _count.text = "成就 " + (state?.CompletedCount ?? 0) + " / " + AchievementCatalog.All.Count; _pageText.text = _page + 1 + " / " + num; ((Selectable)_previous).interactable = _page > 0; ((Selectable)_next).interactable = _page + 1 < num; for (int i = 0; i < 6; i++) { int num2 = _page * 6 + i; ((Component)_cards[i]).gameObject.SetActive(num2 < AchievementCatalog.All.Count); if (num2 < AchievementCatalog.All.Count) { AchievementDefinition achievementDefinition = AchievementCatalog.All[num2]; bool flag = state?.Completed(achievementDefinition.Id) ?? false; ((Graphic)_cards[i]).color = (flag ? new Color(0.09f, 0.19f, 0.19f, 1f) : new Color(0.055f, 0.095f, 0.12f, 1f)); _names[i].text = achievementDefinition.Name; _descriptions[i].text = achievementDefinition.Description; _states[i].text = (flag ? "已达成" : "未达成"); ((Graphic)_states[i]).color = (flag ? new Color(0.4f, 0.82f, 0.75f, 1f) : new Color(0.5f, 0.6f, 0.66f, 1f)); } } } public void Dispose() { ((UnityEventBase)_previous.onClick).RemoveAllListeners(); ((UnityEventBase)_next.onClick).RemoveAllListeners(); } } internal sealed class HoldingActionTarget : MonoBehaviour, IPointerDownHandler, IEventSystemHandler { internal int ItemId; private int _pressedItemId; public void OnPointerDown(PointerEventData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)data.button == 0) { _pressedItemId = ItemId; } } internal int Consume() { int result = ((_pressedItemId > 0) ? _pressedItemId : ItemId); _pressedItemId = 0; return result; } } internal sealed class HoldingsView { private sealed class Row { internal int ItemId; internal RectTransform Root; internal Image Icon; internal Text Name; internal Text Direction; internal Text Margin; internal Text Entry; internal Text Current; internal Text Liquidation; internal Text PnL; internal Text Return; internal Text Held; internal Button Close; internal Button Details; internal HoldingActionTarget CloseTarget; internal HoldingActionTarget DetailsTarget; } private readonly List<Row> _rows = new List<Row>(); private readonly Text _count; private readonly Button _closeAll; private readonly Button _previous; private readonly Button _next; private readonly Text _pageText; private PortfolioSnapshot _lastState; private int _page; internal HoldingsView(NativeUiFactory ui, Transform parent, Action<int> details, Action<int> close, Action closeAll) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_01bb: 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_0215: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0729: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Expected O, but got Unknown //IL_077c: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Expected O, but got Unknown HoldingsView holdingsView = this; ((Graphic)ui.Image("holdings-background", parent, 20f, 101f, 1100f, 627f, new Color(0.03f, 0.055f, 0.07f, 1f))).raycastTarget = true; _count = ui.Text("holdings-title", parent, 40f, 113f, 600f, 38f, "全部持仓", 21, null, (TextAnchor)0); _closeAll = ui.Button("close-all", parent, 916f, 113f, 184f, 36f, "一键全部平仓", (UnityAction)delegate { closeAll(); }, (Color?)new Color(0.4f, 0.27f, 0.23f, 1f)); string[] array = new string[9] { "市场", "方向 / 杠杆", "保证金", "入场价", "最新价", "爆仓价", "浮动盈亏", "收益率", "持有时间" }; float[] array2 = new float[9] { 40f, 194f, 282f, 385f, 473f, 561f, 649f, 772f, 865f }; float[] array3 = new float[9] { 144f, 80f, 95f, 80f, 80f, 80f, 115f, 85f, 75f }; for (int num = 0; num < array.Length; num++) { ui.Text("column-" + num, parent, array2[num], 157f, array3[num], 38f, array[num], 12, (Color?)new Color(0.6f, 0.72f, 0.78f, 1f), (TextAnchor)3); } _previous = ui.Button("holdings-prev", parent, 40f, 686f, 90f, 30f, "上一页", (UnityAction)delegate { holdingsView._page = Math.Max(0, holdingsView._page - 1); holdingsView.Refresh(holdingsView._lastState); }); _next = ui.Button("holdings-next", parent, 1010f, 686f, 90f, 30f, "下一页", (UnityAction)delegate { holdingsView._page++; holdingsView.Refresh(holdingsView._lastState); }); _pageText = ui.Text("holdings-page", parent, 470f, 686f, 200f, 30f, "", 13, null, (TextAnchor)4); for (int num2 = 0; num2 < 9; num2++) { Row row = new Row(); row.Root = ui.Container("holding-" + num2, parent, 34f, 207 + num2 * 52, 1072f, 46f); ui.Image("row-fill", (Transform)(object)row.Root, 0f, 0f, 1072f, 46f, new Color(0.065f, 0.11f, 0.135f, 0.9f)); row.Icon = ui.Image("icon", (Transform)(object)row.Root, 8f, 10f, 28f, 28f, Color.white); row.Name = ui.Text("name", (Transform)(object)row.Root, 44f, 0f, 106f, 46f, "", 14, null, (TextAnchor)3); row.Direction = ui.Text("direction", (Transform)(object)row.Root, 160f, 0f, 80f, 46f, "", 13, null, (TextAnchor)3); row.Direction.supportRichText = true; row.Margin = ui.Text("margin", (Transform)(object)row.Root, 248f, 0f, 95f, 46f, "", 13, null, (TextAnchor)3); row.Entry = ui.Text("entry", (Transform)(object)row.Root, 351f, 0f, 80f, 46f, "", 13, null, (TextAnchor)3); row.Current = ui.Text("current", (Transform)(object)row.Root, 439f, 0f, 80f, 46f, "", 13, null, (TextAnchor)3); row.Liquidation = ui.Text("liquidation", (Transform)(object)row.Root, 527f, 0f, 80f, 46f, "", 13, null, (TextAnchor)3); row.PnL = ui.Text("pnl", (Transform)(object)row.Root, 615f, 0f, 115f, 46f, "", 14, null, (TextAnchor)3); row.PnL.resizeTextForBestFit = true; row.PnL.resizeTextMinSize = 10; row.PnL.resizeTextMaxSize = 14; row.PnL.verticalOverflow = (VerticalWrapMode)0; row.Return = ui.Text("unrealized-return", (Transform)(object)row.Root, 738f, 0f, 85f, 46f, "", 12, null, (TextAnchor)3); row.Held = ui.Text("held", (Transform)(object)row.Root, 831f, 0f, 75f, 46f, "", 13, null, (TextAnchor)3); Text[] array4 = (Text[])(object)new Text[5] { row.Name, row.Direction, row.Margin, row.Return, row.Held }; foreach (Text obj in array4) { obj.resizeTextForBestFit = true; obj.resizeTextMinSize = 9; obj.resizeTextMaxSize = obj.fontSize; obj.verticalOverflow = (VerticalWrapMode)0; } row.Details = ui.Button("details", (Transform)(object)row.Root, 925f, 9f, 60f, 30f, "详情", (UnityAction)delegate { details(row.DetailsTarget.Consume()); }); row.Close = ui.Button("close", (Transform)(object)row.Root, 994f, 9f, 66f, 30f, "平仓", (UnityAction)delegate { close(row.CloseTarget.Consume()); }); row.DetailsTarget = ((Component)row.Details).gameObject.AddComponent<HoldingActionTarget>(); row.CloseTarget = ((Component)row.Close).gameObject.AddComponent<HoldingActionTarget>(); _rows.Add(row); } } internal void Refresh(PortfolioSnapshot state) { //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) _lastState = state; int num = state?.Positions.Count ?? 0; int num2 = Math.Max(1, (num + _rows.Count - 1) / _rows.Count); _page = Math.Max(0, Math.Min(num2 - 1, _page)); _pageText.text = _page + 1 + " / " + num2; ((Selectable)_previous).interactable = _page > 0; ((Selectable)_next).interactable = _page + 1 < num2; _count.text = ((num == 0) ? "全部持仓 · 当前空仓" : ("全部持仓 " + num)); ((Selectable)_closeAll).interactable = state != null && state.Ready && num > 0; for (int i = 0; i < _rows.Count; i++) { Row row = _rows[i]; int num3 = _page * _rows.Count + i; ((Component)row.Root).gameObject.SetActive(num3 < num); if (num3 >= num) { row.ItemId = 0; continue; } PositionSnapshot positionSnapshot = state.Positions[num3]; row.ItemId = positionSnapshot.ItemId; row.DetailsTarget.ItemId = (row.CloseTarget.ItemId = positionSnapshot.ItemId); row.Icon.sprite = positionSnapshot.Icon; ((Behaviour)row.Icon).enabled = (Object)(object)positionSnapshot.Icon != (Object)null; row.Name.text = positionSnapshot.Name; ((RectTransform)((Component)row.Name).transform).anchoredPosition = new Vector2((float)(((Object)(object)positionSnapshot.Icon == (Object)null) ? 10 : 44), 0f); row.Direction.text = NativeUiFactory.DirectionText(positionSnapshot.Direction) + " " + positionSnapshot.Leverage + "×"; row.Margin.text = positionSnapshot.Margin.ToString("#,0.00"); row.Entry.text = positionSnapshot.EntryPrice.ToString("0.0000"); row.Current.text = positionSnapshot.CurrentPrice.ToString("0.0000"); row.Liquidation.text = positionSnapshot.LiquidationPrice.ToString("0.0000"); row.PnL.text = MoneyDisplay.Signed(positionSnapshot.UnrealizedPnL); ((Graphic)row.PnL).color = (Color)((positionSnapshot.UnrealizedPnL > 0m) ? MarketCandleGraphic.Rising : ((positionSnapshot.UnrealizedPnL < 0m) ? MarketCandleGraphic.Falling : new Color(0.6f, 0.72f, 0.78f, 1f))); row.Return.text = MoneyDisplay.Percent(positionSnapshot.UnrealizedReturnRatio); ((Graphic)row.Return).color = ((Graphic)row.PnL).color; row.Held.text = positionSnapshot.HeldCandles.ToString("N0", CultureInfo.InvariantCulture); ((Selectable)row.Close).interactable = state.Ready; } } internal void Dispose() { if ((Object)(object)_closeAll != (Object)null) { ((UnityEventBase)_closeAll.onClick).RemoveAllListeners(); } if ((Object)(object)_previous != (Object)null) { ((UnityEventBase)_previous.onClick).RemoveAllListeners(); } if ((Object)(object)_next != (Object)null) { ((UnityEventBase)_next.onClick).RemoveAllListeners(); } foreach (Row row in _rows) { if ((Object)(object)row.Close != (Object)null) { ((UnityEventBase)row.Close.onClick).RemoveAllListeners(); } if ((Object)(object)row.Details != (Object)null) { ((UnityEventBase)row.Details.onClick).RemoveAllListeners(); } } _rows.Clear(); } } internal static class IntroductionCopy { internal const string Title = "欢迎接入 DSP 交易平台"; internal const string Body = "伊卡洛斯,老实铺产线很枯燥吧!除了扩大生产,你现在还可以通过交易获取物资。\n\n选择交易品种、存入对应物品,即可使用该物品作为保证金,<color=#D45954>开多</color>(预测<color=#D45954>上涨</color>)或<color=#52BA80>开空</color>(预测<color=#52BA80>下跌</color>)。各品种账户<color=#69CCD6>独立</color>,收益可直接提取为同种物资。\n\n<color=#69CCD6>仓位</color>比例决定投入的保证金,<color=#69CCD6>杠杆</color>放大收益与亏损。判断失误、亏损过大超过爆仓线时,持仓将被强制平仓。\n\n特殊的<color=#D9B76B>建筑币</color>可按固定价格双向兑换各种建筑与运输、战斗单位,如果你足够厉害或幸运,或许可以实现建筑自由。如果不想投机,可能也可以寻找一个性价比高的建筑量产建筑币,并兑换其它建筑作为超市使用。\n\n按 <color=#69CCD6>F8</color> 打开或关闭交易界面,右上角持仓面板可随时查看浮动盈亏、平仓或进入兑换。\n\n解锁科技建造<color=#69CCD6>物流塔交付平台</color>绑定物品,可将交易账户连接到工厂物流网络,让盈利物资直接投入生产。\n\n研究相关<color=#69CCD6>科技升级</color>,可以解锁更高等级的建筑兑换并降低交易和兑换手续费。\n\n你可以选择不同的交易风格,满仓百倍杠杆梭哈短线擒龙,或是在低估泡沫时耐心价值投资等待估值回归。\n\n<color=#D9B76B>FX战士伊卡洛斯</color>,祝你交易顺利,期待在主脑交易龙虎榜上看到你的名字!"; } internal sealed class LocalizedText : Text { private static readonly HashSet<LocalizedText> ActiveTexts = new HashSet<LocalizedText>(); private string _source = ""; public override string text { get { return ((Text)this).text; } set { _source = value ?? ""; baseText(); } } protected override void OnEnable() { ((Text)this).OnEnable(); ActiveTexts.Add(this); baseText(); } protected override void OnDisable() { ActiveTexts.Remove(this); ((Text)this).OnDisable(); } protected override void OnDestroy() { ActiveTexts.Remove(this); ((Graphic)this).OnDestroy(); } internal static void RefreshLanguage() { foreach (LocalizedText activeText in ActiveTexts) { if ((Object)(object)activeText != (Object)null) { activeText.baseText(); } } } private void baseText() { ((Text)this).text = TextLocalization.Translate(_source); } } internal sealed class MarketCandleGraphic : MaskableGraphic { internal static readonly Color Rising = new Color(0.83f, 0.35f, 0.33f, 1f); internal static readonly Color Falling = new Color(0.32f, 0.73f, 0.5f, 1f); private readonly List<MarketCandle> _candles = new List<MarketCandle>(); internal float Minimum { get; private set; } internal float Maximum { get; private set; } internal float LiquidationPrice { get; private set; } internal float LiquidationRatio { get { if (!(Maximum <= Minimum)) { return (LiquidationPrice - Minimum) / (Maximum - Minimum); } return 0f; } } internal void SetCandles(IReadOnlyList<MarketCandle> candles, decimal liquidationPrice) { int num = ((candles != null) ? Mathf.Min(60, candles.Count) : 0); int num2 = ((candles != null) ? (candles.Count - num) : 0); bool flag = num != _candles.Count || LiquidationPrice != (float)liquidationPrice; if (!flag) { for (int i = 0; i < num; i++) { if (candles[num2 + i].StartTick != _candles[i].StartTick || candles[num2 + i].Open != _candles[i].Open || candles[num2 + i].Close != _candles[i].Close || candles[num2 + i].DisplayHigh != _candles[i].DisplayHigh || candles[num2 + i].DisplayLow != _candles[i].DisplayLow) { flag = true; break; } } } if (!flag) { return; } LiquidationPrice = (float)liquidationPrice; _candles.Clear(); Minimum = float.MaxValue; Maximum = float.MinValue; if (candles != null) { for (int j = 0; j < num; j++) { MarketCandle marketCandle = candles[num2 + j]; _candles.Add(marketCandle); Minimum = Mathf.Min(Minimum, (float)marketCandle.DisplayLow); Maximum = Mathf.Max(Maximum, (float)marketCandle.DisplayHigh); } } if (num == 0) { Minimum = 0f; Maximum = 1f; } float num3 = Mathf.Max((Maximum - Minimum) * 0.08f, Mathf.Abs(Minimum) * 0.001f); Minimum -= num3; Maximum += num3; ((Graphic)this).SetVerticesDirty(); } protected override void OnPopulateMesh(VertexHelper mesh) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0223: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) mesh.Clear(); Rect rect = ((Graphic)this).rectTransform.rect; Color tint = default(Color); ((Color)(ref tint))..ctor(0.35f, 0.55f, 0.65f, 0.17f); for (int i = 0; i <= 3; i++) { Box(mesh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin + 8f + (((Rect)(ref rect)).height - 16f) * (float)i / 3f, ((Rect)(ref rect)).width, 0.8f, tint); } for (int j = 0; j <= 6; j++) { Box(mesh, ((Rect)(ref rect)).xMin + ((Rect)(ref rect)).width * (float)j / 6f, ((Rect)(ref rect)).yMin, 0.8f, ((Rect)(ref rect)).height, tint); } if (_candles.Count == 0 || Maximum <= Minimum) { return; } Rect plot = default(Rect); ((Rect)(ref plot))..ctor(((Rect)(ref rect)).xMin + 6f, ((Rect)(ref rect)).yMin + 8f, ((Rect)(ref rect)).width - 12f, ((Rect)(ref rect)).height - 16f); float num = ((Rect)(ref plot)).width / (float)Mathf.Max(24, _candles.Count); float num2 = Mathf.Max(3f, num * 0.62f); for (int k = 0; k < _candles.Count; k++) { MarketCandle marketCandle = _candles[k]; float num3 = ((Rect)(ref plot)).xMin + num * ((float)k + 0.5f); float num4 = Y(marketCandle.Open, plot); float num5 = Y(marketCandle.Close, plot); float num6 = Y(marketCandle.DisplayLow, plot); float num7 = Y(marketCandle.DisplayHigh, plot); Color tint2 = (Color)((marketCandle.Close > marketCandle.Open) ? Rising : ((marketCandle.Close < marketCandle.Open) ? Falling : new Color(0.63f, 0.69f, 0.73f, 1f))); Box(mesh, num3 - 0.7f, num6, 1.4f, Mathf.Max(1f, num7 - num6), tint2); Box(mesh, num3 - num2 / 2f, Mathf.Min(num4, num5) - ((Mathf.Abs(num5 - num4) < 1.5f) ? 0.75f : 0f), num2, Mathf.Max(1.5f, Mathf.Abs(num5 - num4)), tint2); } if (LiquidationPrice > 0f) { float y = ((Rect)(ref plot)).yMin + ((Rect)(ref plot)).height * Mathf.Clamp01(LiquidationRatio); Color tint3 = default(Color); ((Color)(ref tint3))..ctor(0.85f, 0.66f, 0.32f, 1f); for (float num8 = ((Rect)(ref plot)).xMin; num8 < ((Rect)(ref plot)).xMax; num8 += 12f) { Box(mesh, num8, y, Mathf.Min(7f, ((Rect)(ref plot)).xMax - num8), 1.3f, tint3); } } } private float Y(decimal value, Rect plot) { return ((Rect)(ref plot)).yMin + ((Rect)(ref plot)).height * ((float)value - Minimum) / (Maximum - Minimum); } private static void Box(VertexHelper mesh, float x, float y, float width, float height, Color tint) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) //IL_0032: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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) int currentVertCount = mesh.currentVertCount; mesh.AddVert(new Vector3(x, y), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); mesh.AddVert(new Vector3(x, y + height), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); mesh.AddVert(new Vector3(x + width, y + height), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); mesh.AddVert(new Vector3(x + width, y), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); mesh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); mesh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3); } } internal sealed class MarketDragHandle : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler { internal RectTransform Window; private Vector2 _startPointer; private Vector2 _startWindow; public void OnBeginDrag(PointerEventData data) { //IL_000f: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Window == (Object)null) && (int)data.button == 0) { Transform parent = ((Transform)Window).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val == (Object)null)) { RectTransformUtility.ScreenPointToLocalPointInRectangle(val, data.position, data.pressEventCamera, ref _startPointer); _startWindow = Window.anchoredPosition; ((Transform)Window).SetAsLastSibling(); } } } public void OnDrag(PointerEventData data) { //IL_000f: 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) //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Window == (Object)null) && (int)data.button == 0) { Transform parent = ((Transform)Window).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); Vector2 val2 = default(Vector2); if (!((Object)(object)val == (Object)null) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, data.position, data.pressEventCamera, ref val2)) { Window.anchoredPosition = _startWindow + val2 - _startPointer; Clamp(Window); } } } internal static void Clamp(RectTransform window) { //IL_0016: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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) Transform parent = ((Transform)window).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } Rect rect = val.rect; if (!(((Rect)(ref rect)).width <= 0f)) { rect = val.rect; if (!(((Rect)(ref rect)).height <= 0f)) { rect = val.rect; float width = ((Rect)(ref rect)).width; rect = window.rect; float num = Mathf.Max(0f, (width - ((Rect)(ref rect)).width * ((Transform)window).localScale.x) * 0.5f - 8f); rect = val.rect; float height = ((Rect)(ref rect)).height; rect = window.rect; float num2 = Mathf.Max(0f, (height - ((Rect)(ref rect)).height * ((Transform)window).localScale.y) * 0.5f - 8f); Vector2 anchoredPosition = window.anchoredPosition; window.anchoredPosition = new Vector2(Mathf.Clamp(anchoredPosition.x, 0f - num, num), Mathf.Clamp(anchoredPosition.y, 0f - num2, num2)); } } } } internal sealed class MarketWindow : IDisposable { private sealed class ExchangeCell { public int ItemId; public Button Button; public Image Icon; public Image Background; public Text Name; public Text Value; } private const float Width = 1140f; private const float Height = 760f; private static readonly Color Muted = new Color(0.6f, 0.72f, 0.78f, 0.9f); private static readonly Color Cyan = new Color(0.4f, 0.82f, 0.85f, 1f); private static readonly Color Warning = new Color(0.85f, 0.64f, 0.36f, 1f); private readonly Func<int, MarketSnapshot> _snapshot; private readonly Action<MarketCommand, int> _execute; private readonly Func<PortfolioSnapshot> _portfolio; private readonly Func<bool> _acknowledgeIntroduction; private readonly Func<TradingAchievementState> _achievements; private RectTransform _achievementsRoot; private AchievementsView _achievementsView; private Button _achievementsButton; private bool _achievementsMode; private readonly TransferSelection _depositSelection = new TransferSelection(); private readonly TransferSelection _withdrawSelection = new TransferSelection(); private int _transferContextItem; private bool _transferContextDelivery; private RectTransform _positionsRoot; private RectTransform _sidebarRoot; private HoldingsView _holdings; private Text _inventoryLabel; private Button _sourceBackpack; private Button _sourceDelivery; private Button _allPositionsButton; private bool _positionsMode; private bool _resourceSelectionMode; private MarketCategory? _categoryOverride; private MarketSnapshot _lastState; private RectTransform _resourcePickerRoot; private Button _chooseResources; private ResourceSelectionView _resourcePicker; private ResourceSidebarView _resourceSidebar; private readonly List<Button> _buttons = new List<Button>(); private readonly List<Button> _allocationButtons = new List<Button>(); private readonly Dictionary<int, Button> _marketButtons = new Dictionary<int, Button>(); private readonly Queue<PositionSettlement> _settlements = new Queue<PositionSettlement>(); private RectTransform _root; private RectTransform _tradeRoot; private RectTransform _exchangeRoot; private RectTransform _transferRoot; private RectTransform _coinFunding; private readonly Dictionary<MarketCategory, Button> _categoryButtons = new Dictionary<MarketCategory, Button>(); private readonly Dictionary<int, Image> _marketIcons = new Dictionary<int, Image>(); private readonly List<ExchangeCell> _exchangeCells = new List<ExchangeCell>(); private Button _coinTradeTab; private Button _exchangeBuy; private Button _exchangeSell; private readonly List<Button> _exchangeTierButtons = new List<Button>(); private readonly Text[] _priceAxis = (Text[])(object)new Text[4]; private Text _marginPreview; private Text _exchangeName; private Text _exchangeValue; private Text _exchangeBackpack; private Text _exchangeWallet; private Text _exchangeTotal; private Text _exchangePageText; private Text _coinBalance; private Image _exchangeIcon; private InputField _exchangeQuantityInput; private Slider _exchangeQuantitySlider; private int _exchangeMaximum; private string _exchangeQuantityValue = "1"; private int _exchangePage; private bool _exchangeMode; private Canvas _canvas; private NativeUiFactory _ui; private InputField _depositInput; private InputField _withdrawInput; private Slider _allocationSlider; private Slider _leverageSlider; private Slider _depositSlider; private Slider _withdrawSlider; private Text _assets; private Text _floating; private Text _floatingReturn; private Text _realized; private Text _returnRate; private Text _positionText; private Text _quote; private Text _preview; private Text _backpack; private Text _withdrawable; private Text _status; private Text _events; private Text _chartRange; private Text _chartTitle; private Text _transferTitle; private Text _liquidationLabel; private Image _liquidationBackground; private Text _allocationLabel; private Text _leverageLabel; private MarketCandleGraphic _chart; private Button _long; private Button _short; private Button _deposit; private Button _withdraw; private Button _closePosition; private GameObject _modal; private PositionSettlement _pendingSettlement; private string _depositValue = "10"; private string _withdrawValue = "10"; private int _allocation = 25; private int _selectedLeverage = 5; private string _localError = ""; private float _nextRefresh; private bool _dirty = true; private bool _clearSelection; private bool _disposed; private int _escapeFrame = -1; private int _inputEndedFrame = -1; internal bool IsOpen { get { if ((Object)(object)_root != (Object)null) { return ((Component)_root).gameObject.activeSelf; } return false; } } internal bool HasSettlement => (Object)(object)_modal != (Object)null; internal bool IsInputFocused { get { if (IsOpen) { if ((!((Object)(object)_depositInput != (Object)null) || !_depositInput.isFocused) && (!((Object)(object)_withdrawInput != (Object)null) || !_withdrawInput.isFocused)) { if ((Object)(object)_exchangeQuantityInput != (Object)null) { return _exchangeQuantityInput.isFocused; } return false; } return true; } return false; } } internal bool BlocksGameInput { get { if (IsOpen) { if (!IsInputFocused && !IsPointerOver) { return (Object)(object)_modal != (Object)null; } return true; } return false; } } internal bool IsPointerOver { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) if (!IsOpen) { return false; } Camera val = (((Object)(object)_canvas == (Object)null || (int)_canvas.renderMode == 0) ? null : _canvas.worldCamera); return RectTransformUtility.RectangleContainsScreenPoint(_root, Vector2.op_Implicit(Input.mousePosition), val); } } internal MarketWindow(Func<int, MarketSnapshot> snapshot, Func<PortfolioSnapshot> portfolio, Action<MarketCommand, int> execute, Func<bool> acknowledgeIntroduction, Func<TradingAchievementState> achievements) { _snapshot = snapshot ?? throw new ArgumentNullException("snapshot"); _portfolio = portfolio ?? throw new ArgumentNullException("portfolio"); _execute = execute ?? throw new ArgumentNullException("execute"); _acknowledgeIntroduction = acknowledgeIntroduction ?? throw new ArgumentNullException("acknowledgeIntroduction"); _achievements = achievements; } internal void Toggle() { if (_disposed) { return; } if (IsOpen) { Close(); } else { if (!GameMain.isRunning || GameMain.data == null || (Object)(object)UIRoot.instance == (Object)null || (Object)(object)UIRoot.instance.uiGame == (Object)null || (Object)(object)UIRoot.instance.uiGame.inserterWindow == (Object)null) { return; } try { Build(); bool num = _acknowledgeIntroduction(); if (num) { _achievementsMode = false; _categoryOverride = MarketCategory.RawMaterials; _positionsMode = (_exchangeMode = false); _resourceSelectionMode = true; } _dirty = true; _nextRefresh = 0f; Tick(); if (num && (Object)(object)_modal == (Object)null) { BuildIntroductionPopup(); } } catch (Exception ex) { Close(); Debug.LogWarning((object)("[FXDSP] Market window is unavailable: " + ex)); } } } internal void ShowAllPositions() { _achievementsMode = false; if (!_disposed) { _positionsMode = true; _categoryOverride = null; _resourceSelectionMode = false; _exchangeMode = false; ClearInputSelection(); if (!IsOpen) { Toggle(); return; } _dirty = true; Refresh(); } } internal void ShowExchange() { _achievementsMode = false; if (!_disposed && !((Object)(object)_modal != (Object)null)) { _positionsMode = (_resourceSelectionMode = false); _categoryOverride = null; _exchangeMode = true; _execute(MarketCommand.SelectMarket, 99000001); ClearInputSelection(); if (!IsOpen) { Toggle(); return; } _dirty = true; Refresh(); } } internal void ShowSettlement(PositionSettlement settlement) { if (settlement == null || _disposed) { return; } if (_pendingSettlement != null) { _settlements.Enqueue(settlement); if (!IsOpen) { Toggle(); } return; } _pendingSettlement = settlement; if (!IsOpen) { Toggle(); } else { BuildSettlementPopup(); } _dirty = true; } internal void ResetNotifications() { _settlements.Clear(); DismissSettlement(); } internal void Tick() { if (_disposed || !IsOpen) { return; } ConsumeEscape(); if (IsOpen) { if (_clearSelection && !IsInputFocused) { _clearSelection = false; ClearInputSelection(); } FitToParent(); if (_dirty || !(Time.unscaledTime < _nextRefresh)) { _dirty = false; _nextRefresh = Time.unscaledTime + 0.2f; Refresh(); } } } internal bool ConsumeEscape() { if (!Input.GetKeyDown((KeyCode)27)) { return false; } if (_escapeFrame == Time.frameCount) { VFInput.UseEscape(); return true; } if (!IsOpen) { return false; } _escapeFrame = Time.frameCount; if ((Object)(object)_modal != (Object)null) { DismissSettlement(); } else if (IsInputFocused || _inputEndedFrame == Time.frameCount) { ClearInputSelection(); } else { Close(); } VFInput.UseEscape(); return true; } internal void Close() { ClearInputSelection(); if ((Object)(object)_depositInput != (Object)null) { _depositValue = _depositInput.text; } if ((Object)(object)_withdrawInput != (Object)null) { _withdrawValue = _withdrawInput.text; } if ((Object)(object)_exchangeQuantityInput != (Object)null) { _exchangeQuantityValue = _exchangeQuantityInput.text; } InputField[] array = (InputField[])(object)new InputField[3] { _depositInput, _withdrawInput, _exchangeQuantityInput }; foreach (InputField val in array) { if ((Object)(object)val != (Object)null) { ((UnityEventBase)val.onValueChanged).RemoveAllListeners(); ((UnityEventBase)val.onEndEdit).RemoveAllListeners(); } } if ((Object)(object)_allocationSlider != (Object)null) { ((UnityEventBase)_allocationSlider.onValueChanged).RemoveAllListeners(); } if ((Object)(object)_leverageSlider != (Object)null) { ((UnityEventBase)_leverageSlider.onValueChanged).RemoveAllListeners(); } if ((Object)(object)_depositSlider != (Object)null) { ((UnityEventBase)_depositSlider.onValueChanged).RemoveAllListeners(); } if ((Object)(object)_withdrawSlider != (Object)null) { ((UnityEventBase)_withdrawSlider.onValueChanged).RemoveAllListeners(); } if ((Object)(object)_exchangeQuantitySlider != (Object)null) { ((UnityEventBase)_exchangeQuantitySlider.onValueChanged).RemoveAllListeners(); } foreach (Button button in _buttons) { if ((Object)(object)button != (Object)null) { ((UnityEventBase)button.onClick).RemoveAllListeners(); } } _buttons.Clear(); _allocationButtons.Clear(); _marketButtons.Clear(); _marketIcons.Clear(); _categoryButtons.Clear(); _exchangeCells.Clear(); _exchangeTierButtons.Clear(); Array.Clear(_priceAxis, 0, _priceAxis.Length); if (_holdings != null) { _holdings.Dispose(); _holdings = null; } _achievementsView?.Dispose(); _achievementsView = null; _achievementsRoot = null; _achievementsButton = null; _inventoryLabel = null; _sourceBackpack = (_sourceDelivery = null); if (_resourcePicker != null) { _resourcePicker.Dispose(); _resourcePicker = null; } if (_resourceSidebar != null) { _resourceSidebar.Dispose(); _resourceSidebar = null; } _resourcePickerRoot = null; _chooseResources = null; _positionsRoot = (_sidebarRoot = null); _allPositionsButton = null; DestroyModal(); if ((Object)(object)_root != (Object)null) { ((Component)_root).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = (_tradeRoot = (_exchangeRoot = (_transferRoot = (_coinFunding = null)))); _canvas = null; _ui = null; _exchangeQuantityInput = null; _exchangeBuy = (_exchangeSell = (_coinTradeTab = null)); _exchangeQuantitySlider = null; _depositInput = (_withdrawInput = null); _allocationSlider = (_leverageSlider = null); _depositSlider = (_withdrawSlider = null); _chart = null; _assets = (_floating = (_floatingReturn = (_realized = (_returnRate = (_positionText = (_quote = (_preview = null))))))); _backpack = (_withdrawable = (_status = (_events = (_chartRange = null)))); _chartTitle = (_transferTitle = (_liquidationLabel = null)); _liquidationBackground = null; _allocationLabel = (_leverageLabel = null); _long = (_short = (_deposit = (_withdraw = (_closePosition = null)))); _clearSelection = false; _localError = ""; } public void Dispose() { if (!_disposed) { Close(); _pendingSettlement = null; _settlements.Clear(); _disposed = true; } } private void Build() { //IL_007b: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Expected O, but got Unknown //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Expected O, but got Unknown //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Expected O, but got Unknown //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) Close(); _ui = new NativeUiFactory(); _root = _ui.Root("FXDSP-market-window", 1140f, 760f); _canvas = ((Component)_root).GetComponentInParent<Canvas>(); ((Graphic)_ui.Image("window-background", (Transform)(object)_root, 0f, 0f, 1140f, 760f, new Color(0.025f, 0.07f, 0.09f, 1f))).raycastTarget = true; Image obj = _ui.Image("title-bar", (Transform)(object)_root, 1f, 1f, 1138f, 51f, new Color(0.14f, 0.23f, 0.28f, 0.92f)); ((Graphic)obj).raycastTarget = true; ((Component)obj).gameObject.AddComponent<MarketDragHandle>().Window = _root; _ui.Text("title", (Transform)(object)_root, 22f, 10f, 640f, 36f, "DSP 交易平台", 22, null, (TextAnchor)3); AddButton("introduction", 990f, 10f, 72f, 32f, "说明", new UnityAction(BuildIntroductionPopup)); AddButton("close", 1081f, 10f, 40f, 32f, "X", new UnityAction(Close)); string[] array = new string[6] { "原料", "材料", "武器", "消耗品", "矩阵", "建筑币" }; for (int i = 0; i < array.Length; i++) { MarketCategory category = (MarketCategory)i; _categoryButtons.Add(category, AddButton("category-" + i, 22 + i * 126, 58f, 116f, 28f, array[i], (UnityAction)delegate { SelectCategory(category); })); } _allPositionsButton = AddButton("all-positions", 800f, 58f, 148f, 28f, "全部持仓", new UnityAction(ShowAllPositions)); _achievementsButton = AddButton("achievements", 966f, 58f, 138f, 28f, "成就", (UnityAction)delegate { if (!((Object)(object)_modal != (Object)null)) { _achievementsMode = true; ClearInputSelection(); _dirty = true; Refresh(); } }); _sidebarRoot = _ui.Container("sidebar", (Transform)(object)_root, 0f, 0f, 1140f, 760f); Panel("sidebar-fill", 20f, 101f, 168f, 627f, (Transform)(object)_sidebarRoot); _ui.Text("markets-label", (Transform)(object)_sidebarRoot, 34f, 111f, 140f, 30f, "交易", 17, Muted, (TextAnchor)4); _resourceSidebar = new ResourceSidebarView(_ui, (Transform)(object)_sidebarRoot, SelectMarket, Refresh); _chooseResources = AddButton("choose-resources", 30f, 682f, 148f, 34f, "选择资源", (UnityAction)delegate { _resourceSelectionMode = true; _positionsMode = false; _exchangeMode = false; ClearInputSelection(); _dirty = true; Refresh(); }, null, (Transform)(object)_sidebarRoot); _coinTradeTab = AddButton("coin-trading", 30f, 151f, 148f, 54f, "行情交易", (UnityAction)delegate { SetExchangeMode(exchange: false); }, null, (Transform)(object)_sidebarRoot); ((Component)_coinTradeTab).GetComponentInChildren<Text>().fontSize = 17; string[] array2 = new string[5] { "一级兑换", "二级兑换", "三级兑换", "四级兑换", "五级兑换" }; string[] array3 = new string[5] { "50A9EA", "E26060", "E8C14A", "AA76D3", "55BC7D" }; Color color = default(Color); for (int num = 0; num < array2.Length; num++) { int tier = num + 1; Button val = AddButton("coin-exchange-" + tier, 30f, 253 + num * 46, 148f, 34f, array2[num], (UnityAction)delegate { _execute(MarketCommand.SelectExchangeTier, tier); _exchangePage = 0; SetExchangeMode(exchange: true); }, null, (Transform)(object)_sidebarRoot); Text componentInChildren = ((Component)val).GetComponentInChildren<Text>(); componentInChildren.supportRichText = false; if (ColorUtility.TryParseHtmlString("#" + array3[num], ref color)) { ((Graphic)componentInChildren).color = color; } _exchangeTierButtons.Add(val); } _tradeRoot = _ui.Container("trading-view", (Transform)(object)_root, 0f, 0f, 1140f, 760f); BuildTrading(); _exchangeRoot = _ui.Container("exchange-view", (Transform)(object)_root, 0f, 0f, 1140f, 760f); BuildExchange(); _resourcePickerRoot = _ui.Container("resource-selection-view", (Transform)(object)_root, 0f, 0f, 1140f, 760f); _resourcePicker = new ResourceSelectionView(_ui, (Transform)(object)_resourcePickerRoot, delegate(int id, bool enabled) { _execute(enabled ? MarketCommand.EnableResource : MarketCommand.DisableResource, id); _dirty = true; Refresh(); }, LeaveResourceSelection, Refresh); _positionsRoot = _ui.Container("all-holdings-view", (Transform)(object)_root, 0f, 0f, 1140f, 760f); _achievementsRoot = _ui.Container("achievements-view", (Transform)(object)_root, 0f, 0f, 1140f, 760f); _achievementsView = new AchievementsView(_ui, (Transform)(object)_achievementsRoot); _holdings = new HoldingsView(_ui, (Transform)(object)_positionsRoot, SelectMarket, delegate(int id) { _execute(MarketCommand.CloseMarketPosition, id); _dirty = true; Refresh(); }, delegate { _execute(MarketCommand.CloseAllPositions, 0); _dirty = true; Refresh(); }); _status = _ui.Text("status", (Transform)(object)_root, 22f, 738f, 1096f, 20f, "", 11, Cyan, (TextAnchor)0); FitToParent(); if (_pendingSettlement != null) { BuildSettlementPopup(); } } private void BuildTrading() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_0166: 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_0204: 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_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Expected O, but got Unknown //IL_07e4: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Expected O, but got Unknown //IL_0832: Unknown result type (might be due to invalid IL or missing references) //IL_086e: 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_0897: Expected O, but got Unknown //IL_08c3: Unknown result type (might be due to invalid IL or missing references) //IL_08dc: Unknown result type (might be due to invalid IL or missing references) //IL_08ec: Expected O, but got Unknown //IL_096e: Unknown result type (might be due to invalid IL or missing references) //IL_09aa: Unknown result type (might be due to invalid IL or missing references) //IL_09c4: Expected O, but got Unknown //IL_09f0: Unknown result type (might be due to invalid IL or missing references) //IL_0a0a: Expected O, but got Unknown //IL_0a3c: Unknown result type (might be due to invalid IL or missing references) //IL_0a7d: Unknown result type (might be due to invalid IL or missing references) //IL_0abb: Unknown result type (might be due to invalid IL or missing references) //IL_0c25: Unknown result type (might be due to invalid IL or missing references) //IL_0c3f: Expected O, but got Unknown //IL_0c6b: Unknown result type (might be due to invalid IL or missing references) //IL_0c85: Expected O, but got Unknown //IL_0d06: Unknown result type (might be due to invalid IL or missing references) //IL_0d44: Unknown result type (might be due to invalid IL or missing references) //IL_0d7f: Unknown result type (might be due to invalid IL or missing references) //IL_0d99: Expected O, but got Unknown //IL_0de1: Unknown result type (might be due to invalid IL or missing references) //IL_0e1a: Unknown result type (might be due to invalid IL or missing references) RectTransform tradeRoot = _tradeRoot; Panel("chart", 204f, 101f, 580f, 455f, (Transform)(object)tradeRoot); _chartTitle = _ui.Text("chart-heading", (Transform)(object)tradeRoot, 220f, 110f, 548f, 34f, "", 17, null, (TextAnchor)3); _chartRange = _ui.Text("chart-range", (Transform)(object)tradeRoot, 220f, 147f, 548f, 24f, "", 14, Muted, (TextAnchor)0); GameObject val = new GameObject("candlestick-chart", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(MarketCandleGraphic) }); NativeUiFactory.Place((RectTransform)val.transform, (Transform)(object)tradeRoot, 222f, 180f, 488f, 215f); _chart = val.GetComponent<MarketCandleGraphic>(); ((Graphic)_chart).raycastTarget = false; for (int i = 0; i < _priceAxis.Length; i++) { _priceAxis[i] = _ui.Text("price-axis-" + i, (Transform)(object)tradeRoot, 715f, 178f + (float)(199 * i) / 3f, 55f, 20f, "", 11, Muted, (TextAnchor)3); } _liquidationBackground = _ui.Image("liquidation-tag", val.transform, 6f, 0f, 204f, 24f, new Color(0.035f, 0.055f, 0.07f, 0.95f)); _liquidationLabel = _ui.Text("liquidation-price", ((Component)_liquidationBackground).transform, 5f, 0f, 194f, 24f, "", 12, Warning, (TextAnchor)3); _liquidationLabel.horizontalOverflow = (HorizontalWrapMode)1; _quote = _ui.Text("quote", (Transform)(object)tradeRoot, 220f, 409f, 548f, 30f, "", 15, null, (TextAnchor)0); _ui.Text("position-heading", (Transform)(object)tradeRoot, 220f, 449f, 548f, 27f, "当前持仓", 18, Muted, (TextAnchor)0); _positionText = _ui.Text("position", (Transform)(object)tradeRoot, 220f, 482f, 414f, 65f, "", 16, null, (TextAnchor)0); _positionText.supportRichText = true; _positionText.resizeTextForBestFit = true; _positionText.resizeTextMinSize = 13; _positionText.resizeTextMaxSize = 16; _positionText.verticalOverflow = (VerticalWrapMode)0; _closePosition = AddButton("close-position", 648f, 510f, 118f, 34f, "平仓", (UnityAction)delegate { Execute(MarketCommand.ClosePosition); }, null, (Transform)(object)tradeRoot); Panel("order", 800f, 101f, 320f, 455f, (Transform)(object)tradeRoot); _ui.Text("assets-heading", (Transform)(object)tradeRoot, 816f, 112f, 288f, 28f, "账户", 18, Muted, (TextAnchor)3); _assets = _ui.Text("assets", (Transform)(object)tradeRoot, 816f, 147f, 288f, 51f, "", 18, null, (TextAnchor)0); _assets.resizeTextForBestFit = true; _assets.resizeTextMinSize = 12; _assets.resizeTextMaxSize = 18; _assets.horizontalOverflow = (HorizontalWrapMode)0; _assets.verticalOverflow = (VerticalWrapMode)0; _floating = _ui.Text("floating-pnl", (Transform)(object)tradeRoot, 816f, 199f, 288f, 23f, "", 16, null, (TextAnchor)3); _floatingReturn = _ui.Text("floating-return", (Transform)(object)tradeRoot, 816f, 222f, 288f, 20f, "", 14, null, (TextAnchor)3); _realized = _ui.Text("realized-pnl", (Transform)(object)tradeRoot, 816f, 244f, 288f, 23f, "", 16, null, (TextAnchor)3); _returnRate = _ui.Text("return-rate", (Transform)(object)tradeRoot, 816f, 268f, 288f, 21f, "", 16, null, (TextAnchor)3); Text[] array = (Text[])(object)new Text[3] { _floating, _realized, _returnRate }; foreach (Text obj in array) { obj.resizeTextForBestFit = true; obj.resizeTextMinSize = 12; obj.resizeTextMaxSize = 16; obj.verticalOverflow = (VerticalWrapMode)0; } _allocationLabel = _ui.Text("allocation-heading", (Transform)(object)tradeRoot, 816f, 294f, 288f, 22f, "", 16, null, (TextAnchor)3); _marginPreview = _ui.Text("margin-preview", (Transform)(object)tradeRoot, 816f, 319f, 288f, 24f, "", 19, Cyan, (TextAnchor)3); _allocationSlider = _ui.Slider("allocation", (Transform)(object)tradeRoot, 818f, 347f, 282f, 20f, 1, 100, _allocation, delegate(float value) { _allocation = Mathf.RoundToInt(value); _localError = ""; _dirty = true; }); int[] array2 = new int[4] { 25, 50, 75, 100 }; for (int num2 = 0; num2 < array2.Length; num2++) { int percent = array2[num2]; _allocationButtons.Add(AddButton("allocation-" + percent, 816 + num2 * 73, 375f, 65f, 26f, percent + "%", (UnityAction)delegate { _allocationSlider.value = percent; ClearInputSelection(); _dirty = true; }, null, (Transform)(object)tradeRoot)); } _leverageLabel = _ui.Text("leverage-label", (Transform)(object)tradeRoot, 816f, 407f, 288f, 24f, "", 16, null, (TextAnchor)3); _leverageSlider = _ui.Slider("leverage", (Transform)(object)tradeRoot, 818f, 438f, 282f, 24f, 1, 100, _selectedLeverage, delegate(float value) { _selectedLeverage = Mathf.RoundToInt(value); _execute(MarketCommand.ChangeLeverage, _selectedLeverage); _localError = ""; _dirty = true; }); int[] array3 = new int[4] { 2, 5, 10, 50 }; for (int num3 = 0; num3 < array3.Length; num3++) { int leverage = array3[num3]; AddButton("leverage-" + leverage, 816 + num3 * 73, 470f, 65f, 26f, leverage + "×", (UnityAction)delegate { _leverageSlider.value = leverage; ClearInputSelection(); _dirty = true; }, null, (Transform)(object)tradeRoot); } _preview = _ui.Text("order-preview", (Transform)(object)tradeRoot, 816f, 500f, 288f, 19f, "", 12, Muted, (TextAnchor)0); _long = AddButton("long", 816f, 521f, 136f, 28f, "做多 / 开多", (UnityAction)delegate { Execute(MarketCommand.OpenLong); }, (Color?)new Color(0.45f, 0.22f, 0.22f, 1f), (Transform)(object)tradeRoot); _short = AddButton("short", 966f, 521f, 138f, 28f, "做空 / 开空", (UnityAction)delegate { Execute(MarketCommand.OpenShort); }, (Color?)new Color(0.18f, 0.39f, 0.28f, 1f), (Transform)(object)tradeRoot); _transferRoot = _ui.Container("item-transfers", (Transform)(object)tradeRoot, 0f, 0f, 1140f, 760f); Panel("transfer", 204f, 574f, 580f, 154f, (Transform)(object)_transferRoot); _transferTitle = _ui.Text("transfer-heading", (Transform)(object)_transferRoot, 220f, 584f, 270f, 28f, "", 16, Muted, (TextAnchor)0); _sourceBackpack = AddButton("source-backpack", 520f, 584f, 114f, 26f, "背包", (UnityAction)delegate { _execute(MarketCommand.UseBackpack, 0); _dirty = true; Refresh(); }, null, (Transform)(object)_transferRoot); _sourceDelivery = AddButton("source-delivery", 646f, 584f, 120f, 26f, "交付平台", (UnityAction)delegate { _execute(MarketCommand.UseDelivery, 0); _dirty = true; Refresh(); }, null, (Transform)(object)_transferRoot); _inventoryLabel = _ui.Text("inventory-label", (Transform)(object)_transferRoot, 220f, 617f, 280f, 20f, "背包可用", 12, Muted, (TextAnchor)0); _ui.Text("withdrawable-label", (Transform)(object)_transferRoot, 510f, 617f, 260f, 20f, "可提取", 12, Muted, (TextAnchor)0); _backpack = _ui.Text("backpack-available", (Transform)(object)_transferRoot, 220f, 636f, 260f, 26f, "0", 18, Cyan, (TextAnchor)0); _withdrawable = _ui.Text("withdrawable", (Transform)(object)_transferRoot, 510f, 636f, 260f, 26f, "0", 18, null, (TextAnchor)0); _depositSlider = _ui.Slider("deposit-amount", (Transform)(object)_transferRoot, 220f, 662f, 256f, 18f, 0, 1000, 0, delegate(float value) { SetTransferSlider(deposit: true, value); }); _withdrawSlider = _ui.Slider("withdraw-amount", (Transform)(object)_transferRoot, 510f, 662f, 256f, 18f, 0, 1000, 0, delegate(float value) { SetTransferSlider(deposit: false, value); }); _depositInput = TransferInput((Transform)(object)_transferRoot, 220f, 686f, 118f, _depositValue, delegate(string value) { SetTransferInput(deposit: true, value); }); _withdrawInput = TransferInput((Transform)(object)_transferRoot, 510f, 686f, 118f, _withdrawValue, delegate(string value) { SetTransferInput(deposit: false, value); }); _deposit = AddButton("deposit", 350f, 686f, 126f, 34f, "存入", (UnityAction)delegate { Execute(MarketCommand.Deposit); }, null, (Transform)(object)_transferRoot); _withdraw = AddButton("withdraw", 640f, 686f, 126f, 34f, "提取", (UnityAction)delegate { Execute(MarketCommand.Withdraw); }, null, (Transform)(object)_transferRoot); _coinFunding = _ui.Container("coin-funding", (Transform)(object)tradeRoot, 0f, 0f, 1140f, 760f); Panel("coin-balance", 204f, 574f, 580f, 154f, (Transform)(object)_coinFunding); _ui.Text("coin-label", (Transform)(object)_coinFunding, 220f, 592f, 300f, 28f, "可用建筑币", 14, Muted, (TextAnchor)0); _coinBalance = _ui.Text("coin-balance-value", (Transform)(object)_coinFunding, 220f, 634f, 340f, 46f, "", 24, Cyan, (TextAnchor)0); AddButton("open-exchange", 596f, 674f, 170f, 36f, "前往建筑兑换", (UnityAction)delegate { SetExchangeMode(exchange: true); }, null, (Transform)(object)_coinFunding); Panel("events", 800f, 574f, 320f, 154f, (Transform)(object)tradeRoot); _ui.Text("events-heading", (Transform)(object)tradeRoot, 816f, 584f, 288f, 28f, "操作记录", 16, Muted, (TextAnchor)0); _events = _ui.Text("events", (Transform)(object)tradeRoot, 816f, 616f, 288f, 108f, "", 12, Muted, (TextAnchor)0); _events.lineSpacing = 0.9f; _events.horizontalOverflow = (HorizontalWrapMode)1; } private void BuildExchange() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: 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_0331: Expected O, but got Unknown //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Expected O, but got Unknown //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_040d: 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_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Expected O, but got Unknown //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Expected O, but got Unknown RectTransform exchangeRoot = _exchangeRoot; Panel("exchange-list", 204f, 101f, 580f, 627f, (Transform)(object)exchangeRoot); Panel("exchange-detail", 800f, 101f, 320f, 627f, (Transform)(object)exchangeRoot); _ui.Text("exchange-title", (Transform)(object)exchangeRoot, 220f, 111f, 300f, 32f, "建筑兑换", 18, null, (TextAnchor)3); _exchangePageText = _ui.Text("exchange-page", (Transform)(object)exchangeRoot, 590f, 114f, 176f, 28f, "", 13, Muted, (TextAnchor)5); for (int i = 0; i < 28; i++) { ExchangeCell cell = new ExchangeCell(); float x = 220 + i % 4 * 137; float y = 155 + i / 4 * 72; cell.Button = AddButton("exchange-item-" + i, x, y, 128f, 64f, "", (UnityAction)delegate { if (cell.ItemId > 0) { _execute(MarketCommand.SelectExchangeItem, cell.ItemId); _dirty = true; Refresh(); } }, null, (Transform)(object)exchangeRoot); cell.Background = _ui.Image("inventory-background", ((Component)cell.Button).transform, 3f, 3f, 122f, 58f, new Color(0.035f, 0.055f, 0.075f, 1f)); ((Graphic)cell.Background).raycastTarget = false; cell.Icon = _ui.Image("icon", ((Component)cell.Button).transform, 7f, 6f, 30f, 30f, Color.white); cell.Name = _ui.Text("name", ((Component)cell.Button).transform, 42f, 3f, 81f, 34f, "", 11, null, (TextAnchor)3); cell.Name.resizeTextForBestFit = true; cell.Name.resizeTextMinSize = 9; cell.Name.resizeTextMaxSize = 11; cell.Name.verticalOverflow = (VerticalWrapMode)0; cell.Value = _ui.Text("value", ((Component)cell.Button).transform, 7f, 40f, 114f, 20f, "", 11, Muted, (TextAnchor)0); _exchangeCells.Add(cell); } AddButton("exchange-prev", 220f, 680f, 100f, 32f, "上一页", (UnityAction)delegate { _exchangePage = Math.Max(0, _exchangePage - 1); _dirty = true; Refresh(); }, null, (Transform)(object)exchangeRoot); AddButton("exchange-next", 666f, 680f, 100f, 32f, "下一页", (UnityAction)delegate { _exchangePage++; _dirty = true; Refresh(); }, null, (Transform)(object)exchangeRoot); _exchangeIcon = _ui.Image("selected-building", (Transform)(object)exchangeRoot, 928f, 126f, 64f, 64f, Color.white); _exchangeIcon.preserveAspect = true; _exchangeName = _ui.Text("building-name", (Transform)(object)exchangeRoot, 816f, 211f, 288f, 46f, "", 19, null, (TextAnchor)4); _exchangeValue = _ui.Text("building-value", (Transform)(object)exchangeRoot, 816f, 271f, 288f, 44f, "", 15, Muted, (TextAnchor)0); _exchangeBackpack = _ui.Text("building-backpack", (Transform)(object)exchangeRoot, 816f, 329f, 288f, 32f, "", 16, null, (TextAnchor)0); _exchangeWallet = _ui.Text("exchange-wallet", (Transform)(object)exchangeRoot, 816f, 373f, 288f, 44f, "", 17, Cyan, (TextAnchor)0); _ui.Text("exchange-quantity-heading", (Transform)(object)exchangeRoot, 816f, 435f, 288f, 26f, "兑换数量", 14, Muted, (TextAnchor)0); _exchangeQuantityInput = TransferInput((Transform)(object)exchangeRoot, 816f, 471f, 288f, _exchangeQuantityValue, delegate(string value) { _exchangeQuantityValue = value; }); _exchangeQuantitySlider = _ui.Slider("exchange-quantity", (Transform)(object)exchangeRoot, 816f, 507f, 288f, 18f, 0, 1000, 0, delegate(float value) { _exchangeQuantityValue = TransferAmounts.FromSlider(Mathf.RoundToInt(value), _exchangeMaximum).ToString(CultureInfo.InvariantCulture); _exchangeQuantityInput.SetTextWithoutNotify(_exchangeQuantityValue); _localError = ""; _dirty = true; }); _exchangeTotal = _ui.Text("exchange-total", (Transform)(object)exchangeRoot, 816f, 527f, 288f, 78f, "", 15, null, (TextAnchor)0); _exchangeBuy = AddButton("exchange-buy", 816f, 622f, 288f, 36f, "建筑币 → 物品", (UnityAction)delegate { Execute(MarketCommand.BuyBuilding); }, null, (Transform)(object)exchangeRoot); _exchangeSell = AddButton("exchange-sell", 816f, 676f, 288f, 36f, "物品 → 建筑币", (UnityAction)delegate { Execute(MarketCommand.SellBuilding); }, (Color?)new Color(0.24f, 0.36f, 0.33f, 1f), (Transform)(object)exchangeRoot); } private InputField TransferInput(Transform parent, float x, float y, float width, string initial, Action<string> save) { InputField obj = _ui.QuantityInput(parent, x, y, width, 34f); obj.text = initial; ((UnityEvent<string>)(object)obj.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { save(value); _localError = ""; _dirty = true; }); ((UnityEvent<string>)(object)obj.onEndEdit).AddListener((UnityAction<string>)OnInputEnded); return obj; } private void Refresh() { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0424: 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_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: 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_0550: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06f8: Unknown result type (might be due to invalid IL or missing references) //IL_0727: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_09f0: Unknown result type (might be due to invalid IL or missing references) //IL_09d5: Unknown result type (might be due to invalid IL or missing references) //IL_0a3c: Unknown result type (might be due to invalid IL or missing references) //IL_0a21: Unknown result type (might be due to invalid IL or missing references) //IL_0c17: Unknown result type (might be due to invalid IL or missing references) //IL_0c1e: Unknown result type (might be due to invalid IL or missing references) //IL_0dae: Unknown result type (might be due to invalid IL or missing references) //IL_0dfc: Unknown result type (might be due to invalid IL or missing references) //IL_0e09: Unknown result type (might be due to invalid IL or missing references) ((Component)_achievementsRoot).gameObject.SetActive(_achievementsMode); ((Graphic)((Selectable)_achievementsButton).image).color = (_achievementsMode ? new Color(0.25f, 0.43f, 0.51f, 1f) : new Color(0.14f, 0.24f, 0.29f, 1f)); if (_achievementsMode) { ((Component)_tradeRoot).gameObject.SetActive(false); ((Component)_exchangeRoot).gameObject.SetActive(false); ((Component)_resourcePickerRoot).gameObject.SetActive(false); ((Component)_sidebarRoot).gameObject.SetActive(false); ((Component)_positionsRoot).gameObject.SetActive(false); ((Graphic)((Selectable)_allPositionsButton).image).color = new Color(0.14f, 0.24f, 0.29f, 1f); _status.text = ""; _achievementsView.Refresh(_achievements()); return; } MarketSnapshot marketSnapshot; try { marketSnapshot = _snapshot(_allocation); } catch (Exception ex) { _status.text = "读取失败:" + ex.Message; ((Graphic)_status).color = Warning; SetCommandsEnabled(open: false, deposit: false, withdraw: false); ((Selectable)_closePosition).interactable = false; return; } if (marketSnapshot == null) { _status.text = "市场尚未载入"; SetCommandsEnabled(open: false, deposit: false, withdraw: false); ((Selectable)_closePosition).interactable = false; return; } _lastState = marketSnapshot; string itemName = marketSnapshot.ItemName; _chartTitle.text = itemName; _transferTitle.text = itemName + "存取"; MarketCategory marketCategory = _categoryOverride ?? MarketCatalog.Category(marketSnapshot.ItemId); bool flag = MarketCatalog.IsSelectableCategory(marketCategory); bool flag2 = marketCategory == MarketCategory.BuildingCurrency; if (!flag2) { _exchangeMode = false; } if (!flag) { _resourceSelectionMode = false; } if (flag && (!marketSnapshot.MarketEnabled || MarketCatalog.Category(marketSnapshot.ItemId) != marketCategory) && !_positionsMode) { _resourceSelectionMode = true; } ((Component)_tradeRoot).gameObject.SetActive(!_exchangeMode && !_positionsMode && !_resourceSelectionMode); ((Component)_exchangeRoot).gameObject.SetActive(_exchangeMode && !_positionsMode && !_resourceSelectionMode); ((Component)_resourcePickerRoot).gameObject.SetActive(_resourceSelectionMode && !_positionsMode); ((Component)_resourceSidebar.Root).gameObject.SetActive(flag); ((Component)_chooseResources).gameObject.SetActive(flag); if (flag) { ((Component)_chooseResources).GetComponentInChildren<Text>().text = "选择" + MarketCatalog.CategoryName(marketCategory); } if (flag) { _resourceSidebar.Refresh(marketSnapshot, marketCategory); } ((Component)_sidebarRoot).gameObject.SetActive(!_positionsMode); ((Component)_positionsRoot).gameObject.SetActive(_positionsMode); ((Graphic)((Selectable)_allPositionsButton).image).color = (_positionsMode ? new Color(0.25f, 0.43f, 0.51f, 1f) : new Color(0.14f, 0.24f, 0.29f, 1f)); ((Component)_transferRoot).gameObject.SetActive(!flag2); ((Component)_coinFunding).gameObject.SetActive(flag2); _coinBalance.text = Amount(marketSnapshot.BuildingCoinBalance); ((Component)_coinTradeTab).gameObject.SetActive(flag2); for (int i = 0; i < _exchangeTierButtons.Count; i++) { Button obj = _exchangeTierButtons[i]; ((Component)obj).gameObject.SetActive(flag2); ((Graphic)((Selectable)obj).image).color = ((_exchangeMode && marketSnapshot.ExchangeTier == i + 1) ? new Color(0.25f, 0.43f, 0.51f, 1f) : new Color(0.14f, 0.24f, 0.29f, 1f)); } foreach (KeyValuePair<MarketCategory, Button> categoryButton in _categoryButtons) { ((Graphic)((Selectable)categoryButton.Value).image).color = ((!_positionsMode && categoryButton.Key == marketCategory) ? new Color(0.25f, 0.43f, 0.51f, 1f) : new Color(0.14f, 0.24f, 0.29f, 1f)); } foreach (KeyValuePair<int, Button> marketButton in _marketButtons) { ((Component)marketButton.Value).gameObject.SetActive(MarketCatalog.Category(marketButton.Key) == marketCategory); ((Graphic)((Selectable)marketButton.Value).image).color = ((marketButton.Key == marketSnapshot.ItemId) ? new Color(0.25f, 0.43f, 0.51f, 1f) : new Color(0.14f, 0.24f, 0.29f, 1f)); } foreach (MarketOption market in marketSnapshot.Markets) { if (_marketIcons.TryGetValue(market.ItemId, out var value)) { value.sprite = market.Icon; ((Behaviour)value).enabled = (Object)(object)market.Icon != (Object)null; } } _assets.text = "可用\u3000\u3000" + Amount(marketSnapshot.AvailableBalance) + "\n总权益\u3000" + Amount(marketSnapshot.Equity); _floating.text = "浮动盈亏 " + Signed(marketSnapshot.UnrealizedPnL); _floatingReturn.text = "收益率 " + MoneyDisplay.Percent(marketSnapshot.UnrealizedReturnRatio); _realized.text = "累计盈亏 " + Signed(marketSnapshot.RealizedPnL); _returnRate.text = "收益率 " + MoneyDisplay.Percent(marketSnapshot.ReturnRatio); ((Graphic)_floating).color = PnLColor(marketSnapshot.UnrealizedPnL); ((Graphic)_floatingReturn).color = (marketSnapshot.UnrealizedReturnRatio.HasValue ? PnLColor(marketSnapshot.UnrealizedPnL) : Muted); ((Graphic)_realized).color = PnLColor(marketSnapshot.RealizedPnL); ((Graphic)_returnRate).color = (marketSnapshot.ReturnRatio.HasValue ? PnLColor(marketSnapshot.ReturnRatio.Value) : Muted); _quote.text = "买入 " + Price(marketSnapshot.Ask) + " 卖出 " + Price(marketSnapshot.Bid) + " 费率 " + (marketSnapshot.FeeRate * 100m).ToString("0.00") + "%"; _allocationLabel.text = "仓位比例 " + _allocation + "%"; _selectedLeverage = marketSnapshot.SelectedLeverage; _leverageLabel.text = "杠杆 " + _selectedLeverage + "×"; _leverageSlider.SetValueWithoutNotify((float)_selectedLeverage); _marginPreview.text = "保证金 " + Amount(marketSnapshot.OrderMargin); _preview.text = "开仓费 " + Amount(marketSnapshot.OpenFee); _positionText.text = (marketSnapshot.HasPosition ? (NativeUiFactory.DirectionText(marketSnapshot.PositionDirection) + " " + marketSnapshot.PositionLeverage + "× 入场 " + Price(marketSnapshot.EntryPrice) + "\n保证金 " + Amount(marketSnapshot.PositionMargin) + " 爆仓价 " + Price(marketSnapshot.LiquidationPrice) + "\n持有时间 " + marketSnapshot.HeldCandles.Value.ToString("N0", CultureInfo.InvariantCulture)) : "空仓"); _backpack.text = marketSnapshot.TransferAvailable.ToString("N0"); _inventoryLabel.text = ((marketSnapshot.ItemId == 1099) ? "沙土可用" : ((!marketSnapshot.UseDelivery) ? "背包可用" : (marketSnapshot.DeliveryBound ? ("平台可用 · " + marketSnapshot.DeliveryName) : "请在交付塔中设置该物品"))); ((Component)_sourceBackpack).GetComponentInChild
plugins/FXDSP/FXDSP.DeliveryBootstrap.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using FXDSP.Core; using HarmonyLib; using UnityEngine; using UnityEngine.UI.Youthcat; using xiaoye97; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FXDSP.DeliveryBootstrap")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c79acf0c7eb1a3efb6903aff5c793433ad2619ae")] [assembly: AssemblyProduct("FXDSP.DeliveryBootstrap")] [assembly: AssemblyTitle("FXDSP.DeliveryBootstrap")] [assembly: AssemblyVersion("1.0.0.0")] namespace FXDSP.Core { public sealed class DeliveryRecipeDefinition { public readonly int ItemId; public readonly int BaseItemId; public readonly string Name; public readonly string Description; public int InputCount { get { if (ItemId != 11702) { return 5; } return 4; } } public int TimeSpend => 3600; public bool Handcraft => false; public DeliveryRecipeDefinition(int itemId, int baseItemId, string name, string description) { ItemId = itemId; BaseItemId = baseItemId; Name = name; Description = description; } } public static class DeliveryRecipes { public static readonly IReadOnlyList<DeliveryRecipeDefinition> Definitions = Array.AsReadOnly(new DeliveryRecipeDefinition[2] { new DeliveryRecipeDefinition(11702, 2103, "行星级交付平台", "在行星物流塔基础上改造而成的现货交付平台,具备原行星物流塔的全部功能,并拥有深不可测的储存容量以应对大单交割。平台槽位设置物品后即唯一绑定交易系统,可在交易面板中从平台中存入或提取物资,该物品不能再被第二个交付平台选中。"), new DeliveryRecipeDefinition(11703, 2104, "星际交付平台", "在星际物流塔基础上改造而成的现货交付平台,具备原星际物流塔的全部功能,并拥有深不可测的储存容量以应对大单交割。平台槽位设置物品后即唯一绑定交易系统,可在交易面板中从平台存入或提取物资,该物品不能再被第二个交付平台选中。") }); public static int AllocateGrid(ISet<int> occupied) { for (int num = 8; num >= 1; num--) { for (int i = 1; i <= 14; i++) { int num2 = 2000 + num * 100 + i; if (occupied.Add(num2)) { return num2; } } } throw new InvalidOperationException("制作面板的建筑分页已满,无法放置交付平台配方。"); } } public sealed class TradeTechnology { public int Id; public int Previous; public int Cost; public int IconItemId; public int Level; public int ExchangeTier; public string Name; public string Description; public string Conclusion; public string UnlockText; public int[] Items; public bool Upgrade; public string InlineIconTag => "fx" + Id.ToString(CultureInfo.InvariantCulture); public string RegistrationName { get { if (!Upgrade) { return Name; } return Name + " " + Level + " 级"; } } public bool ImplicitPrevious { get { if (Upgrade) { return Previous == 1951; } return false; } } public long HashNeeded => (long)Cost * 36L; public int[] ItemPoints => Items.Select((int item) => 100).ToArray(); } public sealed class TradeResearchState { public bool Access; public int FeeLevel; public readonly bool[] Exchange = new bool[6]; public decimal TradingFee => TradeResearch.TradingFee(FeeLevel); public decimal ExchangeFee => TradeResearch.ExchangeFee(FeeLevel); public bool CanExchange(int tier) { if (Access && tier >= 1 && tier <= 5) { return Exchange[tier]; } return false; } public void RequireAccess() { if (!Access) { throw new InvalidOperationException("请先研究“交易系统”。"); } } public void RequireExchange(int tier) { RequireAccess(); if (!CanExchange(tier)) { throw new InvalidOperationException("请先研究“建筑兑换(" + tier + ")”。"); } } } public static class TradeResearch { public const int AccessTech = 1951; private static readonly decimal[] TradingRates = new decimal[7] { 0.003m, 0.002m, 0.001m, 0.0005m, 0.0002m, 0.0001m, 0m }; private static readonly decimal[] ExchangeRates = new decimal[7] { 0.10m, 0.10m, 0.08m, 0.06m, 0.04m, 0.02m, 0m }; public static IReadOnlyList<TradeTechnology> Definitions { get; } = Build(); public static int ExchangeTech(int tier) { return 7700 + tier; } public static int FeeTech(int level) { return 7800 + level; } public static decimal TradingFee(int level) { return TradingRates[Math.Max(0, Math.Min(6, level))]; } public static decimal ExchangeFee(int level) { return ExchangeRates[Math.Max(0, Math.Min(6, level))]; } public static TradeResearchState Read(Func<int, bool> unlocked) { TradeResearchState tradeResearchState = new TradeResearchState { Access = unlocked(1951) }; for (int i = 1; i <= 5; i++) { tradeResearchState.Exchange[i] = unlocked(ExchangeTech(i)); } for (int j = 1; j <= 6; j++) { if (!tradeResearchState.Access) { break; } if (!unlocked(FeeTech(j))) { break; } tradeResearchState.FeeLevel = j; } return tradeResearchState; } public static TradeTechnology Find(int id) { return Definitions.FirstOrDefault((TradeTechnology definition) => definition.Id == id); } private static IReadOnlyList<TradeTechnology> Build() { List<TradeTechnology> list = new List<TradeTechnology>(); list.Add(new TradeTechnology { Id = 1951, Name = "交易系统", UnlockText = "开放DSP交易平台", Description = "老实拍工厂很枯燥吧?创建DSP交易账户,接入主脑交易平台,FX战士伊卡洛斯!", Conclusion = "开放DSP交易平台", Items = new int[2] { 1001, 1002 }, Cost = 10, IconItemId = 1002 }); List<TradeTechnology> list2 = list; int[] array = new int[5] { 200, 400, 1000, 2000, 4000 }; for (int i = 1; i <= 5; i++) { list2.Add(new TradeTechnology { Id = ExchangeTech(i), Previous = ((i == 1) ? 1951 : ExchangeTech(i - 1)), Upgrade = true, Level = i, ExchangeTier = i, Name = "建筑兑换", Description = "在建筑币市场中自由交易兑换各种建筑,或许也是一种建筑超市。", UnlockText = "开放建筑币市场" + i + "级建筑交易", Conclusion = "开放建筑币市场" + i + "级建筑交易", Items = new int[1] { 6000 + i }, Cost = array[i - 1], IconItemId = 6000 + i }); } int[] array2 = new int[6] { 400, 800, 1200, 1600, 2000, 4000 }; for (int j = 1; j <= 6; j++) { string text = "交易手续费降低至" + (TradingFee(j) * 100m).ToString("0.##", CultureInfo.InvariantCulture) + "%\n建筑兑换双向手续费降低至" + (ExchangeFee(j) * 100m).ToString("0.##", CultureInfo.InvariantCulture) + "%"; list2.Add(new TradeTechnology { Id = FeeTech(j), Previous = ((j == 1) ? 1951 : FeeTech(j - 1)), Upgrade = true, Level = j, Name = "交易效率", UnlockText = text, Conclusion = text, Description = ((j == 6) ? "感谢你对主脑作出的贡献,免除交易手续费!" : "为奖励伊卡洛斯上传矩阵提供的算力,降低交易佣金。"), Items = ((j == 6) ? new int[1] { 6006 } : Enumerable.Range(6001, j).ToArray()), Cost = array2[j - 1], IconItemId = ((j == 6) ? 6006 : (6000 + j)) }); } return list2.AsReadOnly(); } } public static class PrototypeOwnership { private static string Key(string kind, int id) { return "FXDSP.PrototypeOwner.v1." + kind + "." + id; } public static void Mark(string kind, int id, object prototype) { if (prototype == null) { throw new ArgumentNullException("prototype"); } AppDomain.CurrentDomain.SetData(Key(kind, id), prototype); } public static bool Owns(string kind, int id, object prototype) { if (prototype != null) { return AppDomain.CurrentDomain.GetData(Key(kind, id)) == prototype; } return false; } } public static class TextLocalization { private sealed class Node { internal readonly Dictionary<char, Node> Children = new Dictionary<char, Node>(); internal string Value; } private static readonly Dictionary<string, string> Entries = new Dictionary<string, string>(StringComparer.Ordinal); private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>(StringComparer.Ordinal); private static readonly Node Root = new Node(); private static bool _loaded; private static bool _english; public static bool English { get { return _english; } set { if (_english != value) { _english = value; Cache.Clear(); } } } public static int EntryCount { get { Load(); return Entries.Count; } } public static string Translate(string source) { if (!_english || string.IsNullOrEmpty(source)) { return source ?? ""; } Load(); if (Entries.TryGetValue(source, out var value) || Cache.TryGetValue(source, out value)) { return value; } bool flag = false; foreach (char c in source) { if (c >= '一' && c <= '鿿') { flag = true; break; } } if (!flag) { return source; } StringBuilder stringBuilder = new StringBuilder(); int num = 0; while (num < source.Length) { Node value2 = Root; string text = null; int num2 = num; for (int j = num; j < source.Length && value2.Children.TryGetValue(source[j], out value2); j++) { if (value2.Value != null) { text = value2.Value; num2 = j + 1; } } if (text == null) { stringBuilder.Append(source[num]); num++; } else { stringBuilder.Append(text); num = num2; } } value = stringBuilder.ToString(); if (Cache.Count >= 512) { Cache.Clear(); } Cache[source] = value; return value; } public static void RegisterNativeName(string source, string translation) { if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(translation) || source == translation) { return; } Load(); if (Entries.ContainsKey(source)) { Entries[source] = translation; Node node = Root; foreach (char key in source) { node = node.Children[key]; } node.Value = translation; } else { Add(source, translation); } Cache.Clear(); } private static void Load() { if (_loaded) { return; } using (Stream stream = typeof(TextLocalization).Assembly.GetManifestResourceStream("FXDSP.Localization.en-US.tsv")) { if (stream == null) { throw new InvalidOperationException("English localization resource is missing."); } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); string text; while ((text = streamReader.ReadLine()) != null) { if (text.Length != 0 && text[0] != '#') { int num = text.IndexOf('\t'); if (num < 1) { throw new InvalidDataException("Invalid localization entry."); } Add(Decode(text.Substring(0, num)), Decode(text.Substring(num + 1))); } } } _loaded = true; } private static void Add(string source, string target) { Entries.Add(source, target); Node node = Root; foreach (char key in source) { if (!node.Children.TryGetValue(key, out var value)) { value = (node.Children[key] = new Node()); } node = value; } node.Value = target; } private static string Decode(string text) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '\\' && i + 1 < text.Length) { char c2 = text[++i]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case '\\': stringBuilder.Append('\\'); break; default: stringBuilder.Append('\\'); stringBuilder.Append(c2); break; } } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } } } namespace FXDSP.DeliveryBootstrap { [BepInPlugin("dspfx.delivery.prototypes", "FXDSP Delivery Buildings", "1.0.0")] [BepInDependency("me.xiaoye97.plugin.Dyson.LDBTool", "3.0.3")] public sealed class DeliveryBootstrap : BaseUnityPlugin { private static readonly int[] Ids = new int[2] { 11702, 11703 }; private static readonly int[] Bases = new int[2] { 2103, 2104 }; private Harmony _harmony; private bool _registered; private int _language = int.MinValue; private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); private static T Clone<T>(T source) { return (T)CloneMethod.Invoke(source, null); } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("dspfx.delivery.prototypes.localization"); _harmony.PatchAll(typeof(DeliveryBootstrap).Assembly); LDBTool.PostAddDataAction = (Action)Delegate.Combine(LDBTool.PostAddDataAction, new Action(Register)); LDBTool.EditDataAction = (Action<Proto>)Delegate.Combine(LDBTool.EditDataAction, new Action<Proto>(FinalizePrototype)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Delivery prototypes scheduled; reloadable trading logic remains in scripts/FXDSP.dll."); } private void Register() { //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_02af: Unknown result type (might be due to invalid IL or missing references) int[] ids = Ids; for (int i = 0; i < ids.Length; i++) { int num = ids[i]; if (((ProtoSet<ItemProto>)(object)LDB.items).Select(num) != null || ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(num) != null) { throw new InvalidOperationException("FXDSP delivery prototype ID conflict: " + num); } } foreach (TradeTechnology definition in TradeResearch.Definitions) { if (((ProtoSet<TechProto>)(object)LDB.techs).Select(definition.Id) != null) { throw new InvalidOperationException("FXDSP technology ID conflict: " + definition.Id); } } try { TechnologyIcons.Load(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded 12 custom FXDSP technology icons."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Custom technology icons unavailable; using native fallback icons: " + ex)); } TechnologyRegistration.Register(); HashSet<int> occupied = new HashSet<int>(((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray.Select((RecipeProto recipe) => recipe.GridIndex).Concat(((ProtoSet<ItemProto>)(object)LDB.items).dataArray.Select((ItemProto item) => item.GridIndex))); foreach (DeliveryRecipeDefinition definition2 in DeliveryRecipes.Definitions) { int itemId = definition2.ItemId; if (((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId) != null || ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(itemId) != null) { throw new InvalidOperationException("FXDSP delivery prototype ID conflict: " + itemId); } ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(definition2.BaseItemId); val.FindPreTech(); ItemProto val2 = Clone<ItemProto>(val); ((Proto)val2).ID = itemId; ((Proto)val2).Name = definition2.Name; ((Proto)val2).name = definition2.Name; string description = (val2.description = definition2.Description); val2.Description = description; int gridIndex = (val2.GridIndex = DeliveryRecipes.AllocateGrid(occupied)); val2.BuildIndex = 0; val2.Upgrades = new int[0]; val2.PreTechOverride = ((val.preTech != null) ? ((Proto)val.preTech).ID : 0); val2.prefabDesc = Clone<PrefabDesc>(val.prefabDesc); val2.prefabDesc.stationMaxItemCount = 1000000; RecipeProto val3 = new RecipeProto(); ((Proto)val3).ID = itemId; ((Proto)val3).Name = definition2.Name; ((Proto)val3).name = definition2.Name; val3.Description = definition2.Description; val3.Type = (ERecipeType)4; val3.Handcraft = definition2.Handcraft; val3.Explicit = false; val3.TimeSpend = definition2.TimeSpend; val3.Items = new int[1] { definition2.BaseItemId }; val3.ItemCounts = new int[1] { definition2.InputCount }; val3.Results = new int[1] { itemId }; val3.ResultCounts = new int[1] { 1 }; val3.GridIndex = gridIndex; val3.IconPath = val.IconPath; val3.preTech = val.preTech; RecipeProto val4 = (val2.maincraft = val3); val2.handcraft = null; val2.recipes = new List<RecipeProto> { val4 }; val2.handcrafts = new List<RecipeProto>(); val2.makes = new List<RecipeProto>(); val2.rawMats = new List<IDCNTINC>(); val2.maincraftProductCount = 1; val2.handcraftProductCount = 0; LDBTool.PostAddProto((Proto)(object)val2); LDBTool.PostAddProto((Proto)(object)val4); if (val2.GridIndex <= 0) { val2.GridIndex = gridIndex; } if (val4.GridIndex <= 0) { val4.GridIndex = gridIndex; } if (((Proto)val2).ID != itemId || ((Proto)val4).ID != itemId) { throw new InvalidOperationException("FXDSP delivery IDs must remain stable in LDBTool configuration."); } PrototypeOwnership.Mark("item", itemId, val2); PrototypeOwnership.Mark("recipe", itemId, val4); if (val.preTech != null) { val.preTech.UnlockRecipes = val.preTech.UnlockRecipes.Concat(new int[1] { itemId }).Distinct().ToArray(); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered two assembler-only FXDSP delivery towers."); _registered = true; } private static void FinalizePrototype(Proto proto) { TechnologyRegistration.Finalize(proto); RecipeProto val = (RecipeProto)(object)((proto is RecipeProto) ? proto : null); if (val != null && Ids.Contains(((Proto)val).ID) && PrototypeOwnership.Owns("recipe", ((Proto)val).ID, val)) { val.Preload(Array.IndexOf(((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray, val)); PrototypeTranslation.Apply((Proto)(object)val); return; } ItemProto val2 = (ItemProto)(object)((proto is ItemProto) ? proto : null); if (val2 != null) { int num = Array.IndexOf(Ids, ((Proto)val2).ID); if (num >= 0 && PrototypeOwnership.Owns("item", ((Proto)val2).ID, val2)) { ItemProto val3 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(Bases[num]); val2.DescFields = (int[])val3.DescFields.Clone(); val2.HpMax = val3.HpMax; val2.prefabDesc = Clone<PrefabDesc>(val3.prefabDesc); val2.prefabDesc.stationMaxItemCount = 1000000; PrototypeTranslation.Apply((Proto)(object)val2); } } } private void LateUpdate() { if (_registered && Localization.Loaded && _language != Localization.CurrentLanguageLCID) { _language = Localization.CurrentLanguageLCID; PrototypeTranslation.RefreshAll(); } } private void OnDestroy() { LDBTool.PostAddDataAction = (Action)Delegate.Remove(LDBTool.PostAddDataAction, new Action(Register)); LDBTool.EditDataAction = (Action<Proto>)Delegate.Remove(LDBTool.EditDataAction, new Action<Proto>(FinalizePrototype)); if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal static class PrototypeTranslation { internal static void Apply(Proto proto) { if (proto == null) { return; } TechProto val = (TechProto)(object)((proto is TechProto) ? proto : null); if (val != null && PrototypeOwnership.Owns("tech", ((Proto)val).ID, val)) { TradeTechnology tradeTechnology = TradeResearch.Find(((Proto)val).ID); if (tradeTechnology == null) { return; } SetLanguage(); ((Proto)val).name = TextLocalization.Translate(tradeTechnology.Name); val.description = TextLocalization.Translate(tradeTechnology.Description); val.conclusion = TextLocalization.Translate(tradeTechnology.Conclusion); TextIconMapping val2 = (((Object)(object)Configs.builtin == (Object)null) ? null : Configs.builtin.generalIconMapping); if (!((Object)(object)val2 != (Object)null) || val2.iconMappings == null) { return; } IconConfig[] iconMappings = val2.iconMappings; foreach (IconConfig val3 in iconMappings) { if (val3 != null && val3.tag == tradeTechnology.InlineIconTag) { val3.name = ((Proto)val).name; } } return; } foreach (DeliveryRecipeDefinition definition in DeliveryRecipes.Definitions) { if (proto.ID == definition.ItemId) { ItemProto val4 = (ItemProto)(object)((proto is ItemProto) ? proto : null); if (val4 != null && PrototypeOwnership.Owns("item", ((Proto)val4).ID, val4)) { SetLanguage(); ((Proto)val4).name = TextLocalization.Translate(definition.Name); val4.description = TextLocalization.Translate(definition.Description); } RecipeProto val5 = (RecipeProto)(object)((proto is RecipeProto) ? proto : null); if (val5 != null && PrototypeOwnership.Owns("recipe", ((Proto)val5).ID, val5)) { SetLanguage(); ((Proto)val5).name = TextLocalization.Translate(definition.Name); val5.description = TextLocalization.Translate(definition.Description); } } } } internal static void RefreshAll() { if ((Object)(object)LDB.techs != (Object)null) { foreach (TradeTechnology definition in TradeResearch.Definitions) { Apply((Proto)(object)((ProtoSet<TechProto>)(object)LDB.techs).Select(definition.Id)); } } if ((Object)(object)LDB.items == (Object)null || (Object)(object)LDB.recipes == (Object)null) { return; } foreach (DeliveryRecipeDefinition definition2 in DeliveryRecipes.Definitions) { Apply((Proto)(object)((ProtoSet<ItemProto>)(object)LDB.items).Select(definition2.ItemId)); Apply((Proto)(object)((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(definition2.ItemId)); } } private static void SetLanguage() { TextLocalization.English = Localization.Loaded && !Localization.isZHCN; } } [HarmonyPatch(typeof(TechProto), "RefreshTranslation")] internal static class TechnologyTranslationPatch { private static void Postfix(TechProto __instance) { PrototypeTranslation.Apply((Proto)(object)__instance); } } [HarmonyPatch(typeof(ItemProto), "RefreshTranslation")] internal static class ItemTranslationPatch { private static void Postfix(ItemProto __instance) { PrototypeTranslation.Apply((Proto)(object)__instance); } } [HarmonyPatch(typeof(RecipeProto), "RefreshTranslation")] internal static class RecipeTranslationPatch { private static void Postfix(RecipeProto __instance) { PrototypeTranslation.Apply((Proto)(object)__instance); } } internal static class TechnologyIcons { private const int Columns = 4; private const int Rows = 3; private const int Count = 12; private const int NativeIconSize = 80; private const string ResourceName = "FXDSP.DeliveryBootstrap.Assets.technology-icons.png"; private static readonly FieldInfo IconField = typeof(TechProto).GetField("_iconSprite", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static Sprite[] _sprites; internal static void Load() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f0: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Expected O, but got Unknown //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) if (_sprites != null) { return; } if (IconField == null) { throw new MissingFieldException(typeof(TechProto).FullName, "_iconSprite"); } byte[] array; using (Stream stream = typeof(TechnologyIcons).Assembly.GetManifestResourceStream("FXDSP.DeliveryBootstrap.Assets.technology-icons.png")) { if (stream == null) { throw new InvalidDataException("Embedded technology icon atlas missing."); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); Sprite[] array2 = (Sprite[])(object)new Sprite[12]; Texture2D[] array3 = (Texture2D[])(object)new Texture2D[12]; try { if (!ImageConversion.LoadImage(val, array, false) || ((Texture)val).width % 4 != 0 || ((Texture)val).height % 3 != 0) { throw new InvalidDataException("Technology atlas must have twelve equal cells in a 4 by 3 grid."); } Color32[] pixels = val.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val2 = pixels[i]; int num = Math.Max(val2.r, Math.Max(val2.g, val2.b)); int num2 = val2.a * ((num >= 224) ? 255 : num) / 255; pixels[i] = new Color32((byte)245, (byte)245, (byte)245, (byte)((num2 > 8) ? ((num2 >= 248) ? byte.MaxValue : ((byte)num2)) : 0)); } int num3 = ((Texture)val).width / 4; int num4 = ((Texture)val).height / 3; for (int j = 0; j < 12; j++) { int num5 = j % 4 * num3; int num6 = ((Texture)val).height - (j / 4 + 1) * num4; int num7 = num3; int num8 = num4; int num9 = -1; int num10 = -1; for (int k = 0; k < num4; k++) { for (int l = 0; l < num3; l++) { if (pixels[(num6 + k) * ((Texture)val).width + num5 + l].a > 32) { num7 = Math.Min(num7, l); num8 = Math.Min(num8, k); num9 = Math.Max(num9, l); num10 = Math.Max(num10, k); } } } if (num9 < num7 || num10 < num8) { throw new InvalidDataException("Empty technology icon cell " + j); } num7 = Math.Max(0, num7 - 2); num8 = Math.Max(0, num8 - 2); num9 = Math.Min(num3 - 1, num9 + 2); num10 = Math.Min(num4 - 1, num10 + 2); int num11 = num9 - num7 + 1; int num12 = num10 - num8 + 1; int num13 = Math.Max(num11, num12); int num14 = Math.Max(8, (num13 + 11) / 12); int num15 = num13 + 2 * num14; Color32[] array4 = (Color32[])(object)new Color32[num15 * num15]; for (int m = 0; m < array4.Length; m++) { array4[m] = new Color32((byte)245, (byte)245, (byte)245, (byte)0); } int num16 = (num15 - num11) / 2; int num17 = (num15 - num12) / 2; for (int n = 0; n < num12; n++) { Array.Copy(pixels, (num6 + num8 + n) * ((Texture)val).width + num5 + num7, array4, (num17 + n) * num15 + num16, num11); } Texture2D val3 = new Texture2D(80, 80, (TextureFormat)4, false) { name = "FXDSP.TechIcon." + j, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Texture2D val4 = (array3[j] = val3); val4.SetPixels32(ResizeMask(array4, num15)); val4.Apply(false, false); array2[j] = Sprite.Create(val4, new Rect(0f, 0f, 80f, 80f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ((Object)array2[j]).name = "FXDSP.TechIcon." + j; ((Object)array2[j]).hideFlags = (HideFlags)61; } _sprites = array2; } catch { Sprite[] array5 = array2; foreach (Sprite val5 in array5) { if ((Object)(object)val5 != (Object)null) { Object.Destroy((Object)(object)val5); } } Texture2D[] array6 = array3; foreach (Texture2D val6 in array6) { if ((Object)(object)val6 != (Object)null) { Object.Destroy((Object)(object)val6); } } throw; } finally { Object.Destroy((Object)(object)val); } } private static Color32[] ResizeMask(Color32[] source, int side) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[6400]; double num = (double)side / 80.0; double num2 = num * num; for (int i = 0; i < 80; i++) { double num3 = (double)i * num; double num4 = (double)(i + 1) * num; int num5 = (int)Math.Floor(num3); int num6 = Math.Min(side, (int)Math.Ceiling(num4)); for (int j = 0; j < 80; j++) { double num7 = (double)j * num; double num8 = (double)(j + 1) * num; double num9 = 0.0; int num10 = (int)Math.Floor(num7); int num11 = Math.Min(side, (int)Math.Ceiling(num8)); for (int k = num5; k < num6; k++) { double num12 = Math.Min(num4, k + 1) - Math.Max(num3, k); for (int l = num10; l < num11; l++) { double num13 = Math.Min(num8, l + 1) - Math.Max(num7, l); num9 += (double)(int)source[k * side + l].a * num13 * num12; } } array[i * 80 + j] = new Color32((byte)245, (byte)245, (byte)245, (byte)Math.Max(0.0, Math.Min(255.0, Math.Round(num9 / num2)))); } } return array; } internal static void Apply(TechProto tech) { if (_sprites == null) { return; } TradeTechnology tradeTechnology = TradeResearch.Find(((Proto)tech).ID); if (tradeTechnology != null) { int num = (tradeTechnology.Upgrade ? ((tradeTechnology.ExchangeTier > 0) ? tradeTechnology.ExchangeTier : (5 + tradeTechnology.Level)) : 0); if (num < 0 || num >= _sprites.Length) { throw new InvalidDataException("Technology icon rank is out of range."); } IconField.SetValue(tech, _sprites[num]); } } } internal static class TechnologyRegistration { internal static void Register() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) float num = ((ProtoSet<TechProto>)(object)LDB.techs).dataArray.Where((TechProto tech) => ((Proto)tech).ID >= 2000).Min((TechProto tech) => tech.Position.y) - 4f; TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(1826); if (val == null) { throw new InvalidOperationException("Cannot locate battlefield analysis technology."); } Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(val.Position.x - 4f, val.Position.y); float num2 = 9f; int num3 = 0; int num4 = 0; foreach (TradeTechnology definition in TradeResearch.Definitions) { if (((ProtoSet<TechProto>)(object)LDB.techs).Select(definition.Id) != null) { throw new InvalidOperationException("FXDSP technology ID conflict: " + definition.Id); } ItemProto val3 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(definition.IconItemId); TechProto val4 = new TechProto(); ((Proto)val4).ID = definition.Id; ((Proto)val4).Name = definition.RegistrationName; ((Proto)val4).name = definition.Name; val4.Desc = definition.Description; val4.Conclusion = definition.Conclusion; val4.Published = true; val4.Level = definition.Level; val4.MaxLevel = definition.Level; val4.IsLabTech = definition.Items.Any((int id) => id >= 6001 && id <= 6006); val4.IconPath = val3.IconPath; val4.IconTag = definition.InlineIconTag; val4.Items = definition.Items; val4.ItemPoints = definition.ItemPoints; val4.HashNeeded = definition.HashNeeded; val4.PreTechs = ((definition.Previous == 0 || definition.ImplicitPrevious) ? Array.Empty<int>() : new int[1] { definition.Previous }); val4.PreTechsImplicit = ((!definition.ImplicitPrevious) ? Array.Empty<int>() : new int[1] { definition.Previous }); val4.PreItem = Array.Empty<int>(); val4.UnlockRecipes = Array.Empty<int>(); val4.UnlockFunctions = Array.Empty<int>(); val4.UnlockValues = Array.Empty<double>(); val4.AddItems = Array.Empty<int>(); val4.AddItemCounts = Array.Empty<int>(); val4.PropertyOverrideItems = Array.Empty<int>(); val4.PropertyItemCounts = Array.Empty<int>(); val4.Position = (Vector2)((!definition.Upgrade) ? val2 : ((definition.ExchangeTier > 0) ? new Vector2(num2 + (float)(num3++ * 4), num) : new Vector2(num2 + (float)(num4++ * 4), num - 4f))); TechProto val5 = val4; LDBTool.PostAddProto((Proto)(object)val5); if (((Proto)val5).ID != definition.Id) { throw new InvalidOperationException("FXDSP technology IDs must remain stable."); } PrototypeOwnership.Mark("tech", ((Proto)val5).ID, val5); ((Proto)val5).Name = definition.Name; } } internal static void Finalize(Proto proto) { TechProto val = (TechProto)(object)((proto is TechProto) ? proto : null); if (val != null) { bool num = PrototypeOwnership.Owns("tech", ((Proto)val).ID, val); if (num) { val.Preload(); } bool flag = DeliveryRecipes.Definitions.Any((DeliveryRecipeDefinition definition) => PrototypeOwnership.Owns("recipe", definition.ItemId, ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(definition.ItemId))); if (num || (flag && (((Proto)val).ID == 1604 || ((Proto)val).ID == 1605))) { val.UnlockRecipes = val.UnlockRecipes.Distinct().ToArray(); val.Preload2(); } if (num) { TechnologyIcons.Apply(val); } if (num) { PrototypeTranslation.Apply((Proto)(object)val); } } } } }