Stage 4: black market orders, escrow, delivery, seller scams, platform rug

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 19:48:26 +08:00
1 parent f43cd487e5
commit 6bc479f710
12 files changed
+592 -35

No files matched your search

+97 -15
View File
@@ -264,7 +264,10 @@ namespace Decentralized
});
}
private static bool _blackDesk;
private enum BlackTab { Shop, Orders, Mine, Desk }
private static BlackTab _blackTab = BlackTab.Shop;
private static PayMode _mode = PayMode.Escrow;
private static Delivery _delivery = Delivery.Door;
private static string _deskAsset = Assets.PSC;
private static bool _deskIn = true;
private static string _payAsset = Assets.CRT;
@@ -278,14 +281,19 @@ namespace Decentralized
if (d.ActiveEvents.Contains(MarketEvent.Crackdown)) { b.AddLabel(L.T("black.offline")); return; }
if (!BlackMarket.Open(rep)) { b.AddLabel(L.T("black.closed", Tuning.BmOpenRep, rep)); return; }
bool desk = BlackMarket.DeskOpen(rep);
if (desk)
b.BeginRow();
foreach (BlackTab t in Enum.GetValues(typeof(BlackTab)))
{
b.BeginRow();
b.AddButton(_blackDesk ? L.T("black.sub.shop") : $"[{L.T("black.sub.shop")}]", () => { _blackDesk = false; _message = null; Open(); });
b.AddButton(_blackDesk ? $"[{L.T("black.sub.desk")}]" : L.T("black.sub.desk"), () => { _blackDesk = true; _message = null; Open(); });
b.End();
if (t == BlackTab.Desk && !desk) continue;
var tab = t;
string name = L.T("black.sub." + t.ToString().ToLowerInvariant());
b.AddButton(tab == _blackTab ? $"[{name}]" : name, () => { _blackTab = tab; _message = null; Open(); });
}
if (desk && _blackDesk) { DeskPage(b, rep, day); return; }
b.End();
if (d.Black.Closed(day)) { b.AddLabel(L.T("black.rugged", d.Black.ClosedUntil - day + 1)); return; }
if (_blackTab == BlackTab.Desk && desk) { DeskPage(b, rep, day); return; }
if (_blackTab == BlackTab.Orders) { OrdersPage(b, day); return; }
if (_blackTab == BlackTab.Mine) { MinePage(b, day); return; }
var w = d.Hot;
Columns(b, l =>
{
@@ -314,14 +322,7 @@ namespace Decentralized
});
}
private static string ItemName(string id)
{
var it = ModHelper.SpawnItem(id);
if (it == null) return id;
string n = it.name;
it.Destroy();
return n;
}
private static string ItemName(string id) => BlackDelivery.ItemName(id);
private static void BuyOffer(BmOffer o)
{
@@ -333,6 +334,87 @@ namespace Decentralized
Open();
}
private static string SellerText(BmSeller s) => L.T("black.seller", s.Name, s.Trades, s.Rating);
/// <summary>订单目录:比现货便宜,要等几天,可能被截获、被骗。</summary>
private static void OrdersPage(CustomUIBuilder b, int day)
{
var d = Session.Data;
var w = d.Hot;
Columns(b, l =>
{
l.AddHeader(L.T("black.orders.h"));
if (d.Black.Catalog.Count == 0) l.AddLabel(L.T("black.empty"));
foreach (var x in d.Black.Catalog.ToList())
{
var listing = x;
var seller = d.Black.Sellers[listing.Seller];
l.AddLabel(L.T("black.listing", ItemName(listing.Item), BlackMarket.Pay(listing.Price, _mode)));
l.AddLabel(" " + SellerText(seller));
bool ok = _mode == PayMode.Escrow || seller.Advance;
l.AddButton(ok ? L.T("black.order") : L.T("black.noadvance"), () => { if (ok) PlaceOrder(listing); });
}
}, r =>
{
r.AddHeader(L.T("black.pay.h"));
foreach (var line in L.T("black.orders.hint", (int)Math.Round(Tuning.BmEscrowFee * 100), (int)Math.Round(Tuning.BmAdvanceDiscount * 100), Tuning.BmAdvanceMinTrades).Split('|')) r.AddLabel(line);
r.BeginRow();
foreach (PayMode m in Enum.GetValues(typeof(PayMode)))
{
var mode = m;
string n = L.T("black.mode." + m);
r.AddButton(mode == _mode ? $"[{n}]" : n, () => { _mode = mode; Open(); });
}
r.End();
r.BeginRow();
foreach (Delivery dl in Enum.GetValues(typeof(Delivery)))
{
var del = dl;
string n = L.T("black.del." + dl, Tuning.BmDoorDays);
r.AddButton(del == _delivery ? $"[{n}]" : n, () => { _delivery = del; Open(); });
}
r.End();
r.AddLabel(L.T("black.del.hint." + _delivery, BlackMarket.Days(_delivery)));
r.BeginRow();
foreach (var a in new[] { Assets.PSC, Assets.CRT, Assets.CRA, Assets.Ponero })
{
var asset = a;
r.AddButton(asset == _payAsset ? $"[{asset}]" : asset, () => { _payAsset = asset; Open(); });
}
r.End();
r.AddLabel(L.T("mixer.balance", _payAsset, Fmt.Num(w.Avail(_payAsset))));
});
}
private static void PlaceOrder(BmListing l)
{
var d = Session.Data;
var o = d.Black.Place(l, _mode, _delivery, d.Hot, _payAsset, StoreStation.GetDayCounter(), Session.Price);
if (o == null) { _message = L.T("msg.balance"); Open(); return; }
_message = L.T("black.ordered", ItemName(o.Item), o.DueDay);
Session.Save();
Open();
}
/// <summary>我的订单与论坛情报。</summary>
private static void MinePage(CustomUIBuilder b, int day)
{
var d = Session.Data;
Columns(b, l =>
{
l.AddHeader(L.T("black.mine.h"));
if (d.Black.Orders.Count == 0) l.AddLabel(L.T("black.mine.none"));
foreach (var o in d.Black.Orders.OrderByDescending(x => x.PlacedDay))
l.AddLabel(L.T("black.mine.line", ItemName(o.Item), o.Seller, L.T("black.mode." + o.Mode), L.T("black.state." + o.State + (o.Why != null && o.State != OrderState.Done ? "." + o.Why : "")), o.DueDay, o.Delivery == Delivery.Drop && o.State == OrderState.Ready ? L.T("black.mine.drop") : ""));
}, r =>
{
r.AddHeader(L.T("black.forum.h"));
if (d.Black.Forum.Count == 0) r.AddLabel(L.T("black.forum.quiet"));
foreach (var f in d.Black.Forum)
r.AddLabel(f.StartsWith("scam:") ? L.T("black.forum.scam", f.Substring(5)) : L.T("black.forum." + f));
});
}
private static void DeskPage(CustomUIBuilder b, int rep, int day)
{
var d = Session.Data;