Multiple hardware wallets: per-wallet devices, wallets page, Poinbase custodial account, PLEDGER item with supply-chain poisoning

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Opus 5.5 committed 2026-11-03 22:58:24 +08:00
1 parent add61a6b5e
commit 783f73989d
19 files changed
+557 -199

No files matched your search

+43
View File
@@ -18,6 +18,9 @@ namespace Decentralized
public const string Guide = "pd_gpu_guide";
public const string Web3Guide = "pd_web3_guide";
public const string GpuPrefix = "pd_gpu_";
public const string HwWallet = "pd_hw_wallet";
/// <summary>硬件钱包被动过手脚(供应链投毒)。外观、说明都不显示。</summary>
public const string PoisonTag = "PD_POISONED";
public const string HealthTag = "PD_HEALTH";
public const string FakeTag = "PD_FAKE_OF";
@@ -26,6 +29,9 @@ namespace Decentralized
public const string LookTag = "PD_LOOK", BackTag = "PD_BACK", SeedTag = "PD_SEED", ClaimTag = "PD_CLAIM", ExposedTag = "PD_EXPOSED", MarkupTag = "PD_MARKUP", EditedTag = "PD_EDITED";
public static Action OpenTerminal;
/// <summary>硬件钱包拖到交易终端上:添加一个钱包(参数:是否被投毒)。</summary>
public static Action<bool> AddWallet;
public static Func<bool> CanAddWallet;
public static void Subscribe() => ModHook.OnModItemDirectoryInit += Register;
public static void Unsubscribe() => ModHook.OnModItemDirectoryInit -= Register;
@@ -40,6 +46,7 @@ namespace Decentralized
dir.Add(Rig, CreateRig);
dir.Add(Guide, CreateGuide);
dir.Add(Web3Guide, CreateWeb3Guide);
dir.Add(HwWallet, CreateHwWallet);
foreach (var spec in Hardware.Specs.Values.Where(s => !s.Asic && !s.Scrap))
{
var s = spec;
@@ -93,6 +100,42 @@ namespace Decentralized
return item;
}
/// <summary>
/// PLEDGER 硬件钱包:和游戏里的升级材料一样,拖到交易终端上用掉,钱包 +1。杰克逊博士卖的是正品;
/// Web3 商城卖的便宜一些,外观和说明完全一样,其中一部分被动过手脚(<see cref="PoisonTag"/>)。
/// </summary>
private static GameItem CreateHwWallet()
{
var item = ItemDirectory.CreateEmptyItem(HwWallet);
item.SetSpriteAndShapeFromMod(ModInfo.Id, "hw_wallet");
item.name = L.T("item.hwwallet.name");
item.shortDescription = L.T("item.hwwallet.desc");
item.unitValue = Tuning.WalletJacksonPrice;
item.SetGameItemType("MATERIAL");
item.maySelectSlotItemFunc = (_, _, _) => true;
item.canSelectSlotItemFunc = (_, _, _) => true;
item.mayThisTargetItemFunc = (Func<GameItem, GameItem, bool>)Delegate.Combine(item.mayThisTargetItemFunc, (Func<GameItem, GameItem, bool>)((s, t) => CanTarget(t)));
item.canThisTargetItemFunc = (Func<GameItem, GameItem, bool>)Delegate.Combine(item.canThisTargetItemFunc, (Func<GameItem, GameItem, bool>)((s, t) => CanTarget(t)));
item.onThisTargetItemFunc = (Action<GameItem, GameItem>)Delegate.Combine(item.onThisTargetItemFunc, (Action<GameItem, GameItem>)((s, t) => Log.Guard("添加硬件钱包", () =>
{
if (!CanTarget(t)) return;
bool poisoned = s.IsTag(PoisonTag);
s.Destroy();
AddWallet?.Invoke(poisoned);
})));
ModHelper.SetSource(item, ModInfo.Id, ModInfo.Name);
return item;
}
private static bool CanTarget(GameItem t) => t != null && t.identifier == Terminal && (CanAddWallet?.Invoke() ?? false);
public static GameItem NewHwWallet(bool poisoned)
{
var item = ModHelper.SpawnItem(HwWallet);
if (item != null && poisoned) item.EnableTag(PoisonTag);
return item;
}
// ---------- 显卡 ----------
/// <summary>RTX70 → "RTX 70",RX800 → "RX 800"。</summary>