场外换币台实测修正:三个选项、换币账单不独占终端

- 原版对话最多三个选项:买币对话去掉"不卖"(第四个选项会越界),不想卖就打发客户;选项那句话带上报价和溢价,删除 otc.tier
- 换币账单单独挂着(OtcClient.Standing),WalletWindow.Pending 没有终端账单时回落到它:不独占 Web3、灰网页,换币、混币开的账单不会把它覆盖;签名后清掉,被挤出内存池时放回
- 到账后刷新终端;手册补一句"不想卖就把客户打发走"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Opus 5.5 committed 2026-11-08 15:10:03 +08:00
1 parent ec578a39d9
commit 7269c253af
12 files changed
+61 -51

No files matched your search

+24 -11
View File
@@ -14,8 +14,10 @@ namespace Decentralized
{
public const string Id = OtcLamp.Target;
private static bool spawning;
/// <summary>买币客户开出的账单:夜里还没付就作废。</summary>
/// <summary>买币客户开出的账单:付清(确认到账)或作废之前一直记着。</summary>
private static WalletWindow.Bill pendingBill;
/// <summary>还没签名付款的换币账单:钱包没有终端账单时用它(见 <see cref="WalletWindow.Pending"/>);签名后清掉,没成交(挤出内存池)时放回来。</summary>
public static WalletWindow.Bill Standing;
public static void Subscribe()
{
@@ -42,6 +44,9 @@ namespace Decentralized
ModHook.OnGoingSleepEarly -= VoidUnpaid;
}
/// <summary>这张账单是不是换币客户开的(终端不让它独占 Web3、灰网页)。</summary>
public static bool IsBill(WalletWindow.Bill bill) => bill != null && bill == pendingBill;
private static void Open(StoreClientManager _) => spawning = true;
private static void Close(StoreClientManager _) => spawning = false;
@@ -162,14 +167,14 @@ namespace Decentralized
{
int t = tier, price = Otc.Quote(o, t);
var say = new Dialogue();
var reply = say.SetText("PLAYER", L.T("otc.buy.say", Fmt.Credits(price))).NextDialogue();
// 选项上显示的是玩家要说的这句话
string line = L.T("otc.buy.say", Fmt.Credits(price), (Tuning.OtcPremium[t] * 100).ToString("0"));
var reply = say.SetText("PLAYER", line).NextDialogue();
reply.SetText(c.displayName, L.T("otc.buy.reject")).SetEndAction(Leave);
ask.AddChoice(DirectoryMaster.Item("$"), L.T("otc.tier", (Tuning.OtcPremium[t] * 100).ToString("0"), Fmt.Credits(price)), "", say,
ask.AddChoice(DirectoryMaster.Item("$"), line, "", say,
() => reply.SetText(c.displayName, AcceptBuy(o, addr, t, price)));
}
var no = new Dialogue();
no.SetText("PLAYER", L.T("otc.buy.no")).NextDialogue().SetText(c.displayName, L.T("otc.refused")).SetEndAction(Leave);
ask.AddChoice(DirectoryMaster.Item("cancel"), L.T("otc.choice.no"), "", no, null);
// 原版的对话最多三个选项(选项气泡只有三个),所以没有"不卖":不想卖就把客户打发走
}
/// <summary>报价:客户按这一档的概率接受。接受就开账单(转到客户地址),确认后现金到账。返回客户的回话。</summary>
@@ -193,27 +198,35 @@ namespace Decentralized
Session.Data.Otc.Record(price);
if (pendingBill == bill) pendingBill = null;
PlayerStore.Instance.AddNightLog(L.T("nightlog.otc.paid", WalletWindow.Amt(qty), asset, Fmt.Credits(price)));
TerminalWindow.Refresh(L.T("nightlog.otc.paid", WalletWindow.Amt(qty), asset, Fmt.Credits(price)));
Log.Info($"换币客户:{qty} {asset} 到账,收现金 {price}");
Session.Save();
}),
};
WalletWindow.Pending = pendingBill = bill;
pendingBill = Standing = bill;
line = L.T("otc.buy.accept", Fmt.Credits(price), ChainAddress.Short(addr));
Log.Info($"换币客户:第 {tier + 1} 档 {price} 成交,待转 {qty} {asset} 到 {addr}");
});
return line;
}
/// <summary>睡觉前:买币客户的账单还没付(仍是待付账单),作废。已经签名、还在确认中的照常到账。</summary>
/// <summary>睡觉前:买币客户的账单还没签名付款,作废。已经签名、还在确认中的照常到账。</summary>
private static void VoidUnpaid()
{
if (pendingBill == null || WalletWindow.Pending != pendingBill) return;
if (Standing == null) return;
var bill = Standing;
Log.Guard("换币账单作废", () =>
{
WalletWindow.Pending = null;
PlayerStore.Instance.AddNightLog(L.T("nightlog.otc.unpaid", WalletWindow.Amt(pendingBill.Amount), pendingBill.Asset), "cc7755");
PlayerStore.Instance.AddNightLog(L.T("nightlog.otc.unpaid", WalletWindow.Amt(bill.Amount), bill.Asset), "cc7755");
Log.Info("换币客户的账单当天没付,作废");
});
Void();
}
/// <summary>作废换币账单(终端的"作废"、夜里没付、读档)。</summary>
public static void Void()
{
Standing = null;
pendingBill = null;
}