Black market tabs: Buy / Sell / Orders; Ponero swap moved into the Web3 trade page

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 22:04:31 +08:00
1 parent 776f66fd2c
commit 5b7013f240
4 files changed
+106 -87

No files matched your search

+1
View File
@@ -30,6 +30,7 @@
- 订单改成商家货架(用户意见):黑市页"订单"改名"商家",每周从 6 种类型里抽 5 家(全新矿卡经销商、二手矿卡贩子、模组高科技、军火、证件芯片、药物),另有 25% 的周出现一家大宗商家(库存 10–25 件、价格系数 0.55–0.75、送货 6 天)。每家有自己的价格系数(订单价 = 基础价 × 系数,一般 0.70–0.95,全新卡 0.85–1.00,二手卡 0.65–0.90),每家 4 种货、库存 3–6 件。一次订 5 件以上 95 折、10 件以上 9 折。界面:件数按钮 ×1 / ×5 / ×10,商家按钮,所选商家的货架。药物(药片、梦尘、管制化学品)只在药物商家和大宗商家出现,也能转手出售。每周货架总值在游戏里抽样 60 周平均 13.2k(目标 1.4 万)。
- 商家类型扩到 18 种 + 大宗(用户意见,对照游戏的物品目录和玩家职业):全新矿卡经销商、二手矿卡贩子、矿架与能源、模组、军火(枪、手雷、炸药、刀具、电击枪)、枪匠配件(枪械配件、3D 打印芯片与模组、枪械零件)、证件芯片、药物(药片、注射器、血袋、手术工具)、化学品(化学用品、助熔剂、化学设备模组、量筒试剂瓶)、酿酒(酵母、荧光莓、啤酒、酒瓶)、水培农场(种子、水培模组、植物分析仪)、养殖(鱼卵、鱼子酱、循环水养殖系统、血清、屠宰机)、矿工(矿石、金属锭、电子元件、拾荒扫描仪)、水务(滤水、净水、储水、检测)、仓储(走私暗格、储藏区扩建、军用背包)、工具(涡轮增压器、等离子切割机、X 射线扫描仪、心智重编程器)、奢侈品(香水、精华液、香烟)。每周 7 家:2 家从矿卡 / 矿架 / 模组 4 类里抽(保证矿工路线总有货),其余 5 家从其余类型里抽;每家 3 种货,库存 2–5 件,单件基础价超过 4000 的不上。游戏里抽样 60 周货架总值平均 13.2k(目标 1.4 万)。药物改成并入药物商家,现货柜台的货不变。所有货都能转手出售。
- 尖端店铺与个人卖家(用户意见):贵货(单件基础价 ≥ 2000:超科技涡轮增压器、超科技储藏区、心智重编程器、顶级显卡等)不再被一刀切掉,改由"尖端店铺"卖:每周只有 15% 的概率出现,2 种货、库存 1–2 件、价格系数 0.85–1.00、送货 5 天;顶级全新显卡也在这里。个人卖家:每周固定 2 位,什么都卖(可能是药、模组、显卡、仍有 10% 混进贵货),每件价格系数各自随机 0.50–1.20(捡漏或被宰),库存 1–2 件,是骗子的概率 25%,都是新号所以只接受托管。常规商家仍只卖基础价 ≤ 4000 的货。
- 黑市标签整理(用户意见):原来的"现货柜台 / 商家 / 出售 / 我的订单与情报 / Ponero 兑换处"改成三个对称的标签"买货 / 卖货 / 订单"。买货页里平台现货是第一家卖家("[平台] 0x…",立即到货,选它时不显示托管 / 提前放款),后面是各商家,件数按钮 ×1 / ×5 / ×10 现货也适用(一次买多件走一次付款确认);论坛情报放到买货页最下面;订单页分"买入"(订单)和"卖出"(上架、改价、撤下)上下两块。Ponero 不再是黑市里的标签:并进 Web3"交易"页的右栏,作为一个带"[匿名币]"标签的通用兑换块(选 PSC / CRT / CRA,兑入 / 兑出,要黑市声望,仍有每日额度和手输地址确认)。游戏内验证:新的三个标签和平台现货货架、订单页、交易页的 Ponero 块,兑入进入付款确认。
- 定价改成直接输价格(用户意见):点货架上的"上架"或"我的订单"里的"改价",出现"设定标价"页,显示参考价(真实价)和输入框;×0.6–×1.8 档位只是帮忙把价格填进输入框,也可以手输整数,输入后显示"标价 83(×1.38)";价格要在参考价的 0.6–1.8 倍之间(显示可输范围),确定后走付款确认(上架费 5% / 改价费 2% 按新标价算)。成交速度和货款污点都按 标价 ÷ 参考价 的实际比例连续计算(不再只有档位)。"我的订单"里每件上架的货显示"参考 60 标价 83(×1.38)",下面是"改价"和"撤下"。出售页顶上的档位按钮保留,作为默认倍率(预填价格、"全部上架"用)。游戏内验证:档位填价(×1.5 → 90)、手输 83(×1.38,上架费 5)、范围外(200)被拒并提示 36–108。
- 自己的储藏区和背包不再出现在可上架的货里,有内容的容器也不行(之前储藏区(扩建)会被列出来,上架会把里面的东西一起带走)。
- 上架后可以改价(用户意见):"我的订单与情报"页每件上架的货下面一排倍率按钮(0.6–1.8,当前的带方括号)和"撤下",点倍率先走付款确认(改价费 2%,`BmRepriceFee`,手输平台地址),标价按参考价重算,成交概率按新倍率走,上架日不变。游戏内验证:0.6 倍的 RTX 70 改成 ×1.2,改价费 12,标价 600。蜜罐基础概率维持 1%(模拟里进取策略罪证 ≥ 300 约 48 天,用户认为可接受)。
@@ -207,8 +207,7 @@ black.upgrade.title,Web3 Black Market
black.upgrade.desc,"Unlocks the black market in the Web3 page: the black-market faction's on-chain arm. Weekly shelves of contraband, occasionally high-tech goods and GPUs (at a markup); buy spot, or order and wait for a courier. Coin only (PSC, CRT, CRA, Ponero), tainted coin accepted. Needs black-market standing; offline during crackdowns."
black.offline,The black market's on-chain entrance is offline during the crackdown.
black.closed,"You need black-market standing of {0} before anyone lets you in (currently {1})."
black.sub.shop,Spot counter
black.sub.desk,Ponero desk
black.sub.buy,Buy
black.shop.h,Spot counter
black.rep,"Black-market standing {0}"
black.empty,Sold out for this week.
@@ -224,8 +223,7 @@ 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,Merchants
black.sub.mine,My orders & intel
black.sub.orders,Orders
black.rugged,"The platform is down; nobody will reopen for {0} more days."
black.seller,"{0}, {1} trades, {2}%"
black.orders.h,Order catalog
@@ -270,7 +268,7 @@ black.kind.Contraband.3,Contraband (high)
black.kind.Tech,High-tech (markup)
nightlog.bm.ready,"Black market: {0} arrived; a courier will come by once you open."
item.web3guide.name,Web3 Handbook
item.web3guide.desc,"Bank: depositing turns credits into CRC; withdrawing turns CRC back into credits and goes through compliance screening. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Payments and transfers (black market, mixer, Ponero desk, listing fees) require typing the payee address (the 0x string in the merchant name, or the platform's own) and a wrong address pays nothing. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometimes turns into enforcement at your door: signing logs the crime on the spot and seizes the goods, refusing only costs the payment. Selling: on the black market's Sell page, list contraband, high-tech goods and GPUs from storage at 0.6x to 1.8x the reference price. The higher the multiplier, the slower the sale (below 0.9x about a day, 1.0x about two, 1.8x about fourteen), and the likelier and larger the taint on the payout, which also grows with how much you sold in the last 7 days; at most 10 listings at a time, 5% listing fee, repricing a listing costs 2% and the sale speed follows the new multiplier, 8% commission, payout held 3 days before reaching your wallet; a fake card may be spotted and returned, hurting your rating; if the platform rugs, listed goods and unreleased payouts are gone. Ponero desk: Ponero is a privacy coin and swapping in wipes the taint on that value; 6% fee each way with a daily limit; coin swapped out of Ponero has no origin and cash-out screening gets stricter."
item.web3guide.desc,"Bank: depositing turns credits into CRC; withdrawing turns CRC back into credits and goes through compliance screening. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Payments and transfers (black market, mixer, Ponero desk, listing fees) require typing the payee address (the 0x string in the merchant name, or the platform's own) and a wrong address pays nothing. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometimes turns into enforcement at your door: signing logs the crime on the spot and seizes the goods, refusing only costs the payment. Selling: on the black market's Sell tab, list contraband, high-tech goods and GPUs from storage at 0.6x to 1.8x the reference price. The higher the multiplier, the slower the sale (below 0.9x about a day, 1.0x about two, 1.8x about fourteen), and the likelier and larger the taint on the payout, which also grows with how much you sold in the last 7 days; at most 10 listings at a time, 5% listing fee, repricing a listing costs 2% and the sale speed follows the new multiplier, 8% commission, payout held 3 days before reaching your wallet; a fake card may be spotted and returned, hurting your rating; if the platform rugs, listed goods and unreleased payouts are gone. Anonymous-coin swap (Web3 trade page, needs black-market standing): Ponero is a privacy coin and swapping in wipes the taint on that value; 6% fee each way with a daily limit; coin swapped out of Ponero has no origin and cash-out screening gets stricter."
courier.odd1,...Package is here.
courier.odd2,"(His hand stays in his pocket.) Sign here."
courier.sign,Sign
@@ -353,3 +351,8 @@ black.edit.ok,OK
black.edit.cancel,Cancel
black.edit.range,"The price must be 0.6 to 1.8 times the reference ({0} to {1})."
black.sell.reprice,Reprice
merchant.Platform,Platform
black.platform.line,"Platform spot instant delivery payee {0}"
black.orders.in,Bought
black.orders.out,Selling
black.desk.pair,"PONERO [anonymous coin] price {0}"
1 # Probably Decentralized localization table: English (en)
207 black.upgrade.desc
208 black.offline
209 black.closed
210 black.sub.shop black.sub.buy
black.sub.desk
211 black.shop.h
212 black.rep
213 black.empty
223 black.desk.out
224 black.desk.go
225 black.desk.fail
226 black.sub.orders
black.sub.mine
227 black.rugged
228 black.seller
229 black.orders.h
268 black.kind.Tech
269 nightlog.bm.ready
270 item.web3guide.name
271 item.web3guide.desc
272 courier.odd1
273 courier.odd2
274 courier.sign
351 black.edit.cancel
352 black.edit.range
353 black.sell.reprice
354 merchant.Platform
355 black.platform.line
356 black.orders.in
357 black.orders.out
358 black.desk.pair
@@ -206,8 +206,7 @@ black.upgrade.title,Web3 黑市
black.upgrade.desc,"解锁 Web3 页里的黑市:黑市派系在链上的实体。货架上每周上一批违禁品,偶尔有高科技物品和显卡(要加价);可以直接买现货,也可以下订单等快递员上门。只收币(PSC、CRT、CRA、Ponero),脏币也收。需要黑市声望,镇压期间下线。"
black.offline,镇压期间,黑市的链上入口已经下线。
black.closed,"黑市声望达到 {0} 才会有人带你进去(现在 {1})。"
black.sub.shop,现货柜台
black.sub.desk,Ponero 兑换处
black.sub.buy,买货
black.shop.h,现货柜台
black.rep,"黑市声望 {0}"
black.empty,这周的货卖完了。
@@ -223,8 +222,7 @@ black.desk.in,兑入 Ponero
black.desk.out,兑出 Ponero
black.desk.go,兑换
black.desk.fail,兑换失败:余额、额度或数量不对。
black.sub.orders,商家
black.sub.mine,我的订单与情报
black.sub.orders,订单
black.rugged,"平台出事了,入口关闭,还要 {0} 天才会有人重新开张。"
black.seller,"{0},成交 {1},好评 {2}%"
black.orders.h,订单目录
@@ -269,7 +267,7 @@ black.kind.Contraband.3,违禁品(高)
black.kind.Tech,高科技物品(加价)
nightlog.bm.ready,"黑市:{0} 到货,开店后会有快递员上门。"
item.web3guide.name,Web3 手册
item.web3guide.desc,"银行:存入把信用点换成 CRC;提取把 CRC 换回信用点,提取要过合规审查。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。付款与转账(黑市、混币器、Ponero 兑换处、上架费)前要手输收款地址(商家名里的 0x 开头那串,或平台自己的地址),输错不会付款。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的出售页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了。Ponero 兑换处:Ponero 是隐私币,兑入时这部分价值的污点被清除;兑入、兑出各收 6% 手续费,每天有额度;从 Ponero 兑出的币来路不明,出金审查会加重。"
item.web3guide.desc,"银行:存入把信用点换成 CRC;提取把 CRC 换回信用点,提取要过合规审查。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。付款与转账(黑市、混币器、Ponero 兑换处、上架费)前要手输收款地址(商家名里的 0x 开头那串,或平台自己的地址),输错不会付款。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的卖货页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了。匿名币兑换(Web3 交易页,要黑市声望):Ponero 是隐私币,兑入时这部分价值的污点被清除;兑入、兑出各收 6% 手续费,每天有额度;从 Ponero 兑出的币来路不明,出金审查会加重。"
courier.odd1,……东西到了。
courier.odd2,"(他的手一直放在口袋里)在这儿签个字。"
courier.sign,签收
@@ -290,7 +288,7 @@ nightlog.bm.sale_sold,"黑市:你上架的 {0} 卖出了,货款 {1},第 {2
nightlog.bm.sale_paid,"黑市:{0} 的货款 {1} 到账(CRT),其中污点 {2}。"
nightlog.bm.sale_fake,"黑市:买家看穿了 {0} 是假卡,退了货,你的好评下降。"
nightlog.bm.sale_rug,"黑市:平台跑路,你的 {0} 和货款({1})没了。"
black.sub.sell,出售
black.sub.sell,卖货
black.sell.h,出售
black.sell.mult,"标价 ×{0}"
black.sell.list,上架
@@ -352,3 +350,8 @@ black.edit.ok,确定
black.edit.cancel,取消
black.edit.range,"标价要在参考价的 0.6 到 1.8 倍之间({0} 到 {1})。"
black.sell.reprice,改价
merchant.Platform,平台
black.platform.line,"平台现货 立即到货 收款地址 {0}"
black.orders.in,买入
black.orders.out,卖出
black.desk.pair,"PONERO [匿名币] 价格 {0}"
1 # Probably Decentralized 本地化表:简体中文(zh)
206 black.upgrade.desc
207 black.offline
208 black.closed
209 black.sub.shop black.sub.buy
black.sub.desk
210 black.shop.h
211 black.rep
212 black.empty
222 black.desk.out
223 black.desk.go
224 black.desk.fail
225 black.sub.orders
black.sub.mine
226 black.rugged
227 black.seller
228 black.orders.h
267 black.kind.Tech
268 nightlog.bm.ready
269 item.web3guide.name
270 item.web3guide.desc
271 courier.odd1
272 courier.odd2
273 courier.sign
288 nightlog.bm.sale_paid
289 nightlog.bm.sale_fake
290 nightlog.bm.sale_rug
291 black.sub.sell
292 black.sell.h
293 black.sell.mult
294 black.sell.list
350 black.edit.cancel
351 black.edit.range
352 black.sell.reprice
353 merchant.Platform
354 black.platform.line
355 black.orders.in
356 black.orders.out
357 black.desk.pair
+88 -76
View File
@@ -271,11 +271,12 @@ namespace Decentralized
r.AddHeader(L.T("trade.h"));
AmountRow(r);
TradeRows(r, Venue.Dex);
if (Unlock.BlackUnlocked && BlackMarket.DeskOpen(StoreReputation.GetBMReputation())) PoneroBlock(r);
});
}
private enum BlackTab { Shop, Orders, Sell, Mine, Desk }
private static BlackTab _blackTab = BlackTab.Shop;
private enum BlackTab { Buy, Sell, Orders }
private static BlackTab _blackTab = BlackTab.Buy;
private static PayMode _mode = PayMode.Escrow;
private static string _deskAsset = Assets.PSC;
private static bool _deskIn = true;
@@ -306,11 +307,9 @@ namespace Decentralized
var d = Session.Data;
if (Night.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);
b.BeginRow();
foreach (BlackTab t in Enum.GetValues(typeof(BlackTab)))
{
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; _pay = null; _edit = null; Open(); });
@@ -318,11 +317,18 @@ namespace Decentralized
b.End();
if (d.Black.Closed(day)) { b.AddLabel(L.T("black.rugged", d.Black.ClosedUntil - day + 1)); return; }
if (_edit != null) { EditPage(b); return; }
if (_blackTab == BlackTab.Desk && desk) { DeskPage(b, rep, day); return; }
if (_blackTab == BlackTab.Mine) { MinePage(b, day); return; }
if (_blackTab == BlackTab.Orders) { OrdersPage(b, day); return; }
if (_blackTab == BlackTab.Sell) { SellPage(b, day); return; }
bool orders = _blackTab == BlackTab.Orders;
BuyPage(b, d, rep);
}
/// <summary>买货:选一家卖家(第一个是平台现货,立即到货但贵,其余是商家,便宜但要等),选件数,下单。论坛情报在最下面。</summary>
private static void BuyPage(CustomUIBuilder b, SaveData d, int rep)
{
var w = d.Hot;
var sellers = d.Black.Sellers;
if (_merchant >= sellers.Count) _merchant = -1;
bool platform = _merchant < 0;
b.AddLabel(L.T("black.rep", rep, BlackMarket.MaxLevel(rep)) + " " + L.T("mixer.balance", _payAsset, Fmt.Num(w.Avail(_payAsset))) + (w.Taint > 0.5 ? " " + L.T("wallet.taint", Fmt.Credits(w.Taint)) : ""));
b.BeginRow();
foreach (var a in new[] { Assets.PSC, Assets.CRT, Assets.CRA, Assets.Ponero })
@@ -330,7 +336,7 @@ namespace Decentralized
var asset = a;
b.AddButton(asset == _payAsset ? $"[{asset}]" : asset, () => { _payAsset = asset; Open(); });
}
if (orders)
if (!platform)
foreach (PayMode m in Enum.GetValues(typeof(PayMode)))
{
var mode = m;
@@ -338,21 +344,49 @@ namespace Decentralized
b.AddButton(mode == _mode ? $"[{n}]" : n, () => { _mode = mode; Open(); });
}
b.End();
b.AddSeparator();
if (!orders)
b.BeginRow();
foreach (var m in Qtys)
{
if (d.Black.Offers.Count == 0) b.AddLabel(L.T("black.empty"));
int q = m;
b.AddButton(q == _qty ? $"[×{q}]" : "×" + q, () => { _qty = q; Open(); });
}
b.End();
var all = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<int, string>> { new System.Collections.Generic.KeyValuePair<int, string>(-1, "[" + L.T("merchant.Platform") + "] " + d.Address("platform")) };
for (int k = 0; k < sellers.Count; k++) all.Add(new System.Collections.Generic.KeyValuePair<int, string>(k, MerchantLabel(sellers[k])));
for (int i = 0; i < all.Count; i += 3)
{
b.BeginRow();
for (int k = i; k < Math.Min(all.Count, i + 3); k++)
{
int idx = all[k].Key; string n = all[k].Value;
b.AddButton(idx == _merchant ? "> " + n : n, () => { _merchant = idx; Open(); });
}
b.End();
}
b.AddSeparator();
if (platform) PlatformShelf(b, d);
else MerchantShelf(b, d);
b.AddSeparator();
b.AddHeader(L.T("black.forum.h"));
if (d.Black.Forum.Count == 0) b.AddLabel(L.T("black.forum.quiet"));
foreach (var f in d.Black.Forum)
b.AddLabel(f.StartsWith("scam:") ? L.T("black.forum.scam", BlackDelivery.DisplayName(f.Substring(5))) : f.StartsWith("busted:") ? L.T("black.forum.busted", f.Substring(7)) : L.T("black.forum." + f));
}
private static void PlatformShelf(CustomUIBuilder b, SaveData d)
{
b.AddLabel(L.T("black.platform.line", d.Address("platform")));
if (d.Black.Offers.Count == 0) { b.AddLabel(L.T("black.empty")); return; }
Shelf(b, d.Black.Offers.Cast<BmGood>().ToList(), (c, g) =>
{
var offer = (BmOffer)g;
int count = Math.Min(_qty, offer.Qty);
GoodHead(c, g, L.T("black.stock", offer.Qty));
c.AddLabel(L.T("black.price", offer.Price));
c.AddLabel(L.T("black.price", offer.Price * count) + (count > 1 ? " ×" + count : ""));
c.AddFlexibleSpace();
c.AddButton(L.T("black.buy"), () => BeginPay(d.Address("platform"), ItemName(offer.Item), offer.Price, () => BuyOffer(offer)));
c.AddButton(L.T("black.buy"), () => BeginPay(d.Address("platform"), ItemName(offer.Item) + (count > 1 ? " ×" + count : ""), offer.Price * count, () => BuyOffer(offer, count)));
});
}
else MerchantShelf(b, d);
}
private static double _sellMult = 1.0;
private static readonly double[] SellMults = { 0.6, 0.8, 0.9, 1.0, 1.2, 1.5, 1.8 };
@@ -429,7 +463,7 @@ namespace Decentralized
private static string MerchantLabel(BmSeller s) => "[" + L.T("merchant." + s.Type) + "] " + s.Name;
private static int _merchant;
private static int _merchant = -1;
private static int _qty = 1;
private static readonly int[] Qtys = { 1, 5, 10 };
@@ -437,26 +471,6 @@ namespace Decentralized
private static void MerchantShelf(CustomUIBuilder b, SaveData d)
{
var sellers = d.Black.Sellers;
if (sellers.Count == 0) { b.AddLabel(L.T("black.empty")); return; }
if (_merchant >= sellers.Count) _merchant = 0;
b.BeginRow();
foreach (var m in Qtys)
{
int q = m;
b.AddButton(q == _qty ? $"[×{q}]" : "×" + q, () => { _qty = q; Open(); });
}
b.End();
for (int i = 0; i < sellers.Count; i += 3)
{
b.BeginRow();
for (int k = i; k < Math.Min(sellers.Count, i + 3); k++)
{
int idx = k;
string n = MerchantLabel(sellers[k]);
b.AddButton(idx == _merchant ? "> " + n : n, () => { _merchant = idx; Open(); });
}
b.End();
}
var seller = sellers[_merchant];
b.AddLabel(L.T("black.seller", MerchantLabel(seller), seller.Trades, seller.Rating) + " " + L.T("black.days", seller.Days));
var goods = d.Black.Catalog.Where(l => l.Seller == _merchant).Cast<BmGood>().ToList();
@@ -533,14 +547,20 @@ namespace Decentralized
b.End();
}
private static void BuyOffer(BmOffer o)
private static void BuyOffer(BmOffer o, int count)
{
var d = Session.Data;
string item = o.Item, model = o.Model, fake = o.FakeOf;
double health = o.Health;
if (!d.Black.Buy(o, d.Hot, _payAsset, Session.Price)) { _message = L.T("msg.balance"); Open(); return; }
int bought = 0;
for (int i = 0; i < count; i++)
{
if (!d.Black.Buy(o, d.Hot, _payAsset, Session.Price)) break;
Items.Give(BlackDelivery.Make(item, model, fake, health));
_message = L.T("black.bought", ItemName(item));
bought++;
}
if (bought == 0) { _message = L.T("msg.balance"); Open(); return; }
_message = L.T("black.bought", ItemName(item) + (bought > 1 ? " ×" + bought : ""));
Session.Save();
Open();
}
@@ -619,54 +639,40 @@ namespace Decentralized
}
/// <summary>我的订单与论坛情报。</summary>
private static void MinePage(CustomUIBuilder b, int day)
private static void OrdersPage(CustomUIBuilder b, int day)
{
var d = Session.Data;
Columns(b, l =>
{
l.AddHeader(L.T("black.mine.h"));
if (d.Black.Orders.Count == 0 && d.Black.Sales.Count == 0) l.AddLabel(L.T("black.mine.none"));
b.AddHeader(L.T("black.orders.in"));
if (d.Black.Orders.Count == 0) b.AddLabel(L.T("black.mine.none"));
foreach (var o in d.Black.Orders.OrderByDescending(x => x.PlacedDay))
b.AddLabel(L.T("black.mine.line", ItemName(o.Item) + (o.Count > 1 ? " ×" + o.Count : ""), BlackDelivery.DisplayName(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));
b.AddSeparator();
b.AddHeader(L.T("black.orders.out"));
if (d.Black.Sales.Count == 0) b.AddLabel(L.T("black.mine.none"));
foreach (var sl in d.Black.Sales.Where(x => x.State != SaleState.Delisted || x.Why == "fake").OrderByDescending(x => x.ListedDay))
{
var sale = sl;
string st = sale.State == SaleState.Sold ? L.T("black.sale.Sold", sale.PayDay) : L.T("black.sale." + sale.State + (sale.State == SaleState.Delisted && sale.Why != null ? "." + sale.Why : ""));
l.AddLabel(L.T("black.mine.sale", ItemName(sale.Item), sale.Ref, sale.ListPrice, sale.Mult.ToString("0.00", CultureInfo.InvariantCulture), st));
b.AddLabel(L.T("black.mine.sale", ItemName(sale.Item), sale.Ref, sale.ListPrice, sale.Mult.ToString("0.00", CultureInfo.InvariantCulture), st));
if (sale.State == SaleState.Listed)
{
l.BeginRow();
l.AddButton(L.T("black.sell.reprice"), () => BeginEdit(new EditPrice { Sale = sale, Id = sale.Item, Ref = sale.Ref }, sale.ListPrice));
l.AddButton(L.T("black.sell.delist"), () => Delist(sale));
l.End();
b.BeginRow();
b.AddButton(L.T("black.sell.reprice"), () => BeginEdit(new EditPrice { Sale = sale, Id = sale.Item, Ref = sale.Ref }, sale.ListPrice));
b.AddButton(L.T("black.sell.delist"), () => Delist(sale));
b.End();
}
}
foreach (var o in d.Black.Orders.OrderByDescending(x => x.PlacedDay))
l.AddLabel(L.T("black.mine.line", ItemName(o.Item) + (o.Count > 1 ? " ×" + o.Count : ""), BlackDelivery.DisplayName(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));
}, 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", BlackDelivery.DisplayName(f.Substring(5))) : f.StartsWith("busted:") ? L.T("black.forum.busted", f.Substring(7)) : L.T("black.forum." + f));
});
}
private static void DeskPage(CustomUIBuilder b, int rep, int day)
/// <summary>匿名币兑换:Web3 交易页里的一个通用兑换块,带"匿名币"标签。要黑市声望,有每日额度;兑入时这部分价值的污点被清除。</summary>
private static void PoneroBlock(CustomUIBuilder r)
{
var d = Session.Data;
var w = d.Hot;
Columns(b, l =>
{
l.AddHeader(L.T("black.desk.h"));
l.AddLabel(L.T("black.desk.left", Fmt.Credits(d.Black.DeskLeft(day)), Fmt.Credits(Tuning.PoneroDailyCap)));
l.AddLabel(L.T("black.desk.price", Fmt.Num(Session.Price(Assets.Ponero))));
Holdings(l, w, a => a == Assets.Ponero || a == _deskAsset);
}, r =>
{
r.AddHeader(L.T("black.desk.swap"));
r.BeginRow();
r.AddButton(_deskIn ? $"[{L.T("black.desk.in")}]" : L.T("black.desk.in"), () => { _deskIn = true; Open(); });
r.AddButton(_deskIn ? L.T("black.desk.out") : $"[{L.T("black.desk.out")}]", () => { _deskIn = false; Open(); });
r.End();
int day = StoreStation.GetDayCounter();
r.AddSeparator();
r.AddLabel(L.T("black.desk.pair", Fmt.Num(Session.Price(Assets.Ponero))));
r.AddLabel(L.T("black.desk.left", Fmt.Credits(d.Black.DeskLeft(day)), Fmt.Credits(Tuning.PoneroDailyCap)));
r.BeginRow();
foreach (var a in new[] { Assets.PSC, Assets.CRT, Assets.CRA })
{
@@ -674,10 +680,16 @@ namespace Decentralized
r.AddButton(asset == _deskAsset ? $"[{asset}]" : asset, () => { _deskAsset = asset; Open(); });
}
r.End();
r.AddLabel(_deskIn ? L.T("mixer.balance", _deskAsset, Fmt.Num(w.Avail(_deskAsset))) : L.T("mixer.balance", Assets.Ponero, Fmt.Num(w.Avail(Assets.Ponero))));
AmountRow(r);
r.AddButton(L.T("black.desk.go"), () => { if (!ReadAmount(out double dv)) return; BeginPay(d.Address("desk"), L.T("pay.swap", Fmt.Num(dv), _deskIn ? _deskAsset : Assets.Ponero), (int)Math.Round(dv * Session.Price(_deskIn ? _deskAsset : Assets.Ponero)), DeskSwap); });
});
r.BeginRow();
r.AddButton(L.T("black.desk.in"), () => { _deskIn = true; Swap(); });
r.AddButton(L.T("black.desk.out"), () => { _deskIn = false; Swap(); });
r.End();
void Swap()
{
if (!ReadAmount(out double dv)) return;
string asset = _deskIn ? _deskAsset : Assets.Ponero;
BeginPay(d.Address("desk"), L.T("pay.swap", Fmt.Num(dv), asset), (int)Math.Round(dv * Session.Price(asset)), DeskSwap);
}
}
private static void DeskSwap()