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

+142
View File
@@ -0,0 +1,142 @@
using System.Linq;
using Decentralized.Domain;
namespace Decentralized
{
/// <summary>
/// Web3 黑市的货物进出:每周刷新现货与订单目录,夜间推进订单并写夜间日志,
/// 上门(快递员当顾客上门)和死投(去垃圾场取货)把到货交给玩家。
/// </summary>
public static class BlackDelivery
{
public static void Subscribe()
{
ModHook.OnGenerateCustomerNormal += OnGenerate;
ModHook.OnAfterhourArriveLate += OnArrive;
}
public static void Unsubscribe()
{
ModHook.OnGenerateCustomerNormal -= OnGenerate;
ModHook.OnAfterhourArriveLate -= OnArrive;
}
public static long Value(string id)
{
var it = ModHelper.SpawnItem(id);
if (it == null) return 0;
long v = it.GetBaseValue();
it.Destroy();
return v;
}
public static string ItemName(string id)
{
var it = ModHelper.SpawnItem(id);
if (it == null) return id;
string n = it.name;
it.Destroy();
return n;
}
/// <summary>每周刷新:现货与订单目录一起。返回是否刷新了。</summary>
public static bool Restock(SaveData d, int day, bool force = false)
{
int rep = StoreReputation.GetBMReputation();
if (d.Black.Closed(day)) return false;
if (force) d.Black.RefreshedDay = -999;
if (!d.Black.Refresh(day, rep, d.Rng, Value)) return false;
d.Black.RefreshOrders(rep, d.Rng, Value);
return true;
}
public static void Night(SaveData d, int day, bool crackdown)
{
var ps = PlayerStore.Instance;
foreach (var e in d.Black.Night(day, crackdown, d.Hot, d.Rng))
{
string name = e.Order != null ? ItemName(e.Order.Item) : null;
Log.Info($"黑市订单事件:{e.Kind} {e.Order?.Item} {e.Order?.Seller} {e.Order?.Mode}/{e.Order?.Delivery} 金额 {e.Amount:0}");
switch (e.Kind)
{
case "ready": ps.AddNightLog(L.T("nightlog.bm.ready." + e.Order.Delivery, name), "99bb66"); break;
case "scam_refund": ps.AddNightLog(L.T("nightlog.bm.scam_refund", e.Order.Seller, name), "cc7755"); break;
case "scam_loss": ps.AddNightLog(L.T("nightlog.bm.scam_loss", e.Order.Seller, name, Fmt.Num(e.Amount)), "cc7755"); break;
case "intercept": ps.AddNightLog(L.T("nightlog.bm.intercept", name, Fmt.Num(e.Amount)), "cc7755"); break;
case "theft": ps.AddNightLog(L.T("nightlog.bm.theft", name, Fmt.Num(e.Amount)), "cc7755"); break;
case "rug": ps.AddNightLog(L.T("nightlog.bm.rug", name, Fmt.Num(e.Amount)), "cc7755"); break;
case "reopen": ps.AddNightLog(L.T("nightlog.bm.reopen"), "99bb66"); break;
}
if (e.Kind == "rug") Night_RugNews(day);
}
if (Unlock.BlackUnlocked && !crackdown) Restock(d, day);
}
private static void Night_RugNews(int day) => News.Show("pd_news_bmrug_" + day, L.T("news.bmrug.title"), L.T("news.bmrug.desc"), 4);
// ---- 上门:开门后有到货的当天,快递员排进顾客队伍 ----
private static int courierDay = -1;
private static void OnGenerate(StoreClientManager manager)
{
if (Session.Data == null || !Unlock.BlackUnlocked) return;
Log.Guard("黑市快递员", () =>
{
int day = StoreStation.GetDayCounter();
if (day == courierDay || !Session.Data.Black.ReadyFor(Delivery.Door).Any()) return;
courierDay = day;
manager.AddClient(CreateCourier());
});
}
public static StoreClient CreateCourier()
{
var rng = Session.Data.Rng;
var c = new StoreClient
{
identifier = "pd_bm_courier",
displayName = L.T("courier.name"),
spriteName = SpriteDict.GetRandomScavSpriteName(),
clientIntent = StoreClient.ClientIntent.SELL,
};
StoreClientFactionSetup.InitScav(c);
c.mainDialogue.SetText(c.displayName, L.T("courier.line1." + rng.Range(1, 2))).NextDialogue().SetText(c.displayName, L.T("courier.line2." + rng.Range(1, 2)))
.SetEndAction(() => Log.Guard("黑市快递交货", () => { DeliverDoor(); PlayerStore.Instance.DismissCurrentClient(); }));
c.AddBasicDialog();
c.CompleteClientCreation();
return c;
}
private static void DeliverDoor()
{
var d = Session.Data;
foreach (var o in d.Black.ReadyFor(Delivery.Door).ToList())
{
Items.Give(ModHelper.SpawnItem(o.Item));
d.Black.Deliver(o);
Log.Info($"黑市快递:{o.Item} 已放进储藏区");
}
Session.Save();
}
// ---- 死投:晚上去垃圾场,货在那里 ----
private static void OnArrive(string locationId)
{
if (locationId != "dumping_ground" || Session.Data == null || !Unlock.BlackUnlocked) return;
Log.Guard("黑市死投", () =>
{
var d = Session.Data;
var list = d.Black.ReadyFor(Delivery.Drop).ToList();
foreach (var o in list)
{
var item = ModHelper.SpawnItem(o.Item);
GeneralHelper.SetItemOwned(item, true);
GraphUtils.EmporiumTryAdd(EmporiumEntry.Instance.afterhourInventory, item);
d.Black.Deliver(o);
Log.Info($"黑市死投:{o.Item} 已放进外出背包");
}
if (list.Count > 0) { Session.Save(); }
});
}
}
}
+9 -9
View File
@@ -51,20 +51,20 @@ namespace Decentralized
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Black market +50 rep, restock (test)", () => Log.Guard("黑市(测试)", () =>
{
StoreReputation.ModReputation("FACTION_BLACK_MARKET", 50);
if (!Unlock.IsUnlocked) ModHelper.GetNetworkUpgrade(Unlock.Id)?.Unlock();
if (!Unlock.BlackUnlocked) ModHelper.GetNetworkUpgrade(Unlock.BlackId)?.Unlock();
var d = Session.Data;
d.Black.RefreshedDay = -999;
d.Hot.Add(Assets.PSC, 20); d.Hot.Add(Assets.CRT, 3000); d.Hot.Taint += 2000; d.Hot.Basis += 1000;
d.Black.Refresh(StoreStation.GetDayCounter(), StoreReputation.GetBMReputation(), d.Rng, id =>
{
var it = ModHelper.SpawnItem(id);
if (it == null) return 0;
long v = it.GetBaseValue();
it.Destroy();
return v;
});
BlackDelivery.Restock(d, StoreStation.GetDayCounter(), true);
Log.Info($"黑市:声望 {StoreReputation.GetBMReputation()},上架 {d.Black.Offers.Count} 种:{string.Join(", ", d.Black.Offers.Select(o => o.Item + "×" + o.Qty + "@" + o.Price))},解锁 {Unlock.BlackUnlocked}");
}));
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Courier (test)", () => Log.Guard("黑市快递(测试)", () =>
{
foreach (var o in Session.Data.Black.Orders.Where(x => x.State == OrderState.Pending)) { o.State = OrderState.Ready; }
PlayerStore.Instance.currentClientInstance = null;
PlayerStore.Instance.storeClientManager.clientStack.Insert(0, BlackDelivery.CreateCourier());
PlayerStore.Instance.TryCallNextClient();
}));
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Coin buyer (test)", () => Log.Guard("用币付款顾客(测试)", () =>
{
var c = new StoreClient
+2
View File
@@ -17,6 +17,7 @@ namespace Decentralized
DealerStock.Subscribe();
UsedDealerClient.Subscribe();
CoinCustomers.Subscribe();
BlackDelivery.Subscribe();
GpuInspectView.Ensure();
ModHook.OnGameLoadedLate += Session.Load;
ModHook.OnNewGameStarted += OnNewGame;
@@ -30,6 +31,7 @@ namespace Decentralized
DealerStock.Unsubscribe();
UsedDealerClient.Unsubscribe();
CoinCustomers.Unsubscribe();
BlackDelivery.Unsubscribe();
GpuInspectView.Remove();
ModHook.OnGameLoadedLate -= Session.Load;
ModHook.OnNewGameStarted -= OnNewGame;
@@ -230,3 +230,50 @@ black.desk.in,Into Ponero
black.desk.out,Out of Ponero
black.desk.go,Swap
black.desk.fail,Swap failed: balance, limit or amount is wrong.
black.sub.orders,Orders
black.sub.mine,My orders & intel
black.rugged,"The platform is down; nobody will reopen for {0} more days."
black.seller,"Seller {0} trades {1} rating {2}%"
black.orders.h,Order catalog
black.listing,"{0} pay {1} credits"
black.order,Order
black.noadvance,This seller does not take advance release
black.orders.hint,"Cheaper than spot, but it takes days|and things can go wrong.|Escrow: {0}% fee, released on delivery;|refunded if the seller runs.|Advance: {1}% off, but a scammer keeps it;|only sellers with >= {2} trades accept.|The platform can rug too; escrow and|advance money both sit with it."
black.mode.Escrow,Escrow
black.mode.Advance,Advance release
black.del.Door,Door delivery
black.del.Drop,Dead drop
black.del.hint.Door,"A courier comes by in {0} days (as a customer when you open); higher interception chance."
black.del.hint.Drop,"Left at the dumping ground in {0} days, pick it up at night; low interception chance, but someone may dig it up first."
black.ordered,"Ordered: {0}, due day {1}."
black.mine.h,My orders
black.mine.none,No orders yet.
black.mine.line,"{0} ({1}, {2}): {3}, day {4}{5}"
black.mine.drop,", pick up at the dumping ground"
black.state.Pending,in transit
black.state.Ready,arrived
black.state.Done,picked up
black.state.Refunded.scam,seller ran, refunded
black.state.Lost.scam,seller ran, money gone
black.state.Lost.rug,platform rugged, money gone
black.state.Lost.intercept,intercepted
black.state.Lost.theft,dug up by someone else
black.forum.h,Forum intel
black.forum.quiet,Quiet lately.
black.forum.scam,"Someone says {0} takes the money and never ships."
black.forum.rug,"Withdrawals have been slow lately, the site is running promos, and a lot of complaint threads got deleted."
nightlog.bm.ready.Door,"Black market: {0} arrived; a courier will come by once you open."
nightlog.bm.ready.Drop,"Black market: {0} is at the dumping ground, go get it at night."
nightlog.bm.scam_refund,"Black market: seller {0} ran; the escrow for {1} was refunded."
nightlog.bm.scam_loss,"Black market: seller {0} took the advance and ran; {1} is gone ({2} credits)."
nightlog.bm.intercept,"Black market: the parcel with {0} was intercepted; {1} credits of payment lost."
nightlog.bm.theft,"Black market: {0} at the dumping ground was dug up by someone else; {1} credits lost."
nightlog.bm.rug,"Black market: the platform rugged; the in-transit funds for {0} ({1}) are gone."
nightlog.bm.reopen,Black market: someone reopened at the old spot.
news.bmrug.title,Black-market platform rugged
news.bmrug.desc,"The black market's on-chain entrance went dark overnight, wiping out all escrow and advance funds. A new entrance will appear in a few days."
courier.name,Courier
courier.line1.1,"Delivery's here."
courier.line1.2,"Package for you."
courier.line2.1,"Don't tell me what's inside. I don't want to know."
courier.line2.2,"Dropped it here. I'm gone."
1 # Probably Decentralized localization table: English (en)
230 black.desk.out
231 black.desk.go
232 black.desk.fail
233 black.sub.orders
234 black.sub.mine
235 black.rugged
236 black.seller
237 black.orders.h
238 black.listing
239 black.order
240 black.noadvance
241 black.orders.hint
242 black.mode.Escrow
243 black.mode.Advance
244 black.del.Door
245 black.del.Drop
246 black.del.hint.Door
247 black.del.hint.Drop
248 black.ordered
249 black.mine.h
250 black.mine.none
251 black.mine.line
252 black.mine.drop
253 black.state.Pending
254 black.state.Ready
255 black.state.Done
256 black.state.Refunded.scam
257 black.state.Lost.scam
258 black.state.Lost.rug
259 black.state.Lost.intercept
260 black.state.Lost.theft
261 black.forum.h
262 black.forum.quiet
263 black.forum.scam
264 black.forum.rug
265 nightlog.bm.ready.Door
266 nightlog.bm.ready.Drop
267 nightlog.bm.scam_refund
268 nightlog.bm.scam_loss
269 nightlog.bm.intercept
270 nightlog.bm.theft
271 nightlog.bm.rug
272 nightlog.bm.reopen
273 news.bmrug.title
274 news.bmrug.desc
275 courier.name
276 courier.line1.1
277 courier.line1.2
278 courier.line2.1
279 courier.line2.2
@@ -229,3 +229,50 @@ black.desk.in,兑入 Ponero
black.desk.out,兑出 Ponero
black.desk.go,兑换
black.desk.fail,兑换失败:余额、额度或数量不对。
black.sub.orders,订单
black.sub.mine,我的订单与情报
black.rugged,"平台出事了,入口关闭,还要 {0} 天才会有人重新开张。"
black.seller,"卖家 {0} 成交 {1} 好评 {2}%"
black.orders.h,订单目录
black.listing,"{0} 实付 {1} 信用点等值"
black.order,下单
black.noadvance,这个卖家不接受提前放款
black.orders.hint,"比现货便宜,但要等几天,|路上可能出事。|托管:多付 {0}% 托管费,|收货后放款,卖家跑路时退款。|提前放款:再打 {1}% 折,|卖家若是骗子钱就没了;|成交 ≥ {2} 的卖家才接受。|平台自己也可能跑路,|托管和提前放款的钱都在它手里。"
black.mode.Escrow,托管
black.mode.Advance,提前放款
black.del.Door,"送货上门"
black.del.Drop,死投点
black.del.hint.Door,"{0} 天后快递员上门(开店时来个顾客),被截获的概率较高。"
black.del.hint.Drop,"{0} 天后货放在垃圾场,晚上去取;被截获的概率低,但可能被别人先挖走。"
black.ordered,"已下单:{0},预计第 {1} 天到。"
black.mine.h,我的订单
black.mine.none,还没有订单。
black.mine.line,"{0}({1},{2}):{3},第 {4} 天{5}"
black.mine.drop,,去垃圾场取
black.state.Pending,在途
black.state.Ready,到货
black.state.Done,已取
black.state.Refunded.scam,卖家跑路,已退款
black.state.Lost.scam,卖家跑路,钱没了
black.state.Lost.rug,平台跑路,钱没了
black.state.Lost.intercept,被截获
black.state.Lost.theft,被别人先挖走
black.forum.h,论坛情报
black.forum.quiet,最近很安静。
black.forum.scam,"有人说 {0} 收了钱不发货。"
black.forum.rug,"最近提币变慢了,全场还在搞促销,投诉帖被删了不少。"
nightlog.bm.ready.Door,"黑市:{0} 到货,开店后会有快递员上门。"
nightlog.bm.ready.Drop,"黑市:{0} 已放在垃圾场,晚上去取。"
nightlog.bm.scam_refund,"黑市:卖家 {0} 跑路了,{1} 的托管款已退回。"
nightlog.bm.scam_loss,"黑市:卖家 {0} 拿了提前放款的钱跑路,{1} 没有了({2} 信用点等值)。"
nightlog.bm.intercept,"黑市:{0} 的包裹被截获,{1} 信用点等值的货款没了。"
nightlog.bm.theft,"黑市:垃圾场的 {0} 被别人先挖走了,{1} 信用点等值的货款没了。"
nightlog.bm.rug,"黑市:平台跑路,{0} 的在途款项({1})归零。"
nightlog.bm.reopen,黑市:有人在老地方重新开张了。
news.bmrug.title,黑市平台跑路
news.bmrug.desc,"黑市的链上入口一夜之间下线,托管和提前放款的资金全部清零。几天后会有新的入口。"
courier.name,快递员
courier.line1.1,"东西到了。"
courier.line1.2,"有你的包裹。"
courier.line2.1,"别问我里面是什么,我也不想知道。"
courier.line2.2,"货放这儿了,我走了。"
1 # Probably Decentralized 本地化表:简体中文(zh)
229 black.desk.out
230 black.desk.go
231 black.desk.fail
232 black.sub.orders
233 black.sub.mine
234 black.rugged
235 black.seller
236 black.orders.h
237 black.listing
238 black.order
239 black.noadvance
240 black.orders.hint
241 black.mode.Escrow
242 black.mode.Advance
243 black.del.Door
244 black.del.Drop
245 black.del.hint.Door
246 black.del.hint.Drop
247 black.ordered
248 black.mine.h
249 black.mine.none
250 black.mine.line
251 black.mine.drop
252 black.state.Pending
253 black.state.Ready
254 black.state.Done
255 black.state.Refunded.scam
256 black.state.Lost.scam
257 black.state.Lost.rug
258 black.state.Lost.intercept
259 black.state.Lost.theft
260 black.forum.h
261 black.forum.quiet
262 black.forum.scam
263 black.forum.rug
264 nightlog.bm.ready.Door
265 nightlog.bm.ready.Drop
266 nightlog.bm.scam_refund
267 nightlog.bm.scam_loss
268 nightlog.bm.intercept
269 nightlog.bm.theft
270 nightlog.bm.rug
271 nightlog.bm.reopen
272 news.bmrug.title
273 news.bmrug.desc
274 courier.name
275 courier.line1.1
276 courier.line1.2
277 courier.line2.1
278 courier.line2.2
+1 -9
View File
@@ -101,15 +101,7 @@ namespace Decentralized
foreach (var t in d.Hot.Thaw(day)) PlayerStore.Instance.AddNightLog(L.T("nightlog.thaw", Fmt.Num(t.Value), t.Key));
if (!wasSanctioned && d.Mixer.Sanctioned(day) && Unlock.MixerUnlocked) News.Show("pd_news_sanction_" + day, L.T("news.sanction.title"), L.T("news.sanction.desc"), 3);
d.ActiveEvents = events;
if (Unlock.BlackUnlocked && !events.Contains(MarketEvent.Crackdown))
d.Black.Refresh(day, StoreReputation.GetBMReputation(), d.Rng, id =>
{
var it = ModHelper.SpawnItem(id);
if (it == null) return 0;
long v = it.GetBaseValue();
it.Destroy();
return v;
});
if (Unlock.BlackUnlocked) BlackDelivery.Night(d, day, events.Contains(MarketEvent.Crackdown));
d.Network.Availability = (events.Contains(MarketEvent.Blackout) ? 0.8 : 1) * (events.Contains(MarketEvent.LowerUnrest) ? 0.9 : 1);
var units = Session.TonightCards.Select(c => (item: c.Key, unit: Items.ToUnit(c.Key), bonus: c.Value)).ToList();
+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;