Compare commits
9
Commits
v1.1.0
..
0f26d88c03
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f26d88c03 | ||
|
|
64f330ef25 | ||
|
|
c2a6d8832a | ||
|
|
71002cbced | ||
|
|
9d95e1f760 | ||
|
|
2badc45a5a | ||
|
|
7269c253af | ||
|
|
ec578a39d9 | ||
|
|
bc23ae056b |
No files matched your search
@@ -1,5 +1,39 @@
|
||||
# Changelog
|
||||
|
||||
## 未发布
|
||||
|
||||
### 第十一阶段 stage 1:污点代替没收、挖矿去上限
|
||||
|
||||
- 预测市场的内幕单不再按概率查处、没收:结算或卖出时照常兑付,内幕份额对应的兑付记为收款钱包的污点,夜间日志写明“警方怀疑这是内幕交易”。原来“内幕持仓达到上限的 40%、70% 概率被查”的规则(`PredictInsiderShare`、`PredictInsiderCatch`)删除,每一份内幕份额都记污点,先买后卖也一样。
|
||||
- 操纵检出:被查的概率不变,被查后照常兑付,预测盘的这笔兑付记钱包污点,永续的这笔盈利记 Poinbase 账户污点;永续账户不再冻结 3 天(`ManipFreezeDays` 删除)。报纸的调查新闻改为“涉事账户已被标记”。
|
||||
- 污点上限:加污点时不超过钱包当时的价值,超出的部分按 50% 记诈骗罪证,每次最多 400(沿用 `PredictFraudShare`、`PredictFraudCap`),日志显示超出的污点额。
|
||||
- 矿架、矿机的模块效果不设上限(原来算力最多 +20%、省电最多 25%、损耗最多 −30%,以及耗电最多 ×2 的隐含限制):9 个无限制神经核心算力 ×5.5、耗电 ×3.25、暴毙率 ×5.5。只保留防出错的下限:算力乘数 ≥ 0、耗电乘数 ≥ 0.2、损耗乘数 ≥ 0。
|
||||
- 出块奖励 100 → 1000 PSC,NPC 初始算力 360 → 3600:均衡时每 H 收入不变(开局 1 H 每晚仍约 26.9 信用点),全网算力放大,玩家算力占比变低。模拟:普通玩法第 30 天挖矿占比 19% → 21%,第 120 天玩家算力占比 33% → 约 2%;大矿工收入明显变高。
|
||||
- 修正:内幕卖出的日志原来写“只退本金”,实际是全部没收。
|
||||
- 手册对应段落 8 种语言更新。
|
||||
|
||||
- 涡轮增压器可以对矿架和矿机用(原来被挡掉),规则和原版机器一样:用一次就多跑一轮,也就是立刻挖一晚——扣一晚的电,产出按当前全网算力计算、发到这台机器的收款地址,同样算一次损耗和暴毙判定,不影响当晚照常挖矿。增压器本身的消耗、充电、可用次数照原版。
|
||||
|
||||
### 第十一阶段 stage 2:场外换币台
|
||||
|
||||
- 新人脉升级“场外换币台”(500,前提是 Web3 治理社区),附赠一盏暗灯。原版暗灯双击切换目标时多一个“换币客户”(解锁后才有),放进展示柜亮黄绿色的光;招客概率、顾客面板、灯的提示都沿用原版暗灯(每盏 15% + 黑市声望的一半,封顶 95%)。
|
||||
- 换币客户一半来卖币、一半来买币,都用现金。客户说明来意后选“到终端上谈”,交易终端打开柜台交易页(标签“柜台”),客户在柜台前等着;可以按 25% / 50% / 75% / 100% 或手输数量只成交一部分,现金按比例折算,客户要的数量随房租增长。选“放弃”或把客户打发走就作废。
|
||||
- 卖币(原来的收黑币并进来,不再单独上门):成交后付现金,币直接进已连接的钱包。帮派火并、镇压期间多是 CRT,袭击上层、下层动荡期间多是 PSC,这类币全额污点;平时在 PSC、CRT、CRA 里随机,污点占市值 20%–90%,要价从市值的 80% 降到 45%。交易页上有客户地址,“查地址”打开浏览器看它的来历(混币器、黑市平台、骗局地址或 Poinbase、DEX);污点同样不超过钱包价值。Ponero 兑换处开放后偶尔有人出手 Ponero;便衣规则不变。
|
||||
- 买币:什么币都可能要,数量按房租 2–8 倍,出价是市价加一个随机溢价(−5% 到 +30%),成不成交由玩家决定。成交后 PLEDGER 弹出,收款地址和数量已填好,签名确认后客户付现金离开。卖出的币不追查污点。换币账单不独占终端的 Web3、灰网页,也不会被换币、混币这些终端账单覆盖,可以先在 DEX 换出客户要的币再成交。
|
||||
- 浏览器里换币客户的地址显示为“换币客户”。
|
||||
- 存档数据版本 4:读旧存档时出块奖励和 NPC 算力按 stage 1 的新数值放大 10 倍(保留减半进度)。
|
||||
- 手册“收黑币”一节改写为“换币客户”,8 种语言。
|
||||
|
||||
### 第十一阶段 stage 3:自营混币器
|
||||
|
||||
- 买下场外换币台就开放,灰网页多一个“自营混币器”标签。注资(PSC、CRC、CRT、CRA,账单转账)后开张,NPC 客户把带污点的币存进来,几天后出款,你收手续费;费率可选 1% / 2% / 3% / 5% / 8% / 12%,可以暂停营业。
|
||||
- 和普通混币器一样,每一轮按匿名集洗掉一部分污点;匿名集主要是你的本金和没取走的收入(客户在途的币按 25% 算),每轮清洗率 = 35% × 匿名集 / (匿名集 + 20,000)。客户拿“费率 + 出款剩下的污点 × 0.1”和 Tumbler 的混币器比,便宜就多来,黑市声望越高客人越多(Tumbler 关停或被制裁时客人更多)。
|
||||
- 手续费收入留在池子里,取回时先取收入(全额带污点),再取本金(带本金自己的污点)。客户在途的币不能取。
|
||||
- 风险:风声随客流累积(池子大能藏得深一点:累积量除以 1 + 匿名集 / 160,000,但客流也大,总体大池子更容易被盯上)、每晚衰减,按风声有概率被治安部查封(本金、收入和客户的币全部没收,记销赃罪证 = 池子价值的 1%、封顶 400,停业 7 天,上报纸);营业的晚上有 3% 概率来一笔便衣存入(记销赃罪证)。随时可以卷款跑路(点两次确认、签名):连同客户的币全部卷走、全额带污点,记诈骗罪证 400、黑市声望 −25,混币器永久关闭。
|
||||
- 模拟(research/mixsim out_v3,费率 3%,第 61–90 天):注资 1 万每天手续费约 316、2 万约 574、4 万约 807、8 万约 991;90 天被查封 1 万 0.12 次、2 万 0.21 次、4 万和 8 万 0.35 次,净收益随本金增长、增速递减(1 万约 2.8 万,8 万约 6.3 万)。
|
||||
- 手册“换币客户”一节加一段自营混币器,8 种语言;夜间日志和报纸新闻。
|
||||
|
||||
|
||||
## 1.1.0
|
||||
|
||||
市场与洗钱的平衡调整:Poinbase 改为订单簿、DEX 稳定币对改为稳定币池、保险基金和爆仓新闻、预测市场流动性、收黑币、浏览器记录钱包的每一笔进出。存档兼容,读旧存档时自动升级。
|
||||
|
||||
Binary file not shown.
+29
-2
@@ -44,6 +44,9 @@ C = {
|
||||
'P': (0xD8, 0xDA, 0xD0), # 墨水屏
|
||||
'K': (0x3C, 0x3F, 0x48), # 石墨机身
|
||||
'E': (0x5A, 0x5E, 0x6A), # 机身受光边
|
||||
# 换币灯的黄绿色霓虹(带透明度:光晕由外向内 20% / 40% / 60% / 80%,灯芯不透明)
|
||||
'N1': (0xB6, 0xF0, 0x5A, 52), 'N2': (0xB6, 0xF0, 0x5A, 103), 'N3': (0xB6, 0xF0, 0x5A, 153), 'N4': (0xB6, 0xF0, 0x5A, 204),
|
||||
'N5': (0xD8, 0xFF, 0x7A), 'N6': (0x6E, 0xA8, 0x2E), 'N7': (0x3E, 0x6A, 0x1E),
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +76,7 @@ class Canvas:
|
||||
for row in self.px:
|
||||
line = bytearray()
|
||||
for c in row:
|
||||
r, g, b, a = (0, 0, 0, 0) if c is None else C[c] + (255,)
|
||||
r, g, b, a = (0, 0, 0, 0) if c is None else (C[c] + (255,))[:4]
|
||||
if bg is not None:
|
||||
r, g, b = (round(v * a / 255 + w * (255 - a) / 255) for v, w in zip((r, g, b), bg))
|
||||
a = 255
|
||||
@@ -665,8 +668,31 @@ def key_drive():
|
||||
return c
|
||||
|
||||
|
||||
def otc_lamp_on():
|
||||
"""换币灯的点亮叠加图(32×48,和原版暗灯同尺寸,(0,0) 对齐):只画灯罩下面的光晕和灯芯,叠在熄灭的暗灯上。
|
||||
光晕是灯罩下沿的椭圆(第 25–40 行),越靠中心越不透明;灯芯是中间一根竖条,底下一圈灯座光。"""
|
||||
c = Canvas(32, 48)
|
||||
rows = { # 每行光晕的左右边界(含)
|
||||
25: (5, 26), 26: (4, 27), 27: (4, 27), 28: (3, 28), 29: (3, 28), 30: (3, 28), 31: (2, 29), 32: (2, 29),
|
||||
33: (2, 29), 34: (3, 28), 35: (3, 28), 36: (4, 27), 37: (5, 26), 38: (6, 25), 39: (9, 22), 40: (13, 18),
|
||||
}
|
||||
for y, (x0, x1) in rows.items():
|
||||
for x in range(x0, x1 + 1):
|
||||
if y == 25 and 7 <= x <= 24:
|
||||
continue # 灯罩下沿正中还是灯罩
|
||||
d = (((x - 15.5) / 14) ** 2 + ((y - 32) / 8.5) ** 2) ** 0.5
|
||||
c.put(x, y, 'N4' if d < 0.45 else 'N3' if d < 0.65 else 'N2' if d < 0.85 else 'N1')
|
||||
for y in range(27, 37): # 灯芯
|
||||
c.put(15, y, 'N5'); c.put(16, y, 'N6')
|
||||
for y, (x0, x1) in {37: (13, 18), 38: (11, 20), 39: (11, 20), 40: (13, 18)}.items():
|
||||
for x in range(x0, x1 + 1): # 灯座反光
|
||||
c.put(x, y, 'N6' if y < 40 else 'N7')
|
||||
for x in range(14, 18):
|
||||
c.put(x, 38, 'N5')
|
||||
return c
|
||||
|
||||
|
||||
SPRITES = {
|
||||
'gpu_guide': guide,
|
||||
'gpu_burnt_f': lambda: gpu_front('e', 'c', burnt=True),
|
||||
'gpu_burnt_b': lambda: gpu_back('e', 'c', burnt=True),
|
||||
'gpu_probidia_b': lambda: gpu_back('G', 'g2'),
|
||||
@@ -779,6 +805,7 @@ OVERLAYS = {
|
||||
'gpu_ov_fin1': lambda: ov_fingers(1), 'gpu_ov_fin2': lambda: ov_fingers(2),
|
||||
'gpu_ov_brk1': lambda: ov_bracket(1),
|
||||
'gpu_ov_stk2': lambda: ov_sticker(2),
|
||||
'otc_lamp_on': otc_lamp_on,
|
||||
}
|
||||
for _n in (1, 2, 3):
|
||||
OVERLAYS['gpu_ov_fan1_%d' % _n] = (lambda n=_n: ov_fan(1, n))
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>一笔黑币报价:卖家手里的币、按现价的市值和他要的现金。Sting 是钓鱼执法(收下就记罪证,币不会到)。</summary>
|
||||
public sealed class HotOffer
|
||||
{
|
||||
public string Asset;
|
||||
public double Qty, Value;
|
||||
public int Cash;
|
||||
public bool Sting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 收黑币:游戏里出了事,手里有来路不明的币的人上门,折价换现金。
|
||||
/// 帮派火并、镇压期间黑市的人出手 CRT;革命军袭击上层、下层动荡期间有人出手抢来的 PSC;黑市声望够了以后偶尔有人出手勒索得来的 Ponero。
|
||||
/// PSC、CRT 链上可追,收下的币按市值全额带污点;Ponero 不可追、不带污点,折扣也小,出口只有 Ponero 兑换处。
|
||||
/// </summary>
|
||||
public static class HotCoins
|
||||
{
|
||||
/// <summary>今天哪种黑币可能有人上门(按游戏当前的事件),没有返回 null。poneroOpen:Ponero 兑换处已开放。</summary>
|
||||
public static string Pick(ICollection<MarketEvent> active, bool poneroOpen, Rng rng)
|
||||
{
|
||||
var c = new List<string>();
|
||||
if (active.Contains(MarketEvent.GangWar) || active.Contains(MarketEvent.Crackdown)) c.Add(Assets.CRT);
|
||||
if (active.Contains(MarketEvent.RevRaidUpper) || active.Contains(MarketEvent.LowerUnrest)) c.Add(Assets.PSC);
|
||||
if (c.Count > 0 && rng.Chance(Tuning.HotEventChance)) return c[rng.Range(0, c.Count - 1)];
|
||||
if (poneroOpen && rng.Chance(Tuning.HotPoneroChance)) return Assets.Ponero;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>开价:市值 = 房租 × 区间,现金要价 = 市值 × 折扣(Ponero 折扣小)。crackdown:镇压期间钓鱼执法更多。</summary>
|
||||
public static HotOffer Make(string asset, double coinPrice, double rent, bool crackdown, Rng rng)
|
||||
{
|
||||
if (coinPrice <= 0 || rent <= 0) return null;
|
||||
double value = rent * rng.Range(Tuning.HotValueMinRents, Tuning.HotValueMaxRents);
|
||||
bool ponero = asset == Assets.Ponero;
|
||||
double cut = ponero ? rng.Range(Tuning.HotPoneroCutMin, Tuning.HotPoneroCutMax) : rng.Range(Tuning.HotCutMin, Tuning.HotCutMax);
|
||||
return new HotOffer
|
||||
{
|
||||
Asset = asset, Qty = value / coinPrice, Value = value, Cash = (int)Math.Round(value * cut),
|
||||
Sting = rng.Chance(Tuning.HotSting + (crackdown ? Tuning.HotStingCrackdown : 0)),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>收下:币进钱包,成本是付出的现金;PSC、CRT 按市值记污点,Ponero 不记。钓鱼执法不在这里处理。</summary>
|
||||
public static void Receive(Wallet w, HotOffer o)
|
||||
{
|
||||
w.Add(o.Asset, o.Qty);
|
||||
w.Basis += o.Cash;
|
||||
if (o.Asset != Assets.Ponero) w.Taint += o.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,8 @@ namespace Decentralized.Domain
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 矿架上游戏模块的效果。机器汇总的三项百分比(性能、效率、品质)各除以 <see cref="Tuning.ModuleRatio"/> 后生效,
|
||||
/// 并有上限,避免模块把挖矿收益放大到破坏经济:算力最多 +20%,省电最多 25%,损耗最多降 30%。
|
||||
/// 性能加成同时按比例提高损耗与暴毙率。负数(例如节能模块的负性能、超频模块的负效率)照常生效,耗电增加不设上限。
|
||||
/// 矿架上游戏模块的效果。机器汇总的三项百分比(性能、效率、品质)各除以 <see cref="Tuning.ModuleRatio"/> 后生效,不设上限(强力模块是玩家自己拿到的)。
|
||||
/// 性能加成同时按比例提高损耗与暴毙率。三个乘数各有防出错的下限:算力不低于 <see cref="Tuning.ModuleHashFloor"/>,耗电不低于 <see cref="Tuning.ModuleKjFloor"/>,损耗不低于 <see cref="Tuning.ModuleWearFloor"/>。
|
||||
/// </summary>
|
||||
public struct ModuleBonus
|
||||
{
|
||||
@@ -84,14 +83,17 @@ namespace Decentralized.Domain
|
||||
public static ModuleBonus From(int performance, int efficiency, int quality)
|
||||
{
|
||||
double r = Tuning.ModuleRatio * 100.0;
|
||||
double hash = Clamp(performance / r, -0.5, Tuning.ModuleHashCap);
|
||||
double save = Clamp(efficiency / r, -1.0, Tuning.ModuleKjCap);
|
||||
double wearCut = Clamp(quality / r, -1.0, Tuning.ModuleWearCap);
|
||||
double hash = performance / r, save = efficiency / r, wearCut = quality / r;
|
||||
double heat = 1 + Math.Max(0, hash);
|
||||
return new ModuleBonus { Hash = 1 + hash, Kj = 1 - save, Wear = (1 - wearCut) * heat, Death = heat };
|
||||
return new ModuleBonus
|
||||
{
|
||||
Hash = Math.Max(Tuning.ModuleHashFloor, 1 + hash),
|
||||
Kj = Math.Max(Tuning.ModuleKjFloor, 1 - save),
|
||||
Wear = Math.Max(Tuning.ModuleWearFloor, (1 - wearCut) * heat),
|
||||
Death = heat,
|
||||
};
|
||||
}
|
||||
|
||||
private static double Clamp(double v, double lo, double hi) => Math.Max(lo, Math.Min(hi, v));
|
||||
}
|
||||
|
||||
/// <summary>一张显卡或一台矿机的实例状态(存进物品标签)。</summary>
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>换币客户的来意:卖币给玩家(玩家付现金收币),或者向玩家买币(玩家转币收现金)。</summary>
|
||||
public enum OtcSide { Sell, Buy }
|
||||
|
||||
/// <summary>
|
||||
/// 一位换币客户的报价。Sell:客户手里的币(Qty、按现价的市值 Value、污点比例 TaintRatio)和他要的现金 Cash;Sting 是便衣(收下就记罪证,币不会到)。
|
||||
/// Buy:客户要买的币和数量,Value 是按现价的市值,Cash 是他出的现金(市价加一个随机的溢价,可能低于市价)。
|
||||
/// 玩家可以只成交一部分(<see cref="Otc.Part"/>),现金、市值按数量比例折算。
|
||||
/// </summary>
|
||||
public sealed class OtcOffer
|
||||
{
|
||||
public OtcSide Side;
|
||||
public string Asset;
|
||||
public double Qty, Value, TaintRatio;
|
||||
public int Cash;
|
||||
public bool Sting;
|
||||
}
|
||||
|
||||
/// <summary>换币台的累计统计(存档):成交额(信用点)、笔数、客户地址编号;混币器提议是否已经发过(第三阶段用)。</summary>
|
||||
public sealed class OtcDesk
|
||||
{
|
||||
public double Volume;
|
||||
public int Deals, Seq;
|
||||
public bool MixerOffered;
|
||||
|
||||
public void Record(double cash) { Volume += Math.Max(0, cash); Deals++; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 换币客户(场外换币台):小偷灯切到"换币客户"后招来,一半来卖币、一半来买币。
|
||||
/// 卖币沿用原来的收黑币:帮派火并、镇压期间多是 CRT,革命军袭击上层、下层动荡期间多是 PSC,这类币全额带污点;
|
||||
/// 其他时候在 PSC、CRT、CRA 里随机,污点比例随机,现金价按污点比例打折;Ponero 兑换处开放后偶尔有人出手 Ponero(不带污点)。
|
||||
/// 买币:什么币都可能要,出价是市价加一个随机溢价,玩家自己决定成不成交;卖出的币不追查污点。两边都可以只成交一部分。
|
||||
/// </summary>
|
||||
public static class Otc
|
||||
{
|
||||
/// <summary>客户卖币时可能出手的币(没有相关事件时随机)。</summary>
|
||||
public static readonly string[] SellAssets = { Assets.PSC, Assets.CRT, Assets.CRA };
|
||||
/// <summary>客户买币时可能要的币。</summary>
|
||||
public static readonly string[] BuyAssets = { Assets.PSC, Assets.CRC, Assets.CRT, Assets.CRA, Assets.SPARK };
|
||||
|
||||
public static OtcSide PickSide(Rng rng) => rng.Chance(Tuning.OtcSellShare) ? OtcSide.Sell : OtcSide.Buy;
|
||||
|
||||
/// <summary>和当前事件有关的币(帮派火并、镇压 → CRT;袭击上层、下层动荡 → PSC),没有返回 null。</summary>
|
||||
public static string EventAsset(ICollection<MarketEvent> active, Rng rng)
|
||||
{
|
||||
var c = new List<string>();
|
||||
if (active.Contains(MarketEvent.GangWar) || active.Contains(MarketEvent.Crackdown)) c.Add(Assets.CRT);
|
||||
if (active.Contains(MarketEvent.RevRaidUpper) || active.Contains(MarketEvent.LowerUnrest)) c.Add(Assets.PSC);
|
||||
return c.Count == 0 ? null : c[rng.Range(0, c.Count - 1)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卖币客户的报价。有相关事件时按 OtcEventChance 出手事件里来的币(全额污点);Ponero 兑换处开放时按 OtcPoneroChance 出手 Ponero;
|
||||
/// 否则在 PSC、CRT、CRA 里随机,污点比例在 OtcTaintMin–OtcTaintMax 之间。市值 = 房租 × 区间;现金价 = 市值 × 折扣,折扣按污点比例从 OtcCutClean 线性降到 OtcCutDirty。
|
||||
/// crackdown:镇压期间便衣更多。
|
||||
/// </summary>
|
||||
public static OtcOffer MakeSell(ICollection<MarketEvent> active, bool poneroOpen, Func<string, double> price, double rent, Rng rng)
|
||||
{
|
||||
if (rent <= 0) return null;
|
||||
string asset = null; double ratio;
|
||||
string ev = EventAsset(active, rng);
|
||||
if (ev != null && rng.Chance(Tuning.OtcEventChance)) { asset = ev; ratio = 1; }
|
||||
else if (poneroOpen && rng.Chance(Tuning.OtcPoneroChance)) { asset = Assets.Ponero; ratio = 0; }
|
||||
else { asset = SellAssets[rng.Range(0, SellAssets.Length - 1)]; ratio = rng.Range(Tuning.OtcTaintMin, Tuning.OtcTaintMax); }
|
||||
double p = price(asset);
|
||||
if (p <= 0) return null;
|
||||
double value = rent * rng.Range(Tuning.OtcValueMinRents, Tuning.OtcValueMaxRents);
|
||||
double cut = asset == Assets.Ponero ? rng.Range(Tuning.OtcPoneroCutMin, Tuning.OtcPoneroCutMax) : CutFor(ratio);
|
||||
bool crackdown = active.Contains(MarketEvent.Crackdown);
|
||||
return new OtcOffer
|
||||
{
|
||||
Side = OtcSide.Sell, Asset = asset, Qty = value / p, Value = value, TaintRatio = ratio, Cash = (int)Math.Round(value * cut),
|
||||
Sting = rng.Chance(Tuning.OtcSting + (crackdown ? Tuning.OtcStingCrackdown : 0)),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>现金价占市值的比例:污点比例 0 时 OtcCutClean,1 时 OtcCutDirty,之间线性。</summary>
|
||||
public static double CutFor(double taintRatio) => Tuning.OtcCutClean + (Tuning.OtcCutDirty - Tuning.OtcCutClean) * Math.Max(0, Math.Min(1, taintRatio));
|
||||
|
||||
/// <summary>买币客户的来意:随机一种币,市值 = 房租 × OtcBuyMinRents–OtcBuyMaxRents,出价 = 市值 × (1 + OtcBidMin–OtcBidMax 之间的随机溢价)。</summary>
|
||||
public static OtcOffer MakeBuy(Func<string, double> price, double rent, Rng rng)
|
||||
{
|
||||
if (rent <= 0) return null;
|
||||
string asset = BuyAssets[rng.Range(0, BuyAssets.Length - 1)];
|
||||
double p = price(asset);
|
||||
if (p <= 0) return null;
|
||||
double value = rent * rng.Range(Tuning.OtcBuyMinRents, Tuning.OtcBuyMaxRents);
|
||||
return new OtcOffer { Side = OtcSide.Buy, Asset = asset, Qty = value / p, Value = value, Cash = (int)Math.Round(value * (1 + rng.Range(Tuning.OtcBidMin, Tuning.OtcBidMax))) };
|
||||
}
|
||||
|
||||
/// <summary>只成交 qty(不超过报价的数量):现金、市值按数量比例折算,污点比例和便衣不变。qty 不合法返回 null。</summary>
|
||||
public static OtcOffer Part(OtcOffer o, double qty)
|
||||
{
|
||||
if (o == null || qty <= 0 || o.Qty <= 0) return null;
|
||||
double f = Math.Min(1, qty / o.Qty);
|
||||
return new OtcOffer { Side = o.Side, Asset = o.Asset, Qty = o.Qty * f, Value = o.Value * f, TaintRatio = o.TaintRatio, Cash = (int)Math.Round(o.Cash * f), Sting = o.Sting };
|
||||
}
|
||||
|
||||
/// <summary>收下卖币客户的币:币进钱包,成本是付出的现金;污点 = 市值 × 污点比例(带上限)。返回超出钱包价值、没加进去的污点。</summary>
|
||||
public static double Receive(Wallet w, OtcOffer o, Func<string, double> price)
|
||||
{
|
||||
w.Add(o.Asset, o.Qty);
|
||||
w.Basis += o.Cash;
|
||||
return o.TaintRatio > 0 ? w.AddTaintCapped(o.Value * o.TaintRatio, price) : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户地址的来历(写进链上账本,玩家在浏览器里能查到):1–OtcHistoryMax 笔转入,每一笔按污点比例的概率来自"脏"的来源(混币器、黑市平台、骗局地址),否则来自 Poinbase 或 DEX。
|
||||
/// 返回 (来源地址, 数量占比) 列表;dirty 和 clean 由接入层给出地址。
|
||||
/// </summary>
|
||||
public static List<KeyValuePair<string, double>> History(OtcOffer o, IList<string> dirty, IList<string> clean, Rng rng)
|
||||
{
|
||||
var list = new List<KeyValuePair<string, double>>();
|
||||
int n = rng.Range(1, Tuning.OtcHistoryMax);
|
||||
double left = 1;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
bool isDirty = dirty.Count > 0 && rng.Chance(o.TaintRatio);
|
||||
var src = isDirty ? dirty[rng.Range(0, dirty.Count - 1)] : clean[rng.Range(0, clean.Count - 1)];
|
||||
double share = i == n - 1 ? left : left * rng.Range(0.3, 0.7);
|
||||
left -= share;
|
||||
list.Add(new KeyValuePair<string, double>(src, share));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>自营混币器里一种币:玩家的本金(数量、污点额)和还没取走的手续费收入(取走时全额带污点)。</summary>
|
||||
public sealed class MixPool
|
||||
{
|
||||
public double Capital, CapTaint, Earned;
|
||||
}
|
||||
|
||||
/// <summary>NPC 客户的一笔存入:扣掉手续费后的数量、存入时的污点额(信用点)、轮数、到期日。</summary>
|
||||
public sealed class OwnMixDeposit
|
||||
{
|
||||
public string Asset;
|
||||
public double Amount, Taint;
|
||||
public int Rounds, ReadyDay;
|
||||
}
|
||||
|
||||
/// <summary>一晚发生的事。Kind:deposit(今晚存入合计)/ payout(今晚出款合计,Ratio 是出款剩下的污点比例)/ sting(便衣存入)/ seized(被查封)。</summary>
|
||||
public sealed class OwnMixEvent
|
||||
{
|
||||
public string Kind;
|
||||
public double Value, Ratio, Crime;
|
||||
public int Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自营混币器:玩家注资开张,NPC 客户把带污点的币存进来,几天后出款,玩家收手续费。和普通混币器一样,每一轮按匿名集洗掉一部分污点:
|
||||
/// 匿名集主要是玩家的本金和没取走的收入(客户在途的币按一个比例折算),注资越多洗得越干净,客户越愿意来。
|
||||
/// 手续费是玩家的收入,留在池子里,取走时全额带污点;本金取回时带着它自己的污点(注资用脏币,取回的也脏)。
|
||||
/// 客流 = 基础需求(天) × 黑市声望 × 和 Tumbler 比的吸引力(费率加上出款剩下的污点,近期出款的滑动平均就是口碑)。
|
||||
/// 风声随客流累积(池子越大越难追查,累积得越慢)、每晚衰减,按风声有概率被查封:池子和在途的存入全部没收,记销赃罪证,停业若干天。营业的晚上可能有便衣存入,记销赃罪证。
|
||||
/// 玩家可以随时卷款跑路:池子连同客户的币全部进钱包、全额带污点,记诈骗罪证,混币器永久关闭。
|
||||
/// </summary>
|
||||
public sealed class OwnMixer
|
||||
{
|
||||
public static readonly string[] AssetsList = { Assets.PSC, Assets.CRC, Assets.CRT, Assets.CRA };
|
||||
|
||||
public bool Open;
|
||||
public bool Closed;
|
||||
public int SeizedUntil = -1;
|
||||
public double Fee = Tuning.OwnMixFeeDefault;
|
||||
/// <summary>口碑:近期出款剩下的污点比例(滑动平均),越低越好;开张时按当时的匿名集估。</summary>
|
||||
public double Rating = 1;
|
||||
public double Heat;
|
||||
public Dictionary<string, MixPool> Pools = new Dictionary<string, MixPool>();
|
||||
public List<OwnMixDeposit> Pending = new List<OwnMixDeposit>();
|
||||
/// <summary>累计手续费收入(信用点,按入账时的价格),统计用。</summary>
|
||||
public double FeesTotal;
|
||||
|
||||
public bool Seized(int day) => day <= SeizedUntil;
|
||||
public bool Running(int day) => Open && !Closed && !Seized(day);
|
||||
|
||||
public MixPool Pool(string asset)
|
||||
{
|
||||
if (!Pools.TryGetValue(asset, out var p)) Pools[asset] = p = new MixPool();
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>一种币在池子里的总数:本金、收入、客户在途的币。</summary>
|
||||
public double Total(string asset) => Pool(asset).Capital + Pool(asset).Earned + Pending.Where(x => x.Asset == asset).Sum(x => x.Amount);
|
||||
|
||||
/// <summary>匿名集(信用点):玩家的本金和收入,加上客户在途的币按 OwnMixPendingWeight 折算(主要靠注资撑起来)。</summary>
|
||||
public double Anonymity(Func<string, double> price) => AssetsList.Sum(a => (Free(a) + Tuning.OwnMixPendingWeight * Pending.Where(x => x.Asset == a).Sum(x => x.Amount)) * price(a));
|
||||
|
||||
/// <summary>每一轮洗掉的污点比例:基准清洗率 × 匿名集 / (匿名集 + OwnMixAnon0)。</summary>
|
||||
public static double RoundRate(double anonymity) => Tuning.MixerCleanRate * anonymity / (anonymity + Tuning.OwnMixAnon0);
|
||||
|
||||
/// <summary>按平均轮数出款时剩下的污点比例。</summary>
|
||||
public static double Remain(double rate) => Math.Pow(1 - rate, Tuning.OwnMixAvgRounds);
|
||||
|
||||
/// <summary>玩家能取走的:本金加收入(客户在途的币不能动)。</summary>
|
||||
public double Free(string asset) => Pool(asset).Capital + Pool(asset).Earned;
|
||||
|
||||
/// <summary>开张(或停业后重新开张):口碑按现在的匿名集估。</summary>
|
||||
public void Start(Func<string, double> price)
|
||||
{
|
||||
Open = true;
|
||||
Rating = Remain(RoundRate(Anonymity(price)));
|
||||
}
|
||||
|
||||
/// <summary>注资:币从钱包进本金,污点按价值比例随币走。</summary>
|
||||
public bool Inject(Wallet w, string asset, double amount, Func<string, double> price)
|
||||
{
|
||||
if (amount <= 0 || w.Avail(asset) + 1e-9 < amount || !AssetsList.Contains(asset)) return false;
|
||||
double total = w.Value(price), share = total > 0 ? Math.Min(1, amount * price(asset) / total) : 0;
|
||||
double taint = w.Taint * share, basis = w.Basis * share;
|
||||
w.Add(asset, -amount); w.Taint -= taint; w.Basis -= basis;
|
||||
var p = Pool(asset);
|
||||
p.Capital += amount; p.CapTaint += taint;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>取回:不超过 <see cref="Free"/>。先取手续费收入(全额带污点),再取本金(按本金的污点比例)。over 是超出钱包价值、没加进去的污点。</summary>
|
||||
public bool Withdraw(Wallet w, string asset, double amount, Func<string, double> price, out double over)
|
||||
{
|
||||
over = 0;
|
||||
var p = Pool(asset);
|
||||
if (amount <= 0 || amount > Free(asset) + 1e-9) return false;
|
||||
double fromFees = Math.Min(amount, p.Earned), fromCap = Math.Min(p.Capital, amount - fromFees);
|
||||
double capTaint = p.Capital > 1e-12 ? p.CapTaint * fromCap / p.Capital : 0;
|
||||
p.Earned -= fromFees; p.Capital -= fromCap; p.CapTaint -= capTaint;
|
||||
w.Add(asset, fromFees + fromCap);
|
||||
over = w.AddTaintCapped(fromFees * price(asset) + capTaint, price);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>卷款跑路:本金、收入和客户在途的币全部进钱包、全额带污点,永久关闭。返回 (币种, 数量);over 是超出钱包价值的污点。</summary>
|
||||
public List<KeyValuePair<string, double>> Rug(Wallet w, Func<string, double> price, out double over)
|
||||
{
|
||||
over = 0;
|
||||
var got = new List<KeyValuePair<string, double>>();
|
||||
foreach (var a in AssetsList)
|
||||
{
|
||||
double amt = Total(a);
|
||||
if (amt <= 1e-9) continue;
|
||||
w.Add(a, amt);
|
||||
over += w.AddTaintCapped(amt * price(a), price);
|
||||
got.Add(new KeyValuePair<string, double>(a, amt));
|
||||
}
|
||||
Pools.Clear(); Pending.Clear();
|
||||
Open = false; Closed = true;
|
||||
return got;
|
||||
}
|
||||
|
||||
/// <summary>今晚的基础需求(信用点):随天数增长。</summary>
|
||||
public static double Demand(int day) => Tuning.OwnMixDemand0 + Tuning.OwnMixDemandPerDay * day;
|
||||
|
||||
/// <summary>
|
||||
/// 和 Tumbler 的混币器比,分到的客流(0–1):客户的成本 = 费率 + 出款剩下的污点比例 × OwnMixTaintWeight,比对手便宜就多分。
|
||||
/// rivalRemain 是对手出款剩下的污点比例;对手关停时客户的另一条路是不混(成本再加 OwnMixRivalGone)。
|
||||
/// </summary>
|
||||
public double Share(double rivalFee, double rivalRemain, bool rivalOpen)
|
||||
{
|
||||
double mine = Fee + Rating * Tuning.OwnMixTaintWeight;
|
||||
double rival = rivalFee + rivalRemain * Tuning.OwnMixTaintWeight + (rivalOpen ? 0 : Tuning.OwnMixRivalGone);
|
||||
return 1 / (1 + Math.Exp((mine - rival) / Tuning.OwnMixFeeScale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 夜间:到期的存入出款(按匿名集洗掉污点),口碑跟着出款走;营业中接新的存入;风声累积、按风声查封。
|
||||
/// bmRep:黑市声望(0–100);rivalFee、rivalRemain、rivalOpen:Tumbler 混币器的费率、出款剩下的污点比例、是否在营业;enforce:剧情带来的执法倍数;crackdown:镇压期间。
|
||||
/// </summary>
|
||||
public List<OwnMixEvent> Night(int day, Func<string, double> price, int bmRep, double rivalFee, double rivalRemain, bool rivalOpen, double enforce, bool crackdown, Rng rng)
|
||||
{
|
||||
var evs = new List<OwnMixEvent>();
|
||||
if (Closed || Seized(day)) return evs;
|
||||
|
||||
// 出款(客户的币回到客户手里,污点按匿名集洗掉一部分)
|
||||
double rate = RoundRate(Anonymity(price));
|
||||
double paid = 0; int paidN = 0;
|
||||
foreach (var dep in Pending.Where(x => x.ReadyDay <= day).ToList())
|
||||
{
|
||||
Pending.Remove(dep);
|
||||
paid += dep.Amount * price(dep.Asset);
|
||||
paidN++;
|
||||
}
|
||||
if (paidN > 0)
|
||||
{
|
||||
double remain = Remain(rate);
|
||||
Rating += Tuning.OwnMixRatingSpeed * (remain - Rating);
|
||||
evs.Add(new OwnMixEvent { Kind = "payout", Value = paid, Ratio = remain, Count = paidN });
|
||||
}
|
||||
|
||||
// 存入
|
||||
double inValue = 0; int n = 0;
|
||||
if (Open)
|
||||
{
|
||||
double repF = Tuning.OwnMixRepMin + (1 - Tuning.OwnMixRepMin) * Math.Max(0, Math.Min(100, bmRep)) / 100.0;
|
||||
double demand = Demand(day) * repF * Share(rivalFee, rivalRemain, rivalOpen);
|
||||
double left = demand * rng.Range(1 - Tuning.OwnMixNoise, 1 + Tuning.OwnMixNoise);
|
||||
while (left > Tuning.MixerMin)
|
||||
{
|
||||
double v = Math.Min(left, Tuning.OwnMixTicket * rng.Range(0.5, 1.5));
|
||||
left -= v;
|
||||
string asset = Pick(rng);
|
||||
double px = price(asset);
|
||||
if (px <= 0) continue;
|
||||
double amt = v / px;
|
||||
Pool(asset).Earned += amt * Fee;
|
||||
FeesTotal += v * Fee;
|
||||
int rounds = rng.Range(1, Tuning.MixerMaxRounds);
|
||||
Pending.Add(new OwnMixDeposit { Asset = asset, Amount = amt * (1 - Fee), Taint = v * rng.Range(Tuning.OwnMixInTaintMin, Tuning.OwnMixInTaintMax), Rounds = rounds, ReadyDay = day + rounds });
|
||||
inValue += v; n++;
|
||||
}
|
||||
if (n > 0)
|
||||
{
|
||||
evs.Add(new OwnMixEvent { Kind = "deposit", Value = inValue, Count = n });
|
||||
// 便衣:营业的晚上按概率有一笔存入来自治安部
|
||||
if (rng.Chance(Tuning.OwnMixSting))
|
||||
{
|
||||
double v = inValue / n;
|
||||
evs.Add(new OwnMixEvent { Kind = "sting", Value = v, Crime = Math.Min(Tuning.CrimeEventCap, v * Tuning.OwnMixStingCrime) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 风声与查封
|
||||
// 池子越大,客户的币越好藏,同样的客流引起的风声越小
|
||||
Heat = Heat * Tuning.OwnMixHeatKeep + inValue / Tuning.OwnMixHeatScale / (1 + Anonymity(price) / Tuning.OwnMixHeatAnon0);
|
||||
if (rng.Chance(SeizeChance(enforce, crackdown)))
|
||||
{
|
||||
double lost = AssetsList.Sum(a => Total(a) * price(a));
|
||||
evs.Add(new OwnMixEvent { Kind = "seized", Value = lost, Crime = Math.Min(Tuning.CrimeEventCap, lost * Tuning.OwnMixSeizeCrime) });
|
||||
Pools.Clear(); Pending.Clear();
|
||||
SeizedUntil = day + Tuning.OwnMixSeizeDays;
|
||||
Heat = 0; Open = false;
|
||||
}
|
||||
return evs;
|
||||
}
|
||||
|
||||
/// <summary>今晚被查封的概率:风声 × 系数 × 执法倍数(镇压期间再乘),封顶。</summary>
|
||||
public double SeizeChance(double enforce, bool crackdown) => Math.Min(Tuning.OwnMixSeizeMax, Tuning.OwnMixSeizeRate * Heat * enforce * (crackdown ? Tuning.OwnMixSeizeCrackdown : 1));
|
||||
|
||||
/// <summary>风声的三档提示:0 低、1 中、2 高(按今晚的查封概率)。</summary>
|
||||
public int HeatLevel(double enforce) { double s = SeizeChance(enforce, false); return s < Tuning.OwnMixHeatMid ? 0 : s < Tuning.OwnMixHeatHigh ? 1 : 2; }
|
||||
|
||||
private static string Pick(Rng rng)
|
||||
{
|
||||
double r = rng.NextDouble() * Tuning.OwnMixAssetWeights.Sum();
|
||||
for (int i = 0; i < AssetsList.Length; i++) { r -= Tuning.OwnMixAssetWeights[i]; if (r <= 0) return AssetsList[i]; }
|
||||
return AssetsList[AssetsList.Length - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,12 +113,13 @@ namespace Decentralized.Domain
|
||||
public bool Held;
|
||||
}
|
||||
|
||||
/// <summary>夜间结算发生的事。Kind:win / lose / void / caught。</summary>
|
||||
/// <summary>夜间结算发生的事。Kind:win / lose / void / insider(内幕份额记了污点)/ manip(被判操纵,整笔兑付记了污点)。
|
||||
/// Amount 是兑付或本金;Taint 是实际加上的污点,Over 是超出钱包价值、折成罪证的部分,Fraud 是罪证。</summary>
|
||||
public sealed class PredictEvent
|
||||
{
|
||||
public string Kind, Title;
|
||||
public PredictMarket Market;
|
||||
public double Amount, Fraud;
|
||||
public double Amount, Taint, Over, Fraud;
|
||||
}
|
||||
|
||||
/// <summary>候选盘口(接入层按游戏当前状态给出):先验概率按窗口算。</summary>
|
||||
@@ -181,29 +182,24 @@ namespace Decentralized.Domain
|
||||
}
|
||||
|
||||
/// <summary>全部卖出这个钱包在盘口里的持仓(盘口关闭前):收回 LMSR 的卖价减手续费,污点按比例退回,赚的部分是干净的。返回收回的 CRC。</summary>
|
||||
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, out double got) => SellAll(acct, m, day, null, out got, out _);
|
||||
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, Func<string, double> price, out double got) => SellAll(acct, m, day, price, out got, out _, out _);
|
||||
|
||||
/// <summary>
|
||||
/// 全部卖出;内幕持仓(这个盘口合计)达到查处线、而且卖出有赚,按查处概率被查:本金和收益全部没收,收益的一半记罪证(fraud > 0)。
|
||||
/// 先买后卖、赶在结算前离场,同样会被查。
|
||||
/// 全部卖出;持仓里的内幕份额(下单时已经知道答案)对应的那部分卖出所得记污点(带上限,见 <see cref="Wallet.AddTaintCapped"/>),
|
||||
/// taint 是实际加上的污点,over 是超出钱包价值、没加进去的部分(由调用方按 <see cref="Wallet.OverflowFraud"/> 折成罪证)。先买后卖、赶在结算前离场也一样。
|
||||
/// </summary>
|
||||
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, Rng rng, out double got, out double fraud)
|
||||
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, Func<string, double> price, out double got, out double taint, out double over)
|
||||
{
|
||||
got = 0; fraud = 0;
|
||||
got = 0; taint = 0; over = 0;
|
||||
var pos = PosOf(m.Id, acct.Address);
|
||||
if (pos == null) return PredictResult.NoPosition;
|
||||
if (!m.IsOpen(day)) return PredictResult.Closed;
|
||||
double value = m.SellValue(pos.Yes, pos.Shares);
|
||||
got = value * (1 - Tuning.PredictFee);
|
||||
bool insider = PosAll(m.Id).Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap;
|
||||
if (pos.Yes) m.QYes -= pos.Shares; else m.QNo -= pos.Shares;
|
||||
Positions.Remove(pos);
|
||||
if (rng != null && insider && pos.Insider > 0 && got > pos.Cost && rng.Chance(Math.Min(1, Tuning.PredictInsiderCatch * StoryMods.Current.Enforce(day))))
|
||||
{
|
||||
fraud = Math.Min(Tuning.PredictFraudCap, (got - pos.Cost) * Tuning.PredictFraudShare);
|
||||
got = 0;
|
||||
}
|
||||
Pay(acct, pos, got);
|
||||
over = MarkInsider(acct, pos, got, price, out taint);
|
||||
return PredictResult.Ok;
|
||||
}
|
||||
|
||||
@@ -213,11 +209,22 @@ namespace Decentralized.Domain
|
||||
acct.Add(Assets.CRC, payout); acct.Taint += pos.Taint * keep; acct.Basis += pos.Basis * keep;
|
||||
}
|
||||
|
||||
/// <summary>内幕份额对应的兑付记污点(带上限)。taint 是实际加上的污点,返回超出钱包价值、没加进去的部分。</summary>
|
||||
private static double MarkInsider(Wallet acct, PredictPos pos, double payout, Func<string, double> price, out double taint)
|
||||
{
|
||||
taint = 0;
|
||||
if (pos.Insider <= 0 || pos.Shares <= 0 || payout <= 0) return 0;
|
||||
double amount = payout * Math.Min(1, pos.Insider / pos.Shares);
|
||||
double over = acct.AddTaintCapped(amount, price);
|
||||
taint = amount - over;
|
||||
return over;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 夜间:先登记今晚的观测,再结算 ToDay 到了的盘口(赢的钱回到下注的钱包,wallet 按地址找)。outcome 由接入层给出(事件 / 派系读观测,纯度和行情读游戏数值),null 表示拿不到数据。
|
||||
/// 赢家每份兑付 1 信用点;内幕持仓达到份额上限的 <see cref="Tuning.PredictInsiderShare"/> 后,有概率被查:本金和收益全部没收,收益的一半记罪证。
|
||||
/// 赢家每份兑付 1 信用点,照常兑付;内幕份额对应的兑付记污点,行情盘被判操纵时整笔兑付记污点(都带上限,超出钱包价值的部分折成罪证)。
|
||||
/// </summary>
|
||||
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng, double push = 0)
|
||||
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Func<string, double> price, Rng rng, double push = 0)
|
||||
{
|
||||
var now = activeNow.Distinct().ToList();
|
||||
if (Prev != null) Started[day] = now.Where(x => !Prev.Contains(x)).ToList();
|
||||
@@ -243,14 +250,6 @@ namespace Decentralized.Domain
|
||||
if (!Stats.TryGetValue(sk, out var st)) Stats[sk] = st = new PredictStat();
|
||||
st.Count++; st.SumP0 += m.P0; if (res.Value) st.Hits++;
|
||||
var winners = all.Where(x => x.Yes == res.Value).ToList();
|
||||
// 操纵:行情盘上,赢家的方向和玩家推价的方向一致时按推价幅度被查——本金和收益都没收,收益的一半记罪证
|
||||
if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Math.Min(1, Market.ManipChance(push) * StoryMods.Current.Enforce(day))))
|
||||
{
|
||||
double profitM = winners.Sum(x => x.Shares) - cost;
|
||||
evs.Add(new PredictEvent { Kind = "manip", Title = m.Title, Market = m, Amount = cost, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profitM) * Tuning.PredictFraudShare) });
|
||||
Record(day, m, m.Outcome, -cost, true);
|
||||
continue;
|
||||
}
|
||||
if (all.Count > 0 && winners.Count == 0)
|
||||
{
|
||||
evs.Add(new PredictEvent { Kind = "lose", Title = m.Title, Market = m, Amount = cost });
|
||||
@@ -259,19 +258,28 @@ namespace Decentralized.Domain
|
||||
else if (winners.Count > 0)
|
||||
{
|
||||
double payout = winners.Sum(x => x.Shares), profit = payout - cost;
|
||||
// 内幕持仓按盘口合计(拆到几个钱包里也一样)
|
||||
if (all.Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap && rng.Chance(Math.Min(1, Tuning.PredictInsiderCatch * StoryMods.Current.Enforce(day))))
|
||||
// 操纵:行情盘上,赢家的方向和玩家推价的方向一致时按推价幅度被查——照常兑付,整笔兑付记污点
|
||||
bool manip = m.Kind == PredictKind.Price && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Math.Min(1, Market.ManipChance(push) * StoryMods.Current.Enforce(day)));
|
||||
double taint = 0, over = 0;
|
||||
foreach (var pos in winners)
|
||||
{
|
||||
// 查实:本金和收益全部没收
|
||||
evs.Add(new PredictEvent { Kind = "caught", Title = m.Title, Market = m, Amount = payout, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profit) * Tuning.PredictFraudShare) });
|
||||
Record(day, m, m.Outcome, -cost, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pos in winners) Pay(wallet(pos.Wallet), pos, pos.Shares);
|
||||
evs.Add(new PredictEvent { Kind = "win", Title = m.Title, Market = m, Amount = payout });
|
||||
Record(day, m, m.Outcome, profit, true);
|
||||
var w = wallet(pos.Wallet);
|
||||
Pay(w, pos, pos.Shares);
|
||||
if (manip)
|
||||
{
|
||||
double o = w.AddTaintCapped(pos.Shares, price);
|
||||
taint += pos.Shares - o; over += o;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 内幕份额(下单时已经知道答案)对应的兑付记污点,每个钱包各算各的
|
||||
over += MarkInsider(w, pos, pos.Shares, price, out double t);
|
||||
taint += t;
|
||||
}
|
||||
}
|
||||
string kind = manip ? "manip" : taint + over > 1e-9 ? "insider" : "win";
|
||||
evs.Add(new PredictEvent { Kind = kind, Title = m.Title, Market = m, Amount = payout, Taint = taint, Over = over, Fraud = Wallet.OverflowFraud(over) });
|
||||
Record(day, m, m.Outcome, profit, true);
|
||||
}
|
||||
else Record(day, m, m.Outcome, 0, false);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ namespace Decentralized.Domain
|
||||
|
||||
// 挖矿
|
||||
public const double PscStartPrice = 100;
|
||||
public const double BlockReward = 100;
|
||||
/// <summary>第十一阶段把出块奖励和 NPC 初始算力同乘的倍数(100 → 1000、360 → 3600);读旧存档时按它放大全网。</summary>
|
||||
public const double MiningScale = 10;
|
||||
public const double BlockReward = 1000;
|
||||
public const int HalvingDays = 90;
|
||||
/// <summary>减半对币价的传导:每次减半在区间内随机一个指数,价格锚上移 2^指数 倍(0.15–0.85 即约 +11% 到 +80%)。
|
||||
/// 参考比特币:每次减半后的涨幅差别很大,市场也已部分预期到,所以既不固定也不翻倍。</summary>
|
||||
@@ -20,15 +22,15 @@ namespace Decentralized.Domain
|
||||
public const double HalvingRamp = 0.08;
|
||||
/// <summary>价格锚向目标的逐晚靠拢比例(约 7 天完成大半)。</summary>
|
||||
public const double SupplyAdjust = 0.15;
|
||||
public const double NpcHash0 = 360;
|
||||
public const double NpcHash0 = 3600;
|
||||
public const double NpcKjPerH = 2.4;
|
||||
public const double ElecPrice = 1.5;
|
||||
public const double NpcTargetRatio = 3.5;
|
||||
public const double NpcAdj = 0.05;
|
||||
public const double PoolFee = 0.03;
|
||||
public const int RigPrice = 400, RigKj = 2;
|
||||
/// <summary>矿架上模块百分比的折算系数(原版机器用 2–4),以及各项上限。</summary>
|
||||
public const double ModuleRatio = 4, ModuleHashCap = 0.20, ModuleKjCap = 0.25, ModuleWearCap = 0.30;
|
||||
/// <summary>矿架上模块百分比的折算系数(原版机器用 2–4)。模块效果不设上限,只有防出错的下限:算力、耗电、每日损耗三个乘数各自不低于下面的值。</summary>
|
||||
public const double ModuleRatio = 4, ModuleHashFloor = 0, ModuleKjFloor = 0.2, ModuleWearFloor = 0;
|
||||
public const double DeathBase = 0.001, DeathWorn = 0.03, FakeDeathFactor = 2;
|
||||
public const double RefurbishHealth = 30;
|
||||
|
||||
@@ -244,14 +246,14 @@ namespace Decentralized.Domain
|
||||
public const double EraKjMult = 0.5;
|
||||
|
||||
/// <summary>预测市场:游戏第几天起开放;手续费;单盘额度 = 基础 + 每天增量 × 天数;所有钱包在单盘合计的份额上限(额度的倍数);
|
||||
/// 同时开放的盘口数量范围、每天最多新开几个;内幕持仓达到上限份额的多少比例后结算被查的概率,查实后收益记罪证的比例与上限;
|
||||
/// 同时开放的盘口数量范围、每天最多新开几个;污点超出钱包价值的部分折成诈骗罪证的比例与单次上限(内幕、操纵记污点时通用);
|
||||
/// 派系行动的日均开始概率(先验);先验概率的夹紧范围;结算记录保留条数。</summary>
|
||||
public const int PredictUnlockDay = 8;
|
||||
public const double PredictFee = 0.01, PredictLoss0 = 800, PredictLossPerDay = 25, PredictCap = 2;
|
||||
/// <summary>预测盘的流动性:LMSR 的 b = 倍数 × 单盘额度 / ln 2,与先验无关(低先验盘不再更浅)。单盘额度只决定份额上限和消息价。</summary>
|
||||
public const double PredictDepth = 1.8;
|
||||
public const int PredictOpenMin = 3, PredictOpenMax = 6, PredictNewPerDay = 2;
|
||||
public const double PredictInsiderShare = 0.4, PredictInsiderCatch = 0.7, PredictFraudShare = 0.5, PredictFraudCap = 400;
|
||||
public const double PredictFraudShare = 0.5, PredictFraudCap = 400;
|
||||
public const double PredictFactionDaily = 0.06, PredictPMin = 0.03, PredictPMax = 0.97;
|
||||
public const int PredictHistory = 8;
|
||||
/// <summary>gas 盘的公开价里"不知道相位"的权重:越大,数清七天周期的玩家越赚。金融审查(agy_fin/subsim)发现 0.5 时 gas 盘胜率 96%、每周净赚约 1,400,调到 0.15。</summary>
|
||||
@@ -265,9 +267,8 @@ namespace Decentralized.Domain
|
||||
public static readonly double[] IntelTipPrice = { 0.02, 0.05, 0.12 }, IntelTipAcc = { 0.60, 0.80, 0.95 };
|
||||
public const int IntelRep = 20;
|
||||
/// <summary>操纵检出:玩家自己的大单把价格推离"没有你时的水平"的对数幅度(取绝对值)低于 ManipFree 不查;
|
||||
/// 超过后被查概率 = ManipBase + ManipSlope × (幅度 − ManipFree),封顶 ManipMax;被查后永续账户冻结几天。</summary>
|
||||
/// 超过后被查概率 = ManipBase + ManipSlope × (幅度 − ManipFree),封顶 ManipMax;被查后照常兑付,赚到的钱记污点。</summary>
|
||||
public const double ManipFree = 0.16, ManipBase = 0.25, ManipSlope = 3, ManipMax = 0.95;
|
||||
public const int ManipFreezeDays = 3;
|
||||
|
||||
/// <summary>高息理财(庞氏):第几天起开放、开张的宣传费(CRC)、可选日息、每晚新存入的基数(随天数)和对日息的敏感指数、
|
||||
/// 池子上限(随天数)、每晚被取走的比例、每晚被举报概率(基础 + 日息系数 + 池子占上限的比例系数)、卷走或崩盘时记的罪证。</summary>
|
||||
@@ -290,10 +291,35 @@ namespace Decentralized.Domain
|
||||
public const double YieldPoolChance = 0.25, YieldRugNightly = 0.18, YieldCap0 = 4000, YieldCapPerDay = 120, YieldReserveDays = 25;
|
||||
public static readonly double[] YieldRates = { 0.01, 0.02, 0.03 }, YieldScamByRate = { 0.15, 0.40, 0.75 };
|
||||
public const double YieldScamTimelock = 0.25, YieldScamAudit = 0.20;
|
||||
/// <summary>收黑币:相关事件期间每天有人上门的概率(PSC、CRT),Ponero 兑换处开放后每天的概率;币的市值(房租的倍数);
|
||||
/// 现金要价占市值的比例(PSC、CRT 与 Ponero 分开);钓鱼执法的概率与镇压期间的加成。</summary>
|
||||
public const double HotEventChance = 0.35, HotPoneroChance = 0.05, HotValueMinRents = 4, HotValueMaxRents = 15;
|
||||
public const double HotCutMin = 0.45, HotCutMax = 0.60, HotPoneroCutMin = 0.70, HotPoneroCutMax = 0.80, HotSting = 0.05, HotStingCrackdown = 0.10;
|
||||
/// <summary>换币客户(场外换币台):人脉升级价格;来卖币的比例(其余来买币)。</summary>
|
||||
public const int OtcUnlockPrice = 500;
|
||||
public const double OtcSellShare = 0.5;
|
||||
/// <summary>卖币客户:有相关事件时出手事件里来的币(全额污点)的概率,Ponero 兑换处开放后出手 Ponero 的概率;币的市值(房租的倍数);
|
||||
/// 其他币的污点比例范围;现金价占市值的比例(污点比例 0 时、1 时,之间线性;Ponero 单独一档);便衣的概率与镇压期间的加成;客户地址来历的最多笔数。</summary>
|
||||
public const double OtcEventChance = 0.7, OtcPoneroChance = 0.15, OtcValueMinRents = 4, OtcValueMaxRents = 15;
|
||||
public const double OtcTaintMin = 0.2, OtcTaintMax = 0.9, OtcCutClean = 0.80, OtcCutDirty = 0.45, OtcPoneroCutMin = 0.70, OtcPoneroCutMax = 0.80;
|
||||
public const double OtcSting = 0.05, OtcStingCrackdown = 0.10;
|
||||
public const int OtcHistoryMax = 3;
|
||||
/// <summary>买币客户:要买的币的市值(房租的倍数);出价相对市价的随机溢价范围(可能低于市价,成不成交由玩家决定)。</summary>
|
||||
public const double OtcBuyMinRents = 2, OtcBuyMaxRents = 8;
|
||||
public const double OtcBidMin = -0.05, OtcBidMax = 0.30;
|
||||
/// <summary>
|
||||
/// 自营混币器(买下场外换币台就开放):默认费率、可选费率;口碑(近期出款剩下的污点比例)跟出款走的速度、客户把剩下的污点比例折成费率的权重、Tumbler 关停时客户不混的额外成本、匿名集的半饱和值(每轮清洗率 = 基准 × 匿名集 /(匿名集 + 它))、平均轮数、客户在途的币计入匿名集的比例;
|
||||
/// 基础需求(信用点,随天数增长)、黑市声望 0 时的需求系数、客流对成本差的灵敏度、每晚需求的随机幅度、单笔存入的平均额;
|
||||
/// 客户存入的币的污点比例范围;各币种的需求权重(PSC、CRC、CRT、CRA);营业时每晚有便衣存入的概率和记罪证的比例(按一笔存入的额);
|
||||
/// 风声每晚保留的比例和累积的标度、池子越大越难追查的半值(风声累积 = 存入 / 标度 / (1 + 匿名集 / 它))、按风声的查封概率系数与上限、镇压期间的倍数、查封记罪证的比例、停业天数、风声提示的两档界线;卷款跑路记的诈骗罪证和黑市声望损失。
|
||||
/// </summary>
|
||||
public const double OwnMixFeeDefault = 0.03;
|
||||
public static readonly double[] OwnMixFees = { 0.01, 0.02, 0.03, 0.05, 0.08, 0.12 };
|
||||
public const double OwnMixRatingSpeed = 0.2, OwnMixTaintWeight = 0.1, OwnMixRivalGone = 0.03, OwnMixAnon0 = 20000, OwnMixAvgRounds = 3, OwnMixPendingWeight = 0.25;
|
||||
public const double OwnMixDemand0 = 40000, OwnMixDemandPerDay = 1400, OwnMixRepMin = 0.3, OwnMixFeeScale = 0.015, OwnMixNoise = 0.3, OwnMixTicket = 800;
|
||||
public const double OwnMixInTaintMin = 0.4, OwnMixInTaintMax = 1.0;
|
||||
public static readonly double[] OwnMixAssetWeights = { 0.3, 0.1, 0.4, 0.2 };
|
||||
public const double OwnMixSting = 0.03, OwnMixStingCrime = 0.1;
|
||||
public const double OwnMixHeatKeep = 0.9, OwnMixHeatScale = 100000, OwnMixHeatAnon0 = 160000, OwnMixSeizeRate = 0.002, OwnMixSeizeMax = 0.5, OwnMixSeizeCrackdown = 2, OwnMixSeizeCrime = 0.01, OwnMixHeatMid = 0.01, OwnMixHeatHigh = 0.03;
|
||||
public const int OwnMixSeizeDays = 7, OwnMixRugRep = 25;
|
||||
public const double OwnMixRugCrime = 400;
|
||||
|
||||
/// <summary>假客服:每天上门的概率;伪造转账:用币付款的顾客里是骗子的比例;两者都从第几天起。</summary>
|
||||
public const double FakeSupportChance = 0.04, FakeTransferShare = 0.08;
|
||||
public const int ScamMinDay = 10;
|
||||
|
||||
@@ -249,16 +249,6 @@ namespace Decentralized.Domain
|
||||
["HalvingPassMin"] = Tuning.HalvingPassMin,
|
||||
["HalvingRamp"] = Tuning.HalvingRamp,
|
||||
["HalvingRampDays"] = Tuning.HalvingRampDays,
|
||||
["HotCutMax"] = Tuning.HotCutMax,
|
||||
["HotCutMin"] = Tuning.HotCutMin,
|
||||
["HotEventChance"] = Tuning.HotEventChance,
|
||||
["HotPoneroChance"] = Tuning.HotPoneroChance,
|
||||
["HotPoneroCutMax"] = Tuning.HotPoneroCutMax,
|
||||
["HotPoneroCutMin"] = Tuning.HotPoneroCutMin,
|
||||
["HotSting"] = Tuning.HotSting,
|
||||
["HotStingCrackdown"] = Tuning.HotStingCrackdown,
|
||||
["HotValueMaxRents"] = Tuning.HotValueMaxRents,
|
||||
["HotValueMinRents"] = Tuning.HotValueMinRents,
|
||||
["IntelBriefPrice"] = Tuning.IntelBriefPrice,
|
||||
["IntelFake"] = Tuning.IntelFake,
|
||||
["IntelRep"] = Tuning.IntelRep,
|
||||
@@ -266,9 +256,9 @@ namespace Decentralized.Domain
|
||||
["LedgerShow"] = Tuning.LedgerShow,
|
||||
["ManipBase"] = Tuning.ManipBase,
|
||||
["ManipFree"] = Tuning.ManipFree,
|
||||
["ManipFreezeDays"] = Tuning.ManipFreezeDays,
|
||||
["ManipMax"] = Tuning.ManipMax,
|
||||
["ManipSlope"] = Tuning.ManipSlope,
|
||||
["MiningScale"] = Tuning.MiningScale,
|
||||
["MixerCleanRate"] = Tuning.MixerCleanRate,
|
||||
["MixerFee"] = Tuning.MixerFee,
|
||||
["MixerMaxRounds"] = Tuning.MixerMaxRounds,
|
||||
@@ -278,14 +268,62 @@ namespace Decentralized.Domain
|
||||
["MixerSanctionChance"] = Tuning.MixerSanctionChance,
|
||||
["MixerSanctionDays"] = Tuning.MixerSanctionDays,
|
||||
["MixerUnlockPrice"] = Tuning.MixerUnlockPrice,
|
||||
["ModuleHashCap"] = Tuning.ModuleHashCap,
|
||||
["ModuleKjCap"] = Tuning.ModuleKjCap,
|
||||
["ModuleHashFloor"] = Tuning.ModuleHashFloor,
|
||||
["ModuleKjFloor"] = Tuning.ModuleKjFloor,
|
||||
["ModuleRatio"] = Tuning.ModuleRatio,
|
||||
["ModuleWearCap"] = Tuning.ModuleWearCap,
|
||||
["ModuleWearFloor"] = Tuning.ModuleWearFloor,
|
||||
["NpcAdj"] = Tuning.NpcAdj,
|
||||
["NpcHash0"] = Tuning.NpcHash0,
|
||||
["NpcKjPerH"] = Tuning.NpcKjPerH,
|
||||
["NpcTargetRatio"] = Tuning.NpcTargetRatio,
|
||||
["OtcBidMax"] = Tuning.OtcBidMax,
|
||||
["OtcBidMin"] = Tuning.OtcBidMin,
|
||||
["OtcBuyMaxRents"] = Tuning.OtcBuyMaxRents,
|
||||
["OtcBuyMinRents"] = Tuning.OtcBuyMinRents,
|
||||
["OtcCutClean"] = Tuning.OtcCutClean,
|
||||
["OtcCutDirty"] = Tuning.OtcCutDirty,
|
||||
["OtcEventChance"] = Tuning.OtcEventChance,
|
||||
["OtcHistoryMax"] = Tuning.OtcHistoryMax,
|
||||
["OtcPoneroChance"] = Tuning.OtcPoneroChance,
|
||||
["OtcPoneroCutMax"] = Tuning.OtcPoneroCutMax,
|
||||
["OtcPoneroCutMin"] = Tuning.OtcPoneroCutMin,
|
||||
["OtcSellShare"] = Tuning.OtcSellShare,
|
||||
["OtcSting"] = Tuning.OtcSting,
|
||||
["OtcStingCrackdown"] = Tuning.OtcStingCrackdown,
|
||||
["OtcTaintMax"] = Tuning.OtcTaintMax,
|
||||
["OtcTaintMin"] = Tuning.OtcTaintMin,
|
||||
["OtcUnlockPrice"] = Tuning.OtcUnlockPrice,
|
||||
["OtcValueMaxRents"] = Tuning.OtcValueMaxRents,
|
||||
["OtcValueMinRents"] = Tuning.OtcValueMinRents,
|
||||
["OwnMixAnon0"] = Tuning.OwnMixAnon0,
|
||||
["OwnMixAvgRounds"] = Tuning.OwnMixAvgRounds,
|
||||
["OwnMixDemand0"] = Tuning.OwnMixDemand0,
|
||||
["OwnMixDemandPerDay"] = Tuning.OwnMixDemandPerDay,
|
||||
["OwnMixFeeDefault"] = Tuning.OwnMixFeeDefault,
|
||||
["OwnMixFeeScale"] = Tuning.OwnMixFeeScale,
|
||||
["OwnMixHeatAnon0"] = Tuning.OwnMixHeatAnon0,
|
||||
["OwnMixHeatHigh"] = Tuning.OwnMixHeatHigh,
|
||||
["OwnMixHeatKeep"] = Tuning.OwnMixHeatKeep,
|
||||
["OwnMixHeatMid"] = Tuning.OwnMixHeatMid,
|
||||
["OwnMixHeatScale"] = Tuning.OwnMixHeatScale,
|
||||
["OwnMixInTaintMax"] = Tuning.OwnMixInTaintMax,
|
||||
["OwnMixInTaintMin"] = Tuning.OwnMixInTaintMin,
|
||||
["OwnMixNoise"] = Tuning.OwnMixNoise,
|
||||
["OwnMixPendingWeight"] = Tuning.OwnMixPendingWeight,
|
||||
["OwnMixRatingSpeed"] = Tuning.OwnMixRatingSpeed,
|
||||
["OwnMixRepMin"] = Tuning.OwnMixRepMin,
|
||||
["OwnMixRivalGone"] = Tuning.OwnMixRivalGone,
|
||||
["OwnMixRugCrime"] = Tuning.OwnMixRugCrime,
|
||||
["OwnMixRugRep"] = Tuning.OwnMixRugRep,
|
||||
["OwnMixSeizeCrackdown"] = Tuning.OwnMixSeizeCrackdown,
|
||||
["OwnMixSeizeCrime"] = Tuning.OwnMixSeizeCrime,
|
||||
["OwnMixSeizeDays"] = Tuning.OwnMixSeizeDays,
|
||||
["OwnMixSeizeMax"] = Tuning.OwnMixSeizeMax,
|
||||
["OwnMixSeizeRate"] = Tuning.OwnMixSeizeRate,
|
||||
["OwnMixSting"] = Tuning.OwnMixSting,
|
||||
["OwnMixStingCrime"] = Tuning.OwnMixStingCrime,
|
||||
["OwnMixTaintWeight"] = Tuning.OwnMixTaintWeight,
|
||||
["OwnMixTicket"] = Tuning.OwnMixTicket,
|
||||
["PerpAdlHaircut"] = Tuning.PerpAdlHaircut,
|
||||
["PerpBanDays"] = Tuning.PerpBanDays,
|
||||
["PerpDebtDays"] = Tuning.PerpDebtDays,
|
||||
@@ -342,8 +380,6 @@ namespace Decentralized.Domain
|
||||
["PredictFraudShare"] = Tuning.PredictFraudShare,
|
||||
["PredictGasBlind"] = Tuning.PredictGasBlind,
|
||||
["PredictHistory"] = Tuning.PredictHistory,
|
||||
["PredictInsiderCatch"] = Tuning.PredictInsiderCatch,
|
||||
["PredictInsiderShare"] = Tuning.PredictInsiderShare,
|
||||
["PredictLoss0"] = Tuning.PredictLoss0,
|
||||
["PredictLossPerDay"] = Tuning.PredictLossPerDay,
|
||||
["PredictMoveLog"] = Tuning.PredictMoveLog,
|
||||
@@ -483,6 +519,8 @@ namespace Decentralized.Domain
|
||||
["CraSpiralPath"] = Array.ConvertAll(Tuning.CraSpiralPath, v => (double)v),
|
||||
["IntelTipAcc"] = Array.ConvertAll(Tuning.IntelTipAcc, v => (double)v),
|
||||
["IntelTipPrice"] = Array.ConvertAll(Tuning.IntelTipPrice, v => (double)v),
|
||||
["OwnMixAssetWeights"] = Array.ConvertAll(Tuning.OwnMixAssetWeights, v => (double)v),
|
||||
["OwnMixFees"] = Array.ConvertAll(Tuning.OwnMixFees, v => (double)v),
|
||||
["PonziRates"] = Array.ConvertAll(Tuning.PonziRates, v => (double)v),
|
||||
["SparkSpiralPath"] = Array.ConvertAll(Tuning.SparkSpiralPath, v => (double)v),
|
||||
["UsedHealthMax"] = Array.ConvertAll(Tuning.UsedHealthMax, v => (double)v),
|
||||
|
||||
@@ -118,6 +118,21 @@ namespace Decentralized.Domain
|
||||
|
||||
public double Value(Func<string, double> price) => Balances.Sum(kv => kv.Value * price(kv.Key));
|
||||
|
||||
/// <summary>
|
||||
/// 加污点,加完不超过钱包当时的价值(只在加的这一刻检查,之后币价涨跌不再调整)。
|
||||
/// 返回加不进去的部分(超出额),由调用方按 <see cref="OverflowFraud"/> 折成罪证。
|
||||
/// </summary>
|
||||
public double AddTaintCapped(double amount, Func<string, double> price)
|
||||
{
|
||||
if (amount <= 0) return 0;
|
||||
double add = Math.Min(amount, Math.Max(0, Value(price) - Taint));
|
||||
Taint += add;
|
||||
return amount - add;
|
||||
}
|
||||
|
||||
/// <summary>污点超出钱包价值的部分折成的诈骗罪证:超出额 × <see cref="Tuning.PredictFraudShare"/>,单次封顶 <see cref="Tuning.PredictFraudCap"/>。</summary>
|
||||
public static double OverflowFraud(double overflow) => Math.Min(Tuning.PredictFraudCap, Math.Max(0, overflow) * Tuning.PredictFraudShare);
|
||||
|
||||
/// <summary>
|
||||
/// 转出:taint 和 basis 按转出价值占地址总价值的比例带走;被标记的地址转出可追踪的币,收款地址也被标记。
|
||||
/// Ponero 等不可追踪资产转入时,污点和标记都不随之进入目标地址。
|
||||
|
||||
@@ -137,6 +137,7 @@ namespace Decentralized
|
||||
|
||||
private static void NightDraw(GameItem m, GameSlotInventory battery, GameInventory modules)
|
||||
{
|
||||
if (TurboMine.Boosting) { Boost(m, battery, modules); return; }
|
||||
if (!Session.TonightDrawn.Add(m.uniqueId)) return;
|
||||
var u = Items.ToUnit(m);
|
||||
Session.TonightRigs++;
|
||||
@@ -151,6 +152,18 @@ namespace Decentralized
|
||||
Update(m, modules);
|
||||
}
|
||||
|
||||
/// <summary>涡轮增压:扣一晚的电,立刻挖一轮(不影响今晚照常挖矿)。</summary>
|
||||
private static void Boost(GameItem m, GameSlotInventory battery, GameInventory modules)
|
||||
{
|
||||
var u = Items.ToUnit(m);
|
||||
if (u.Dead) return;
|
||||
var b = Items.Bonus(m, modules);
|
||||
int kj = (int)Math.Ceiling(u.Kj(b));
|
||||
if (battery.childItems.Count == 0 || !PowerHelper.DrawPowerSource(battery.childItem, kj)) { Log.Info("涡轮增压:矿机电池电量不够,这一轮没挖"); return; }
|
||||
TurboMine.Round(m, new List<KeyValuePair<GameItem, ModuleBonus>> { new KeyValuePair<GameItem, ModuleBonus>(m, b) });
|
||||
Update(m, modules);
|
||||
}
|
||||
|
||||
/// <summary>造一台矿机:按健康度写标签。</summary>
|
||||
public static GameItem New(string model, double health)
|
||||
{
|
||||
|
||||
@@ -47,4 +47,18 @@ namespace Decentralized
|
||||
public static string Num(double v) => Math.Abs(v) >= 100 ? v.ToString("N0") : Math.Abs(v) >= 1 ? v.ToString("0.##") : v.ToString("0.####");
|
||||
public static string Credits(double v) => v.ToString("N0");
|
||||
}
|
||||
|
||||
/// <summary>污点超出钱包价值的部分:按 <see cref="Decentralized.Domain.Wallet.OverflowFraud"/> 记诈骗罪证,返回接在消息后面的一句(没有超出返回空串)。</summary>
|
||||
public static class TaintCrime
|
||||
{
|
||||
public static string Commit(double over)
|
||||
{
|
||||
if (over <= 1e-9) return "";
|
||||
int fraud = (int)Math.Round(Decentralized.Domain.Wallet.OverflowFraud(over));
|
||||
if (fraud > 0) PlayerStore.Instance.secData.CommitCrime("FRAUD", fraud);
|
||||
// 接在上一句后面:中日文不加空格,其他语言隔一个空格
|
||||
string sep = L.Code.StartsWith("zh") || L.Code.StartsWith("ja") ? "" : " ";
|
||||
return sep + L.T("taint.overflow", Fmt.Credits(over));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using Decentralized.Domain;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>
|
||||
/// 收黑币的上门顾客(游戏的对话顾客):游戏里出了事,有人拿着来路不明的币折价换现金,见 <see cref="HotCoins"/>。
|
||||
/// 一天最多一位。收下:付现金,币进已连接的钱包(PSC、CRT 全额带污点);钓鱼执法:现金被没收并记销赃罪证,币不会到。
|
||||
/// </summary>
|
||||
public static class HotCoinSeller
|
||||
{
|
||||
private static int seenDay = -1;
|
||||
|
||||
public static void Subscribe()
|
||||
{
|
||||
ModHook.OnGenerateCustomerLate += OnGenerate;
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Hot coin seller (test)", () => Log.Guard("收黑币(测试)", () =>
|
||||
{
|
||||
var d = Session.Data;
|
||||
string[] assets = { Assets.CRT, Assets.PSC, Assets.Ponero };
|
||||
var c = Create(assets[d.Rng.Range(0, assets.Length - 1)]);
|
||||
if (c == null) return;
|
||||
PlayerStore.Instance.currentClientInstance = null;
|
||||
PlayerStore.Instance.storeClientManager.clientStack.Insert(0, c);
|
||||
PlayerStore.Instance.TryCallNextClient();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void Unsubscribe() => ModHook.OnGenerateCustomerLate -= OnGenerate;
|
||||
|
||||
private static void OnGenerate(StoreClientManager manager)
|
||||
{
|
||||
var d = Session.Data;
|
||||
if (d == null || !Unlock.IsUnlocked || !d.Connected) return;
|
||||
Log.Guard("收黑币", () =>
|
||||
{
|
||||
int day = StoreStation.GetDayCounter();
|
||||
if (day == seenDay) return;
|
||||
seenDay = day;
|
||||
bool ponero = Unlock.BlackUnlocked && BlackMarket.DeskOpen(StoreReputation.GetBMReputation());
|
||||
string asset = HotCoins.Pick(Night.ActiveEvents(), ponero, d.Rng);
|
||||
if (asset == null) return;
|
||||
var c = Create(asset);
|
||||
if (c != null) manager.AddClient(c);
|
||||
});
|
||||
}
|
||||
|
||||
private static StoreClient Create(string asset)
|
||||
{
|
||||
var d = Session.Data;
|
||||
bool crackdown = Night.ActiveEvents().Contains(MarketEvent.Crackdown);
|
||||
var o = HotCoins.Make(asset, Session.Price(asset), Session.Rent(), crackdown, d.Rng);
|
||||
if (o == null) return null;
|
||||
var c = new StoreClient
|
||||
{
|
||||
identifier = "pd_hot_coins", displayName = L.T("hot.name"),
|
||||
spriteName = asset == Assets.CRT ? SpriteDict.GetRandomBMMaleSpriteName() : asset == Assets.PSC ? SpriteDict.GetRandomRevSpriteName() : SpriteDict.GetRandomShadySpriteName(),
|
||||
clientIntent = StoreClient.ClientIntent.DIALOGUE,
|
||||
};
|
||||
// 选项的动作先于下一句执行:在动作里结算,再把卖家的回话换成结果
|
||||
var yes = new Dialogue();
|
||||
var reply = yes.SetText("PLAYER", L.T("hot.say.yes")).NextDialogue();
|
||||
reply.SetText(c.displayName, L.T("hot.refused")).SetEndAction(Leave);
|
||||
var no = new Dialogue();
|
||||
no.SetText("PLAYER", L.T("hot.say.no")).NextDialogue().SetText(c.displayName, L.T("hot.refused")).SetEndAction(Leave);
|
||||
c.mainDialogue.SetText(c.displayName, L.T("hot.intro." + asset)).NextDialogue()
|
||||
.SetText(c.displayName, L.T("hot.offer", Fmt.Num(o.Qty), asset, Fmt.Credits(o.Value), Fmt.Credits(o.Cash)))
|
||||
.AddChoice(DirectoryMaster.Item("yes"), L.T("hot.choice.yes"), "", yes, () => reply.SetText(c.displayName, L.T(Accept(o))))
|
||||
.AddChoice(DirectoryMaster.Item("cancel"), L.T("hot.choice.no"), "", no, null);
|
||||
ModHelper.SetClientSource(c, ModInfo.Id);
|
||||
c.AddBasicDialog();
|
||||
c.CompleteClientCreation();
|
||||
Log.Info($"收黑币上门:{o.Qty:0.##} {asset},市值 {o.Value:0},要价 {o.Cash}{(o.Sting ? "(钓鱼执法)" : "")}");
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary>选了收下:现金不够或没连钱包就作罢;钓鱼执法没收现金、记罪证;否则付现金、币进钱包。返回卖家回话的键。</summary>
|
||||
private static string Accept(HotOffer o)
|
||||
{
|
||||
string line = "hot.refused";
|
||||
Log.Guard("收黑币成交", () =>
|
||||
{
|
||||
var d = Session.Data;
|
||||
if (!d.Connected) { line = "hot.nowallet"; return; }
|
||||
if (PlayerStore.Instance.playerCash < o.Cash) { line = "hot.nocash"; return; }
|
||||
ModHelper.AddCredit(-o.Cash, false);
|
||||
if (o.Sting)
|
||||
{
|
||||
PlayerStore.Instance.secData.CommitCrime("FENCING", (int)Math.Min(Tuning.CrimeEventCap, o.Cash));
|
||||
line = "hot.sting";
|
||||
Log.Info($"收黑币:钓鱼执法,现金 {o.Cash} 没收,记销赃罪证");
|
||||
}
|
||||
else
|
||||
{
|
||||
HotCoins.Receive(d.Hot, o);
|
||||
d.Chain(ChainAddress.Make(d.Rng.NextUInt()), d.Hot.Address, o.Asset, o.Qty);
|
||||
line = "hot.done";
|
||||
Log.Info($"收黑币:{o.Qty:0.##} {o.Asset} 进 {WalletWindow.NameOf(d.Hot)},付现金 {o.Cash},钱包污点 {d.Hot.Taint:0}");
|
||||
}
|
||||
Session.Save();
|
||||
});
|
||||
return line;
|
||||
}
|
||||
|
||||
private static void Leave() => DialogUIManager.Instance.CurrentClientLeave();
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ namespace Decentralized
|
||||
dir.Add(Rig, CreateRig);
|
||||
WrapElectronics(dir);
|
||||
WrapTurbos(dir);
|
||||
OtcLamp.Wrap(dir);
|
||||
dir.Add(Guide, CreateGuide);
|
||||
dir.Add(HwWallet, CreateHwWallet);
|
||||
dir.Add(KeyDrive, CreateKeyDrive);
|
||||
@@ -540,8 +541,8 @@ namespace Decentralized
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 涡轮增压器不能作用于矿架和 ASIC 矿机:它们带"标准机器"标签,原版涡轮只看这个标签,还会手动触发目标的夜间结算(等于白天多扣一次电)。
|
||||
/// 在原版涡轮工厂外包一层,对这两类目标返回否;是替换判断函数而不是追加(追加是"或",原来的"是"还会生效)。
|
||||
/// 涡轮增压器作用于矿架和 ASIC 矿机:照原版机器的规则多跑一轮,这一轮是立刻挖一晚(见 <see cref="TurboMine"/>)。
|
||||
/// 原版增压器调用机器的夜间周期回调,所以在它的作用函数外包一层,作用于矿机时打上标记,回调据此改为立刻结算;判断、消耗、充电都照原版。
|
||||
/// </summary>
|
||||
private static void WrapTurbos(ModItemDirectory dir)
|
||||
{
|
||||
@@ -552,10 +553,13 @@ namespace Decentralized
|
||||
dir.Set(id, () =>
|
||||
{
|
||||
var it = make();
|
||||
var may = it.mayThisTargetItemFunc;
|
||||
var can = it.canThisTargetItemFunc;
|
||||
it.mayThisTargetItemFunc = (s, t) => !IsMiner(t) && (may?.Invoke(s, t) ?? false);
|
||||
it.canThisTargetItemFunc = (s, t) => !IsMiner(t) && (can?.Invoke(s, t) ?? false);
|
||||
var on = it.onThisTargetItemFunc;
|
||||
it.onThisTargetItemFunc = (s, t) =>
|
||||
{
|
||||
if (!IsMiner(t)) { on?.Invoke(s, t); return; }
|
||||
TurboMine.Boosting = true;
|
||||
try { on?.Invoke(s, t); } finally { TurboMine.Boosting = false; }
|
||||
};
|
||||
return it;
|
||||
});
|
||||
}
|
||||
@@ -640,6 +644,7 @@ namespace Decentralized
|
||||
/// <summary>夜间早段:按矿架上的显卡总耗电(含模块效果)从电池扣电;扣电成功,登记今晚参与挖矿的显卡和模块效果。</summary>
|
||||
private static void NightDraw(GameItem rig, GameSlotInventory battery, GameInventory modules, GameInventory cards)
|
||||
{
|
||||
if (TurboMine.Boosting) { Boost(rig, battery, modules, cards); return; }
|
||||
if (!Session.TonightDrawn.Add(rig.uniqueId)) return;
|
||||
var list = Cards(cards).Where(c => !c.IsTag(DeadTag)).ToList();
|
||||
Session.TonightRigs++;
|
||||
@@ -653,6 +658,18 @@ namespace Decentralized
|
||||
UpdateRig(rig, modules, cards);
|
||||
}
|
||||
|
||||
/// <summary>涡轮增压:扣一晚的电,立刻挖一轮(不影响今晚照常挖矿)。</summary>
|
||||
private static void Boost(GameItem rig, GameSlotInventory battery, GameInventory modules, GameInventory cards)
|
||||
{
|
||||
var list = Cards(cards).Where(c => !c.IsTag(DeadTag)).ToList();
|
||||
if (list.Count == 0) return;
|
||||
var b = Bonus(rig, modules);
|
||||
int kj = RigKj(cards, b);
|
||||
if (battery.childItems.Count == 0 || !PowerHelper.DrawPowerSource(battery.childItem, kj)) { Log.Info("涡轮增压:矿架电池电量不够,这一轮没挖"); return; }
|
||||
TurboMine.Round(rig, list.Select(c => new KeyValuePair<GameItem, ModuleBonus>(c, b)).ToList());
|
||||
UpdateRig(rig, modules, cards);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 放进储藏区(游戏 EmporiumTryAdd 的默认目标,放不下时游戏自己找位置)。
|
||||
/// 不放柜台:测试中柜台上的物品过夜后会消失(未在正常流程中确认);ModHelper.MoveItemTo* 放满时会静默失败。
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Decentralized
|
||||
DealerStock.Subscribe();
|
||||
UsedDealerClient.Subscribe();
|
||||
CoinCustomers.Subscribe();
|
||||
HotCoinSeller.Subscribe();
|
||||
OtcClient.Subscribe();
|
||||
BlackDelivery.Subscribe();
|
||||
TumblerStory.Subscribe();
|
||||
GpuInspectView.Ensure();
|
||||
@@ -38,7 +38,7 @@ namespace Decentralized
|
||||
DealerStock.Unsubscribe();
|
||||
UsedDealerClient.Unsubscribe();
|
||||
CoinCustomers.Unsubscribe();
|
||||
HotCoinSeller.Unsubscribe();
|
||||
OtcClient.Unsubscribe();
|
||||
BlackDelivery.Unsubscribe();
|
||||
TumblerStory.Unsubscribe();
|
||||
GpuInspectView.Remove();
|
||||
|
||||
@@ -50,6 +50,7 @@ report.burnt,Durchgebrannte Karten: {0}
|
||||
report.price,PSC-Preis: {0} Credits
|
||||
nightlog.mined,Mining-Rigs haben {0} PSC geschürft.
|
||||
nightlog.burnt,{0} ist durchgebrannt.
|
||||
nightlog.turbo,{0} per Turbo-Booster beschleunigt: sofort {1} PSC geschürft.
|
||||
coinpay.line,Abgemacht. {0} {1}.
|
||||
nightlog.coinpay,Zahlungen in Coins ergaben {0} Credits; die Coins wurden an die Hot-Wallet übertragen.
|
||||
nightlog.unpowered,Mining-Rigs oder Miner ohne Strom: {0}.
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,Schmuggelware (hoch)
|
||||
black.kind.Tech,Hightech (Aufpreis)
|
||||
nightlog.bm.ready,"Schwarzmarkt: {0} eingetroffen; sobald du öffnest, kommt ein Kurier vorbei."
|
||||
guide.web3.title,Web3-Handbuch
|
||||
guide.web3.text,"Bank und Handel: Die Bankseite ist nur lesbar und zeigt Bargeld, Miete und das CRC auf dem Poinbase-Konto. Die Seite „Guthaben“ von Poinbase regelt Ein- und Auszahlungen; zuerst wird der Coin gewählt: CRC geht über das Bankkonto oder die Wallet, alle anderen Coins nur über die Wallet. Eine Einzahlung von der Bank wandelt Credits in CRC auf deinem Poinbase-Konto um; eine Auszahlung auf die Bank wandelt CRC zurück in Credits um und durchläuft eine Compliance-Prüfung, die die Kontamination des Poinbase-Kontos bewertet. Eine Auszahlung auf eine Wallet braucht die Zieladresse und mehrere Bestätigungen bis zur Gutschrift; die Gasgebühr ist fest auf Normal gesetzt und wird vom abgehenden Coin abgezogen. Ist das Adressformat oder die Prüfziffer falsch, wird abgelehnt; bei einer formal gültigen Adresse, die niemand nutzt, sind die Coins nach der Überweisung weg.¶Handel: PSC steht für Probably Stolen Coin, den durch Grafikkarten und Miner geschürften Coin. Der Poinbase-Spotmarkt hat zwei Paare, PSC/CRC und SPARK/CRC, je nach dem im Chart gewählten Coin. Käufe und Verkäufe werden beide als Menge des gehandelten Coins eingegeben; die Vorschau zeigt den gezahlten oder erhaltenen Notierungs-Coin, der Durchschnittspreis enthält die Gebühr, die Slippage nicht.¶Auf der Web3-Handelsseite lassen sich beliebige zwei Coins tauschen, stets über CRC als Zwischenschritt: Ist CRC eine Seite, läuft der Tausch über einen Pool, sonst über zwei Pools mit zwei Gebühren und sich addierender Slippage; die Vorschau zeigt Menge, Anzahl der Pools und Verlust. Stablecoin-Tausch (CRT oder CRA gegen CRC) läuft über Stable-Pools: {StableFee:%} Gebühr und kaum Slippage nahe der Bindung; beim Depeg wird die Liquidität dünner, beim Zusammenbruch wird sie abgezogen und die Slippage springt.§Hardware-Wallets: On-Chain-Coins liegen auf PLEDGER-Hardware-Wallets, jede mit eigenem Guthaben und eigener Kontamination. Eine Wallet ist ein Gegenstand: Ziehe sie auf das Handelsterminal, um sie zu laden. Öffne sie auf der Wallets-Seite des Terminals; verbinde und trenne sie oben rechts im Terminal. Der Handel der Web3-Seite sowie Shop und Mixer der Graunetz-Seite nutzen die verbundene Wallet; ohne Wallet oder ohne Verbindung sind sie nur lesbar und alle Guthaben zeigen 0. Kunden, die in Coins zahlen, zahlen auf die verbundene Wallet.¶Zahlungen (Shop, Mixer, Ponero-Schalter, Einstellgebühren) beginnen als Rechnung auf dem Handelsterminal; gib die Empfängeradresse auf der Wallet ein und halte zum Signieren ✓ gedrückt. Die letzten beiden Zeichen einer Adresse bilden eine Prüfsumme, sodass ein einzelner Tippfehler meist abgefangen wird; gelegentlich ist die Eingabe dennoch gültig und die Coins gehen an eine ungenutzte Adresse. Auch DEX-Swaps erfordern eine Signatur auf der Wallet.¶Poinbase ist ein Verwahrkonto; Einzahlungen erfolgen von der Wallet an die Einzahlungsadresse von Poinbase (nur PSC, CRC und SPARK; die regulierte Börse nimmt weder das CRT des Schwarzmarkts noch das CRA der Revolution, und die Wallet blockiert Überweisungen dieser Coins an die Einzahlungsadresse), Auszahlungen werden auf der Seite „Guthaben“ von Poinbase gestartet. Der Explorer auf der Wallets-Seite zeigt Überweisungen nach Adresse, ausschließlich tatsächlich erfolgte: jede Bewegung in und aus deinen Wallets (Überweisungen, DEX-Tausch und andere Vertragsaufrufe, Miner-Erträge, Auszahlungen, Coins, die andere dir schicken); Ponero ist ein Privacy Coin und erscheint nie. Weitere Hardware-Wallets verkauft Dr. Jackson; ziehe eine auf das Handelsterminal, um sie hinzuzufügen, bis zu {WalletMax}. Im Shop gibt es günstigere Exemplare. Eine nicht mehr benötigte Wallet kann auf der Wallets-Seite zerstört werden; ihre Coins sind dauerhaft verloren, ebenso alles, was danach an ihre Adresse gesendet wird.¶Überweisungen kosten Gasgebühren: langsam, normal oder schnell, und die Gas-Preise steigen und fallen im Wochenverlauf; bei Netzwerküberlastung steigen die Gasgebühren und langsame Transaktionen können aus dem Mempool fliegen. Vor dem Senden die vollständige Adresse prüfen.§Staking: Im Revolution-Pool gestakte CRA erzielen einen Tageszinssatz, der dem Einsatz zugeschlagen wird; eine Auszahlung erfordert einen vorherigen Antrag und vier Tage Wartezeit – ohne Zinsen während des Wartens und ohne vorzeitige Entnahme. CRA ist teilbesichert: Jedes CRA wird von CRC-Reserven der Revolution und vom Ausgleichstoken SPARK gedeckt; Reservedeckung und Besicherungsquote stehen auf der Staking-Seite. Zinsen werden in neuem, unbesichertem CRA gezahlt, das die Reservedeckung verwässert, umso schneller, je mehr gestakt ist; bei zu niedriger Deckung senkt die Revolution den Zinssatz. Die Revolution greift manchmal in die Reserve; zuvor gibt es Gerüchte, das ist das Vorzeichen. Fällt die Deckung danach unter {CraCrashRatio:%}, bricht das System zusammen: CRA ist binnen drei Tagen wertlos und vier Tage Entsperrung sind zu langLine truncated
|
||||
guide.web3.text,"Bank und Handel: Die Bankseite ist nur lesbar und zeigt Bargeld, Miete und das CRC auf dem Poinbase-Konto. Die Seite „Guthaben“ von Poinbase regelt Ein- und Auszahlungen; zuerst wird der Coin gewählt: CRC geht über das Bankkonto oder die Wallet, alle anderen Coins nur über die Wallet. Eine Einzahlung von der Bank wandelt Credits in CRC auf deinem Poinbase-Konto um; eine Auszahlung auf die Bank wandelt CRC zurück in Credits um und durchläuft eine Compliance-Prüfung, die die Kontamination des Poinbase-Kontos bewertet. Eine Auszahlung auf eine Wallet braucht die Zieladresse und mehrere Bestätigungen bis zur Gutschrift; die Gasgebühr ist fest auf Normal gesetzt und wird vom abgehenden Coin abgezogen. Ist das Adressformat oder die Prüfziffer falsch, wird abgelehnt; bei einer formal gültigen Adresse, die niemand nutzt, sind die Coins nach der Überweisung weg.¶Handel: PSC steht für Probably Stolen Coin, den durch Grafikkarten und Miner geschürften Coin. Der Poinbase-Spotmarkt hat zwei Paare, PSC/CRC und SPARK/CRC, je nach dem im Chart gewählten Coin. Käufe und Verkäufe werden beide als Menge des gehandelten Coins eingegeben; die Vorschau zeigt den gezahlten oder erhaltenen Notierungs-Coin, der Durchschnittspreis enthält die Gebühr, die Slippage nicht.¶Auf der Web3-Handelsseite lassen sich beliebige zwei Coins tauschen, stets über CRC als Zwischenschritt: Ist CRC eine Seite, läuft der Tausch über einen Pool, sonst über zwei Pools mit zwei Gebühren und sich addierender Slippage; die Vorschau zeigt Menge, Anzahl der Pools und Verlust. Stablecoin-Tausch (CRT oder CRA gegen CRC) läuft über Stable-Pools: {StableFee:%} Gebühr und kaum Slippage nahe der Bindung; beim Depeg wird die Liquidität dünner, beim Zusammenbruch wird sie abgezogen und die Slippage springt.§Hardware-Wallets: On-Chain-Coins liegen auf PLEDGER-Hardware-Wallets, jede mit eigenem Guthaben und eigener Kontamination. Eine Wallet ist ein Gegenstand: Ziehe sie auf das Handelsterminal, um sie zu laden. Öffne sie auf der Wallets-Seite des Terminals; verbinde und trenne sie oben rechts im Terminal. Der Handel der Web3-Seite sowie Shop und Mixer der Graunetz-Seite nutzen die verbundene Wallet; ohne Wallet oder ohne Verbindung sind sie nur lesbar und alle Guthaben zeigen 0. Kunden, die in Coins zahlen, zahlen auf die verbundene Wallet.¶Zahlungen (Shop, Mixer, Ponero-Schalter, Einstellgebühren) beginnen als Rechnung auf dem Handelsterminal; gib die Empfängeradresse auf der Wallet ein und halte zum Signieren ✓ gedrückt. Die letzten beiden Zeichen einer Adresse bilden eine Prüfsumme, sodass ein einzelner Tippfehler meist abgefangen wird; gelegentlich ist die Eingabe dennoch gültig und die Coins gehen an eine ungenutzte Adresse. Auch DEX-Swaps erfordern eine Signatur auf der Wallet.¶Poinbase ist ein Verwahrkonto; Einzahlungen erfolgen von der Wallet an die Einzahlungsadresse von Poinbase (nur PSC, CRC und SPARK; die regulierte Börse nimmt weder das CRT des Schwarzmarkts noch das CRA der Revolution, und die Wallet blockiert Überweisungen dieser Coins an die Einzahlungsadresse), Auszahlungen werden auf der Seite „Guthaben“ von Poinbase gestartet. Der Explorer auf der Wallets-Seite zeigt Überweisungen nach Adresse, ausschließlich tatsächlich erfolgte: jede Bewegung in und aus deinen Wallets (Überweisungen, DEX-Tausch und andere Vertragsaufrufe, Miner-Erträge, Auszahlungen, Coins, die andere dir schicken); Ponero ist ein Privacy Coin und erscheint nie. Weitere Hardware-Wallets verkauft Dr. Jackson; ziehe eine auf das Handelsterminal, um sie hinzuzufügen, bis zu {WalletMax}. Im Shop gibt es günstigere Exemplare. Eine nicht mehr benötigte Wallet kann auf der Wallets-Seite zerstört werden; ihre Coins sind dauerhaft verloren, ebenso alles, was danach an ihre Adresse gesendet wird.¶Überweisungen kosten Gasgebühren: langsam, normal oder schnell, und die Gas-Preise steigen und fallen im Wochenverlauf; bei Netzwerküberlastung steigen die Gasgebühren und langsame Transaktionen können aus dem Mempool fliegen. Vor dem Senden die vollständige Adresse prüfen.§Staking: Im Revolution-Pool gestakte CRA erzielen einen Tageszinssatz, der dem Einsatz zugeschlagen wird; eine Auszahlung erfordert einen vorherigen Antrag und vier Tage Wartezeit – ohne Zinsen während des Wartens und ohne vorzeitige Entnahme. CRA ist teilbesichert: Jedes CRA wird von CRC-Reserven der Revolution und vom Ausgleichstoken SPARK gedeckt; Reservedeckung und Besicherungsquote stehen auf der Staking-Seite. Zinsen werden in neuem, unbesichertem CRA gezahlt, das die Reservedeckung verwässert, umso schneller, je mehr gestakt ist; bei zu niedriger Deckung senkt die Revolution den Zinssatz. Die Revolution greift manchmal in die Reserve; zuvor gibt es Gerüchte, das ist das Vorzeichen. Fällt die Deckung danach unter {CraCrashRatio:%}, bricht das System zusammen: CRA ist binnen drei Tagen wertlos und vier Tage Entsperrung sind zu langLine truncated
|
||||
courier.odd1,...Paket ist da.
|
||||
courier.odd2,(Seine Hand bleibt in der Tasche.) Hier unterschreiben.
|
||||
courier.sign,Unterschreiben
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Wasser (Obere Ebene)
|
||||
nightlog.predict.win,"Prognose richtig: „{0}“, {1} ausgezahlt."
|
||||
nightlog.predict.lose,"Prognose falsch: „{0}“, Einsatz {1} verloren."
|
||||
nightlog.predict.void,"Prognose ungültig: „{0}“, Einsatz {1} erstattet."
|
||||
nightlog.predict.caught,"Insider-Wette aufgeflogen: „{0}“, Einsatz und Gewinn {1} beschlagnahmt, Betrug vermerkt."
|
||||
nightlog.predict.insider,"""{0}"" mit {1} abgerechnet. Die Polizei vermutet Insiderhandel; die Auszahlung wird markiert und die Kontamination der Wallet steigt um {2}."
|
||||
predict.tab.markets,Märkte
|
||||
predict.tab.intel,Informationen
|
||||
predict.acct.crt,{0}: CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}: Operation geplant
|
||||
predict.brief.none,{0}: Keine Operation möglich
|
||||
predict.brief.can,{0}: Kann {1} starten
|
||||
predict.clue.push,Preis um {0}% bewegt: hohes Manipulationsrisiko
|
||||
nightlog.predict.manip,"Prognose als Marktmanipulation gewertet: „{0}“, Einsatz {1} beschlagnahmt, Betrug vermerkt."
|
||||
nightlog.predict.manip,"""{0}"" mit {1} abgerechnet. Die Aufsichtsbehörden vermuten Marktmanipulation; die Auszahlung wird markiert und die Kontamination der Wallet steigt um {2}."
|
||||
news.manip.title,Börse untersucht ungewöhnlichen Handel
|
||||
news.manip.desc,Regulierer melden: Jemand bewegte den Preis mit großen Spot-Orders und profitierte bei Derivaten und Prognosen; Gelder wurden beschlagnahmt.
|
||||
perp.manip,Schließungsgewinn {0} als Marktmanipulation gewertet und beschlagnahmt; Perpetual-Konto eingefroren (Tage: {1}).
|
||||
news.manip.desc,"Die Aufsichtsbehörden melden, dass jemand den Preis mit großen Spot-Orders bewegt und aus Derivaten sowie Prognosen profitiert hat; die betroffenen Konten wurden markiert."
|
||||
taint.overflow,Die Kontamination übersteigt nun den Wert der Wallet; der Überschuss von {0} wird als Betrug erfasst.
|
||||
perp.manip,Mit Gewinn von {0} geschlossen. Die Aufsichtsbehörden vermuten Marktmanipulation; der Gewinn wird markiert und die Kontamination des Poinbase-Kontos steigt um {1}.
|
||||
web3.sub.ponzi,Rendite
|
||||
ponzi.h,Schneeballsystem
|
||||
ponzi.acct,Emittenten-Wallet {0}: CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Poinbase-Support
|
||||
scam.support.1,"Hallo, hier ist der Poinbase-Support. Wir haben eine ungewöhnliche Anmeldung in Ihrem Konto festgestellt und es wurde markiert."
|
||||
scam.support.2,Bitte senden Sie heute {0} CRC zur Verifizierung an die sichere Adresse {1}; der Betrag wird direkt im Anschluss zurückerstattet.
|
||||
scam.support.3,"Andernfalls wird das Konto dauerhaft gefroren. Ich muss los, denken Sie an die Überweisung."
|
||||
predict.sold.caught,"Insiderhandel beim Verkauf aufgeflogen: Einsatz und Gewinn beschlagnahmt, Betrug vermerkt."
|
||||
predict.sold.caught,"Verkauft, {0} erhalten. Die Polizei vermutet Insiderhandel; der Erlös wird markiert und die Kontamination der Wallet steigt um {1}."
|
||||
predict.row.move," (letzte Nacht {0} {1})"
|
||||
predict.stats.h,Verlauf (durchschnittl. Eröffnungskurs / tatsächliche Quote)
|
||||
predict.stats.row,"{0}: {1} Märkte, Eröffnungsschnitt {2}, eingetreten {3}%"
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,"{0} fällt an einem Tag um {1}%, {2} Trader liquidiert"
|
||||
news.wipe.down.desc,"Am vergangenen Tag wurden {1} Long-Positionen auf {0}-Perps liquidiert, insgesamt {2} Credits. Der Versicherungsfonds von Poinbase steht bei {3} Credits."
|
||||
news.wipe.up.title,"{0} steigt an einem Tag um {1}%, {2} Trader liquidiert"
|
||||
news.wipe.up.desc,"Am vergangenen Tag wurden {1} Short-Positionen auf {0}-Perps liquidiert, insgesamt {2} Credits. Der Versicherungsfonds von Poinbase steht bei {3} Credits."
|
||||
hot.name,Verkäufer
|
||||
hot.intro.CRT,"Gerade ist die Lage angespannt, und dieses CRT ist mir zu heiß. Ich brauche schnell Bargeld."
|
||||
hot.intro.PSC,"Die Wallet einer Mining-Farm hat letzte Nacht den Besitzer gewechselt. Das PSC liegt jetzt bei mir, und ich nehme nur Bargeld."
|
||||
hot.intro.PONERO,"Lösegeld, in Ponero. Niemand kann es zurückverfolgen. Nur Bargeld."
|
||||
hot.offer,"{0} {1}, zum heutigen Kurs {2} wert. Gib mir {3} in bar, und die Coins gehören sofort dir."
|
||||
hot.choice.yes,Annehmen
|
||||
hot.choice.no,Ablehnen
|
||||
hot.say.yes,Abgemacht.
|
||||
hot.say.no,Davon lasse ich die Finger.
|
||||
hot.done,Coins sind raus. Wir haben uns nie gesehen.
|
||||
hot.refused,Andere nehmen es gern.
|
||||
hot.nocash,Du hast nicht mal das Bargeld? Vergiss es.
|
||||
hot.nowallet,"Keine Wallet verbunden, wohin sollen die Coins? Vergiss es."
|
||||
hot.sting,"Keine Bewegung. Security. Ankauf gestohlener Gelder: Das Bargeld wird beschlagnahmt, und das kommt in deine Akte."
|
||||
otc.name,OTC-Kunde
|
||||
otc.intro.CRT,"Gerade ist die Lage angespannt, und dieses CRT ist mir zu heiß. Ich brauche schnell Bargeld."
|
||||
otc.intro.PSC,"Die Wallet einer Mining-Farm hat letzte Nacht den Besitzer gewechselt. Das PSC liegt jetzt bei mir, und ich nehme nur Bargeld."
|
||||
otc.intro.PONERO,"Lösegeld, in Ponero. Niemand kann es zurückverfolgen. Nur Bargeld."
|
||||
otc.offer,"{0} {1}, zum heutigen Kurs {2} wert, gesendet von {4}. {3} in bar für alles, oder nimm nur einen Teil."
|
||||
otc.intro.sell,"Habe etwas {0}, das ich zu Bargeld machen will. Prüf die Herkunft, wenn du willst."
|
||||
otc.buy.ask,"Ich möchte {0} {1}, zum heutigen Kurs {2} wert. {3} in bar für alles, oder verkauf mir einen Teil."
|
||||
otc.intro.buy,"Habe gehört, du tauschst hier Coins. Ich kaufe, gegen bar."
|
||||
otc.say.trade,Lass uns das am Terminal machen.
|
||||
otc.wait,"Gut, ich warte."
|
||||
otc.paid,Angekommen. Hier ist dein Bargeld.
|
||||
tab.otc,Schalter
|
||||
otc.h,Schalterhandel
|
||||
otc.k.side,Kunde
|
||||
otc.side.sell,Verkauft {0}
|
||||
otc.side.buy,Kauft {0}
|
||||
otc.k.qty,Betrag
|
||||
otc.k.value,Marktwert
|
||||
otc.k.ask,Forderung (gesamt)
|
||||
otc.k.bid,Gebot (gesamt)
|
||||
otc.k.unit,Einzelpreis
|
||||
otc.k.addr,Kundenadresse: {0}
|
||||
otc.lookup,Prüfen
|
||||
otc.preview.take,"{0} Bargeld zahlen, {1} {2} erhalten"
|
||||
otc.preview.give,"{0} {1} senden, {2} Bargeld erhalten"
|
||||
otc.deal,Abschließen
|
||||
otc.cancel,Passen
|
||||
otc.msg.gone,Der Kunde ist gegangen.
|
||||
otc.msg.cash,Nicht genug Bargeld.
|
||||
otc.msg.sting,"Der Kunde war ein verdeckter Ermittler: {0} Bargeld beschlagnahmt, Hehlerei erfasst."
|
||||
otc.msg.bought,"{0} {1} erhalten, {2} Bargeld gezahlt."
|
||||
otc.msg.sold,"{0} {1} gesendet, {2} Bargeld erhalten."
|
||||
gray.sub.own,Eigener Mixer
|
||||
ownmix.h,Eigener Mixer
|
||||
ownmix.status.closed,Geschlossen (Rug Pull)
|
||||
ownmix.status.seized,"Beschlagnahmt, geschlossen bis Tag {0}"
|
||||
ownmix.status.open,Geöffnet
|
||||
ownmix.status.paused,Pausiert
|
||||
ownmix.k.fee,Gebühr
|
||||
ownmix.k.rating,Ansehen (Restkontamination)
|
||||
ownmix.k.heat,Fahndungsdruck
|
||||
ownmix.heat.0,Niedrig
|
||||
ownmix.heat.1,Mittel
|
||||
ownmix.heat.2,Hoch
|
||||
ownmix.k.anon,Anonymitätsset
|
||||
ownmix.k.fees,Erzielte Gebühren
|
||||
ownmix.col.capital,Kapital
|
||||
ownmix.col.earned,Einnahmen
|
||||
ownmix.col.pending,Kunden-Coins
|
||||
ownmix.open,Öffnen
|
||||
ownmix.pause,Pausieren
|
||||
ownmix.inject,Einzahlung
|
||||
ownmix.withdraw,Auszahlung
|
||||
ownmix.free,Auszahlbar: {0} {1}
|
||||
ownmix.err,Übersteigt den auszahlbaren Betrag.
|
||||
ownmix.injected,{0} {1} eingezahlt.
|
||||
ownmix.withdrawn,{0} {1} ausgezahlt.
|
||||
ownmix.withdraw.sum,{0} {1} aus eigenem Mixer auszahlen
|
||||
pay.ownmix,Einzahlung eigener Mixer: {0} {1}
|
||||
ownmix.rug,Rug Pull ({0})
|
||||
ownmix.rug.confirm,"Erneut klicken, um {0} einzustecken"
|
||||
ownmix.rug.sum,Alle Gelder aus eigenem Mixer einstecken
|
||||
ownmix.rugged,{0} eingesteckt; der Mixer ist geschlossen.
|
||||
nightlog.ownmix.in,"Eigener Mixer: Einzahlungen: {0}, gesamt {1}, Gebühren: {2}."
|
||||
nightlog.ownmix.sting,Eine Einzahlung im eigenen Mixer stammte von einem verdeckten Ermittler; Hehlerei erfasst.
|
||||
nightlog.ownmix.seized,"Security hat den eigenen Mixer beschlagnahmt: Der Pool von {0} wurde konfisziert, Hehlerei erfasst."
|
||||
news.ownmix.seized.title,Security schließt Mixing-Dienst
|
||||
news.ownmix.seized.desc,Security hat einen auf der Unteren Ebene betriebenen Mixing-Dienst geschlossen und sämtliche Gelder beschlagnahmt. Der Betreiber wurde bisher nicht identifiziert.
|
||||
news.ownmix.rug.title,Mixing-Dienst verschwindet mit Geldern
|
||||
news.ownmix.rug.desc,"Ein Mixing-Dienst auf der Unteren Ebene hat über Nacht den Betrieb eingestellt, und alle Nutzergelder im Transit sind verschwunden."
|
||||
pay.otc,OTC-Kunde {0} {1} (Bargeld {2})
|
||||
otc.upgrade.title,OTC-Schalter
|
||||
otc.upgrade.desc,"Fügt der Schwarzen Lampe ein neues Ziel hinzu: OTC-Kunden. Einige verkaufen Coins unbekannter Herkunft, andere kaufen Coins; alle Geschäfte werden in bar abgewickelt. Enthält eine Schwarze Lampe."
|
||||
otc.say.no,Diesmal passe ich.
|
||||
otc.done,Coins sind raus. Wir haben uns nie gesehen.
|
||||
otc.refused,Dann suche ich mir jemand anderen.
|
||||
otc.nocash,Du hast nicht mal das Bargeld? Vergiss es.
|
||||
otc.nowallet,"Keine Wallet verbunden, wohin sollen die Coins? Vergiss es."
|
||||
otc.sting,"Keine Bewegung. Security. Ankauf gestohlener Gelder: Das Bargeld wird beschlagnahmt, und das kommt in deine Akte."
|
||||
hw.err.poinbase,Poinbase nimmt kein {0} an.
|
||||
@@ -50,6 +50,7 @@ report.burnt,Cards burnt out: {0}
|
||||
report.price,PSC price: {0} credits
|
||||
nightlog.mined,Mining rigs produced {0} PSC.
|
||||
nightlog.burnt,A {0} burnt out.
|
||||
nightlog.turbo,{0} turbo-boosted: mined {1} PSC right away.
|
||||
coinpay.line,Deal. {0} {1}.
|
||||
nightlog.coinpay,Customers paying in coin settled {0} credits; the coins went to the hot wallet.
|
||||
nightlog.unpowered,{0} mining rig(s) or miner(s) had no power.
|
||||
@@ -247,7 +248,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.
|
||||
guide.web3.title,Web3 Handbook
|
||||
guide.web3.text,"Bank and trading: the Bank page is read-only and shows cash, rent and the CRC in your Poinbase account. Poinbase's Funds page handles deposits and withdrawals; pick the coin first: CRC can go through the bank account or a wallet, every other coin only through a wallet. Depositing from the bank turns credits into CRC in your Poinbase account; withdrawing to the bank turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Withdrawing to a wallet needs a payee address and a few confirmations before it arrives; the gas fee is fixed at the normal tier and taken from the coin sent. A wrong address format or checksum is rejected; a correctly formatted address nobody uses means the coins are gone.¶Trading: PSC stands for Probably Stolen Coin, the coin mined by GPUs and miners. Poinbase spot has two pairs, PSC/CRC and SPARK/CRC, following the coin picked on the chart. Buys and sells are both entered as an amount of the traded coin; the preview shows the quote coin paid or received, the average price includes the fee and the slippage does not.¶The Web3 trade page can swap any two coins, always through CRC: with CRC on one side it uses one pool, otherwise two pools, with two fees and stacked slippage; the preview shows the amount received, the pools crossed and the loss. Stablecoin swaps (CRT or CRA against CRC) use stable pools: a {StableFee:%} fee and almost no slippage near the peg; during a depeg liquidity thins, and in a collapse it is pulled and slippage jumps.§Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint. A wallet is an item: drag it onto the trading terminal to load it. Open it on the terminal's Wallets page; connect and disconnect at the top right of the terminal. Trading on the Web3 page and the shop and mixer on the Gray Net page use the connected wallet; with no wallet or no connection they are view-only and every balance reads 0. Coin-paying customers pay into the connected wallet.¶Payments (shop, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet.¶Poinbase is a custodial account; deposits are sent from a wallet to Poinbase's deposit address (only PSC, CRC and SPARK; the compliant exchange takes neither the black market's CRT nor the Revolution's CRA, and the wallet blocks sending them to the deposit address) and withdrawals are started on Poinbase's Funds page. The Explorer on the Wallets page looks up transfers by address and shows only transfers that really happened: every movement in and out of your wallets (transfers, DEX swaps and other contract calls, miner payouts, withdrawals, coins others send you); Ponero is a privacy coin and never shows. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to {WalletMax}. The shop has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page; its coins are lost for good, and anything sent to its address afterwards is lost too.¶Transfers pay a gas fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested gas fees rise and slow transactions may be dropped from the mempool. Check the full address before sending.§Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. CRA is partly collateralized: each CRA is backed by the CRC reserve the Revolution holds and by the balance token SPARK; reserve coverage and the collateral ratio are shown on the staking page. Interest is paid in new uncollateralized CRA, which dilutes reserve coverage, faster the more is staked; when coverage is too low the Revolution cuts the rate. The Revolution sometimes diverts the reserve, preceded by rumors: that is the warning. If coverage then falls below {CraCrashRatio:%} it collapses: CRA is worthless within three days and four days of unlocking is too slow; above that there is only a discount, and money from raiding the upper class slowly refills the reserve.¶Official minting: deposit CRC and SPARK (ratio per the current collateral ratio; the preview shows what is needed) to mint CRA, queued {CraMintDaysMin}-{CraMintDaysMax} days; the minted CRA goes straight into staking. Burning turns CRA back into CRC and SPARK, waiting as long as the unlock period; when the reserve is short the CRC share is cut by coverage. Queued mints and burns may be dishonored in full by the Revolution: the nightly chance is how far the CRA price is below 1 times {CraRugPerDepeg}; if the price is not below 1 it cLine truncated
|
||||
guide.web3.text,"Bank and trading: the Bank page is read-only and shows cash, rent and the CRC in your Poinbase account. Poinbase's Funds page handles deposits and withdrawals; pick the coin first: CRC can go through the bank account or a wallet, every other coin only through a wallet. Depositing from the bank turns credits into CRC in your Poinbase account; withdrawing to the bank turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Withdrawing to a wallet needs a payee address and a few confirmations before it arrives; the gas fee is fixed at the normal tier and taken from the coin sent. A wrong address format or checksum is rejected; a correctly formatted address nobody uses means the coins are gone.¶Trading: PSC stands for Probably Stolen Coin, the coin mined by GPUs and miners. Poinbase spot has two pairs, PSC/CRC and SPARK/CRC, following the coin picked on the chart. Buys and sells are both entered as an amount of the traded coin; the preview shows the quote coin paid or received, the average price includes the fee and the slippage does not.¶The Web3 trade page can swap any two coins, always through CRC: with CRC on one side it uses one pool, otherwise two pools, with two fees and stacked slippage; the preview shows the amount received, the pools crossed and the loss. Stablecoin swaps (CRT or CRA against CRC) use stable pools: a {StableFee:%} fee and almost no slippage near the peg; during a depeg liquidity thins, and in a collapse it is pulled and slippage jumps.§Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint. A wallet is an item: drag it onto the trading terminal to load it. Open it on the terminal's Wallets page; connect and disconnect at the top right of the terminal. Trading on the Web3 page and the shop and mixer on the Gray Net page use the connected wallet; with no wallet or no connection they are view-only and every balance reads 0. Coin-paying customers pay into the connected wallet.¶Payments (shop, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet.¶Poinbase is a custodial account; deposits are sent from a wallet to Poinbase's deposit address (only PSC, CRC and SPARK; the compliant exchange takes neither the black market's CRT nor the Revolution's CRA, and the wallet blocks sending them to the deposit address) and withdrawals are started on Poinbase's Funds page. The Explorer on the Wallets page looks up transfers by address and shows only transfers that really happened: every movement in and out of your wallets (transfers, DEX swaps and other contract calls, miner payouts, withdrawals, coins others send you); Ponero is a privacy coin and never shows. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to {WalletMax}. The shop has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page; its coins are lost for good, and anything sent to its address afterwards is lost too.¶Transfers pay a gas fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested gas fees rise and slow transactions may be dropped from the mempool. Check the full address before sending.§Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. CRA is partly collateralized: each CRA is backed by the CRC reserve the Revolution holds and by the balance token SPARK; reserve coverage and the collateral ratio are shown on the staking page. Interest is paid in new uncollateralized CRA, which dilutes reserve coverage, faster the more is staked; when coverage is too low the Revolution cuts the rate. The Revolution sometimes diverts the reserve, preceded by rumors: that is the warning. If coverage then falls below {CraCrashRatio:%} it collapses: CRA is worthless within three days and four days of unlocking is too slow; above that there is only a discount, and money from raiding the upper class slowly refills the reserve.¶Official minting: deposit CRC and SPARK (ratio per the current collateral ratio; the preview shows what is needed) to mint CRA, queued {CraMintDaysMin}-{CraMintDaysMax} days; the minted CRA goes straight into staking. Burning turns CRA back into CRC and SPARK, waiting as long as the unlock period; when the reserve is short the CRC share is cut by coverage. Queued mints and burns may be dishonored in full by the Revolution: the nightly chance is how far the CRA price is below 1 times {CraRugPerDepeg}; if the price is not below 1 it cLine truncated
|
||||
courier.odd1,...Package is here.
|
||||
courier.odd2,(His hand stays in his pocket.) Sign here.
|
||||
courier.sign,Sign
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Upper water
|
||||
nightlog.predict.win,"Prediction right: ""{0}"", paid out {1}."
|
||||
nightlog.predict.lose,"Prediction wrong: ""{0}"", stake {1} lost."
|
||||
nightlog.predict.void,"Prediction void: ""{0}"", stake {1} refunded."
|
||||
nightlog.predict.caught,"Insider bet caught: ""{0}"", stake and winnings {1} confiscated, fraud on record."
|
||||
nightlog.predict.insider,"""{0}"" settled for {1}. Police suspect insider trading; the payout is marked and the wallet's taint rises by {2}."
|
||||
predict.tab.markets,Markets
|
||||
predict.tab.intel,Intel
|
||||
predict.acct.crt,{0}: CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}: operation scheduled
|
||||
predict.brief.none,{0}: nothing to launch
|
||||
predict.brief.can,{0}: can launch {1}
|
||||
predict.clue.push,You moved the price {0}%: risky
|
||||
nightlog.predict.manip,"Prediction ruled manipulation: ""{0}"", stake {1} confiscated, fraud on record."
|
||||
nightlog.predict.manip,"""{0}"" settled for {1}. Regulators suspect you manipulated the price; the payout is marked and the wallet's taint rises by {2}."
|
||||
news.manip.title,Exchange probes unusual trading
|
||||
news.manip.desc,Regulators report that someone moved the price with large spot orders and profited from derivatives and predictions; the funds were seized.
|
||||
perp.manip,Profit {0} on close ruled price manipulation and seized; perp account frozen for {1} days.
|
||||
news.manip.desc,Regulators report that someone moved the price with large spot orders and profited from derivatives and predictions; the accounts involved have been flagged.
|
||||
taint.overflow,Taint now exceeds the wallet's value; the excess {0} goes on record as fraud.
|
||||
perp.manip,Closed with profit {0}. Regulators suspect price manipulation; the profit is marked and the Poinbase account's taint rises by {1}.
|
||||
web3.sub.ponzi,Yield
|
||||
ponzi.h,High-yield scheme
|
||||
ponzi.acct,Issuer wallet {0}: CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Poinbase Support
|
||||
scam.support.1,"Hello, Poinbase support here. We detected an unusual login on your account and it has been flagged."
|
||||
scam.support.2,Please send {0} CRC to the safe address {1} today for verification; it will be returned right after.
|
||||
scam.support.3,"Otherwise the account will be frozen for good. I have to go, remember to send it."
|
||||
predict.sold.caught,"Insider trading caught on sale: stake and profit confiscated, fraud on record."
|
||||
predict.sold.caught,"Sold, received {0}. Police suspect insider trading; the proceeds are marked and the wallet's taint rises by {1}."
|
||||
predict.row.move," (last night {0} {1})"
|
||||
predict.stats.h,History (avg opening price / actual rate)
|
||||
predict.stats.row,"{0}: {1} markets, avg open {2}, happened {3}%"
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,"{0} falls {1}% in a day, {2} traders liquidated"
|
||||
news.wipe.down.desc,"Over the past day {1} long positions on {0} perps were liquidated, {2} credits in total. The Poinbase insurance fund stands at {3} credits."
|
||||
news.wipe.up.title,"{0} jumps {1}% in a day, {2} traders liquidated"
|
||||
news.wipe.up.desc,"Over the past day {1} short positions on {0} perps were liquidated, {2} credits in total. The Poinbase insurance fund stands at {3} credits."
|
||||
hot.name,Seller
|
||||
hot.intro.CRT,"Things are tense lately and this CRT is too hot to hold. I need cash, fast."
|
||||
hot.intro.PSC,"A mining farm's wallet changed hands last night. The PSC is with me now, and I only take cash."
|
||||
hot.intro.PONERO,"Ransom money, in Ponero. Nobody can trace it. Cash only."
|
||||
hot.offer,"{0} {1}, worth {2} at today's price. Give me {3} in cash and the coins are yours right now."
|
||||
hot.choice.yes,Take it
|
||||
hot.choice.no,Pass
|
||||
hot.say.yes,Deal.
|
||||
hot.say.no,I'm not touching that.
|
||||
hot.done,Coins sent. We never met.
|
||||
hot.refused,Plenty of others will take it.
|
||||
hot.nocash,You can't even put up the cash? Forget it.
|
||||
hot.nowallet,"No wallet connected, so where would the coins go? Forget it."
|
||||
hot.sting,Don't move. Security. Buying stolen funds: the cash is confiscated and this goes on your record.
|
||||
otc.name,OTC client
|
||||
otc.intro.CRT,"Things are tense lately and this CRT is too hot to hold. I need cash, fast."
|
||||
otc.intro.PSC,"A mining farm's wallet changed hands last night. The PSC is with me now, and I only take cash."
|
||||
otc.intro.PONERO,"Ransom money, in Ponero. Nobody can trace it. Cash only."
|
||||
otc.offer,"{0} {1}, worth {2} at today's price, sent from {4}. {3} in cash for all of it, or take part of it."
|
||||
otc.intro.sell,Got some {0} I want to turn into cash. Check where it came from if you like.
|
||||
otc.buy.ask,"I want {0} {1}, worth {2} at today's price. {3} in cash for all of it, or sell me part of it."
|
||||
otc.intro.buy,"Heard you trade coins here. I'm buying, cash."
|
||||
otc.say.trade,Let's do it at the terminal.
|
||||
otc.wait,"Fine, I'll wait."
|
||||
otc.paid,Got it. Here's your cash.
|
||||
tab.otc,Counter
|
||||
otc.h,Counter trade
|
||||
otc.k.side,Client
|
||||
otc.side.sell,Selling {0}
|
||||
otc.side.buy,Buying {0}
|
||||
otc.k.qty,Amount
|
||||
otc.k.value,Market value
|
||||
otc.k.ask,Asking (all)
|
||||
otc.k.bid,Bid (all)
|
||||
otc.k.unit,Unit price
|
||||
otc.k.addr,Client address: {0}
|
||||
otc.lookup,Look up
|
||||
otc.preview.take,"Pay {0} cash, receive {1} {2}"
|
||||
otc.preview.give,"Send {0} {1}, receive {2} cash"
|
||||
otc.deal,Deal
|
||||
otc.cancel,Pass
|
||||
otc.msg.gone,The client has left.
|
||||
otc.msg.cash,Not enough cash.
|
||||
otc.msg.sting,"The client was undercover: {0} cash confiscated, fencing on record."
|
||||
otc.msg.bought,"Received {0} {1}, paid {2} cash."
|
||||
otc.msg.sold,"Sent {0} {1}, received {2} cash."
|
||||
gray.sub.own,My mixer
|
||||
ownmix.h,My mixer
|
||||
ownmix.status.closed,Closed (rug pulled)
|
||||
ownmix.status.seized,"Seized, closed until day {0}"
|
||||
ownmix.status.open,Open
|
||||
ownmix.status.paused,Paused
|
||||
ownmix.k.fee,Fee
|
||||
ownmix.k.rating,Reputation (taint left on payouts)
|
||||
ownmix.k.heat,Heat
|
||||
ownmix.heat.0,Low
|
||||
ownmix.heat.1,Medium
|
||||
ownmix.heat.2,High
|
||||
ownmix.k.anon,Anonymity set
|
||||
ownmix.k.fees,Fees earned
|
||||
ownmix.col.capital,Capital
|
||||
ownmix.col.earned,Earnings
|
||||
ownmix.col.pending,Client coins
|
||||
ownmix.open,Open
|
||||
ownmix.pause,Pause
|
||||
ownmix.inject,Fund
|
||||
ownmix.withdraw,Withdraw
|
||||
ownmix.free,Withdrawable: {0} {1}
|
||||
ownmix.err,More than the withdrawable amount.
|
||||
ownmix.injected,Funded {0} {1}.
|
||||
ownmix.withdrawn,Withdrew {0} {1}.
|
||||
ownmix.withdraw.sum,Withdraw {0} {1} from my mixer
|
||||
pay.ownmix,My mixer funding {0} {1}
|
||||
ownmix.rug,Pull the rug ({0})
|
||||
ownmix.rug.confirm,Click again to take {0}
|
||||
ownmix.rug.sum,Take all funds from my mixer
|
||||
ownmix.rugged,Took {0}; the mixer is closed.
|
||||
nightlog.ownmix.in,"My mixer: {0} deposits, {1} in total, fees {2}."
|
||||
nightlog.ownmix.sting,A deposit at my mixer came from an undercover officer; fencing on record.
|
||||
nightlog.ownmix.seized,"Security seized my mixer: the pool of {0} was confiscated, fencing on record."
|
||||
news.ownmix.seized.title,Security shuts down a mixing service
|
||||
news.ownmix.seized.desc,Security has shut down a mixing service operating in the lower levels and confiscated all its funds. The operator has not been identified.
|
||||
news.ownmix.rug.title,Mixing service vanishes with funds
|
||||
news.ownmix.rug.desc,"A mixing service in the lower levels shut down overnight, and all user funds in transit are gone."
|
||||
pay.otc,OTC client {0} {1} (cash {2})
|
||||
otc.upgrade.title,OTC Desk
|
||||
otc.upgrade.desc,"Adds a Black Lamp target: OTC clients. Some come to sell coins of unknown origin, some come to buy coins; all deals are settled in cash. Includes one Black Lamp."
|
||||
otc.say.no,I'll pass on this one.
|
||||
otc.done,Coins sent. We never met.
|
||||
otc.refused,Then I'll find someone else.
|
||||
otc.nocash,You can't even put up the cash? Forget it.
|
||||
otc.nowallet,"No wallet connected, so where would the coins go? Forget it."
|
||||
otc.sting,Don't move. Security. Buying stolen funds: the cash is confiscated and this goes on your record.
|
||||
hw.err.poinbase,Poinbase does not accept {0}.
|
||||
@@ -50,6 +50,7 @@ report.burnt,Tarjetas quemadas: {0}
|
||||
report.price,Precio de PSC: {0} créditos
|
||||
nightlog.mined,Las plataformas de minería produjeron {0} PSC.
|
||||
nightlog.burnt,Se quemó una {0}.
|
||||
nightlog.turbo,{0} con turbo: minó {1} PSC al instante.
|
||||
coinpay.line,Trato hecho. {0} {1}.
|
||||
nightlog.coinpay,Los pagos de clientes en monedas liquidaron {0} créditos; las monedas fueron a la billetera caliente.
|
||||
nightlog.unpowered,{0} plataforma(s) de minería o minero(s) (máquina) sin energía.
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,Contrabando (alto)
|
||||
black.kind.Tech,Alta tecnología (con sobreprecio)
|
||||
nightlog.bm.ready,Mercado negro: {0} ha llegado; un mensajero pasará en cuanto abras.
|
||||
guide.web3.title,Manual de Web3
|
||||
guide.web3.text,"Banco y comercio: la página del banco es de solo lectura y muestra efectivo, alquiler y el CRC de la cuenta de Poinbase. La página Fondos de Poinbase gestiona depósitos y retiros; primero se elige la moneda: el CRC puede ir por la cuenta bancaria o la billetera, las demás monedas solo por la billetera. Depositar desde el banco convierte créditos en CRC en tu cuenta de Poinbase; retirar al banco convierte CRC nuevamente en créditos y pasa por una revisión de cumplimiento que evalúa la contaminación de la cuenta de Poinbase. Retirar a una billetera exige la dirección de destino y varias confirmaciones hasta acreditarse; la comisión de gas es fija, nivel normal, y se descuenta de la moneda enviada. Si el formato de la dirección o el dígito de control es incorrecto, se rechaza; si el formato es válido pero nadie usa esa dirección, las monedas enviadas se pierden.¶Comercio: PSC significa Probably Stolen Coin, la moneda minada por tarjetas gráficas y mineros (máquinas). El mercado spot de Poinbase tiene dos pares, PSC/CRC y SPARK/CRC, según la moneda elegida en el gráfico. Tanto las compras como las ventas se introducen como cantidad de la moneda negociada; la vista previa muestra la moneda de cotización pagada o recibida, el precio medio incluye la comisión y el deslizamiento no.¶La página de comercio de Web3 permite intercambiar cualquier par de monedas, siempre a través de CRC: si CRC está en un extremo se usa un fondo, si no, dos fondos, con dos comisiones y deslizamiento acumulado; la vista previa muestra la cantidad obtenida, los fondos recorridos y la pérdida. Los canjes entre stablecoins (CRT o CRA contra CRC) usan fondos estables: comisión de {StableFee:%} y casi sin deslizamiento cerca de la paridad; durante una pérdida de paridad la liquidez se reduce, y en un colapso se retira y el deslizamiento se dispara.§Billeteras de hardware: las monedas en cadena residen en billeteras de hardware PLEDGER, cada una con sus propios saldos y contaminación. Una billetera es un objeto: arrástrala a la terminal de comercio para cargarla. Ábrela en la página Billeteras de la terminal; conéctala y desconéctala arriba a la derecha de la terminal. El comercio de la página Web3, la tienda y el mezclador de la página Red gris usan la billetera conectada; sin billetera o sin conexión, son solo de lectura y todos los saldos marcan 0. Los clientes que pagan con monedas pagan a la billetera conectada.¶Los pagos (tienda, mezclador, mostrador de Ponero, tarifas de publicación) comienzan como una factura en la terminal; ingresa la dirección del destinatario en la billetera y mantén presionado ✓ para firmar. Los dos últimos caracteres de una dirección son una suma de verificación, por lo que un error tipográfico de un carácter suele detectarse; de vez en cuando resulta válido y las monedas van a una dirección que nadie usa. Los intercambios en DEX también requieren firmar en la billetera.¶Poinbase es una cuenta de custodia; los depósitos se envían desde la billetera a la dirección de depósito de Poinbase (solo PSC, CRC y SPARK; la plataforma regulada no acepta el CRT del mercado negro ni el CRA de la Revolución, y la billetera bloquea su envío a la dirección de depósito) y los retiros se inician en la página Fondos de Poinbase. El Explorador de la página Billeteras permite consultar transferencias por dirección y solo muestra transferencias realmente ocurridas: cada entrada y salida de tus billeteras (transferencias, canjes en DEX y otras llamadas a contratos, ingresos de mineros, retiros, monedas que otros te envían); Ponero es una moneda de privacidad y nunca aparece. El Dr. Jackson vende más billeteras de hardware; arrastra una a la terminal de comercio para agregarla, hasta {WalletMax}. La tienda tiene opciones más baratas. Una billetera que ya no desees puede destruirse en la página Billeteras; sus monedas se pierden para siempre, y todo lo que se envíe después a su dirección también.¶Las transferencias pagan una comisión de gas: lenta, normal o rápida, y los precios del gas suben y bajan en aproximadamente una semana; cuando la red se congestiona, las comisiones de gas suben y las transacciones lentas pueden ser descartadas del mempool. Verifica la dirección completa antes de enviar.§Staking: el CRA en staking en el fondo de la Revolución genera una tasa diaria que se capitaliza en el monto; retirar implica solicitarlo primero y esperar cuatro días, sin intereses durante la espera y sin forma de retirarlo antes. CRA está parcialmente colateralizado: cada CRA está respaldado por la reserva de CRC de la Revolución y por el token de balance SPARK; la cobertura de la reserva y la tasa de colateralización aparecen en la página de staking. Los intereses se pagan con CRA nuevo sin colateral, lo que diluye la cobertura de la reserva, más rápido cuanto más staking haya; si la cobertura es demasiado baja, la Revolución recorta la Line truncated
|
||||
guide.web3.text,"Banco y comercio: la página del banco es de solo lectura y muestra efectivo, alquiler y el CRC de la cuenta de Poinbase. La página Fondos de Poinbase gestiona depósitos y retiros; primero se elige la moneda: el CRC puede ir por la cuenta bancaria o la billetera, las demás monedas solo por la billetera. Depositar desde el banco convierte créditos en CRC en tu cuenta de Poinbase; retirar al banco convierte CRC nuevamente en créditos y pasa por una revisión de cumplimiento que evalúa la contaminación de la cuenta de Poinbase. Retirar a una billetera exige la dirección de destino y varias confirmaciones hasta acreditarse; la comisión de gas es fija, nivel normal, y se descuenta de la moneda enviada. Si el formato de la dirección o el dígito de control es incorrecto, se rechaza; si el formato es válido pero nadie usa esa dirección, las monedas enviadas se pierden.¶Comercio: PSC significa Probably Stolen Coin, la moneda minada por tarjetas gráficas y mineros (máquinas). El mercado spot de Poinbase tiene dos pares, PSC/CRC y SPARK/CRC, según la moneda elegida en el gráfico. Tanto las compras como las ventas se introducen como cantidad de la moneda negociada; la vista previa muestra la moneda de cotización pagada o recibida, el precio medio incluye la comisión y el deslizamiento no.¶La página de comercio de Web3 permite intercambiar cualquier par de monedas, siempre a través de CRC: si CRC está en un extremo se usa un fondo, si no, dos fondos, con dos comisiones y deslizamiento acumulado; la vista previa muestra la cantidad obtenida, los fondos recorridos y la pérdida. Los canjes entre stablecoins (CRT o CRA contra CRC) usan fondos estables: comisión de {StableFee:%} y casi sin deslizamiento cerca de la paridad; durante una pérdida de paridad la liquidez se reduce, y en un colapso se retira y el deslizamiento se dispara.§Billeteras de hardware: las monedas en cadena residen en billeteras de hardware PLEDGER, cada una con sus propios saldos y contaminación. Una billetera es un objeto: arrástrala a la terminal de comercio para cargarla. Ábrela en la página Billeteras de la terminal; conéctala y desconéctala arriba a la derecha de la terminal. El comercio de la página Web3, la tienda y el mezclador de la página Red gris usan la billetera conectada; sin billetera o sin conexión, son solo de lectura y todos los saldos marcan 0. Los clientes que pagan con monedas pagan a la billetera conectada.¶Los pagos (tienda, mezclador, mostrador de Ponero, tarifas de publicación) comienzan como una factura en la terminal; ingresa la dirección del destinatario en la billetera y mantén presionado ✓ para firmar. Los dos últimos caracteres de una dirección son una suma de verificación, por lo que un error tipográfico de un carácter suele detectarse; de vez en cuando resulta válido y las monedas van a una dirección que nadie usa. Los intercambios en DEX también requieren firmar en la billetera.¶Poinbase es una cuenta de custodia; los depósitos se envían desde la billetera a la dirección de depósito de Poinbase (solo PSC, CRC y SPARK; la plataforma regulada no acepta el CRT del mercado negro ni el CRA de la Revolución, y la billetera bloquea su envío a la dirección de depósito) y los retiros se inician en la página Fondos de Poinbase. El Explorador de la página Billeteras permite consultar transferencias por dirección y solo muestra transferencias realmente ocurridas: cada entrada y salida de tus billeteras (transferencias, canjes en DEX y otras llamadas a contratos, ingresos de mineros, retiros, monedas que otros te envían); Ponero es una moneda de privacidad y nunca aparece. El Dr. Jackson vende más billeteras de hardware; arrastra una a la terminal de comercio para agregarla, hasta {WalletMax}. La tienda tiene opciones más baratas. Una billetera que ya no desees puede destruirse en la página Billeteras; sus monedas se pierden para siempre, y todo lo que se envíe después a su dirección también.¶Las transferencias pagan una comisión de gas: lenta, normal o rápida, y los precios del gas suben y bajan en aproximadamente una semana; cuando la red se congestiona, las comisiones de gas suben y las transacciones lentas pueden ser descartadas del mempool. Verifica la dirección completa antes de enviar.§Staking: el CRA en staking en el fondo de la Revolución genera una tasa diaria que se capitaliza en el monto; retirar implica solicitarlo primero y esperar cuatro días, sin intereses durante la espera y sin forma de retirarlo antes. CRA está parcialmente colateralizado: cada CRA está respaldado por la reserva de CRC de la Revolución y por el token de balance SPARK; la cobertura de la reserva y la tasa de colateralización aparecen en la página de staking. Los intereses se pagan con CRA nuevo sin colateral, lo que diluye la cobertura de la reserva, más rápido cuanto más staking haya; si la cobertura es demasiado baja, la Revolución recorta la Line truncated
|
||||
courier.odd1,...Llegó el paquete.
|
||||
courier.odd2,(Mantiene la mano en el bolsillo). Firma aquí.
|
||||
courier.sign,Firmar
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Agua del nivel superior
|
||||
nightlog.predict.win,"Predicción acertada: ""{0}""; se pagaron {1}."
|
||||
nightlog.predict.lose,"Predicción fallida: ""{0}""; perdiste la apuesta de {1}."
|
||||
nightlog.predict.void,"Predicción anulada: ""{0}""; se reembolsó la apuesta de {1}."
|
||||
nightlog.predict.caught,"Apuesta con información privilegiada detectada: ""{0}""; se confiscaron la apuesta y las ganancias por {1}, registro por fraude."
|
||||
nightlog.predict.insider,"""{0}"" se liquidó por {1}. La policía sospecha de información privilegiada; el pago queda marcado y los fondos contaminados de la billetera aumentan en {2}."
|
||||
predict.tab.markets,Mercados
|
||||
predict.tab.intel,Información
|
||||
predict.acct.crt,{0}: CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}: operación programada
|
||||
predict.brief.none,{0}: nada que iniciar
|
||||
predict.brief.can,{0}: puede iniciar {1}
|
||||
predict.clue.push,Moviste el precio un {0}%: riesgoso
|
||||
nightlog.predict.manip,"Predicción clasificada como manipulación: ""{0}""; apuesta de {1} confiscada, registro por fraude."
|
||||
nightlog.predict.manip,"""{0}"" se liquidó por {1}. Los reguladores sospechan que manipulaste el precio; el pago queda marcado y los fondos contaminados de la billetera aumentan en {2}."
|
||||
news.manip.title,El exchange investiga operaciones inusuales
|
||||
news.manip.desc,Los reguladores informan que alguien manipuló el precio con grandes órdenes al contado para lucrar con derivados y predicciones; los fondos fueron incautados.
|
||||
perp.manip,Ganancia de {0} al cerrar dictaminada como manipulación de precio y confiscada; cuenta de perpetuos congelada por {1} día(s).
|
||||
news.manip.desc,Los reguladores informan que alguien movió el precio con grandes órdenes al contado y obtuvo ganancias con derivados y predicciones; las cuentas involucradas han sido marcadas.
|
||||
taint.overflow,Los fondos contaminados superan ahora el valor de la billetera; el exceso de {0} se registra como fraude.
|
||||
perp.manip,Cierre con ganancias de {0}. Los reguladores sospechan de manipulación de precio; la ganancia queda marcada y los fondos contaminados de la cuenta de Poinbase aumentan en {1}.
|
||||
web3.sub.ponzi,Rendimiento
|
||||
ponzi.h,Esquema Ponzi
|
||||
ponzi.acct,Billetera emisora {0}: CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Soporte de Poinbase
|
||||
scam.support.1,"Hola, soporte de Poinbase por aquí. Detectamos un inicio de sesión inusual en tu cuenta y fue marcada."
|
||||
scam.support.2,Envía {0} CRC hoy a la dirección segura {1} para verificación; se devolverá inmediatamente después.
|
||||
scam.support.3,"De lo contrario, la cuenta quedará congelada para siempre. Me tengo que ir, no olvides enviarlo."
|
||||
predict.sold.caught,"Información privilegiada detectada al vender: apuesta y ganancias confiscadas, fraude registrado."
|
||||
predict.sold.caught,"Vendido, se recibieron {0}. La policía sospecha de información privilegiada; los ingresos quedan marcados y los fondos contaminados de la billetera aumentan en {1}."
|
||||
predict.row.move," (anoche {0} {1})"
|
||||
predict.stats.h,Historial (precio prom. apertura / tasa real)
|
||||
predict.stats.row,"{0}: {1} mercados, prom. apertura {2}, ocurrió {3}%"
|
||||
@@ -911,7 +913,7 @@ mint.sum.in,Acuñar {0} CRA con {1} CRC y {2} SPARK ({3}–{4} días)
|
||||
mint.sum.out,Quemar {0} CRA por CRC y SPARK ({1} días)
|
||||
mint.done.in,Orden de acuñación enviada; vence el día {0}.
|
||||
mint.done.out,Orden de quema enviada; vence el día {0}.
|
||||
nightlog.cra.minted,{0} CRA acuñados, ya en staking ({1}).
|
||||
nightlog.cra.minted,"{0} CRA acuñados, ya en staking ({1})."
|
||||
nightlog.cra.burned,"{0} CRA quemados: +{1} CRC, +{2} SPARK ({3})."
|
||||
predict.clue.subsidy,"Reserva al {0}%; a cero, la advertencia es segura"
|
||||
air.noapprove,sin permiso sobre tokens
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,{0} cae un {1}% en un día: {2} traders liquidados
|
||||
news.wipe.down.desc,"En el último día se liquidaron {1} posiciones largas en perpetuos de {0}, por un total de {2} créditos. El fondo de seguro de Poinbase queda en {3} créditos."
|
||||
news.wipe.up.title,{0} sube un {1}% en un día: {2} traders liquidados
|
||||
news.wipe.up.desc,"En el último día se liquidaron {1} posiciones cortas en perpetuos de {0}, por un total de {2} créditos. El fondo de seguro de Poinbase queda en {3} créditos."
|
||||
hot.name,Vendedor
|
||||
hot.intro.CRT,"Las cosas están tensas y este CRT quema. Necesito efectivo, rápido."
|
||||
hot.intro.PSC,"La billetera de una granja de minería cambió de dueño anoche. El PSC lo tengo yo, y solo acepto efectivo."
|
||||
hot.intro.PONERO,"Un rescate, en Ponero. Nadie puede rastrearlo. Solo efectivo."
|
||||
hot.offer,"{0} {1}, que valen {2} al precio de hoy. Dame {3} en efectivo y las monedas son tuyas ahora mismo."
|
||||
hot.choice.yes,Aceptar
|
||||
hot.choice.no,Rechazar
|
||||
hot.say.yes,Trato hecho.
|
||||
hot.say.no,No pienso tocar eso.
|
||||
hot.done,Monedas enviadas. Nunca nos vimos.
|
||||
hot.refused,Ya habrá otro que lo quiera.
|
||||
hot.nocash,¿Ni siquiera tienes el efectivo? Olvídalo.
|
||||
hot.nowallet,"No hay billetera conectada, ¿adónde mando las monedas? Olvídalo."
|
||||
hot.sting,Quieto. Seguridad. Compra de fondos robados: el efectivo queda confiscado y esto va a tu expediente.
|
||||
otc.name,Cliente OTC
|
||||
otc.intro.CRT,"Las cosas están tensas y este CRT quema. Necesito efectivo, rápido."
|
||||
otc.intro.PSC,"La billetera de una granja de minería cambió de dueño anoche. El PSC lo tengo yo, y solo acepto efectivo."
|
||||
otc.intro.PONERO,"Un rescate, en Ponero. Nadie puede rastrearlo. Solo efectivo."
|
||||
otc.offer,"{0} {1}, con valor de {2} al precio de hoy, enviados desde {4}. {3} en efectivo por todo, o toma una parte."
|
||||
otc.intro.sell,Tengo algo de {0} que quiero convertir en efectivo. Revisa de dónde viene si quieres.
|
||||
otc.buy.ask,"Quiero {0} {1}, con valor de {2} al precio de hoy. {3} en efectivo por todo, o véndeme una parte."
|
||||
otc.intro.buy,"Escuché que cambias monedas aquí. Quiero comprar, en efectivo."
|
||||
otc.say.trade,Hablemos en la terminal.
|
||||
otc.wait,"Está bien, espero."
|
||||
otc.paid,Recibido. Aquí tienes tu efectivo.
|
||||
tab.otc,Mostrador
|
||||
otc.h,Comercio en mostrador
|
||||
otc.k.side,Cliente
|
||||
otc.side.sell,Vendiendo {0}
|
||||
otc.side.buy,Comprando {0}
|
||||
otc.k.qty,Cantidad
|
||||
otc.k.value,Valor de mercado
|
||||
otc.k.ask,Precio pedido (total)
|
||||
otc.k.bid,Precio ofertado (total)
|
||||
otc.k.unit,Precio unitario
|
||||
otc.k.addr,Dirección del cliente: {0}
|
||||
otc.lookup,Consultar
|
||||
otc.preview.take,"Paga {0} en efectivo, recibe {1} {2}"
|
||||
otc.preview.give,"Envía {0} {1}, recibe {2} en efectivo"
|
||||
otc.deal,Trato
|
||||
otc.cancel,Pasar
|
||||
otc.msg.gone,El cliente se fue.
|
||||
otc.msg.cash,Efectivo insuficiente.
|
||||
otc.msg.sting,"El cliente era un agente encubierto: {0} en efectivo confiscado, receptación registrada."
|
||||
otc.msg.bought,"Recibiste {0} {1}, pagaste {2} en efectivo."
|
||||
otc.msg.sold,"Enviaste {0} {1}, recibiste {2} en efectivo."
|
||||
gray.sub.own,Mi mezclador
|
||||
ownmix.h,Mi mezclador
|
||||
ownmix.status.closed,Cerrado (rug pull)
|
||||
ownmix.status.seized,"Clausurado, cerrado hasta el día {0}"
|
||||
ownmix.status.open,Abierto
|
||||
ownmix.status.paused,Pausado
|
||||
ownmix.k.fee,Comisión
|
||||
ownmix.k.rating,Reputación (contaminación restante en pagos)
|
||||
ownmix.k.heat,Alerta
|
||||
ownmix.heat.0,Baja
|
||||
ownmix.heat.1,Media
|
||||
ownmix.heat.2,Alta
|
||||
ownmix.k.anon,Conjunto de anonimato
|
||||
ownmix.k.fees,Comisiones ganadas
|
||||
ownmix.col.capital,Capital
|
||||
ownmix.col.earned,Ganancias
|
||||
ownmix.col.pending,Monedas de clientes
|
||||
ownmix.open,Abrir
|
||||
ownmix.pause,Pausar
|
||||
ownmix.inject,Inyectar
|
||||
ownmix.withdraw,Retiro
|
||||
ownmix.free,Retirable: {0} {1}
|
||||
ownmix.err,Supera la cantidad retirable.
|
||||
ownmix.injected,Se inyectaron {0} {1}.
|
||||
ownmix.withdrawn,Se retiraron {0} {1}.
|
||||
ownmix.withdraw.sum,Retirar {0} {1} de mi mezclador
|
||||
pay.ownmix,Inyección a mi mezclador: {0} {1}
|
||||
ownmix.rug,Hacer rug pull ({0})
|
||||
ownmix.rug.confirm,Haz clic de nuevo para llevarte {0}
|
||||
ownmix.rug.sum,Llevarse todos los fondos de mi mezclador
|
||||
ownmix.rugged,Te llevaste {0}; el mezclador quedó cerrado.
|
||||
nightlog.ownmix.in,"Mi mezclador: depósitos: {0}, total: {1}, comisiones: {2}."
|
||||
nightlog.ownmix.sting,Un depósito en mi mezclador provino de un agente encubierto; se registró receptación.
|
||||
nightlog.ownmix.seized,"Seguridad clausuró mi mezclador: se confiscó el fondo de {0}, se registró receptación."
|
||||
news.ownmix.seized.title,Seguridad clausura un servicio de mezclado
|
||||
news.ownmix.seized.desc,Seguridad clausuró un servicio de mezclado que operaba en el Nivel inferior y confiscó todos sus fondos. No se ha identificado al operador.
|
||||
news.ownmix.rug.title,Un servicio de mezclado desaparece con los fondos
|
||||
news.ownmix.rug.desc,Un servicio de mezclado en el Nivel inferior cerró de la noche a la mañana y todos los fondos de los usuarios en tránsito han desaparecido.
|
||||
pay.otc,Cliente OTC {0} {1} (efectivo {2})
|
||||
otc.upgrade.title,Mostrador OTC
|
||||
otc.upgrade.desc,Añade un objetivo a la Lámpara negra: Clientes OTC. Algunos vienen a vender monedas de origen desconocido y otros a comprar; todos los tratos se liquidan en efectivo. Incluye una Lámpara negra.
|
||||
otc.say.no,Paso esta vez.
|
||||
otc.done,Monedas enviadas. Nunca nos vimos.
|
||||
otc.refused,Entonces buscaré a alguien más.
|
||||
otc.nocash,¿Ni siquiera tienes el efectivo? Olvídalo.
|
||||
otc.nowallet,"No hay billetera conectada, ¿adónde mando las monedas? Olvídalo."
|
||||
otc.sting,Quieto. Seguridad. Compra de fondos robados: el efectivo queda confiscado y esto va a tu expediente.
|
||||
hw.err.poinbase,Poinbase no acepta {0}.
|
||||
@@ -50,6 +50,7 @@ report.burnt,Cartes grillées : {0}
|
||||
report.price,Prix du PSC : {0} crédits
|
||||
nightlog.mined,Les plateformes de minage ont produit {0} PSC.
|
||||
nightlog.burnt,Une {0} a grillé.
|
||||
nightlog.turbo,{0} turbo-boosté : {1} PSC minés immédiatement.
|
||||
coinpay.line,Marché conclu. {0} {1}.
|
||||
nightlog.coinpay,Les paiements en pièces ont réglé {0} crédits ; les pièces ont été transférées sur le portefeuille chaud.
|
||||
nightlog.unpowered,Plateformes de minage ou mineurs non alimentés : {0}.
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,Contrebande (élevée)
|
||||
black.kind.Tech,High-tech (majoration)
|
||||
nightlog.bm.ready,Marché noir : {0} est arrivé ; un livreur passera dès l'ouverture.
|
||||
guide.web3.title,Manuel Web3
|
||||
guide.web3.text,"Banque et trading : la page Banque est en lecture seule et affiche les espèces, le loyer et les CRC du compte Poinbase. La page Fonds de Poinbase gère dépôts et retraits ; on choisit d'abord la pièce : le CRC passe par le compte bancaire ou le portefeuille, les autres pièces uniquement par le portefeuille. Le dépôt depuis la banque convertit les crédits en CRC sur votre compte Poinbase ; le retrait vers la banque reconvertit les CRC en crédits et passe par un contrôle de conformité, qui évalue la contamination du compte Poinbase. Un retrait vers un portefeuille demande l'adresse du destinataire et plusieurs confirmations avant d'arriver ; les frais de gas sont fixés au niveau normal et prélevés sur la pièce envoyée. Un format d'adresse ou un chiffre de contrôle incorrect est refusé ; une adresse au format valide mais que personne n'utilise fait perdre les pièces envoyées.¶Trading : PSC signifie Probably Stolen Coin, la pièce minée par les cartes graphiques et les mineurs (machines). Le spot de Poinbase propose deux paires, PSC/CRC et SPARK/CRC, selon la pièce choisie sur le graphique. Les achats comme les ventes se saisissent en quantité de la monnaie échangée ; l'aperçu indique la monnaie de cotation payée ou reçue, le prix moyen inclut les frais et le glissement non.¶La page de trading Web3 permet d'échanger deux pièces au choix, toujours via le CRC : si le CRC est d'un côté, un seul pool est utilisé, sinon deux pools, avec deux frais et un glissement cumulé ; l'aperçu indique le montant obtenu, le nombre de pools traversés et la perte. Les échanges entre stablecoins (CRT ou CRA contre CRC) passent par des pools stables : {StableFee:%} de frais et quasiment aucun glissement près de l'ancrage ; en cas de désancrage la liquidité s'amincit, et en cas d'effondrement elle est retirée et le glissement s'envole.§Portefeuilles matériels : les pièces sur la blockchain sont conservées dans des portefeuilles matériels PLEDGER, chacun avec ses propres soldes et sa contamination. Un portefeuille est un objet : glissez-le sur le terminal de trading pour le charger. Ouvrez-le sur la page Portefeuilles du terminal ; connectez et déconnectez-le en haut à droite du terminal. Le trading de la page Web3, la boutique et le mixeur de la page Réseau gris utilisent le portefeuille connecté ; sans portefeuille ou sans connexion, ils sont en lecture seule et tous les soldes affichent 0. Les clients qui paient en pièces paient sur le portefeuille connecté.¶Les paiements (boutique, mixeur, comptoir Ponero, frais de mise en vente) débutent par une facture sur le terminal ; saisissez l'adresse du destinataire sur le portefeuille et maintenez ✓ pour signer. Les deux derniers caractères d'une adresse sont une somme de contrôle, de sorte qu'une faute de frappe d'un caractère est généralement interceptée ; il arrive parfois qu'elle soit valide par hasard et les pièces partent alors vers une adresse inutilisée. Les échanges sur le DEX nécessitent également une signature sur le portefeuille.¶Poinbase est un compte dépositaire ; le dépôt s'effectue depuis le portefeuille vers l'adresse de dépôt de Poinbase (uniquement PSC, CRC et SPARK ; la plateforme réglementée n'accepte ni le CRT du Marché noir ni le CRA de la Révolution, et le portefeuille bloque leur envoi vers l'adresse de dépôt), le retrait se lance depuis la page Fonds de Poinbase. L'Explorateur de la page Portefeuilles permet de consulter les transferts par adresse, en n'affichant que les transferts réellement effectués : chaque entrée et sortie de vos portefeuilles (transferts, échanges DEX et autres appels de contrat, gains des mineurs, retraits, pièces que d'autres vous envoient) ; Ponero est une monnaie de confidentialité et n'apparaît jamais. D'autres portefeuilles matériels sont vendus par le Pr Jackson ; glissez-en un sur le terminal de trading pour l'ajouter, jusqu'à {WalletMax} au total. La boutique en propose des moins chers. Un portefeuille devenu inutile peut être détruit sur la page Portefeuilles ; ses pièces sont perdues définitivement, et tout ce qui est envoyé ensuite à son adresse l'est aussi.¶Les transferts sont soumis à des frais de gas : lent, normal ou rapide, et le prix du gas monte et descend sur environ une semaine ; lorsque le réseau est saturé, les frais de gas augmentent et les transactions lentes peuvent être évincées de la mempool. Vérifiez l'adresse complète avant d'envoyer.§Staking : le CRA staké dans le pool de la Révolution rapporte un taux quotidien capitalisé dans le montant staké ; retirer nécessite d'en faire la demande préalable et d'attendre quatre jours, sans intérêt durant cette période ni moyen de récupérer les fonds plus tôt. Le CRA est partiellement collatéralisé : chaque CRA est soutenu par la réserve de CRC détenue par la Révolution et par le jeton d'équilibre SPARK ; le taux de couverture de laLine truncated
|
||||
guide.web3.text,"Banque et trading : la page Banque est en lecture seule et affiche les espèces, le loyer et les CRC du compte Poinbase. La page Fonds de Poinbase gère dépôts et retraits ; on choisit d'abord la pièce : le CRC passe par le compte bancaire ou le portefeuille, les autres pièces uniquement par le portefeuille. Le dépôt depuis la banque convertit les crédits en CRC sur votre compte Poinbase ; le retrait vers la banque reconvertit les CRC en crédits et passe par un contrôle de conformité, qui évalue la contamination du compte Poinbase. Un retrait vers un portefeuille demande l'adresse du destinataire et plusieurs confirmations avant d'arriver ; les frais de gas sont fixés au niveau normal et prélevés sur la pièce envoyée. Un format d'adresse ou un chiffre de contrôle incorrect est refusé ; une adresse au format valide mais que personne n'utilise fait perdre les pièces envoyées.¶Trading : PSC signifie Probably Stolen Coin, la pièce minée par les cartes graphiques et les mineurs (machines). Le spot de Poinbase propose deux paires, PSC/CRC et SPARK/CRC, selon la pièce choisie sur le graphique. Les achats comme les ventes se saisissent en quantité de la monnaie échangée ; l'aperçu indique la monnaie de cotation payée ou reçue, le prix moyen inclut les frais et le glissement non.¶La page de trading Web3 permet d'échanger deux pièces au choix, toujours via le CRC : si le CRC est d'un côté, un seul pool est utilisé, sinon deux pools, avec deux frais et un glissement cumulé ; l'aperçu indique le montant obtenu, le nombre de pools traversés et la perte. Les échanges entre stablecoins (CRT ou CRA contre CRC) passent par des pools stables : {StableFee:%} de frais et quasiment aucun glissement près de l'ancrage ; en cas de désancrage la liquidité s'amincit, et en cas d'effondrement elle est retirée et le glissement s'envole.§Portefeuilles matériels : les pièces sur la blockchain sont conservées dans des portefeuilles matériels PLEDGER, chacun avec ses propres soldes et sa contamination. Un portefeuille est un objet : glissez-le sur le terminal de trading pour le charger. Ouvrez-le sur la page Portefeuilles du terminal ; connectez et déconnectez-le en haut à droite du terminal. Le trading de la page Web3, la boutique et le mixeur de la page Réseau gris utilisent le portefeuille connecté ; sans portefeuille ou sans connexion, ils sont en lecture seule et tous les soldes affichent 0. Les clients qui paient en pièces paient sur le portefeuille connecté.¶Les paiements (boutique, mixeur, comptoir Ponero, frais de mise en vente) débutent par une facture sur le terminal ; saisissez l'adresse du destinataire sur le portefeuille et maintenez ✓ pour signer. Les deux derniers caractères d'une adresse sont une somme de contrôle, de sorte qu'une faute de frappe d'un caractère est généralement interceptée ; il arrive parfois qu'elle soit valide par hasard et les pièces partent alors vers une adresse inutilisée. Les échanges sur le DEX nécessitent également une signature sur le portefeuille.¶Poinbase est un compte dépositaire ; le dépôt s'effectue depuis le portefeuille vers l'adresse de dépôt de Poinbase (uniquement PSC, CRC et SPARK ; la plateforme réglementée n'accepte ni le CRT du Marché noir ni le CRA de la Révolution, et le portefeuille bloque leur envoi vers l'adresse de dépôt), le retrait se lance depuis la page Fonds de Poinbase. L'Explorateur de la page Portefeuilles permet de consulter les transferts par adresse, en n'affichant que les transferts réellement effectués : chaque entrée et sortie de vos portefeuilles (transferts, échanges DEX et autres appels de contrat, gains des mineurs, retraits, pièces que d'autres vous envoient) ; Ponero est une monnaie de confidentialité et n'apparaît jamais. D'autres portefeuilles matériels sont vendus par le Pr Jackson ; glissez-en un sur le terminal de trading pour l'ajouter, jusqu'à {WalletMax} au total. La boutique en propose des moins chers. Un portefeuille devenu inutile peut être détruit sur la page Portefeuilles ; ses pièces sont perdues définitivement, et tout ce qui est envoyé ensuite à son adresse l'est aussi.¶Les transferts sont soumis à des frais de gas : lent, normal ou rapide, et le prix du gas monte et descend sur environ une semaine ; lorsque le réseau est saturé, les frais de gas augmentent et les transactions lentes peuvent être évincées de la mempool. Vérifiez l'adresse complète avant d'envoyer.§Staking : le CRA staké dans le pool de la Révolution rapporte un taux quotidien capitalisé dans le montant staké ; retirer nécessite d'en faire la demande préalable et d'attendre quatre jours, sans intérêt durant cette période ni moyen de récupérer les fonds plus tôt. Le CRA est partiellement collatéralisé : chaque CRA est soutenu par la réserve de CRC détenue par la Révolution et par le jeton d'équilibre SPARK ; le taux de couverture de laLine truncated
|
||||
courier.odd1,...Le colis est là.
|
||||
courier.odd2,(Sa main reste dans sa poche.) Signez ici.
|
||||
courier.sign,Signer
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Eau du niveau supérieur
|
||||
nightlog.predict.win,"Prédiction correcte : ""{0}"", {1} versés."
|
||||
nightlog.predict.lose,"Prédiction incorrecte : ""{0}"", mise de {1} perdue."
|
||||
nightlog.predict.void,"Prédiction annulée : ""{0}"", mise de {1} remboursée."
|
||||
nightlog.predict.caught,"Pari d'initié détecté : ""{0}"", mise et gains de {1} confisqués, fraude inscrite au dossier."
|
||||
nightlog.predict.insider,« {0} » réglé pour {1}. La police soupçonne un délit d'initié ; le paiement est marqué et les fonds contaminés du portefeuille augmentent de {2}.
|
||||
predict.tab.markets,Marchés
|
||||
predict.tab.intel,Infos secrètes
|
||||
predict.acct.crt,{0} : CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0} : opération programmée
|
||||
predict.brief.none,{0} : rien à lancer
|
||||
predict.brief.can,{0} : peut lancer {1}
|
||||
predict.clue.push,Vous avez fait bouger le prix de {0} % : risqué
|
||||
nightlog.predict.manip,"Prédiction jugée comme manipulation de marché : ""{0}"", mise de {1} confisquée, fraude inscrite au dossier."
|
||||
nightlog.predict.manip,« {0} » réglé pour {1}. Les régulateurs vous soupçonnent d'avoir manipulé le cours ; le paiement est marqué et les fonds contaminés du portefeuille augmentent de {2}.
|
||||
news.manip.title,La bourse enquête sur des transactions inhabituelles
|
||||
news.manip.desc,Les régulateurs signalent que des ordres au comptant massifs ont servi à faire bouger les prix pour tirer profit des dérivés et des prédictions ; les fonds ont été saisis.
|
||||
perp.manip,Le profit de clôture de {0} a été jugé comme manipulation de marché et confisqué ; compte de contrats perpétuels gelé pour {1} jours.
|
||||
news.manip.desc,Les régulateurs indiquent qu'un acteur a fait bouger le cours avec de gros ordres spot pour tirer profit des dérivés et des prédictions ; les comptes impliqués ont été signalés.
|
||||
taint.overflow,Les fonds contaminés dépassent désormais la valeur du portefeuille ; l'excédent de {0} est enregistré comme fraude.
|
||||
perp.manip,Clôturé avec un gain de {0}. Les régulateurs soupçonnent une manipulation de marché ; le profit est marqué et les fonds contaminés du compte Poinbase augmentent de {1}.
|
||||
web3.sub.ponzi,Rendement
|
||||
ponzi.h,Système de Ponzi
|
||||
ponzi.acct,Portefeuille émetteur {0} : CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Support Poinbase
|
||||
scam.support.1,"Bonjour, ici le support Poinbase. Nous avons détecté une connexion anormale sur votre compte et celui-ci a été signalé."
|
||||
scam.support.2,Veuillez envoyer aujourd'hui {0} CRC à l'adresse sécurisée {1} pour vérification ; ils seront restitués immédiatement après.
|
||||
scam.support.3,"Sinon, le compte sera gelé définitivement. Je dois filer, n'oubliez pas d'effectuer l'envoi."
|
||||
predict.sold.caught,"Délit d'initié détecté lors de la vente : mise et profits confisqués, fraude inscrite au dossier."
|
||||
predict.sold.caught,"Vendu, reçu {0}. La police soupçonne un délit d'initié ; le produit de la vente est marqué et les fonds contaminés du portefeuille augmentent de {1}."
|
||||
predict.row.move," (la nuit dernière {0} {1})"
|
||||
predict.stats.h,Historique (prix ouv. moy. / taux réel)
|
||||
predict.stats.row,"{0} : {1} marchés, ouv. moy. {2}, survenu {3} %"
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,"{0} chute de {1}% en un jour, {2} traders liquidés"
|
||||
news.wipe.down.desc,"Au cours de la dernière journée, {1} positions longues sur les perps {0} ont été liquidées, pour {2} crédits au total. Le fonds d'assurance de Poinbase s'établit à {3} crédits."
|
||||
news.wipe.up.title,"{0} bondit de {1}% en un jour, {2} traders liquidés"
|
||||
news.wipe.up.desc,"Au cours de la dernière journée, {1} positions courtes sur les perps {0} ont été liquidées, pour {2} crédits au total. Le fonds d'assurance de Poinbase s'établit à {3} crédits."
|
||||
hot.name,Vendeur
|
||||
hot.intro.CRT,"Ça chauffe en ce moment et ce CRT me brûle les doigts. Il me faut du liquide, vite."
|
||||
hot.intro.PSC,"Le portefeuille d'une ferme de minage a changé de main cette nuit. Le PSC est chez moi, et je ne prends que du liquide."
|
||||
hot.intro.PONERO,"Une rançon, en Ponero. Personne ne peut la tracer. Liquide uniquement."
|
||||
hot.offer,"{0} {1}, soit {2} au cours du jour. Donnez-moi {3} en liquide et les pièces sont à vous tout de suite."
|
||||
hot.choice.yes,Accepter
|
||||
hot.choice.no,Refuser
|
||||
hot.say.yes,Marché conclu.
|
||||
hot.say.no,Je n'y touche pas.
|
||||
hot.done,Pièces envoyées. On ne s'est jamais vus.
|
||||
hot.refused,D'autres le prendront.
|
||||
hot.nocash,Vous n'avez même pas le liquide ? Laissez tomber.
|
||||
hot.nowallet,"Aucun portefeuille connecté, où envoyer les pièces ? Laissez tomber."
|
||||
hot.sting,Pas un geste. Sécurité. Achat de fonds volés : le liquide est confisqué et ce sera inscrit à votre dossier.
|
||||
otc.name,Client OTC
|
||||
otc.intro.CRT,"Ça chauffe en ce moment et ce CRT me brûle les doigts. Il me faut du liquide, vite."
|
||||
otc.intro.PSC,"Le portefeuille d'une ferme de minage a changé de main cette nuit. Le PSC est chez moi, et je ne prends que du liquide."
|
||||
otc.intro.PONERO,"Une rançon, en Ponero. Personne ne peut la tracer. Liquide uniquement."
|
||||
otc.offer,"{0} {1}, d'une valeur de {2} au cours du jour, envoyé depuis {4}. {3} en espèces pour la totalité, ou prenez-en une partie."
|
||||
otc.intro.sell,J'ai du {0} à convertir en liquide. Vérifie la provenance si tu veux.
|
||||
otc.buy.ask,"Je cherche {0} {1}, d'une valeur de {2} au cours du jour. {3} en espèces pour la totalité, ou vendez-m'en une partie."
|
||||
otc.intro.buy,"Paraît qu'on échange des cryptos ici. J'achète, en espèces."
|
||||
otc.say.trade,Parlons-en au terminal.
|
||||
otc.wait,"D'accord, j'attends."
|
||||
otc.paid,Reçu. Voilà vos espèces.
|
||||
tab.otc,Comptoir
|
||||
otc.h,Échange au comptoir
|
||||
otc.k.side,Client
|
||||
otc.side.sell,Vente de {0}
|
||||
otc.side.buy,Achat de {0}
|
||||
otc.k.qty,Montant
|
||||
otc.k.value,Valeur marchande
|
||||
otc.k.ask,Prix demandé (total)
|
||||
otc.k.bid,Prix proposé (total)
|
||||
otc.k.unit,Prix unitaire
|
||||
otc.k.addr,Adresse du client : {0}
|
||||
otc.lookup,Consulter
|
||||
otc.preview.take,"Payer {0} en espèces, recevoir {1} {2}"
|
||||
otc.preview.give,"Envoyer {0} {1}, recevoir {2} en espèces"
|
||||
otc.deal,Conclure
|
||||
otc.cancel,Passer
|
||||
otc.msg.gone,Le client est parti.
|
||||
otc.msg.cash,Espèces insuffisantes.
|
||||
otc.msg.sting,"Le client était sous couverture : {0} en espèces confisqués, recel consigné."
|
||||
otc.msg.bought,"Reçu {0} {1}, payé {2} en espèces."
|
||||
otc.msg.sold,"Envoyé {0} {1}, reçu {2} en espèces."
|
||||
gray.sub.own,Mon mixeur
|
||||
ownmix.h,Mon mixeur
|
||||
ownmix.status.closed,Fermé (rug pull)
|
||||
ownmix.status.seized,"Saisi, fermé jusqu'au jour {0}"
|
||||
ownmix.status.open,Ouvert
|
||||
ownmix.status.paused,En pause
|
||||
ownmix.k.fee,Frais
|
||||
ownmix.k.rating,Réputation (contamination restante)
|
||||
ownmix.k.heat,Alerte
|
||||
ownmix.heat.0,Faible
|
||||
ownmix.heat.1,Moyenne
|
||||
ownmix.heat.2,Élevée
|
||||
ownmix.k.anon,Ensemble d'anonymat
|
||||
ownmix.k.fees,Frais perçus
|
||||
ownmix.col.capital,Capital
|
||||
ownmix.col.earned,Gains
|
||||
ownmix.col.pending,Pièces clients
|
||||
ownmix.open,Ouvrir
|
||||
ownmix.pause,Suspendre
|
||||
ownmix.inject,Injecter
|
||||
ownmix.withdraw,Retrait
|
||||
ownmix.free,Retrait possible : {0} {1}
|
||||
ownmix.err,Dépasse le montant disponible au retrait.
|
||||
ownmix.injected,Injection de {0} {1}.
|
||||
ownmix.withdrawn,Retrait de {0} {1}.
|
||||
ownmix.withdraw.sum,Retirer {0} {1} de mon mixeur
|
||||
pay.ownmix,Financement de mon mixeur : {0} {1}
|
||||
ownmix.rug,Rug pull ({0})
|
||||
ownmix.rug.confirm,Cliquer à nouveau pour emporter {0}
|
||||
ownmix.rug.sum,Emporter tous les fonds de mon mixeur
|
||||
ownmix.rugged,{0} emportés ; le mixeur est fermé.
|
||||
nightlog.ownmix.in,"Mon mixeur : dépôts : {0}, total : {1}, frais : {2}."
|
||||
nightlog.ownmix.sting,Un dépôt dans mon mixeur provenait d'un agent infiltré de la Sécurité ; recel consigné.
|
||||
nightlog.ownmix.seized,"La Sécurité a saisi mon mixeur : le pool de {0} a été confisqué, recel consigné."
|
||||
news.ownmix.seized.title,La Sécurité ferme un service de mixage
|
||||
news.ownmix.seized.desc,La Sécurité a fermé un service de mixage opérant au Niveau inférieur et a confisqué tous ses fonds. L'opérateur n'a pas été identifié.
|
||||
news.ownmix.rug.title,Un service de mixage disparaît avec les fonds
|
||||
news.ownmix.rug.desc,"Un service de mixage du Niveau inférieur a fermé du jour au lendemain, et tous les fonds des utilisateurs en transit ont disparu."
|
||||
pay.otc,Client OTC {0} {1} (liquide {2})
|
||||
otc.upgrade.title,Comptoir OTC
|
||||
otc.upgrade.desc,"Ajoute une cible à la Lampe noire : Clients OTC. Certains viennent vendre des jetons d'origine inconnue, d'autres viennent en acheter ; toutes les transactions se règlent en liquide. Inclut une Lampe noire."
|
||||
otc.say.no,Je passe pour cette fois.
|
||||
otc.done,Pièces envoyées. On ne s'est jamais vus.
|
||||
otc.refused,Alors j'irai voir ailleurs.
|
||||
otc.nocash,Vous n'avez même pas le liquide ? Laissez tomber.
|
||||
otc.nowallet,"Aucun portefeuille connecté, où envoyer les pièces ? Laissez tomber."
|
||||
otc.sting,Pas un geste. Sécurité. Achat de fonds volés : le liquide est confisqué et ce sera inscrit à votre dossier.
|
||||
hw.err.poinbase,Poinbase n'accepte pas le {0}.
|
||||
@@ -50,6 +50,7 @@ report.burnt,焼損ボード:{0}
|
||||
report.price,PSC価格:{0}クレジット
|
||||
nightlog.mined,マイニングリグが{0} PSCを採掘しました。
|
||||
nightlog.burnt,{0}が1枚焼損した。
|
||||
nightlog.turbo,{0}をターボブースト:直ちに{1} PSCを採掘。
|
||||
coinpay.line,取引成立。{0} {1}。
|
||||
nightlog.coinpay,コイン決済の客からの代金は計{0}クレジットが精算され、コインはホットウォレットに入った。
|
||||
nightlog.unpowered,{0}台のマイニングリグまたは専用採掘機に電力が供給されていませんでした。
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,禁制品(高)
|
||||
black.kind.Tech,ハイテク品(割増)
|
||||
nightlog.bm.ready,闇市場:{0} が到着。開店後に配達人が届けてくれる。
|
||||
guide.web3.title,Web3ハンドブック
|
||||
guide.web3.text,銀行と取引:銀行ページは閲覧専用で、現金、家賃、Poinbase口座のCRCを表示する。入金と出金はPoinbaseの資金ページで行い、先にコインを選ぶ。CRCは銀行口座とウォレットのどちらでも可能で、他のコインはウォレットのみ。銀行からの入金はクレジットをPoinbase口座のCRCに変換し、銀行への出金はCRCをクレジットに戻すが、Poinbase口座の汚染を対象としたコンプライアンス審査が行われる。ウォレットへの出金は受取アドレスの入力が必要で、数回の承認を経て着金する。ガス代は通常の段階で固定され、送るコインから差し引かれる。アドレスの形式やチェックディジットが誤っていると拒否される。形式が正しくても誰も使っていないアドレスに送ったコインは失われる。¶取引:PSCは Probably Stolen Coin の略称で、グラフィックボードや専用採掘機で採掘されるコイン。Poinbaseの現物にはPSC/CRCとSPARK/CRCの2つのペアがあり、チャートで選んだコインに合わせて切り替わる。買いも売りも取引対象のコインの数量で入力する。プレビューには支払う・受け取る決済通貨が表示され、平均価格は手数料込み、スリッページは手数料を含まない。¶Web3の取引ページでは任意の2種類のコインを交換でき、必ずCRCを経由する。CRCが片側なら1つのプール、そうでなければ2つのプールを通り、手数料は2回、スリッページは重なる。プレビューに受取数量、経由するプール数、損失が表示される。ステーブルコイン同士(CRT・CRAとCRC)はステーブルプールを使い、手数料は{StableFee:%}、ペッグ付近ではスリッページがほぼない。ペッグが外れると流動性が薄くなり、崩壊時には流動性が引き揚げられてスリッページが急増する。§ハードウェアウォレット:チェーン上のコインはPLEDGERハードウェアウォレットに保管され、ウォレットごとに残高と汚染が個別に管理される。ウォレットはアイテムで、取引ターミナルにドラッグして読み込む。ターミナルのウォレットページで開き、ターミナル右上で接続・切断する。Web3ページの取引とグレーネットページのショップ、ミキサーは接続されたウォレットを使用する。ウォレットがない、または接続していないときは閲覧のみで、残高はすべて0になる。コイン決済の客は接続されたウォレットに支払う。¶支払い(ショップ、ミキサー、Ponero窓口、出品手数料)はまずターミナルで請求書を発行し、ウォレット側で送金先アドレスを入力して✓を長押しして署名する。アドレスの末尾2文字はチェックサムのため、1文字の誤入力なら通常は検出されるが、偶然有効なアドレスに一致した場合は誰も使っていないアドレスにコインが送られてしまう。DEXでのスワップもウォレットでの署名が必要となる。¶Poinbaseはカストディ口座で、入金はウォレットからPoinbaseの入金アドレスへ送金し(受け付けるのはPSC、CRC、SPARKのみ。規制下の取引所なので闇市場のCRTと革命軍のCRAは受け付けず、入金アドレスへの送金はウォレットが止める)、出金はPoinbaseの資金ページで行う。ウォレットページのエクスプローラーではアドレスで送金履歴を検索でき、実際に行われた送金のみが表示される:自分のウォレットのすべての入出金(送金、DEXスワップなどのコントラクト呼び出し、採掘機の収益、出金、他人から送られたコイン)。Poneroはプライバシーコインのため表示されない。追加のハードウェアウォレットはジャックソン博士から購入し、取引ターミナルにドラッグして追加する(最大{WalletMax}個)。ショップにはより安価なものもある。不要になったウォレットは、ウォレットページで破棄できる。中のコインは永久に失われ、その後このアドレスに送られたものも失われる。¶送金にはガス代が必要で、低速・通常・高速の3段階があり、ガス価格は約1週間周期で上下する。ネットワーク混雑時はガス代が高騰し、低速のトランザクションはメムプールから除外されることがある。送金前にアドレス全体を必ず確認すること。§ステーキング:革命家のプールにCRAをステーキングすると日利が付与され、利息は元本に複利で組み入れられる。出金するにはまず申請しLine truncated
|
||||
guide.web3.text,銀行と取引:銀行ページは閲覧専用で、現金、家賃、Poinbase口座のCRCを表示する。入金と出金はPoinbaseの資金ページで行い、先にコインを選ぶ。CRCは銀行口座とウォレットのどちらでも可能で、他のコインはウォレットのみ。銀行からの入金はクレジットをPoinbase口座のCRCに変換し、銀行への出金はCRCをクレジットに戻すが、Poinbase口座の汚染を対象としたコンプライアンス審査が行われる。ウォレットへの出金は受取アドレスの入力が必要で、数回の承認を経て着金する。ガス代は通常の段階で固定され、送るコインから差し引かれる。アドレスの形式やチェックディジットが誤っていると拒否される。形式が正しくても誰も使っていないアドレスに送ったコインは失われる。¶取引:PSCは Probably Stolen Coin の略称で、グラフィックボードや専用採掘機で採掘されるコイン。Poinbaseの現物にはPSC/CRCとSPARK/CRCの2つのペアがあり、チャートで選んだコインに合わせて切り替わる。買いも売りも取引対象のコインの数量で入力する。プレビューには支払う・受け取る決済通貨が表示され、平均価格は手数料込み、スリッページは手数料を含まない。¶Web3の取引ページでは任意の2種類のコインを交換でき、必ずCRCを経由する。CRCが片側なら1つのプール、そうでなければ2つのプールを通り、手数料は2回、スリッページは重なる。プレビューに受取数量、経由するプール数、損失が表示される。ステーブルコイン同士(CRT・CRAとCRC)はステーブルプールを使い、手数料は{StableFee:%}、ペッグ付近ではスリッページがほぼない。ペッグが外れると流動性が薄くなり、崩壊時には流動性が引き揚げられてスリッページが急増する。§ハードウェアウォレット:チェーン上のコインはPLEDGERハードウェアウォレットに保管され、ウォレットごとに残高と汚染が個別に管理される。ウォレットはアイテムで、取引ターミナルにドラッグして読み込む。ターミナルのウォレットページで開き、ターミナル右上で接続・切断する。Web3ページの取引とグレーネットページのショップ、ミキサーは接続されたウォレットを使用する。ウォレットがない、または接続していないときは閲覧のみで、残高はすべて0になる。コイン決済の客は接続されたウォレットに支払う。¶支払い(ショップ、ミキサー、Ponero窓口、出品手数料)はまずターミナルで請求書を発行し、ウォレット側で送金先アドレスを入力して✓を長押しして署名する。アドレスの末尾2文字はチェックサムのため、1文字の誤入力なら通常は検出されるが、偶然有効なアドレスに一致した場合は誰も使っていないアドレスにコインが送られてしまう。DEXでのスワップもウォレットでの署名が必要となる。¶Poinbaseはカストディ口座で、入金はウォレットからPoinbaseの入金アドレスへ送金し(受け付けるのはPSC、CRC、SPARKのみ。規制下の取引所なので闇市場のCRTと革命軍のCRAは受け付けず、入金アドレスへの送金はウォレットが止める)、出金はPoinbaseの資金ページで行う。ウォレットページのエクスプローラーではアドレスで送金履歴を検索でき、実際に行われた送金のみが表示される:自分のウォレットのすべての入出金(送金、DEXスワップなどのコントラクト呼び出し、採掘機の収益、出金、他人から送られたコイン)。Poneroはプライバシーコインのため表示されない。追加のハードウェアウォレットはジャックソン博士から購入し、取引ターミナルにドラッグして追加する(最大{WalletMax}個)。ショップにはより安価なものもある。不要になったウォレットは、ウォレットページで破棄できる。中のコインは永久に失われ、その後このアドレスに送られたものも失われる。¶送金にはガス代が必要で、低速・通常・高速の3段階があり、ガス価格は約1週間周期で上下する。ネットワーク混雑時はガス代が高騰し、低速のトランザクションはメムプールから除外されることがある。送金前にアドレス全体を必ず確認すること。§ステーキング:革命家のプールにCRAをステーキングすると日利が付与され、利息は元本に複利で組み入れられる。出金するにはまず申請しLine truncated
|
||||
courier.odd1,……荷物が届いた。
|
||||
courier.odd2,(ポケットに手を入れたままだ)ここにサインを。
|
||||
courier.sign,サイン
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,上層水
|
||||
nightlog.predict.win,予測的中:「{0}」、{1}が払い戻された。
|
||||
nightlog.predict.lose,予測不的中:「{0}」、賭け金{1}を失った。
|
||||
nightlog.predict.void,予測無効:「{0}」、賭け金{1}が返還された。
|
||||
nightlog.predict.caught,インサイダー取引が摘発:「{0}」、賭け金と配当{1}が没収され、詐欺の犯罪証拠が記録された。
|
||||
nightlog.predict.insider,「{0}」が {1} で決済。警察はインサイダー取引を疑っており、払戻金がマークされウォレットの汚染が {2} 増加した。
|
||||
predict.tab.markets,市場
|
||||
predict.tab.intel,情報
|
||||
predict.acct.crt,{0}:CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}:作戦予定あり
|
||||
predict.brief.none,{0}:発動可能な作戦なし
|
||||
predict.brief.can,{0}:{1}を発動可能
|
||||
predict.clue.push,プレイヤーの価格誘導 {0}%: 操縦リスク高
|
||||
nightlog.predict.manip,予測が価格操縦と認定:「{0}」、賭け金{1}が没収され、詐欺の犯罪証拠が記録された。
|
||||
nightlog.predict.manip,「{0}」が {1} で決済。規制当局は価格操縦を疑っており、払戻金がマークされウォレットの汚染が {2} 増加した。
|
||||
news.manip.title,取引所が不審な取引を調査
|
||||
news.manip.desc,規制当局の発表によると、大口現物注文で価格を操作し、デリバティブや予測市場で不当な利益を得た者がおり、関係資金は差し押さえられた。
|
||||
perp.manip,決済利益{0}が価格操縦と認定され没収。無期限先物口座が{1}日間凍結された。
|
||||
news.manip.desc,規制当局の発表によると、大口の現物注文で価格を動かし、デリバティブや予測市場から利益を得た者が存在し、関係口座はフラグ付きとなった。
|
||||
taint.overflow,汚染がウォレットの価値を超過。超過した {0} は詐欺の罪状として記録される。
|
||||
perp.manip,決済利益 {0}。規制当局は価格操縦を疑っており、利益がマークされPoinbaseアカウントの汚染が {1} 増加した。
|
||||
web3.sub.ponzi,利回り
|
||||
ponzi.h,ポンジ・スキーム
|
||||
ponzi.acct,発行者ウォレット {0}:CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Poinbaseサポート
|
||||
scam.support.1,こんにちは、Poinbaseサポートです。お客様のアカウントで異常なログインが検出され、フラグ付きとなりました。
|
||||
scam.support.2,本日中に確認のため安全アドレス {1} へ {0} CRC を送金してください。確認後すぐに返金されます。
|
||||
scam.support.3,対応いただけない場合、アカウントは永久に凍結されます。では失礼します、送金を忘れずに。
|
||||
predict.sold.caught,売却時にインサイダー取引が発覚:元本と利益をすべて没収、詐欺の証拠を記録。
|
||||
predict.sold.caught,売却完了、{0} を受領。警察はインサイダー取引を疑っており、受取金がマークされウォレットの汚染が {1} 増加した。
|
||||
predict.row.move,(昨晩 {0} {1})
|
||||
predict.stats.h,履歴(始値平均 / 実際の発生率)
|
||||
predict.stats.row,{0}:{1}件、始値平均 {2}、発生率 {3}%
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,{0}が1日で{1}%下落、{2}人がロスカット
|
||||
news.wipe.down.desc,この1日で{0}無期限先物のロングポジション{1}件がロスカットされ、総額は{2}クレジットに上った。Poinbaseの保険基金残高は{3}クレジット。
|
||||
news.wipe.up.title,{0}が1日で{1}%上昇、{2}人がロスカット
|
||||
news.wipe.up.desc,この1日で{0}無期限先物のショートポジション{1}件がロスカットされ、総額は{2}クレジットに上った。Poinbaseの保険基金残高は{3}クレジット。
|
||||
hot.name,売り手
|
||||
hot.intro.CRT,最近は物騒で、このCRTを持っているのは危ない。急いで現金にしたい。
|
||||
hot.intro.PSC,ある採掘場のウォレットが昨夜持ち主を変えた。PSCは今こっちにある。現金しか受け取らない。
|
||||
hot.intro.PONERO,身代金だ、Poneroで。出所は誰にも追えない。現金のみ。
|
||||
hot.offer,{0} {1}、今の相場で{2}相当だ。現金{3}で、コインはこの場で送る。
|
||||
hot.choice.yes,受け取る
|
||||
hot.choice.no,断る
|
||||
hot.say.yes,取引成立だ。
|
||||
hot.say.no,それには手を出さない。
|
||||
hot.done,送った。俺たちは会っていない。
|
||||
hot.refused,欲しがる奴はいくらでもいる。
|
||||
hot.nocash,現金も用意できないのか?ならやめだ。
|
||||
hot.nowallet,ウォレットがつながっていない。コインをどこに送れと?やめだ。
|
||||
hot.sting,動くな、警察だ。盗まれた資金の買い取りだな。現金は没収、記録にも残る。
|
||||
otc.name,OTC客
|
||||
otc.intro.CRT,最近は物騒で、このCRTを持っているのは危ない。急いで現金にしたい。
|
||||
otc.intro.PSC,ある採掘場のウォレットが昨夜持ち主を変えた。PSCは今こっちにある。現金しか受け取らない。
|
||||
otc.intro.PONERO,身代金だ、Poneroで。出所は誰にも追えない。現金のみ。
|
||||
otc.offer,{0} {1}、時価{2}相当、{4}から送金。全額なら現金{3}、一部だけでも構わない。
|
||||
otc.intro.sell,手持ちの{0}を現金に換えたい。出所は自分で調べてくれ。
|
||||
otc.buy.ask,{0} {1}を買いたい、時価{2}相当だ。全額なら現金{3}支払う、一部だけでも構わない。
|
||||
otc.intro.buy,ここで通貨を取引できると聞いた。現金で買いたい。
|
||||
otc.say.trade,ターミナルで話そう。
|
||||
otc.wait,分かった、待ってるよ。
|
||||
otc.paid,着金した。現金を受け取ってくれ。
|
||||
tab.otc,カウンター
|
||||
otc.h,カウンター取引
|
||||
otc.k.side,顧客
|
||||
otc.side.sell,{0}売却
|
||||
otc.side.buy,{0}購入
|
||||
otc.k.qty,数量
|
||||
otc.k.value,時価
|
||||
otc.k.ask,売値(全額)
|
||||
otc.k.bid,買値(全額)
|
||||
otc.k.unit,単価
|
||||
otc.k.addr,顧客アドレス:{0}
|
||||
otc.lookup,アドレス照会
|
||||
otc.preview.take,現金{0}を支払い、{1} {2}を受け取る
|
||||
otc.preview.give,{0} {1}を送金し、現金{2}を受け取る
|
||||
otc.deal,成約
|
||||
otc.cancel,見送り
|
||||
otc.msg.gone,客はすでに立ち去った。
|
||||
otc.msg.cash,現金が足りない。
|
||||
otc.msg.sting,相手は潜入捜査官だった:現金{0}が没収され、盗品売買が記録された。
|
||||
otc.msg.bought,{0} {1}を受け取り、現金{2}を支払った。
|
||||
otc.msg.sold,{0} {1}を送金し、現金{2}を受け取った。
|
||||
gray.sub.own,自営ミキサー
|
||||
ownmix.h,自営ミキサー
|
||||
ownmix.status.closed,閉鎖(ラグプル)
|
||||
ownmix.status.seized,差し押さえ、第{0}日まで閉鎖
|
||||
ownmix.status.open,営業中
|
||||
ownmix.status.paused,一時停止中
|
||||
ownmix.k.fee,手数料率
|
||||
ownmix.k.rating,評判(出金に残る汚染)
|
||||
ownmix.k.heat,警戒度
|
||||
ownmix.heat.0,低
|
||||
ownmix.heat.1,中
|
||||
ownmix.heat.2,高
|
||||
ownmix.k.anon,匿名セット
|
||||
ownmix.k.fees,累計手数料
|
||||
ownmix.col.capital,元本
|
||||
ownmix.col.earned,収益
|
||||
ownmix.col.pending,顧客コイン
|
||||
ownmix.open,営業開始
|
||||
ownmix.pause,一時停止
|
||||
ownmix.inject,資金投入
|
||||
ownmix.withdraw,出金
|
||||
ownmix.free,出金可能:{0} {1}
|
||||
ownmix.err,出金可能な数量を超えています。
|
||||
ownmix.injected,{0} {1}を投入した。
|
||||
ownmix.withdrawn,{0} {1}を出金した。
|
||||
ownmix.withdraw.sum,自営ミキサーから{0} {1}を出金
|
||||
pay.ownmix,自営ミキサーへの資金投入 {0} {1}
|
||||
ownmix.rug,ラグプル({0})
|
||||
ownmix.rug.confirm,再度クリックして{0}を持ち逃げ
|
||||
ownmix.rug.sum,自営ミキサーの全資金を持ち逃げ
|
||||
ownmix.rugged,{0}を持ち逃げした。ミキサーは閉鎖された。
|
||||
nightlog.ownmix.in,自営ミキサー:入金{0}件、合計{1}、手数料{2}。
|
||||
nightlog.ownmix.sting,自営ミキサーへの入金の1件が警察の潜入捜査官によるものだった。故買の罪証が記録された。
|
||||
nightlog.ownmix.seized,警察が自営ミキサーを摘発:プール内の{0}が全額没収され、故買の罪証が記録された。
|
||||
news.ownmix.seized.title,警察がミキサーサービスを摘発
|
||||
news.ownmix.seized.desc,警察は下層で運営されていたミキサーサービスを摘発し、全資金を押収した。運営者の身元は特定されていない。
|
||||
news.ownmix.rug.title,ミキサーサービスが資金を持ち逃げ
|
||||
news.ownmix.rug.desc,下層のミキサーサービスが一夜にして閉鎖され、送金途中の全ユーザー資金が消失した。
|
||||
pay.otc,OTC客 {0} {1}(現金 {2})
|
||||
otc.upgrade.title,OTCデスク
|
||||
otc.upgrade.desc,黒いランプの対象に「OTC客」が追加される。出所不明のコインを売りに来る者や、コインを買いに来る者が訪れ、すべての取引は現金で決済される。黒いランプが1個付属。
|
||||
otc.say.no,今回は見送るよ。
|
||||
otc.done,送った。俺たちは会っていない。
|
||||
otc.refused,なら他を当たるよ。
|
||||
otc.nocash,現金も用意できないのか?ならやめだ。
|
||||
otc.nowallet,ウォレットがつながっていない。コインをどこに送れと?やめだ。
|
||||
otc.sting,動くな、警察だ。盗まれた資金の買い取りだな。現金は没収、記録にも残る。
|
||||
hw.err.poinbase,Poinbaseは{0}を受け付けない。
|
||||
@@ -50,6 +50,7 @@ report.burnt,Przepalone karty: {0}
|
||||
report.price,Cena PSC: {0} kredytów
|
||||
nightlog.mined,Koparki wydobyły {0} PSC.
|
||||
nightlog.burnt,Karta {0} uległa przepaleniu.
|
||||
nightlog.turbo,{0} – turbodoładowanie: natychmiast wydobyto {1} PSC.
|
||||
coinpay.line,Zgoda. {0} {1}.
|
||||
nightlog.coinpay,Klienci płacący monetami uregulowali {0} kredytów; monety trafiły do gorącego portfela.
|
||||
nightlog.unpowered,Koparki bez zasilania: {0}.
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,Kontrabanda (wysoki poziom)
|
||||
black.kind.Tech,Zaawansowana technologia (marża)
|
||||
nightlog.bm.ready,Czarny Rynek: {0} na miejscu; kurier pojawi się po otwarciu lokalu.
|
||||
guide.web3.title,Podręcznik Web3
|
||||
guide.web3.text,"Bank i handel: strona banku jest tylko do odczytu i pokazuje gotówkę, czynsz oraz CRC na koncie Poinbase. Strona Środki w Poinbase obsługuje wpłaty i wypłaty; najpierw wybiera się monetę: CRC może iść przez konto bankowe lub portfel, pozostałe monety tylko przez portfel. Wpłata z banku zamienia kredyty na CRC na koncie Poinbase; wypłata do banku zamienia CRC z powrotem na kredyty i podlega kontroli zgodności, sprawdzającej skażenie konta Poinbase. Wypłata do portfela wymaga podania adresu odbiorcy i kilku potwierdzeń do zaksięgowania; opłata gas jest stała, na poziomie normalnym, i pobierana z wysyłanej monety. Błędny format adresu lub cyfra kontrolna powoduje odrzucenie; adres o poprawnym formacie, którego nikt nie używa, oznacza utratę wysłanych monet.¶Handel: PSC to skrót od Probably Stolen Coin, monety wydobywanej przez karty graficzne i koparki. Rynek spot Poinbase ma dwie pary, PSC/CRC i SPARK/CRC, zależnie od monety wybranej na wykresie. Zarówno zakup, jak i sprzedaż wpisuje się jako ilość monety bazowej; podgląd pokazuje zapłaconą lub otrzymaną monetę kwotowaną, średnia cena zawiera prowizję, a poślizg nie.¶Strona handlu Web3 pozwala wymienić dowolne dwie monety, zawsze przez CRC: gdy CRC jest po jednej stronie, używana jest jedna pula, w przeciwnym razie dwie, z dwiema opłatami i sumującym się poślizgiem; podgląd pokazuje otrzymaną ilość, liczbę pul i stratę. Wymiany między stablecoinami (CRT lub CRA na CRC) idą przez pule stabilne: prowizja {StableFee:%} i prawie zerowy poślizg blisko powiązania; przy utracie powiązania płynność maleje, a przy krachu zostaje wycofana i poślizg gwałtownie rośnie.§Portfele sprzętowe: monety w łańcuchu znajdują się w portfelach sprzętowych PLEDGER, a każdy z nich ma własne saldo i poziom skażenia. Portfel jest przedmiotem: przeciągnij go na terminal handlowy, aby go załadować. Otwórz go na stronie Portfele w terminalu; połącz i odłącz w prawym górnym rogu terminala. Handel na stronie Web3 oraz sklep i mikser na stronie Szara sieć korzystają z połączonego portfela; bez portfela lub bez połączenia są tylko do odczytu, a wszystkie salda wynoszą 0. Klienci płacący monetami płacą na połączony portfel.¶Płatności (sklep, mikser, kantor Ponero, opłaty za wystawienie) zaczynają się od rachunku w terminalu; wpisz adres odbiorcy w portfelu i przytrzymaj ✓, aby podpisać. Dwa ostatnie znaki adresu to suma kontrolna, więc pomyłka o jeden znak jest zwykle wychwytywana; sporadycznie zdarza się, że okazuje się poprawny i monety trafiają pod adres, z którego nikt nie korzysta. Wymiany na DEX również wymagają podpisu na portfelu.¶Poinbase to konto powiernicze; wpłaty wysyła się z portfela na adres wpłat Poinbase (tylko PSC, CRC i SPARK; regulowana giełda nie przyjmuje CRT Czarnego Rynku ani CRA Rewolucji, a portfel blokuje wysłanie ich na adres wpłat), a wypłaty zleca się na stronie Środki w Poinbase. Eksplorator na stronie Portfele pozwala sprawdzać przelewy według adresu i pokazuje wyłącznie przelewy, które faktycznie miały miejsce: każdy ruch do i z twoich portfeli (przelewy, wymiany na DEX i inne wywołania kontraktów, zyski koparek, wypłaty, monety wysyłane ci przez innych); Ponero to moneta prywatności i nigdy się nie pojawia. Więcej portfeli sprzętowych sprzedaje Dr Jackson; przeciągnij portfel na terminal handlowy, aby go dodać – maksymalnie do {WalletMax}. W sklepie dostępne są tańsze. Niepotrzebny portfel można zniszczyć na stronie Portfele; jego monety przepadają na zawsze, podobnie jak wszystko, co zostanie później wysłane na jego adres.¶Przelewy wymagają opłaty gas: wolnej, normalnej lub szybkiej, a ceny gasu rosną i spadają w cyklu około tygodnia; gdy sieć jest przeciążona, opłaty gas rosną, a powolne transakcje mogą zostać usunięte z mempoola. Przed wysłaniem sprawdź pełny adres.§Staking: CRA ulokowane w puli Rewolucji przynosi dzienny zysk według stawki dziennej, doliczany do wkładu; wypłata wymaga wcześniejszego złożenia wniosku i odczekania czterech dni, bez naliczania odsetek w okresie oczekiwania i bez możliwości wcześniejszego odbioru. CRA jest częściowo zabezpieczone: każde CRA wspierają rezerwa CRC należąca do Rewolucji oraz token równoważący SPARK; pokrycie rezerwy i stopa zabezpieczenia widnieją na stronie stakingu. Odsetki wypłacane są w nowych, niezabezpieczonych CRA, co rozwadnia pokrycie rezerwy, tym szybciej, im więcej w stakingu; przy zbyt niskim pokryciu Rewolucja obniża stawkę. Rewolucja czasem sięga po rezerwę, a wcześniej krążą pogłoski: to zapowiedź. Jeśli potem pokrycie spadnie poniżej {CraCrashRatio:%}, następuje krach: CRA staje się bezwartościowe w ciągu trzech dni, a cztery dni na odblokowanie to za wolno; powyżej tego progu jest tylko dyskonto, a środki z grabieży Górnego poziomu stopniowo odbudowują rezerwę.Line truncated
|
||||
guide.web3.text,"Bank i handel: strona banku jest tylko do odczytu i pokazuje gotówkę, czynsz oraz CRC na koncie Poinbase. Strona Środki w Poinbase obsługuje wpłaty i wypłaty; najpierw wybiera się monetę: CRC może iść przez konto bankowe lub portfel, pozostałe monety tylko przez portfel. Wpłata z banku zamienia kredyty na CRC na koncie Poinbase; wypłata do banku zamienia CRC z powrotem na kredyty i podlega kontroli zgodności, sprawdzającej skażenie konta Poinbase. Wypłata do portfela wymaga podania adresu odbiorcy i kilku potwierdzeń do zaksięgowania; opłata gas jest stała, na poziomie normalnym, i pobierana z wysyłanej monety. Błędny format adresu lub cyfra kontrolna powoduje odrzucenie; adres o poprawnym formacie, którego nikt nie używa, oznacza utratę wysłanych monet.¶Handel: PSC to skrót od Probably Stolen Coin, monety wydobywanej przez karty graficzne i koparki. Rynek spot Poinbase ma dwie pary, PSC/CRC i SPARK/CRC, zależnie od monety wybranej na wykresie. Zarówno zakup, jak i sprzedaż wpisuje się jako ilość monety bazowej; podgląd pokazuje zapłaconą lub otrzymaną monetę kwotowaną, średnia cena zawiera prowizję, a poślizg nie.¶Strona handlu Web3 pozwala wymienić dowolne dwie monety, zawsze przez CRC: gdy CRC jest po jednej stronie, używana jest jedna pula, w przeciwnym razie dwie, z dwiema opłatami i sumującym się poślizgiem; podgląd pokazuje otrzymaną ilość, liczbę pul i stratę. Wymiany między stablecoinami (CRT lub CRA na CRC) idą przez pule stabilne: prowizja {StableFee:%} i prawie zerowy poślizg blisko powiązania; przy utracie powiązania płynność maleje, a przy krachu zostaje wycofana i poślizg gwałtownie rośnie.§Portfele sprzętowe: monety w łańcuchu znajdują się w portfelach sprzętowych PLEDGER, a każdy z nich ma własne saldo i poziom skażenia. Portfel jest przedmiotem: przeciągnij go na terminal handlowy, aby go załadować. Otwórz go na stronie Portfele w terminalu; połącz i odłącz w prawym górnym rogu terminala. Handel na stronie Web3 oraz sklep i mikser na stronie Szara sieć korzystają z połączonego portfela; bez portfela lub bez połączenia są tylko do odczytu, a wszystkie salda wynoszą 0. Klienci płacący monetami płacą na połączony portfel.¶Płatności (sklep, mikser, kantor Ponero, opłaty za wystawienie) zaczynają się od rachunku w terminalu; wpisz adres odbiorcy w portfelu i przytrzymaj ✓, aby podpisać. Dwa ostatnie znaki adresu to suma kontrolna, więc pomyłka o jeden znak jest zwykle wychwytywana; sporadycznie zdarza się, że okazuje się poprawny i monety trafiają pod adres, z którego nikt nie korzysta. Wymiany na DEX również wymagają podpisu na portfelu.¶Poinbase to konto powiernicze; wpłaty wysyła się z portfela na adres wpłat Poinbase (tylko PSC, CRC i SPARK; regulowana giełda nie przyjmuje CRT Czarnego Rynku ani CRA Rewolucji, a portfel blokuje wysłanie ich na adres wpłat), a wypłaty zleca się na stronie Środki w Poinbase. Eksplorator na stronie Portfele pozwala sprawdzać przelewy według adresu i pokazuje wyłącznie przelewy, które faktycznie miały miejsce: każdy ruch do i z twoich portfeli (przelewy, wymiany na DEX i inne wywołania kontraktów, zyski koparek, wypłaty, monety wysyłane ci przez innych); Ponero to moneta prywatności i nigdy się nie pojawia. Więcej portfeli sprzętowych sprzedaje Dr Jackson; przeciągnij portfel na terminal handlowy, aby go dodać – maksymalnie do {WalletMax}. W sklepie dostępne są tańsze. Niepotrzebny portfel można zniszczyć na stronie Portfele; jego monety przepadają na zawsze, podobnie jak wszystko, co zostanie później wysłane na jego adres.¶Przelewy wymagają opłaty gas: wolnej, normalnej lub szybkiej, a ceny gasu rosną i spadają w cyklu około tygodnia; gdy sieć jest przeciążona, opłaty gas rosną, a powolne transakcje mogą zostać usunięte z mempoola. Przed wysłaniem sprawdź pełny adres.§Staking: CRA ulokowane w puli Rewolucji przynosi dzienny zysk według stawki dziennej, doliczany do wkładu; wypłata wymaga wcześniejszego złożenia wniosku i odczekania czterech dni, bez naliczania odsetek w okresie oczekiwania i bez możliwości wcześniejszego odbioru. CRA jest częściowo zabezpieczone: każde CRA wspierają rezerwa CRC należąca do Rewolucji oraz token równoważący SPARK; pokrycie rezerwy i stopa zabezpieczenia widnieją na stronie stakingu. Odsetki wypłacane są w nowych, niezabezpieczonych CRA, co rozwadnia pokrycie rezerwy, tym szybciej, im więcej w stakingu; przy zbyt niskim pokryciu Rewolucja obniża stawkę. Rewolucja czasem sięga po rezerwę, a wcześniej krążą pogłoski: to zapowiedź. Jeśli potem pokrycie spadnie poniżej {CraCrashRatio:%}, następuje krach: CRA staje się bezwartościowe w ciągu trzech dni, a cztery dni na odblokowanie to za wolno; powyżej tego progu jest tylko dyskonto, a środki z grabieży Górnego poziomu stopniowo odbudowują rezerwę.Line truncated
|
||||
courier.odd1,...Paczka dotarła.
|
||||
courier.odd2,(Trzyma rękę w kieszeni.) Podpisz tutaj.
|
||||
courier.sign,Podpisz
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Woda z Górnego poziomu
|
||||
nightlog.predict.win,"Trafna predykcja: „{0}”, wypłacono {1}."
|
||||
nightlog.predict.lose,"Błędna predykcja: „{0}”, utracono stawkę {1}."
|
||||
nightlog.predict.void,"Predykcja unieważniona: „{0}”, zwrócono stawkę {1}."
|
||||
nightlog.predict.caught,"Wykryto transakcję poufną: „{0}”, skonfiskowano stawkę i wygraną w kwocie {1}, odnotowano oszustwo."
|
||||
nightlog.predict.insider,"""{0}"" rozliczono na {1}. Policja podejrzewa transakcje poufne; wypłata została oznaczona, a skażenie portfela wzrasta o {2}."
|
||||
predict.tab.markets,Rynki
|
||||
predict.tab.intel,Informacje
|
||||
predict.acct.crt,{0}: CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}: operacja zaplanowana
|
||||
predict.brief.none,{0}: brak operacji do rozpoczęcia
|
||||
predict.brief.can,{0}: można rozpocząć {1}
|
||||
predict.clue.push,Przesunięcie ceny o {0}%: wysokie ryzyko
|
||||
nightlog.predict.manip,"Predykcja uznana za manipulację rynkową: „{0}”, skonfiskowano stawkę {1}, odnotowano oszustwo."
|
||||
nightlog.predict.manip,"""{0}"" rozliczono na {1}. Regulatorzy podejrzewają manipulację rynkową; wypłata została oznaczona, a skażenie portfela wzrasta o {2}."
|
||||
news.manip.title,Giełda bada nietypowe transakcje
|
||||
news.manip.desc,"Organy regulacyjne donoszą, że za pomocą dużych zleceń spot manipulowano ceną, by czerpać zyski z instrumentów pochodnych i predykcji; środki przejęto."
|
||||
perp.manip,Zysk z zamknięcia w kwocie {0} uznano za manipulację rynkową i skonfiskowano; konto kontraktów wieczystych zamrożone na {1} dni.
|
||||
news.manip.desc,"Regulatorzy donoszą, że ktoś wpłynął na cenę dużymi zleceniami spot, czerpiąc zyski z instrumentów pochodnych i rynków predykcyjnych; powiązane konta zostały oznaczone."
|
||||
taint.overflow,Skażenie przekracza obecnie wartość portfela; nadwyżka {0} zostaje odnotowana jako oszustwo.
|
||||
perp.manip,"Zamknięto z zyskiem: {0}. Regulatorzy podejrzewają manipulację rynkową; zysk został oznaczony, a skażenie konta Poinbase wzrasta o {1}."
|
||||
web3.sub.ponzi,Lokaty
|
||||
ponzi.h,Piramida finansowa
|
||||
ponzi.acct,Portfel emitenta {0}: CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Wsparcie Poinbase
|
||||
scam.support.1,"Dzień dobry, tutaj wsparcie Poinbase. Wykryliśmy nietypowe logowanie na twoim koncie i zostało ono oznaczone."
|
||||
scam.support.2,Prześlij dzisiaj {0} CRC na bezpieczny adres {1} w celu weryfikacji; zostaną zwrócone zaraz potem.
|
||||
scam.support.3,"W przeciwnym razie konto zostanie trwale zamrożone. Muszę lecieć, pamiętaj o przelewie."
|
||||
predict.sold.caught,"Wykryto transakcje poufne przy sprzedaży: stawka i zysk skonfiskowane, oszustwo w kartotece."
|
||||
predict.sold.caught,"Sprzedano, otrzymano {0}. Policja podejrzewa transakcje poufne; uzyskane środki zostały oznaczone, a skażenie portfela wzrasta o {1}."
|
||||
predict.row.move," (ubiegłej nocy {0} {1})"
|
||||
predict.stats.h,Historia (śr. cena otwarcia / wskaźnik rzeczywisty)
|
||||
predict.stats.row,"{0}: rynki: {1}, śr. otwarcie {2}, wystąpienie: {3}%"
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,"{0} spada o {1}% w jeden dzień, {2} traderów zlikwidowan
|
||||
news.wipe.down.desc,"W ciągu ostatniego dnia zlikwidowano {1} długich pozycji na kontraktach perp {0}, łącznie {2} kredytów. Fundusz ubezpieczeniowy Poinbase wynosi {3} kredytów."
|
||||
news.wipe.up.title,"{0} rośnie o {1}% w jeden dzień, {2} traderów zlikwidowanych"
|
||||
news.wipe.up.desc,"W ciągu ostatniego dnia zlikwidowano {1} krótkich pozycji na kontraktach perp {0}, łącznie {2} kredytów. Fundusz ubezpieczeniowy Poinbase wynosi {3} kredytów."
|
||||
hot.name,Sprzedawca
|
||||
hot.intro.CRT,"Ostatnio jest gorąco, a te CRT parzą w ręce. Potrzebuję gotówki, szybko."
|
||||
hot.intro.PSC,Portfel pewnej kopalni zmienił wczoraj właściciela. PSC jest teraz u mnie i biorę tylko gotówkę.
|
||||
hot.intro.PONERO,"Okup, w Ponero. Nikt tego nie wyśledzi. Tylko gotówka."
|
||||
hot.offer,"{0} {1}, warte {2} po dzisiejszym kursie. Daj mi {3} w gotówce, a monety są twoje od razu."
|
||||
hot.choice.yes,Przyjmij
|
||||
hot.choice.no,Odmów
|
||||
hot.say.yes,Umowa stoi.
|
||||
hot.say.no,Nie tknę tego.
|
||||
hot.done,Monety wysłane. Nigdy się nie spotkaliśmy.
|
||||
hot.refused,Inni chętnie wezmą.
|
||||
hot.nocash,Nie masz nawet gotówki? Daj spokój.
|
||||
hot.nowallet,"Brak podłączonego portfela, gdzie mam wysłać monety? Daj spokój."
|
||||
hot.sting,"Nie ruszaj się. Ochrona. Skup kradzionych środków: gotówka zostaje skonfiskowana, a to trafi do twoich akt."
|
||||
otc.name,Klient OTC
|
||||
otc.intro.CRT,"Ostatnio jest gorąco, a te CRT parzą w ręce. Potrzebuję gotówki, szybko."
|
||||
otc.intro.PSC,Portfel pewnej kopalni zmienił wczoraj właściciela. PSC jest teraz u mnie i biorę tylko gotówkę.
|
||||
otc.intro.PONERO,"Okup, w Ponero. Nikt tego nie wyśledzi. Tylko gotówka."
|
||||
otc.offer,"{0} {1}, o wartości {2} po dzisiejszym kursie, wysłane z {4}. {3} w gotówce za całość albo weź część."
|
||||
otc.intro.sell,"Mam trochę {0}, chcę to wymienić na gotówkę. Sprawdź, skąd pochodzą, jeśli chcesz."
|
||||
otc.buy.ask,"Chcę kupić {0} {1}, o wartości {2} po dzisiejszym kursie. {3} w gotówce za całość albo sprzedaj mi część."
|
||||
otc.intro.buy,"Podobno wymieniasz tu monety. Kupuję, za gotówkę."
|
||||
otc.say.trade,Przejdźmy do terminala.
|
||||
otc.wait,"W porządku, poczekam."
|
||||
otc.paid,Dotarło. Oto gotówka.
|
||||
tab.otc,Lada
|
||||
otc.h,Handel przy ladzie
|
||||
otc.k.side,Klient
|
||||
otc.side.sell,Sprzedaje {0}
|
||||
otc.side.buy,Kupuje {0}
|
||||
otc.k.qty,Kwota
|
||||
otc.k.value,Wartość rynkowa
|
||||
otc.k.ask,Żądana (całość)
|
||||
otc.k.bid,Oferowana (całość)
|
||||
otc.k.unit,Cena jednostkowa
|
||||
otc.k.addr,Adres klienta: {0}
|
||||
otc.lookup,Sprawdź
|
||||
otc.preview.take,"Zapłać {0} w gotówce, otrzymaj {1} {2}"
|
||||
otc.preview.give,"Wyślij {0} {1}, otrzymaj {2} w gotówce"
|
||||
otc.deal,Zgoda
|
||||
otc.cancel,Pas
|
||||
otc.msg.gone,Klient odszedł.
|
||||
otc.msg.cash,Za mało gotówki.
|
||||
otc.msg.sting,"Klient był tajniakiem: skonfiskowano {0} w gotówce, odnotowano paserstwo."
|
||||
otc.msg.bought,"Otrzymano {0} {1}, zapłacono {2} w gotówce."
|
||||
otc.msg.sold,"Wysłano {0} {1}, otrzymano {2} w gotówce."
|
||||
gray.sub.own,Mój mikser
|
||||
ownmix.h,Mój mikser
|
||||
ownmix.status.closed,Zamknięty (rug pull)
|
||||
ownmix.status.seized,"Zajęty, zamknięty do dnia {0}"
|
||||
ownmix.status.open,Czynny
|
||||
ownmix.status.paused,Wstrzymany
|
||||
ownmix.k.fee,Prowizja
|
||||
ownmix.k.rating,Reputacja (skażenie wypłat)
|
||||
ownmix.k.heat,Rozgłos
|
||||
ownmix.heat.0,Niski
|
||||
ownmix.heat.1,Średni
|
||||
ownmix.heat.2,Wysoki
|
||||
ownmix.k.anon,Zbiór anonimowości
|
||||
ownmix.k.fees,Zarobione prowizje
|
||||
ownmix.col.capital,Kapitał
|
||||
ownmix.col.earned,Zyski
|
||||
ownmix.col.pending,Monety klientów
|
||||
ownmix.open,Otwórz
|
||||
ownmix.pause,Wstrzymaj
|
||||
ownmix.inject,Zasil
|
||||
ownmix.withdraw,Wypłata
|
||||
ownmix.free,Do wypłaty: {0} {1}
|
||||
ownmix.err,Przekracza kwotę dostępną do wypłaty.
|
||||
ownmix.injected,Zasilono {0} {1}.
|
||||
ownmix.withdrawn,Wypłacono {0} {1}.
|
||||
ownmix.withdraw.sum,Wypłata {0} {1} z mojego miksera
|
||||
pay.ownmix,Zasilenie mojego miksera {0} {1}
|
||||
ownmix.rug,Rug pull ({0})
|
||||
ownmix.rug.confirm,"Kliknij ponownie, aby zabrać {0}"
|
||||
ownmix.rug.sum,Zabierz wszystkie środki z mojego miksera
|
||||
ownmix.rugged,Zabrano {0}; mikser został zamknięty.
|
||||
nightlog.ownmix.in,"Mój mikser: wpłaty: {0}, łącznie {1}, prowizje: {2}."
|
||||
nightlog.ownmix.sting,Wpłata do mojego miksera pochodziła od tajnego funkcjonariusza Ochrony; odnotowano paserstwo.
|
||||
nightlog.ownmix.seized,"Ochrona zajęła mój mikser: pula {0} została skonfiskowana, odnotowano paserstwo."
|
||||
news.ownmix.seized.title,Ochrona zamyka serwis miksujący
|
||||
news.ownmix.seized.desc,Ochrona zamknęła serwis miksujący działający na Dolnym poziomie i skonfiskowała wszystkie jego środki. Tożsamość operatora nie została ustalona.
|
||||
news.ownmix.rug.title,Serwis miksujący znika ze środkami
|
||||
news.ownmix.rug.desc,"Serwis miksujący na Dolnym poziomie zamknął się z dnia na dzień, a wszystkie przetwarzane środki użytkowników zniknęły."
|
||||
pay.otc,Klient OTC {0} {1} (gotówka {2})
|
||||
otc.upgrade.title,Punkt OTC
|
||||
otc.upgrade.desc,"Dodaje cel Czarnej lampy: Klienci OTC. Jedni przychodzą sprzedać monety nieznanego pochodzenia, inni kupić monety; wszystkie transakcje są rozliczane w gotówce. Zawiera jedną Czarną lampę."
|
||||
otc.say.no,Tym razem spasuję.
|
||||
otc.done,Monety wysłane. Nigdy się nie spotkaliśmy.
|
||||
otc.refused,To poszukam kogoś innego.
|
||||
otc.nocash,Nie masz nawet gotówki? Daj spokój.
|
||||
otc.nowallet,"Brak podłączonego portfela, gdzie mam wysłać monety? Daj spokój."
|
||||
otc.sting,"Nie ruszaj się. Ochrona. Skup kradzionych środków: gotówka zostaje skonfiskowana, a to trafi do twoich akt."
|
||||
hw.err.poinbase,Poinbase nie przyjmuje {0}.
|
||||
@@ -50,6 +50,7 @@ report.burnt,Сгорело видеокарт: {0}
|
||||
report.price,Цена PSC: {0} кредитов
|
||||
nightlog.mined,Майнинг-фермы добыли {0} PSC.
|
||||
nightlog.burnt,Сгорела видеокарта {0}.
|
||||
nightlog.turbo,"{0}: турбоускорение, сразу добыто {1} PSC."
|
||||
coinpay.line,Сделка: {0} {1}.
|
||||
nightlog.coinpay,Оплата монетами составила {0} кредитов; средства поступили в горячий кошелёк.
|
||||
nightlog.unpowered,Майнинг-ферм или асик-майнеров без питания: {0}.
|
||||
@@ -247,7 +248,7 @@ black.kind.Contraband.3,Контрабанда (высок.)
|
||||
black.kind.Tech,Высокие технологии (наценка)
|
||||
nightlog.bm.ready,Чёрный рынок: доставлен товар «{0}»; курьер заглянет после открытия.
|
||||
guide.web3.title,Руководство по Web3
|
||||
guide.web3.text,"Банк и торговля: страница банка только для чтения и показывает наличные, аренду и CRC на счёте Poinbase. Страница «Средства» в Poinbase отвечает за ввод и вывод; сначала выбирается монета: CRC можно вводить и выводить через банковский счёт или кошелёк, остальные монеты только через кошелёк. Депозит из банка конвертирует кредиты в CRC на счёте Poinbase; вывод в банк меняет CRC обратно на кредиты и проходит проверку соответствия, оценивающую загрязнение счёта Poinbase. Вывод на кошелёк требует адрес получателя и нескольких подтверждений до зачисления; комиссия за газ фиксирована на обычном уровне и списывается с отправляемой монеты. Неверный формат адреса или контрольная сумма приводят к отказу; адрес с верным форматом, которым никто не пользуется, означает потерю отправленных монет.¶Торговля: PSC означает Probably Stolen Coin — это монета, которую добывают видеокарты и асик-майнеры. На спотовом рынке Poinbase две пары, PSC/CRC и SPARK/CRC, по монете, выбранной на графике. И покупка, и продажа вводятся как количество торгуемой монеты; в предпросмотре видно, сколько котируемой монеты уйдёт или придёт, средняя цена включает комиссию, проскальзывание — нет.¶На торговой странице Web3 можно обменять любые две монеты, всегда через CRC: если CRC с одной стороны, используется один пул, иначе два пула, две комиссии и суммирующееся проскальзывание; предпросмотр показывает получаемое количество, число пулов и потери. Обмен стейблкоинов (CRT или CRA на CRC) идёт через стабильные пулы: комиссия {StableFee:%} и почти нулевое проскальзывание возле привязки; при отвязке ликвидность редеет, при обвале её выводят, и проскальзывание резко растёт.§Аппаратные кошельки: ончейн-монеты хранятся на аппаратных кошельках PLEDGER, баланс и загрязнение у каждого свои. Кошелёк — это предмет: перетащите его на торговый терминал, чтобы загрузить. Открывайте его на странице «Кошельки» терминала; подключайте и отключайте в правом верхнем углу терминала. Торговля на странице Web3, магазин и миксер на странице «Серая сеть» используют подключённый кошелёк; без кошелька или без подключения они доступны только для просмотра, а все балансы равны 0. Покупатели, платящие монетами, платят на подключённый кошелёк.¶Платежи (магазин, миксер, пункт обмена Ponero, комиссия за размещение) начинаются со счёта на терминале; введите адрес получателя на кошельке и удерживайте ✓, чтобы подписать. Последние два символа адреса — контрольная сумма, поэтому опечатка в один символ обычно отсекается; изредка адрес случайно оказывается валидным, и монеты уходят на адрес, которым никто не пользуется. Для обмена на DEX также требуется подпись на кошельке.¶Poinbase — кастодиальный аккаунт; депозит отправляется с кошелька на адрес депозита Poinbase (только PSC, CRC и SPARK; регулируемая биржа не принимает ни CRT чёрного рынLine truncated
|
||||
guide.web3.text,"Банк и торговля: страница банка только для чтения и показывает наличные, аренду и CRC на счёте Poinbase. Страница «Средства» в Poinbase отвечает за ввод и вывод; сначала выбирается монета: CRC можно вводить и выводить через банковский счёт или кошелёк, остальные монеты только через кошелёк. Депозит из банка конвертирует кредиты в CRC на счёте Poinbase; вывод в банк меняет CRC обратно на кредиты и проходит проверку соответствия, оценивающую загрязнение счёта Poinbase. Вывод на кошелёк требует адрес получателя и нескольких подтверждений до зачисления; комиссия за газ фиксирована на обычном уровне и списывается с отправляемой монеты. Неверный формат адреса или контрольная сумма приводят к отказу; адрес с верным форматом, которым никто не пользуется, означает потерю отправленных монет.¶Торговля: PSC означает Probably Stolen Coin — это монета, которую добывают видеокарты и асик-майнеры. На спотовом рынке Poinbase две пары, PSC/CRC и SPARK/CRC, по монете, выбранной на графике. И покупка, и продажа вводятся как количество торгуемой монеты; в предпросмотре видно, сколько котируемой монеты уйдёт или придёт, средняя цена включает комиссию, проскальзывание — нет.¶На торговой странице Web3 можно обменять любые две монеты, всегда через CRC: если CRC с одной стороны, используется один пул, иначе два пула, две комиссии и суммирующееся проскальзывание; предпросмотр показывает получаемое количество, число пулов и потери. Обмен стейблкоинов (CRT или CRA на CRC) идёт через стабильные пулы: комиссия {StableFee:%} и почти нулевое проскальзывание возле привязки; при отвязке ликвидность редеет, при обвале её выводят, и проскальзывание резко растёт.§Аппаратные кошельки: ончейн-монеты хранятся на аппаратных кошельках PLEDGER, баланс и загрязнение у каждого свои. Кошелёк — это предмет: перетащите его на торговый терминал, чтобы загрузить. Открывайте его на странице «Кошельки» терминала; подключайте и отключайте в правом верхнем углу терминала. Торговля на странице Web3, магазин и миксер на странице «Серая сеть» используют подключённый кошелёк; без кошелька или без подключения они доступны только для просмотра, а все балансы равны 0. Покупатели, платящие монетами, платят на подключённый кошелёк.¶Платежи (магазин, миксер, пункт обмена Ponero, комиссия за размещение) начинаются со счёта на терминале; введите адрес получателя на кошельке и удерживайте ✓, чтобы подписать. Последние два символа адреса — контрольная сумма, поэтому опечатка в один символ обычно отсекается; изредка адрес случайно оказывается валидным, и монеты уходят на адрес, которым никто не пользуется. Для обмена на DEX также требуется подпись на кошельке.¶Poinbase — кастодиальный аккаунт; депозит отправляется с кошелька на адрес депозита Poinbase (только PSC, CRC и SPARK; регулируемая биржа не принимает ни CRT чёрного рынLine truncated
|
||||
courier.odd1,...Посылка пришла.
|
||||
courier.odd2,(Его рука остаётся в кармане.) Подпиши здесь.
|
||||
courier.sign,Подписать
|
||||
@@ -548,7 +549,7 @@ predict.purity.rust,Вода верхнего уровня
|
||||
nightlog.predict.win,"Прогноз сбылся: «{0}», выплачено {1}."
|
||||
nightlog.predict.lose,"Прогноз не оправдался: «{0}», ставка {1} потеряна."
|
||||
nightlog.predict.void,"Прогноз аннулирован: «{0}», ставка {1} возвращена."
|
||||
nightlog.predict.caught,"Вскрыта инсайдерская сделка: «{0}», ставка и выигрыш {1} конфискованы, зафиксировано мошенничество."
|
||||
nightlog.predict.insider,"«{0}»: расчёт на {1}. Полиция подозревает инсайдерскую сделку; выплата помечена, «грязные» средства кошелька выросли на {2}."
|
||||
predict.tab.markets,Рынки
|
||||
predict.tab.intel,Информация
|
||||
predict.acct.crt,{0}: CRT {1}
|
||||
@@ -591,10 +592,11 @@ predict.brief.queued,{0}: операция запланирована
|
||||
predict.brief.none,{0}: нечего запускать
|
||||
predict.brief.can,{0}: можно начать {1}
|
||||
predict.clue.push,Вы сдвинули цену на {0}%: рискованно
|
||||
nightlog.predict.manip,"Прогноз признан манипуляцией ценой: «{0}», ставка {1} конфискована, зафиксировано мошенничество."
|
||||
nightlog.predict.manip,"«{0}»: расчёт на {1}. Регуляторы подозревают манипуляцию ценой; выплата помечена, «грязные» средства кошелька выросли на {2}."
|
||||
news.manip.title,Биржа расследует подозрительные сделки
|
||||
news.manip.desc,Регуляторы сообщают: некто манипулировал ценой крупными спотовыми ордерами и получал прибыль на деривативах и прогнозах; средства изъяты.
|
||||
perp.manip,"Прибыль {0} при закрытии признана манипуляцией ценой и изъята; счёт бессрочных фьючерсов заморожен, дней заморозки: {1}."
|
||||
news.manip.desc,Регуляторы сообщают: кто-то сдвинул цену крупными спотовыми ордерами и получил прибыль на деривативах и предсказаниях; причастные счета помечены.
|
||||
taint.overflow,«Грязные» средства превысили стоимость кошелька; излишек {0} занесён в дело как мошенничество.
|
||||
perp.manip,"Закрыто с прибылью {0}. Регуляторы подозревают манипуляцию ценой; прибыль помечена, «грязные» средства на счёте Poinbase выросли на {1}."
|
||||
web3.sub.ponzi,Доходность
|
||||
ponzi.h,Схема Понци
|
||||
ponzi.acct,Кошелёк эмитента {0}: CRC {1}
|
||||
@@ -685,7 +687,7 @@ scam.support.name,Поддержка Poinbase
|
||||
scam.support.1,"Здравствуйте, служба поддержки Poinbase. Мы зафиксировали подозрительный вход в ваш аккаунт, он был помечен."
|
||||
scam.support.2,"Пожалуйста, переведите сегодня {0} CRC на безопасный адрес {1} для проверки; средства вернут сразу после неё."
|
||||
scam.support.3,"Иначе аккаунт будет заморожен навсегда. Мне пора, не забудьте перевести."
|
||||
predict.sold.caught,"Инсайдерская сделка раскрыта при продаже: ставка и прибыль конфискованы, зафиксировано мошенничество."
|
||||
predict.sold.caught,"Продано, получено {0}. Полиция подозревает инсайдерскую сделку; выручка помечена, «грязные» средства кошелька выросли на {1}."
|
||||
predict.row.move," (прошлой ночью {0} {1})"
|
||||
predict.stats.h,История (ср. цена открытия / факт. частота)
|
||||
predict.stats.row,"{0}: рынков: {1}, ср. открытие {2}, сбылось {3}%"
|
||||
@@ -963,18 +965,83 @@ news.wipe.down.title,"{0} упал на {1}% за день, ликвидиров
|
||||
news.wipe.down.desc,За прошедшие сутки ликвидировано {1} длинных позиций по бессрочным контрактам {0} на общую сумму {2} кредитов. Страховой фонд Poinbase составляет {3} кредитов.
|
||||
news.wipe.up.title,"{0} вырос на {1}% за день, ликвидировано трейдеров: {2}"
|
||||
news.wipe.up.desc,За прошедшие сутки ликвидировано {1} коротких позиций по бессрочным контрактам {0} на общую сумму {2} кредитов. Страховой фонд Poinbase составляет {3} кредитов.
|
||||
hot.name,Продавец
|
||||
hot.intro.CRT,"Сейчас неспокойно, а этот CRT жжёт руки. Мне нужны наличные, быстро."
|
||||
hot.intro.PSC,"Кошелёк одной майнинг-фермы прошлой ночью сменил владельца. PSC теперь у меня, и я беру только наличные."
|
||||
hot.intro.PONERO,"Выкуп, в Ponero. Никто не отследит. Только наличные."
|
||||
hot.offer,"{0} {1}, по сегодняшнему курсу это {2}. Дайте мне {3} наличными, и монеты сразу ваши."
|
||||
hot.choice.yes,Взять
|
||||
hot.choice.no,Отказаться
|
||||
hot.say.yes,По рукам.
|
||||
hot.say.no,Я в это не полезу.
|
||||
hot.done,Монеты отправлены. Мы не встречались.
|
||||
hot.refused,Найдутся другие.
|
||||
hot.nocash,Даже наличных нет? Забудьте.
|
||||
hot.nowallet,"Кошелёк не подключён, куда слать монеты? Забудьте."
|
||||
hot.sting,"Не двигаться. Служба безопасности. Скупка краденых средств: наличные изъяты, это пойдёт в ваше досье."
|
||||
otc.name,OTC-клиент
|
||||
otc.intro.CRT,"Сейчас неспокойно, а этот CRT жжёт руки. Мне нужны наличные, быстро."
|
||||
otc.intro.PSC,"Кошелёк одной майнинг-фермы прошлой ночью сменил владельца. PSC теперь у меня, и я беру только наличные."
|
||||
otc.intro.PONERO,"Выкуп, в Ponero. Никто не отследит. Только наличные."
|
||||
otc.offer,"{0} {1}, стоимость по текущему курсу: {2}, перевод с {4}. {3} наличными за всё, либо возьмите часть."
|
||||
otc.intro.sell,"Есть немного {0}, хочу обменять на наличные. Можешь проверить, откуда они, если хочешь."
|
||||
otc.buy.ask,"Куплю {0} {1}, стоимость по текущему курсу: {2}. За всё дам {3} наличными, либо продайте часть."
|
||||
otc.intro.buy,"Слышал, здесь меняют монеты. Я покупаю, за наличные."
|
||||
otc.say.trade,Обсудим у терминала.
|
||||
otc.wait,"Ладно, я подожду."
|
||||
otc.paid,Пришло. Вот ваши наличные.
|
||||
tab.otc,Стойка
|
||||
otc.h,Торговля у стойки
|
||||
otc.k.side,Клиент
|
||||
otc.side.sell,Продажа {0}
|
||||
otc.side.buy,Покупка {0}
|
||||
otc.k.qty,Сумма
|
||||
otc.k.value,Рын. стоимость
|
||||
otc.k.ask,Запрос (всего)
|
||||
otc.k.bid,Предл. (всего)
|
||||
otc.k.unit,Цена за ед.
|
||||
otc.k.addr,Адрес клиента: {0}
|
||||
otc.lookup,Проверить
|
||||
otc.preview.take,"Заплатить {0} наличными, получить {1} {2}"
|
||||
otc.preview.give,"Отправить {0} {1}, получить {2} наличными"
|
||||
otc.deal,Сделка
|
||||
otc.cancel,Отказ
|
||||
otc.msg.gone,Клиент ушёл.
|
||||
otc.msg.cash,Недостаточно наличных.
|
||||
otc.msg.sting,"Клиент был под прикрытием: конфисковано {0} наличными, зафиксирован сбыт краденого."
|
||||
otc.msg.bought,"Получено {0} {1}, выплачено {2} наличными."
|
||||
otc.msg.sold,"Отправлено {0} {1}, получено {2} наличными."
|
||||
gray.sub.own,Мой миксер
|
||||
ownmix.h,Мой миксер
|
||||
ownmix.status.closed,Закрыт (рагпул)
|
||||
ownmix.status.seized,"Опечатан, закрыт до дня {0}"
|
||||
ownmix.status.open,Открыт
|
||||
ownmix.status.paused,Приостановлен
|
||||
ownmix.k.fee,Комиссия
|
||||
ownmix.k.rating,Репутация (остаток «грязи»)
|
||||
ownmix.k.heat,Шумиха
|
||||
ownmix.heat.0,Низкая
|
||||
ownmix.heat.1,Средняя
|
||||
ownmix.heat.2,Высокая
|
||||
ownmix.k.anon,Анонимный пул
|
||||
ownmix.k.fees,Всего комиссий
|
||||
ownmix.col.capital,Капитал
|
||||
ownmix.col.earned,Доход
|
||||
ownmix.col.pending,Монеты клиентов
|
||||
ownmix.open,Открыть
|
||||
ownmix.pause,Пауза
|
||||
ownmix.inject,Внести
|
||||
ownmix.withdraw,Вывод
|
||||
ownmix.free,Доступно для вывода: {0} {1}
|
||||
ownmix.err,Превышает доступную для вывода сумму.
|
||||
ownmix.injected,Внесено {0} {1}.
|
||||
ownmix.withdrawn,Выведено {0} {1}.
|
||||
ownmix.withdraw.sum,Вывод {0} {1} из моего миксера
|
||||
pay.ownmix,Взнос в мой миксер: {0} {1}
|
||||
ownmix.rug,Совершить рагпул ({0})
|
||||
ownmix.rug.confirm,"Нажмите ещё раз, чтобы забрать {0}"
|
||||
ownmix.rug.sum,Забрать все средства из моего миксера
|
||||
ownmix.rugged,Забрано {0}; миксер закрыт.
|
||||
nightlog.ownmix.in,"Мой миксер: депозитов: {0}, всего {1}, комиссии: {2}."
|
||||
nightlog.ownmix.sting,Один из депозитов в моём миксере поступил от офицера под прикрытием; зафиксирован сбыт краденого.
|
||||
nightlog.ownmix.seized,"Служба безопасности закрыла мой миксер: пул в {0} конфискован, зафиксирован сбыт краденого."
|
||||
news.ownmix.seized.title,Служба безопасности закрыла сервис-миксер
|
||||
news.ownmix.seized.desc,"Служба безопасности закрыла сервис-миксер, работавший на Нижнем уровне, и конфисковала все его средства. Личность оператора пока не установлена."
|
||||
news.ownmix.rug.title,Сервис-миксер исчез вместе со средствами
|
||||
news.ownmix.rug.desc,"Сервис-миксер на Нижнем уровне внезапно закрылся за ночь, а все средства пользователей в обработке исчезли."
|
||||
pay.otc,OTC-клиент {0} {1} (наличные {2})
|
||||
otc.upgrade.title,OTC-стойка
|
||||
otc.upgrade.desc,"Добавляет новую цель для Чёрной лампы: OTC-клиенты. Одни приходят продать монеты неизвестного происхождения, другие — купить монеты; все сделки рассчитываются наличными. Включает одну Чёрную лампу."
|
||||
otc.say.no,В этот раз я откажусь.
|
||||
otc.done,Монеты отправлены. Мы не встречались.
|
||||
otc.refused,Тогда поищу кого-нибудь ещё.
|
||||
otc.nocash,Даже наличных нет? Забудьте.
|
||||
otc.nowallet,"Кошелёк не подключён, куда слать монеты? Забудьте."
|
||||
otc.sting,"Не двигаться. Служба безопасности. Скупка краденых средств: наличные изъяты, это пойдёт в ваше досье."
|
||||
hw.err.poinbase,Poinbase не принимает {0}.
|
||||
@@ -49,6 +49,7 @@ report.burnt,烧毁的显卡:{0}
|
||||
report.price,PSC 价格:{0} 信用点
|
||||
nightlog.mined,矿架挖出 {0} PSC。
|
||||
nightlog.burnt,一张 {0} 烧毁了。
|
||||
nightlog.turbo,{0} 涡轮增压,立刻挖出 {1} PSC。
|
||||
coinpay.line,成交,{0} {1}。
|
||||
nightlog.coinpay,代币支付共结算 {0} 信用点,已兑换并存入热钱包。
|
||||
nightlog.unpowered,{0} 台矿架或矿机未通电。
|
||||
@@ -246,7 +247,7 @@ black.kind.Contraband.3,违禁品(高)
|
||||
black.kind.Tech,高科技物品(加价)
|
||||
nightlog.bm.ready,商店:{0} 到货,开店后会有快递员上门。
|
||||
guide.web3.title,Web3 手册
|
||||
guide.web3.text,"银行与交易:银行页只读,显示现金、房租和 Poinbase 账户里的 CRC。Poinbase 的资金页管入金和出金,先选币种:CRC 可以走银行账户或钱包,其他币只能走钱包。从银行入金把信用点换成 Poinbase 账户里的 CRC;出金到银行把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。出金到钱包要填收款地址,等几次确认才到账,Gas 费固定按普通档、从转出的币里扣;地址格式或校验位不对会被拒绝,格式对但没人用的地址,币转过去就没了。¶交易:PSC 全称 Probably Stolen Coin,是显卡和矿机挖出的币。Poinbase 现货有 PSC/CRC 和 SPARK/CRC 两个交易对,跟着行情图选中的币切换。买入和卖出都填所交易币的数量,预览显示要付或能得到的计价币,均价含手续费,滑点不含。¶Web3 交易页可以任选两种币互换,实际都经 CRC 中转:CRC 在一端走一个池,否则走两个池,付两次手续费、滑点叠加,预览里会显示得到的数量、经过的池数和损耗。稳定币之间(CRT、CRA 对 CRC)走稳定币池:手续费 {StableFee:%},挂钩附近几乎没有滑点;脱锚时流动性变差,崩盘时流动性被撤走,滑点急剧变大。§硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点分别计算。钱包是一件物品,拖到交易终端上加载;在终端的钱包页打开,在终端右上角连接或断开。Web3 页的交易和灰网页的商店、混币器用已连接的钱包,没有钱包或没有连接时只能看,余额都是 0;用币付款的顾客也进已连接的钱包。¶付款(商店、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。¶Poinbase 是托管账户,入金要从钱包转到它的充值地址(只收 PSC、CRC、SPARK;黑市的 CRT、革命军的 CRA 合规交易所不收,往充值地址转会被钱包拦下),出金在 Poinbase 的资金页发起。钱包页的浏览器可以按地址查转账记录,只显示真实发生的转账:你的钱包的每一笔进出(转账、DEX 兑换和其他合约调用、矿机收益、出金、别人转来的币);Ponero 是隐私币,不显示。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 {WalletMax} 个;商店里也有更便宜的。不要的钱包可以在钱包页销毁,里面的币永久丢失,之后发到这个地址的币也丢了。¶转账要付 Gas 费,分慢、普通、快三档,Gas 价格大约一周一个起落;网络拥堵时 Gas 费变贵,慢档可能被挤出内存池。转账前核对完整地址。§质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。CRA 是部分抵押的:每份 CRA 由革命军持有的 CRC 储备和平衡代币 SPARK 共同支撑,储备覆盖率和抵押率显示在质押页。质押利息以没有抵押的新 CRA 付出,会稀释储备覆盖率,质押的人越多稀释越快;覆盖率太低革命军会降息。革命军有时会挪用储备,先有风声,那是预兆;挪用后覆盖率跌破 {CraCrashRatio:%} 就崩盘:三天内 CRA 归零,四天的解锁期来不及;没跌破只是折价,劫掠上层带来的资金会慢慢把储备补回来。¶官方铸造:存入 CRC 和 SPARK(比例按当前抵押率,界面预览需要多少)铸造 CRA,排 {CraMintDaysMin}~{CraMintDaysMax} 天,铸出的 CRA 直接进质押;销毁把 CRA 换回 CRC 和 SPARK,等待和解锁期一样长,储备不足时 CRC 份额按覆盖率打折。排队的铸造和销毁,官方可能整笔不兑现:每晚的概率是 CRA 价格低于 1 的幅度乘以 {CraRugPerDepeg},价格不低于 1 就不会。¶质押可以存 CRA、CRC、CRT、SPARK:后三种先在二级市场按市价换成 CRA(经 CRC 中转,付手续费和滑点)再质押。SPARK 价格波动很大,崩盘时会跟着暴跌。质押、铸造、销毁都是合约调用,要在钱包上签名。§矿机:RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在商店的矿机商那里有,要黑市声望(M1 {AsicRepM1}、M2 {AsicRepM2}、M3 {AsicRepM3}),偶尔有二手的。烧毁后须按顺序把电子元件拖到它身上修复,修复后健康降低 {AsicRepairHealthCut}。第 {EraMin} 到 {EraMax} 天之间会有一次""矿机时代"",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡Line truncated
|
||||
guide.web3.text,"银行与交易:银行页只读,显示现金、房租和 Poinbase 账户里的 CRC。Poinbase 的资金页管入金和出金,先选币种:CRC 可以走银行账户或钱包,其他币只能走钱包。从银行入金把信用点换成 Poinbase 账户里的 CRC;出金到银行把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。出金到钱包要填收款地址,等几次确认才到账,Gas 费固定按普通档、从转出的币里扣;地址格式或校验位不对会被拒绝,格式对但没人用的地址,币转过去就没了。¶交易:PSC 全称 Probably Stolen Coin,是显卡和矿机挖出的币。Poinbase 现货有 PSC/CRC 和 SPARK/CRC 两个交易对,跟着行情图选中的币切换。买入和卖出都填所交易币的数量,预览显示要付或能得到的计价币,均价含手续费,滑点不含。¶Web3 交易页可以任选两种币互换,实际都经 CRC 中转:CRC 在一端走一个池,否则走两个池,付两次手续费、滑点叠加,预览里会显示得到的数量、经过的池数和损耗。稳定币之间(CRT、CRA 对 CRC)走稳定币池:手续费 {StableFee:%},挂钩附近几乎没有滑点;脱锚时流动性变差,崩盘时流动性被撤走,滑点急剧变大。§硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点分别计算。钱包是一件物品,拖到交易终端上加载;在终端的钱包页打开,在终端右上角连接或断开。Web3 页的交易和灰网页的商店、混币器用已连接的钱包,没有钱包或没有连接时只能看,余额都是 0;用币付款的顾客也进已连接的钱包。¶付款(商店、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。¶Poinbase 是托管账户,入金要从钱包转到它的充值地址(只收 PSC、CRC、SPARK;黑市的 CRT、革命军的 CRA 合规交易所不收,往充值地址转会被钱包拦下),出金在 Poinbase 的资金页发起。钱包页的浏览器可以按地址查转账记录,只显示真实发生的转账:你的钱包的每一笔进出(转账、DEX 兑换和其他合约调用、矿机收益、出金、别人转来的币);Ponero 是隐私币,不显示。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 {WalletMax} 个;商店里也有更便宜的。不要的钱包可以在钱包页销毁,里面的币永久丢失,之后发到这个地址的币也丢了。¶转账要付 Gas 费,分慢、普通、快三档,Gas 价格大约一周一个起落;网络拥堵时 Gas 费变贵,慢档可能被挤出内存池。转账前核对完整地址。§质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。CRA 是部分抵押的:每份 CRA 由革命军持有的 CRC 储备和平衡代币 SPARK 共同支撑,储备覆盖率和抵押率显示在质押页。质押利息以没有抵押的新 CRA 付出,会稀释储备覆盖率,质押的人越多稀释越快;覆盖率太低革命军会降息。革命军有时会挪用储备,先有风声,那是预兆;挪用后覆盖率跌破 {CraCrashRatio:%} 就崩盘:三天内 CRA 归零,四天的解锁期来不及;没跌破只是折价,劫掠上层带来的资金会慢慢把储备补回来。¶官方铸造:存入 CRC 和 SPARK(比例按当前抵押率,界面预览需要多少)铸造 CRA,排 {CraMintDaysMin}~{CraMintDaysMax} 天,铸出的 CRA 直接进质押;销毁把 CRA 换回 CRC 和 SPARK,等待和解锁期一样长,储备不足时 CRC 份额按覆盖率打折。排队的铸造和销毁,官方可能整笔不兑现:每晚的概率是 CRA 价格低于 1 的幅度乘以 {CraRugPerDepeg},价格不低于 1 就不会。¶质押可以存 CRA、CRC、CRT、SPARK:后三种先在二级市场按市价换成 CRA(经 CRC 中转,付手续费和滑点)再质押。SPARK 价格波动很大,崩盘时会跟着暴跌。质押、铸造、销毁都是合约调用,要在钱包上签名。§矿机:RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在商店的矿机商那里有,要黑市声望(M1 {AsicRepM1}、M2 {AsicRepM2}、M3 {AsicRepM3}),偶尔有二手的。烧毁后须按顺序把电子元件拖到它身上修复,修复后健康降低 {AsicRepairHealthCut}。第 {EraMin} 到 {EraMax} 天之间会有一次""矿机时代"",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡Line truncated
|
||||
courier.odd1,……东西到了。
|
||||
courier.odd2,"(他的手一直放在口袋里)在这儿签个字。"
|
||||
courier.sign,签收
|
||||
@@ -547,7 +548,7 @@ predict.purity.rust,上层水
|
||||
nightlog.predict.win,预测押中:「{0}」,兑付 {1}。
|
||||
nightlog.predict.lose,预测押错:「{0}」,本金 {1} 没了。
|
||||
nightlog.predict.void,预测作废:「{0}」,退回本金 {1}。
|
||||
nightlog.predict.caught,内幕下注被查:「{0}」,本金和收益 {1} 全部没收,记诈骗罪证。
|
||||
nightlog.predict.insider,「{0}」结算 {1}。警方怀疑这是内幕交易,这笔收益被标记,钱包污点增加 {2}。
|
||||
predict.tab.markets,盘口
|
||||
predict.tab.intel,情报
|
||||
predict.acct.crt,链上钱包 {0}:CRT {1}
|
||||
@@ -590,10 +591,11 @@ predict.brief.queued,{0}:行动已排期
|
||||
predict.brief.none,{0}:暂时发起不了
|
||||
predict.brief.can,{0}:可发起 {1}
|
||||
predict.clue.push,玩家推价 {0}%,操纵风险高
|
||||
nightlog.predict.manip,预测被判操纵:「{0}」,本金 {1} 没收,记诈骗罪证。
|
||||
nightlog.predict.manip,「{0}」结算 {1}。监管部门怀疑你操纵了价格,这笔兑付被标记,钱包污点增加 {2}。
|
||||
news.manip.title,交易所调查异常交易
|
||||
news.manip.desc,监管部门通报,有人用大额现货单推动价格,从合约和预测里获利,涉事资金已被追缴。
|
||||
perp.manip,平仓盈利 {0} 被判操纵价格,已没收,永续账户冻结 {1} 天。
|
||||
news.manip.desc,监管部门通报,有人用大额现货单推动价格,从合约和预测里获利,涉事账户已被标记。
|
||||
taint.overflow,污点已超过钱包价值,超出的 {0} 记为诈骗罪证。
|
||||
perp.manip,平仓盈利 {0}。监管部门怀疑你操纵了价格,这笔盈利被标记,Poinbase 账户污点增加 {1}。
|
||||
web3.sub.ponzi,理财
|
||||
ponzi.h,高息理财
|
||||
ponzi.acct,发行钱包 {0}:CRC {1}
|
||||
@@ -684,7 +686,7 @@ scam.support.name,Poinbase 客服
|
||||
scam.support.1,您好,我是 Poinbase 客服。系统检测到您的账户有异常登录,已经被风控了。
|
||||
scam.support.2,请在今天内把 {0} CRC 转到安全地址 {1} 做验证,验证完马上退回。
|
||||
scam.support.3,不处理的话账户会被永久冻结。我先走了,记得转。
|
||||
predict.sold.caught,卖出时内幕交易被查:本金和收益全部没收,记诈骗罪证。
|
||||
predict.sold.caught,卖出,收回 {0}。警方怀疑这是内幕交易,这笔收益被标记,钱包污点增加 {1}。
|
||||
predict.row.move,(昨晚 {0} {1})
|
||||
predict.stats.h,历史(开盘均价 / 实际发生)
|
||||
predict.stats.row,{0}:{1} 个,开盘均价 {2},发生 {3}%
|
||||
@@ -962,18 +964,83 @@ news.wipe.down.title,{0} 单日下跌 {1}%,{2} 人爆仓
|
||||
news.wipe.down.desc,过去一天,{0} 永续合约有 {1} 个多头仓位爆仓,爆仓总额 {2} 信用点。Poinbase 保险基金余额 {3} 信用点。
|
||||
news.wipe.up.title,{0} 单日上涨 {1}%,{2} 人爆仓
|
||||
news.wipe.up.desc,过去一天,{0} 永续合约有 {1} 个空头仓位爆仓,爆仓总额 {2} 信用点。Poinbase 保险基金余额 {3} 信用点。
|
||||
hot.name,出货人
|
||||
hot.intro.CRT,最近风声紧,这批 CRT 留在手里烫手,得尽快换成现金。
|
||||
hot.intro.PSC,有家矿场的钱包昨晚换了主人。PSC 在我这儿,我只要现金。
|
||||
hot.intro.PONERO,一笔赎金,Ponero,查不到来路。我只收现金。
|
||||
hot.offer,{0} {1},按现价值 {2}。给我 {3} 现金,币当场转给你。
|
||||
hot.choice.yes,收下
|
||||
hot.choice.no,不要
|
||||
hot.say.yes,成交。
|
||||
hot.say.no,这钱我不碰。
|
||||
hot.done,币转过去了。我们没见过。
|
||||
hot.refused,有的是人要。
|
||||
hot.nocash,现金都拿不出来?那算了。
|
||||
hot.nowallet,钱包都没连上,币往哪儿转?算了。
|
||||
hot.sting,别动,治安部。收购赃款,现金没收,这笔会记进你的档案。
|
||||
otc.name,换币客户
|
||||
otc.intro.CRT,最近风声紧,这批 CRT 留在手里烫手,得尽快换成现金。
|
||||
otc.intro.PSC,有家矿场的钱包昨晚换了主人。PSC 在我这儿,我只要现金。
|
||||
otc.intro.PONERO,一笔赎金,Ponero,查不到来路。我只收现金。
|
||||
otc.offer,{0} {1},按现价值 {2},从 {4} 转出。全收给我 {3} 现金,收一部分也行。
|
||||
otc.intro.sell,手上有点 {0} 想换成现金。来路你自己查。
|
||||
otc.buy.ask,我想买 {0} {1},按现价值 {2}。全给我的话出 {3} 现金,卖一部分也行。
|
||||
otc.intro.buy,听说你这儿能换币。我拿现金买。
|
||||
otc.say.trade,到终端上谈。
|
||||
otc.wait,行,我等着。
|
||||
otc.paid,到了。现金拿好。
|
||||
tab.otc,柜台
|
||||
otc.h,柜台交易
|
||||
otc.k.side,客户
|
||||
otc.side.sell,卖 {0}
|
||||
otc.side.buy,买 {0}
|
||||
otc.k.qty,数量
|
||||
otc.k.value,市值
|
||||
otc.k.ask,要价(全部)
|
||||
otc.k.bid,出价(全部)
|
||||
otc.k.unit,单价
|
||||
otc.k.addr,客户地址:{0}
|
||||
otc.lookup,查地址
|
||||
otc.preview.take,付现金 {0},收到 {1} {2}
|
||||
otc.preview.give,转出 {0} {1},收现金 {2}
|
||||
otc.deal,成交
|
||||
otc.cancel,放弃
|
||||
otc.msg.gone,客户已经走了。
|
||||
otc.msg.cash,现金不够。
|
||||
otc.msg.sting,对方是便衣:现金 {0} 被没收,记销赃罪证。
|
||||
otc.msg.bought,收到 {0} {1},付现金 {2}。
|
||||
otc.msg.sold,转出 {0} {1},收现金 {2}。
|
||||
gray.sub.own,自营混币器
|
||||
ownmix.h,自营混币器
|
||||
ownmix.status.closed,已关闭(卷款跑路)
|
||||
ownmix.status.seized,被查封,停业到第 {0} 天
|
||||
ownmix.status.open,营业中
|
||||
ownmix.status.paused,暂停营业
|
||||
ownmix.k.fee,费率
|
||||
ownmix.k.rating,口碑(出款剩下的污点)
|
||||
ownmix.k.heat,风声
|
||||
ownmix.heat.0,低
|
||||
ownmix.heat.1,中
|
||||
ownmix.heat.2,高
|
||||
ownmix.k.anon,匿名集
|
||||
ownmix.k.fees,累计手续费
|
||||
ownmix.col.capital,本金
|
||||
ownmix.col.earned,收入
|
||||
ownmix.col.pending,客户在途
|
||||
ownmix.open,开张
|
||||
ownmix.pause,暂停营业
|
||||
ownmix.inject,注资
|
||||
ownmix.withdraw,取回
|
||||
ownmix.free,可取回:{0} {1}
|
||||
ownmix.err,超出可取回的数量。
|
||||
ownmix.injected,注资 {0} {1}。
|
||||
ownmix.withdrawn,取回 {0} {1}。
|
||||
ownmix.withdraw.sum,从自营混币器取回 {0} {1}
|
||||
pay.ownmix,自营混币器注资 {0} {1}
|
||||
ownmix.rug,卷款跑路({0})
|
||||
ownmix.rug.confirm,再点一次,卷走 {0}
|
||||
ownmix.rug.sum,卷走自营混币器的全部资金
|
||||
ownmix.rugged,卷走 {0},混币器关闭。
|
||||
nightlog.ownmix.in,自营混币器:{0} 笔存入,共 {1},手续费 {2}。
|
||||
nightlog.ownmix.sting,自营混币器有一笔存入来自治安部便衣,记销赃罪证。
|
||||
nightlog.ownmix.seized,自营混币器被治安部查封,池子 {0} 全部没收,记销赃罪证。
|
||||
news.ownmix.seized.title,治安部查封一家混币服务
|
||||
news.ownmix.seized.desc,治安部宣布查封一家在下层区运营的混币服务,没收全部资金,运营者身份仍在调查。
|
||||
news.ownmix.rug.title,混币服务卷款跑路
|
||||
news.ownmix.rug.desc,下层区一家混币服务突然关闭,用户在途的资金全部消失。
|
||||
pay.otc,换币客户 {0} {1}(现金 {2})
|
||||
otc.upgrade.title,场外换币台
|
||||
otc.upgrade.desc,暗灯多一个目标:换币客户。有人来卖来路不明的币,有人来买币,都用现金结算。附赠一盏暗灯。
|
||||
otc.say.no,这单我不做。
|
||||
otc.done,币转过去了。我们没见过。
|
||||
otc.refused,那我找别人。
|
||||
otc.nocash,现金都拿不出来?那算了。
|
||||
otc.nowallet,钱包都没连上,币往哪儿转?算了。
|
||||
otc.sting,别动,治安部。收购赃款,现金没收,这笔会记进你的档案。
|
||||
hw.err.poinbase,Poinbase 不收 {0}。
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 240 B |
+42
-13
@@ -72,6 +72,17 @@ namespace Decentralized
|
||||
}
|
||||
|
||||
/// <summary>挖矿产出按各台机器的算力占比,发到每台机器设置的收款地址;没设置或地址对应的钱包已销毁,这一份丢失。</summary>
|
||||
/// <summary>一台机器的产出发到它的收款地址;没设置或钱包已销毁返回 false(产出丢失)。</summary>
|
||||
public static bool PayMachine(SaveData d, GameItem machine, double amount)
|
||||
{
|
||||
string addr = Payout.Get(machine);
|
||||
var w = string.IsNullOrEmpty(addr) ? null : d.Own(addr);
|
||||
if (w == null) return false;
|
||||
w.Add(Assets.PSC, amount);
|
||||
d.Chain(d.Address("pool"), w.Address, Assets.PSC, amount, history: false);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void PayMined(SaveData d, IEnumerable<(GameItem item, double hash)> cards, double mined, double totalHash)
|
||||
{
|
||||
var byMachine = new Dictionary<GameItem, double>();
|
||||
@@ -84,11 +95,7 @@ namespace Decentralized
|
||||
foreach (var kv in byMachine)
|
||||
{
|
||||
double share = mined * kv.Value / totalHash;
|
||||
string addr = Payout.Get(kv.Key);
|
||||
var w = string.IsNullOrEmpty(addr) ? null : d.Own(addr);
|
||||
if (w == null) { lost += share; continue; }
|
||||
w.Add(Assets.PSC, share);
|
||||
d.Chain(d.Address("pool"), w.Address, Assets.PSC, share, history: false);
|
||||
if (!PayMachine(d, kv.Key, share)) lost += share;
|
||||
}
|
||||
if (lost > 1e-9)
|
||||
{
|
||||
@@ -97,6 +104,31 @@ namespace Decentralized
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>自营混币器的夜间:客户存入、出款、便衣、查封。对手是 Tumbler 的混币器(关停或被制裁时不算对手)。</summary>
|
||||
private static void OwnMixNight(SaveData d, int day, PlayerStore ps)
|
||||
{
|
||||
var m = d.OwnMix;
|
||||
bool rivalOpen = !d.Story.MixerClosed && !d.Mixer.Sanctioned(day);
|
||||
double rivalRemain = Math.Pow(1 - Mixer.RoundRate(Tuning.OwnMixTicket), Tuning.OwnMixAvgRounds);
|
||||
var evs = m.Night(day, Session.Price, StoreReputation.GetBMReputation(), Mixer.Fee, rivalRemain, rivalOpen, StoryMods.Current.Sanction(day), ActiveEvents().Contains(MarketEvent.Crackdown), d.Rng);
|
||||
foreach (var e in evs)
|
||||
{
|
||||
if (e.Kind == "deposit") ps.AddNightLog(L.T("nightlog.ownmix.in", e.Count, Fmt.Credits(e.Value), Fmt.Credits(e.Value * m.Fee)));
|
||||
else if (e.Kind == "sting")
|
||||
{
|
||||
ps.secData.CommitCrime("FENCING", (int)Math.Round(e.Crime));
|
||||
ps.AddNightLog(L.T("nightlog.ownmix.sting"), "cc7755");
|
||||
}
|
||||
else if (e.Kind == "seized")
|
||||
{
|
||||
ps.secData.CommitCrime("FENCING", (int)Math.Round(e.Crime));
|
||||
ps.AddNightLog(L.T("nightlog.ownmix.seized", Fmt.Credits(e.Value)), "cc7755");
|
||||
News.Show("pd_news_ownmix_seized_" + day, L.T("news.ownmix.seized.title"), L.T("news.ownmix.seized.desc"), 4, 8);
|
||||
}
|
||||
Log.Info($"自营混币器 {e.Kind}:{e.Value:0}({e.Count} 笔),比例 {e.Ratio:0.00},罪证 {e.Crime:0},口碑 {m.Rating:0.00},风声 {m.Heat:0.00}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSleepEarly()
|
||||
{
|
||||
Session.TonightCards.Clear();
|
||||
@@ -269,6 +301,7 @@ namespace Decentralized
|
||||
|
||||
var ps = PlayerStore.Instance;
|
||||
if (mined > 0) ps.AddNightLog(L.T("nightlog.mined", Fmt.Num(mined)));
|
||||
if (Unlock.OtcUnlocked) OwnMixNight(d, day, ps);
|
||||
var mixBefore = d.SnapshotAll();
|
||||
var mixed = d.Mixer.Night(d.WalletAt, day, Session.Price, d.Rng);
|
||||
d.ChainDiffAll(mixBefore, d.Address("mixer"));
|
||||
@@ -301,7 +334,7 @@ namespace Decentralized
|
||||
}
|
||||
var predictBefore = d.SnapshotAll();
|
||||
var predictEvents = PredictGame.Available(day) || d.Predict.Markets.Count > 0
|
||||
? d.Predict.Night(day, PredictGame.ActiveIds(), m => PredictGame.Outcome(m, d), d.WalletAt, d.Rng, PredictGame.ClosePush) : new List<PredictEvent>();
|
||||
? d.Predict.Night(day, PredictGame.ActiveIds(), m => PredictGame.Outcome(m, d), d.WalletAt, Session.Price, d.Rng, PredictGame.ClosePush) : new List<PredictEvent>();
|
||||
d.ChainDiffAll(predictBefore, d.Address("predict"));
|
||||
foreach (var mv in d.Predict.Drift(day, m => PredictGame.PublicProb(m, d, day), d.Rng))
|
||||
{
|
||||
@@ -341,15 +374,11 @@ namespace Decentralized
|
||||
else if (e.Kind == "void") ps.AddNightLog(L.T("nightlog.predict.void", PredictGame.Question(e.Market), Fmt.Credits(e.Amount)));
|
||||
else if (e.Kind == "manip")
|
||||
{
|
||||
ps.secData.CommitCrime("FRAUD", (int)Math.Round(e.Fraud));
|
||||
ps.AddNightLog(L.T("nightlog.predict.manip", PredictGame.Question(e.Market), Fmt.Credits(e.Amount)), "cc7755");
|
||||
ps.AddNightLog(L.T("nightlog.predict.manip", PredictGame.Question(e.Market), Fmt.Credits(e.Amount), Fmt.Credits(e.Taint)) + TaintCrime.Commit(e.Over), "cc7755");
|
||||
News.Show("pd_news_manip_" + day, L.T("news.manip.title"), L.T("news.manip.desc"), 3);
|
||||
}
|
||||
else if (e.Kind == "caught")
|
||||
{
|
||||
ps.secData.CommitCrime("FRAUD", (int)Math.Round(e.Fraud));
|
||||
ps.AddNightLog(L.T("nightlog.predict.caught", PredictGame.Question(e.Market), Fmt.Credits(e.Amount)), "cc7755");
|
||||
}
|
||||
else if (e.Kind == "insider")
|
||||
ps.AddNightLog(L.T("nightlog.predict.insider", PredictGame.Question(e.Market), Fmt.Credits(e.Amount), Fmt.Credits(e.Taint)) + TaintCrime.Commit(e.Over), "cc7755");
|
||||
}
|
||||
foreach (var e in perpEvents)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Decentralized.Domain;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>
|
||||
/// 换币客户(游戏的对话顾客),由切到"换币客户"的暗灯招来,见 <see cref="OtcLamp"/> 与 <see cref="Otc"/>。
|
||||
/// 客户说明来意后选"去终端交易":打开交易终端的柜台交易页(<see cref="TerminalWindow"/>),客户留在柜台前等着。
|
||||
/// 在终端里定成交数量(可以只成交一部分):卖币的客户收现金、币直接进已连接的钱包(便衣会没收现金并记销赃罪证);
|
||||
/// 买币的客户弹出 PLEDGER,收款地址和数量已填好,签名确认后客户付现金。客户走了(被打发、没成交)就作废。
|
||||
/// 原版取顾客名字时也会调用工厂:只有在生成顾客的那段时间里(普通顾客回调之间,原版在这里按展示柜生成顾客)才生成报价、写链上账本。
|
||||
/// </summary>
|
||||
public static class OtcClient
|
||||
{
|
||||
public const string Id = OtcLamp.Target;
|
||||
private static bool spawning;
|
||||
|
||||
/// <summary>正在柜台前、已经去终端交易的客户:报价、收款地址和顾客对象(用来判断他还在不在)。</summary>
|
||||
public static OtcOffer Active;
|
||||
public static string ActiveAddress;
|
||||
private static StoreClient activeClient;
|
||||
|
||||
/// <summary>买币客户的账单:确认到账或作废之前一直记着。</summary>
|
||||
private static WalletWindow.Bill pendingBill;
|
||||
/// <summary>还没签名付款的换币账单:钱包没有终端账单时用它(见 <see cref="WalletWindow.Pending"/>);签名后清掉,没成交(挤出内存池)时放回来。</summary>
|
||||
public static WalletWindow.Bill Standing;
|
||||
|
||||
public static void Subscribe()
|
||||
{
|
||||
StoreClientListDict.storeClientDict[Id] = Create;
|
||||
ModHook.OnGenerateCustomerNormal += Open;
|
||||
ModHook.OnGenerateCustomerLate += Close;
|
||||
ModHook.OnGoingSleepEarly += Drop;
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "OTC client (test)", () => Log.Guard("换币客户(测试)", () =>
|
||||
{
|
||||
spawning = true;
|
||||
StoreClient c;
|
||||
try { c = Create(); } finally { spawning = false; }
|
||||
PlayerStore.Instance.currentClientInstance = null;
|
||||
PlayerStore.Instance.storeClientManager.clientStack.Insert(0, c);
|
||||
PlayerStore.Instance.TryCallNextClient();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void Unsubscribe()
|
||||
{
|
||||
StoreClientListDict.storeClientDict.Remove(Id);
|
||||
ModHook.OnGenerateCustomerNormal -= Open;
|
||||
ModHook.OnGenerateCustomerLate -= Close;
|
||||
ModHook.OnGoingSleepEarly -= Drop;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
/// <summary>顾客表里的工厂。</summary>
|
||||
private static StoreClient Create()
|
||||
{
|
||||
StoreClient c = null;
|
||||
if (spawning && Session.Data != null && Unlock.OtcUnlocked) Log.Guard("换币客户上门", () => c = Real());
|
||||
return c ?? Shell();
|
||||
}
|
||||
|
||||
/// <summary>只有名字的顾客(原版取名字时用;生成失败时上门说一句就走)。</summary>
|
||||
private static StoreClient Shell()
|
||||
{
|
||||
var c = Base();
|
||||
c.mainDialogue.SetText(c.displayName, L.T("otc.refused")).SetEndAction(Leave);
|
||||
Finish(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
private static StoreClient Base() => new StoreClient
|
||||
{
|
||||
identifier = Id, displayName = L.T("otc.name"), spriteName = SpriteDict.GetRandomShadySpriteName(),
|
||||
clientIntent = StoreClient.ClientIntent.DIALOGUE,
|
||||
};
|
||||
|
||||
private static void Finish(StoreClient c)
|
||||
{
|
||||
ModHelper.SetClientSource(c, ModInfo.Id);
|
||||
c.AddBasicDialog();
|
||||
c.CompleteClientCreation();
|
||||
}
|
||||
|
||||
private static StoreClient Real()
|
||||
{
|
||||
var d = Session.Data;
|
||||
var side = Otc.PickSide(d.Rng);
|
||||
bool ponero = Unlock.BlackUnlocked && BlackMarket.DeskOpen(StoreReputation.GetBMReputation());
|
||||
var o = side == OtcSide.Sell ? Otc.MakeSell(Night.ActiveEvents(), ponero, Session.Price, Session.Rent(), d.Rng) : Otc.MakeBuy(Session.Price, Session.Rent(), d.Rng);
|
||||
if (o == null) return null;
|
||||
string addr = d.Address("otc:" + (++d.Otc.Seq));
|
||||
var c = Base();
|
||||
if (o.Side == OtcSide.Sell) WriteHistory(d, o, addr);
|
||||
Build(c, o, addr);
|
||||
Finish(c);
|
||||
Log.Info(o.Side == OtcSide.Sell
|
||||
? $"换币客户(卖币):{o.Qty:0.##} {o.Asset},市值 {o.Value:0},污点比例 {o.TaintRatio:0.00},要价 {o.Cash}{(o.Sting ? "(便衣)" : "")}"
|
||||
: $"换币客户(买币):{o.Qty:0.##} {o.Asset},市值 {o.Value:0},出价 {o.Cash}");
|
||||
Session.Save();
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary>客户地址的来历写进链上账本(Ponero 不上账本):脏的来源是混币器、黑市平台和骗局地址,干净的是 Poinbase 和 DEX。</summary>
|
||||
private static void WriteHistory(SaveData d, OtcOffer o, string addr)
|
||||
{
|
||||
if (o.Asset == Assets.Ponero) return;
|
||||
var dirty = new List<string> { d.Address("mixer"), d.Address("platform") };
|
||||
dirty.AddRange(d.Scams.ScamAddrs);
|
||||
var clean = new List<string> { d.Address("poinbase"), d.Address("dex") };
|
||||
foreach (var kv in Otc.History(o, dirty, clean, d.Rng)) d.Chain(kv.Key, addr, o.Asset, o.Qty * kv.Value);
|
||||
}
|
||||
|
||||
/// <summary>对话:来意和报价,选"去终端交易"打开柜台交易页、客户留下等着;选"算了"客户走人。</summary>
|
||||
private static void Build(StoreClient c, OtcOffer o, string addr)
|
||||
{
|
||||
var trade = new Dialogue();
|
||||
trade.SetText("PLAYER", L.T("otc.say.trade")).NextDialogue().SetText(c.displayName, L.T("otc.wait"));
|
||||
var no = new Dialogue();
|
||||
no.SetText("PLAYER", L.T("otc.say.no")).NextDialogue().SetText(c.displayName, L.T("otc.refused")).SetEndAction(Leave);
|
||||
string intro = o.Side == OtcSide.Buy ? "otc.intro.buy" : o.TaintRatio >= 1 || o.Asset == Assets.Ponero ? "otc.intro." + o.Asset : "otc.intro.sell";
|
||||
string offer = o.Side == OtcSide.Buy
|
||||
? L.T("otc.buy.ask", Fmt.Num(o.Qty), o.Asset, Fmt.Credits(o.Value), Fmt.Credits(o.Cash))
|
||||
: L.T("otc.offer", Fmt.Num(o.Qty), o.Asset, Fmt.Credits(o.Value), Fmt.Credits(o.Cash), ChainAddress.Short(addr));
|
||||
c.mainDialogue.SetText(c.displayName, L.T(intro, o.Asset)).NextDialogue()
|
||||
.SetText(c.displayName, offer)
|
||||
.AddChoice(DirectoryMaster.Item("yes"), L.T("otc.say.trade"), "", trade, () => Begin(c, o, addr))
|
||||
.AddChoice(DirectoryMaster.Item("cancel"), L.T("otc.say.no"), "", no, null);
|
||||
}
|
||||
|
||||
/// <summary>去终端交易:记下在场的客户,打开交易终端的柜台交易页。</summary>
|
||||
private static void Begin(StoreClient c, OtcOffer o, string addr)
|
||||
{
|
||||
Log.Guard("换币客户去终端交易", () =>
|
||||
{
|
||||
Active = o; ActiveAddress = addr; activeClient = c;
|
||||
TerminalWindow.OpenOtc();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>客户还在柜台前吗(没被打发、没走)。不在了就作废这笔交易。</summary>
|
||||
public static bool Present()
|
||||
{
|
||||
if (Active == null) return false;
|
||||
var cur = PlayerStore.Instance?.currentClientInstance?.GetClientBlueprint();
|
||||
if (cur != null && cur == activeClient) return true;
|
||||
Log.Info("换币客户已经离开,交易作废");
|
||||
Drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终端里点"成交":qty 是成交的数量(不超过报价)。卖币:付现金、币进已连接的钱包;买币:开账单、弹出钱包(地址已填好)。
|
||||
/// 返回终端显示的消息(null 表示弹出了钱包,等签名)。
|
||||
/// </summary>
|
||||
public static string Deal(double qty)
|
||||
{
|
||||
if (!Present()) return L.T("otc.msg.gone");
|
||||
var part = Otc.Part(Active, qty);
|
||||
if (part == null) return L.T("msg.amount");
|
||||
return part.Side == OtcSide.Sell ? Take(part) : Give(part);
|
||||
}
|
||||
|
||||
/// <summary>收下客户卖的币:没连钱包、现金不够就作罢;便衣没收现金、记销赃罪证;否则付现金、币进钱包。客户随后离开。</summary>
|
||||
private static string Take(OtcOffer o)
|
||||
{
|
||||
var d = Session.Data;
|
||||
var ps = PlayerStore.Instance;
|
||||
if (!d.Connected) return L.T("web3.err.noconn");
|
||||
if (ps.playerCash < o.Cash) return L.T("otc.msg.cash");
|
||||
string msg = null;
|
||||
Log.Guard("换币客户成交(卖币)", () =>
|
||||
{
|
||||
ModHelper.AddCredit(-o.Cash, false);
|
||||
if (o.Sting)
|
||||
{
|
||||
ps.secData.CommitCrime("FENCING", (int)Math.Min(Tuning.CrimeEventCap, o.Cash));
|
||||
Say(L.T("otc.sting"));
|
||||
msg = L.T("otc.msg.sting", Fmt.Credits(o.Cash));
|
||||
Log.Info($"换币客户:便衣,现金 {o.Cash} 没收,记销赃罪证");
|
||||
}
|
||||
else
|
||||
{
|
||||
double over = Otc.Receive(d.Hot, o, Session.Price);
|
||||
d.Chain(ActiveAddress, d.Hot.Address, o.Asset, o.Qty);
|
||||
d.Otc.Record(o.Cash);
|
||||
msg = L.T("otc.msg.bought", Fmt.Num(o.Qty), o.Asset, Fmt.Credits(o.Cash)) + TaintCrime.Commit(over);
|
||||
Say(L.T("otc.done"));
|
||||
Log.Info($"换币客户:{o.Qty:0.##} {o.Asset} 进 {WalletWindow.NameOf(d.Hot)},付现金 {o.Cash},钱包污点 {d.Hot.Taint:0},超出 {over:0}");
|
||||
}
|
||||
Drop();
|
||||
Session.Save();
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>卖币给客户:开账单(客户地址已填好),弹出钱包签名;确认后客户付现金、离开。</summary>
|
||||
private static string Give(OtcOffer o)
|
||||
{
|
||||
double qty = WalletWindow.RoundUp(o.Qty);
|
||||
string asset = o.Asset;
|
||||
int cash = o.Cash;
|
||||
WalletWindow.Bill bill = null;
|
||||
bill = new WalletWindow.Bill
|
||||
{
|
||||
Address = ActiveAddress, Asset = asset, Amount = qty, Prefill = true, Summary = L.T("pay.otc", WalletWindow.Amt(qty), asset, Fmt.Credits(cash)),
|
||||
Execute = pw => Log.Guard("换币客户到账", () =>
|
||||
{
|
||||
pw.Spend(asset, qty, Session.Price);
|
||||
ModHelper.AddCredit(cash, true);
|
||||
Session.Data.Otc.Record(cash);
|
||||
if (pendingBill == bill) pendingBill = null;
|
||||
if (Active != null && Present()) { Say(L.T("otc.paid")); Active = null; ActiveAddress = null; activeClient = null; }
|
||||
TerminalWindow.Refresh(L.T("otc.msg.sold", WalletWindow.Amt(qty), asset, Fmt.Credits(cash)));
|
||||
Log.Info($"换币客户:{qty} {asset} 到账,收现金 {cash}");
|
||||
Session.Save();
|
||||
}),
|
||||
};
|
||||
pendingBill = Standing = bill;
|
||||
WalletWindow.OpenForBill(bill);
|
||||
Log.Info($"换币客户:卖出 {qty} {asset},现金 {cash},等签名");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>客户说最后一句,然后离开。</summary>
|
||||
private static void Say(string line)
|
||||
{
|
||||
var c = activeClient;
|
||||
if (c == null || DialogUIManager.Instance == null) return;
|
||||
var dl = new Dialogue();
|
||||
dl.SetText(c.displayName, line).SetEndAction(Leave);
|
||||
DialogUIManager.Instance.StartDialogue(dl);
|
||||
}
|
||||
|
||||
/// <summary>放弃(终端的"放弃"):客户说一句走人,交易作废。</summary>
|
||||
public static void Cancel()
|
||||
{
|
||||
if (Present()) Say(L.T("otc.refused"));
|
||||
Drop();
|
||||
}
|
||||
|
||||
/// <summary>这位客户的交易结束(成交、作废、离开,或者睡觉前):还没签名的账单一起作废;已经签名、还在确认中的照常到账。</summary>
|
||||
private static void Drop()
|
||||
{
|
||||
Active = null; ActiveAddress = null; activeClient = null;
|
||||
Void();
|
||||
}
|
||||
|
||||
/// <summary>作废换币账单(终端的"作废"、客户离开、读档)。</summary>
|
||||
public static void Void()
|
||||
{
|
||||
if (Standing != null && WalletWindow.Pending == Standing) WalletWindow.Pending = null;
|
||||
Standing = null;
|
||||
if (pendingBill != null && Standing == null) pendingBill = null;
|
||||
}
|
||||
|
||||
private static void Leave() => DialogUIManager.Instance.CurrentClientLeave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>
|
||||
/// 借用原版小偷灯招揽换币客户:在原版小偷灯的工厂外包一层,切换顺序末尾加一个目标"换币客户"(解锁换币台后才有)。
|
||||
/// 原版按灯的目标去公开的顾客表(<see cref="StoreClientListDict.storeClientDict"/>)里造顾客,所以顾客面板、灯的提示、概率都走原版逻辑。
|
||||
/// 霓虹色:底图换成原版图集里熄灭的暗灯(存档里记的仍是原版的图,卸载后不缺图),上面用原版的图片叠加层
|
||||
/// (getItemSpriteModifierForItemFunc,运行时委托,不进存档)画黄绿色光晕。原版遇到不认识的目标会点亮成第一种颜色,我们排在它后面改回熄灭的底图。
|
||||
/// 切换只接管进出我们目标的那一步,其余交给原来的切换函数,别的 mod 往灯上加的目标也照样能切到。
|
||||
/// </summary>
|
||||
public static class OtcLamp
|
||||
{
|
||||
/// <summary>灯的目标 = 顾客表里的顾客标识。</summary>
|
||||
public const string Target = "pd_otc";
|
||||
private const string OverlaySprite = "otc_lamp_on";
|
||||
/// <summary>原版暗灯所在的图集与熄灭时的图(BlackLampHelper 里是私有常量)。</summary>
|
||||
private const string LampAtlas = "Items/items_sign", LampOff = "black_lamp";
|
||||
|
||||
private static readonly Action<GameItem, GameInventory, SlotMarker> OnShowcaseChanged = (item, _, __) => Log.Guard("展示柜刷新换币灯", () => Refresh(item));
|
||||
|
||||
public static bool IsLamp(GameItem item) => item != null && item.identifier == BlackLampHelper.BLACK_LAMP_ID;
|
||||
public static bool IsOurs(GameItem item) => IsLamp(item) && BlackLampHelper.GetTarget(item) == Target;
|
||||
|
||||
/// <summary>在原版小偷灯的工厂外包一层(物品目录初始化时)。</summary>
|
||||
public static void Wrap(ModItemDirectory dir)
|
||||
{
|
||||
try
|
||||
{
|
||||
var make = DirectoryMaster.GetFactory<GameItem>(BlackLampHelper.BLACK_LAMP_ID);
|
||||
if (make == null) { Log.Warn("[OTC] 找不到原版小偷灯"); return; }
|
||||
dir.Set(BlackLampHelper.BLACK_LAMP_ID, () =>
|
||||
{
|
||||
var lamp = make();
|
||||
var prev = lamp.onActivateSlotItemFunc;
|
||||
lamp.onActivateSlotItemFunc = (it, inv, slot) => Log.Guard("小偷灯切换", () => Cycle(it, inv, slot, prev));
|
||||
var prevSprites = lamp.getItemSpriteModifierForItemFunc;
|
||||
lamp.getItemSpriteModifierForItemFunc = it => Overlay(it, prevSprites);
|
||||
return lamp;
|
||||
});
|
||||
Log.Info("[OTC] 已包装原版小偷灯");
|
||||
}
|
||||
catch (Exception ex) { Log.Error("[OTC] 包装小偷灯失败:" + ex); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换:当前是"换币客户"时回到原版第一个目标;否则先走原来的切换,原来的切换绕回第一个目标、而且换币台已解锁时,改成"换币客户"。
|
||||
/// </summary>
|
||||
private static void Cycle(GameItem lamp, GameInventory inv, SlotMarker slot, Action<GameItem, GameInventory, SlotMarker> prev)
|
||||
{
|
||||
string first = BlackLampHelper.TARGETS[0];
|
||||
if (IsOurs(lamp))
|
||||
{
|
||||
SetTarget(lamp, first);
|
||||
BlackLampHelper.RefreshLampSprite(lamp);
|
||||
AudioManager.Instance.Play2("click_vintage");
|
||||
}
|
||||
else
|
||||
{
|
||||
string before = BlackLampHelper.GetTarget(lamp);
|
||||
prev?.Invoke(lamp, inv, slot);
|
||||
if (Unlock.OtcUnlocked && before != first && BlackLampHelper.GetTarget(lamp) == first) SetTarget(lamp, Target);
|
||||
}
|
||||
Refresh(lamp);
|
||||
}
|
||||
|
||||
public static void SetTarget(GameItem lamp, string target) => lamp.ModifyTag(BlackLampHelper.LAMP_TARGET_TAG, s => { s.Enable().SetString(target); });
|
||||
|
||||
/// <summary>目标是"换币客户"、而且灯在展示柜里时,叠一层霓虹灯图(盖住原版退回的点亮图)。</summary>
|
||||
private static List<ItemSpriteModifier> Overlay(GameItem lamp, Func<GameItem, List<ItemSpriteModifier>> prev)
|
||||
{
|
||||
var list = prev?.Invoke(lamp) ?? new List<ItemSpriteModifier>();
|
||||
if (IsOurs(lamp) && InShowcase(lamp))
|
||||
{
|
||||
var sprite = Items.ModSprite(OverlaySprite);
|
||||
if (sprite != null) list.Add(new ItemSpriteModifier(sprite, Vector2.zero, 0, isFlipped: false, 10, haveMask: false, Color.white));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static bool InShowcase(GameItem item)
|
||||
{
|
||||
var sc = EmporiumEntry.Instance?.showcaseElement;
|
||||
return sc != null && sc.childItems.Contains(item);
|
||||
}
|
||||
|
||||
/// <summary>换币灯在展示柜里:底图改成熄灭的暗灯(光晕由叠加层画);然后重画。</summary>
|
||||
private static void Refresh(GameItem item)
|
||||
{
|
||||
if (!IsLamp(item)) return;
|
||||
if (IsOurs(item) && InShowcase(item)) item.SetSpriteQuick(LampAtlas, LampOff);
|
||||
item.Validate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读档、开新游戏后:在展示柜的放入、取出回调后面挂上刷新(原版在这两个回调里重设灯的底图,我们排在它后面重画叠加层),
|
||||
/// 先解绑再挂,避免读档几次挂几次;再把展示柜里的灯刷新一遍。
|
||||
/// </summary>
|
||||
public static void Attach()
|
||||
{
|
||||
var sc = EmporiumEntry.Instance?.showcaseElement;
|
||||
if (sc == null) return;
|
||||
sc.onSlotAddItemLateFunc = (Action<GameItem, GameInventory, SlotMarker>)Delegate.Remove(sc.onSlotAddItemLateFunc, OnShowcaseChanged);
|
||||
sc.onSlotAddItemLateFunc = (Action<GameItem, GameInventory, SlotMarker>)Delegate.Combine(sc.onSlotAddItemLateFunc, OnShowcaseChanged);
|
||||
sc.onSlotRemoveItemEndFunc = (Action<GameItem, GameInventory, SlotMarker>)Delegate.Remove(sc.onSlotRemoveItemEndFunc, OnShowcaseChanged);
|
||||
sc.onSlotRemoveItemEndFunc = (Action<GameItem, GameInventory, SlotMarker>)Delegate.Combine(sc.onSlotRemoveItemEndFunc, OnShowcaseChanged);
|
||||
foreach (var item in sc.childItems) Refresh(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ namespace Decentralized
|
||||
/// <summary>一局的 mod 状态。整体序列化成 JSON 存进游戏的 mod 存档数据;显卡的健康度等存在显卡物品的标签上。</summary>
|
||||
public sealed class SaveData
|
||||
{
|
||||
/// <summary>存档数据的版本:2 起保险基金用新的数值,3 起 Poinbase 主池是订单簿。</summary>
|
||||
public int Version = 3;
|
||||
/// <summary>存档数据的版本:2 起保险基金用新的数值,3 起 Poinbase 主池是订单簿,4 起出块奖励和 NPC 算力 ×10(第十一阶段)。</summary>
|
||||
public int Version = 4;
|
||||
public int Day;
|
||||
public Rng Rng = new Rng((ulong)DateTime.UtcNow.Ticks);
|
||||
public Market Market;
|
||||
@@ -88,6 +88,10 @@ namespace Decentralized
|
||||
public double ChainValue(Func<string, double> price) { double v = 0; foreach (var w in Wallets) v += w.Value(price); return v; }
|
||||
public Exchange Exchange = new Exchange();
|
||||
public Mixer Mixer = new Mixer();
|
||||
/// <summary>换币台的累计成交与客户地址编号。</summary>
|
||||
public OtcDesk Otc = new OtcDesk();
|
||||
/// <summary>自营混币器(买下场外换币台就开放)。</summary>
|
||||
public OwnMixer OwnMix = new OwnMixer();
|
||||
public BlackMarket Black = new BlackMarket();
|
||||
public List<MarketEvent> ActiveEvents = new List<MarketEvent>();
|
||||
public NightReport LastNight;
|
||||
@@ -189,9 +193,20 @@ namespace Decentralized
|
||||
Data.Market.AddPoinSpark(Data.Stable.Spark, StoreStation.GetDayCounter());
|
||||
Data.Market.UpgradeDexPools(StoreStation.GetDayCounter());
|
||||
if (Data.Version < 3) { Data.Version = 3; Log.Info("存档数据升级到版本 3:保险基金、Poinbase 订单簿"); }
|
||||
// 第十一阶段:出块奖励和 NPC 算力同乘 10(均衡时每 H 收入不变,玩家算力占比变低);旧存档按当时的减半进度一起放大
|
||||
if (Data.Version < 4)
|
||||
{
|
||||
Data.Network.Reward *= Tuning.MiningScale;
|
||||
Data.Network.NpcHash *= Tuning.MiningScale;
|
||||
Data.Version = 4;
|
||||
Log.Info($"存档数据升级到版本 4:出块奖励 {Data.Network.Reward:0}、NPC 算力 {Data.Network.NpcHash:0}");
|
||||
}
|
||||
if (Data.Otc == null) Data.Otc = new OtcDesk();
|
||||
if (Data.OwnMix == null) Data.OwnMix = new OwnMixer();
|
||||
if (Data.Story == null) Data.Story = new StoryMods();
|
||||
StoryMods.Current = Data.Story;
|
||||
Log.Info($"状态已载入(第 {Data.Day} 天,PSC {Data.Market.Price:0.00})");
|
||||
Log.Guard("换币灯", OtcLamp.Attach);
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Decentralized.Domain;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>灰网页的"自营混币器"(买下场外换币台就有):状态、口碑、风声、池子,费率、开张或暂停、注资、取回、卷款跑路。规则见 <see cref="OwnMixer"/>。</summary>
|
||||
public static partial class TerminalWindow
|
||||
{
|
||||
private static string _ownAsset = Assets.CRT;
|
||||
private static bool _ownRugConfirm;
|
||||
private static readonly float[] OwnWBase = { 70f, 110f, 110f, 110f };
|
||||
private static float[] OwnW => Sc(OwnWBase);
|
||||
private static readonly TextAnchor[] OwnAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
|
||||
|
||||
private static void OwnMixPage(CustomUIBuilder b)
|
||||
{
|
||||
var d = Session.Data;
|
||||
var m = d.OwnMix;
|
||||
int day = StoreStation.GetDayCounter();
|
||||
double enforce = StoryMods.Current.Sanction(day);
|
||||
Columns(b, l =>
|
||||
{
|
||||
l.AddHeader(L.T("ownmix.h"));
|
||||
string status = m.Closed ? L.T("ownmix.status.closed") : m.Seized(day) ? L.T("ownmix.status.seized", m.SeizedUntil + 1) : m.Open ? L.T("ownmix.status.open") : L.T("ownmix.status.paused");
|
||||
l.AddLabel(status, m.Closed || m.Seized(day) ? "ownmix_status_note" : "ownmix_status_dim");
|
||||
var w = new[] { 220f, 200f };
|
||||
TableRow(l, w, L.T("ownmix.k.fee"), (m.Fee * 100).ToString("0", CultureInfo.InvariantCulture) + "%");
|
||||
TableRow(l, w, L.T("ownmix.k.rating"), (m.Rating * 100).ToString("0", CultureInfo.InvariantCulture) + "%");
|
||||
TableRow(l, w, L.T("ownmix.k.heat"), L.T("ownmix.heat." + m.HeatLevel(enforce)));
|
||||
TableRow(l, w, L.T("ownmix.k.anon"), Fmt.Credits(m.Anonymity(Session.Price)));
|
||||
TableRow(l, w, L.T("ownmix.k.fees"), Fmt.Credits(m.FeesTotal));
|
||||
l.AddSeparator();
|
||||
TableHeader(l, OwnW.Sum() + 8f, OwnW, OwnAligns, L.T("col.asset"), L.T("ownmix.col.capital"), L.T("ownmix.col.earned"), L.T("ownmix.col.pending"));
|
||||
foreach (var a in OwnMixer.AssetsList)
|
||||
{
|
||||
var p = m.Pool(a);
|
||||
double pend = m.Total(a) - m.Free(a);
|
||||
TableRow(l, OwnW.Sum() + 8f, OwnW, OwnAligns, new[] { a, Fmt.Num(p.Capital), Fmt.Num(p.Earned), Fmt.Num(pend) });
|
||||
}
|
||||
}, r =>
|
||||
{
|
||||
if (m.Closed || m.Seized(day)) { r.AddLabel(m.Closed ? L.T("ownmix.status.closed") : L.T("ownmix.status.seized", m.SeizedUntil + 1), "ownmix_closed_note"); return; }
|
||||
var w = d.Hot;
|
||||
r.AddHeader(L.T("ownmix.k.fee"));
|
||||
r.BeginRow(4f);
|
||||
foreach (var f in Tuning.OwnMixFees)
|
||||
{
|
||||
double fee = f;
|
||||
PledgerSkin.Pick(r, (fee * 100).ToString("0", CultureInfo.InvariantCulture) + "%", Math.Abs(fee - m.Fee) < 1e-9, () => { m.Fee = fee; Session.Save(); Open(); }, _picked);
|
||||
}
|
||||
r.End();
|
||||
r.AddButton(m.Open ? L.T("ownmix.pause") : L.T("ownmix.open"), () =>
|
||||
{
|
||||
if (m.Open) m.Open = false; else m.Start(Session.Price);
|
||||
Log.Info($"自营混币器:{(m.Open ? "开张" : "暂停")},费率 {m.Fee:P0}");
|
||||
Session.Save(); Open();
|
||||
});
|
||||
r.AddSeparator();
|
||||
r.BeginRow(4f);
|
||||
foreach (var a in OwnMixer.AssetsList)
|
||||
{
|
||||
var asset = a;
|
||||
PledgerSkin.Pick(r, asset, asset == _ownAsset, () => { _ownAsset = asset; Open(); }, _picked);
|
||||
}
|
||||
r.End();
|
||||
r.AddLabel(L.T("mixer.balance", _ownAsset, Fmt.Num(w.Avail(_ownAsset))));
|
||||
r.AddLabel(L.T("ownmix.free", Fmt.Num(m.Free(_ownAsset)), _ownAsset));
|
||||
AmountRow(r, true, _ownAsset);
|
||||
r.BeginRow(6f);
|
||||
r.AddButton(L.T("ownmix.inject"), () =>
|
||||
{
|
||||
if (!ReadAmount(out double v)) return;
|
||||
string asset = _ownAsset;
|
||||
BillFor(d.Address("ownmix"), L.T("pay.ownmix", Fmt.Num(v), asset), asset, v, pw =>
|
||||
{
|
||||
if (!m.Inject(pw, asset, v, Session.Price)) { _message = L.T("msg.balance"); Open(); return; }
|
||||
_message = L.T("ownmix.injected", Fmt.Num(v), asset);
|
||||
Log.Info($"自营混币器注资 {v} {asset},匿名集 {m.Anonymity(Session.Price):0}");
|
||||
Session.Save(); Open();
|
||||
});
|
||||
});
|
||||
r.AddButton(L.T("ownmix.withdraw"), () =>
|
||||
{
|
||||
if (!ReadAmount(out double v)) return;
|
||||
string asset = _ownAsset;
|
||||
// 页面上的可取回数量是四舍五入后的,照着填会比实际多一点点:差在显示精度以内就按全部取回
|
||||
double free = m.Free(asset);
|
||||
if (v > free && v - free < 0.01) v = free;
|
||||
if (v > free + 1e-9) { _message = L.T("ownmix.err"); Open(); return; }
|
||||
_message = L.T("hw.wait");
|
||||
Open();
|
||||
WalletWindow.OpenForBill(new WalletWindow.Bill
|
||||
{
|
||||
Contract = true, Party = d.Address("ownmix"), Asset = asset, Amount = 0, Spend = 0, FeeAsset = BestFeeAsset(w),
|
||||
Summary = L.T("ownmix.withdraw.sum", Fmt.Num(v), asset),
|
||||
Execute = pw =>
|
||||
{
|
||||
if (!m.Withdraw(pw, asset, v, Session.Price, out double over)) { _message = L.T("ownmix.err"); Open(); return; }
|
||||
_message = L.T("ownmix.withdrawn", Fmt.Num(v), asset) + TaintCrime.Commit(over);
|
||||
Log.Info($"自营混币器取回 {v} {asset},钱包污点 {pw.Taint:0},超出 {over:0}");
|
||||
Session.Save(); Open();
|
||||
},
|
||||
});
|
||||
});
|
||||
r.End();
|
||||
r.AddSeparator();
|
||||
double total = OwnMixer.AssetsList.Sum(a => m.Total(a) * Session.Price(a));
|
||||
if (total <= 1e-9) return;
|
||||
r.AddButton(_ownRugConfirm ? L.T("ownmix.rug.confirm", Fmt.Credits(total)) : L.T("ownmix.rug", Fmt.Credits(total)), () =>
|
||||
{
|
||||
if (!_ownRugConfirm) { _ownRugConfirm = true; Open(); return; }
|
||||
_ownRugConfirm = false;
|
||||
_message = L.T("hw.wait");
|
||||
Open();
|
||||
WalletWindow.OpenForBill(new WalletWindow.Bill
|
||||
{
|
||||
Contract = true, Party = d.Address("ownmix"), Asset = Assets.CRT, Amount = 0, Spend = 0, FeeAsset = BestFeeAsset(w),
|
||||
Summary = L.T("ownmix.rug.sum"),
|
||||
Execute = pw =>
|
||||
{
|
||||
if (m.Closed) return;
|
||||
double value = OwnMixer.AssetsList.Sum(a => m.Total(a) * Session.Price(a));
|
||||
m.Rug(pw, Session.Price, out double over);
|
||||
PlayerStore.Instance.secData.CommitCrime("FRAUD", (int)Tuning.OwnMixRugCrime);
|
||||
StoreReputation.ModReputation(StoreReputation.FACTION_BLACK_MARKET, -Tuning.OwnMixRugRep);
|
||||
News.Show("pd_news_ownmix_rug_" + StoreStation.GetDayCounter(), L.T("news.ownmix.rug.title"), L.T("news.ownmix.rug.desc"), 4);
|
||||
_message = L.T("ownmix.rugged", Fmt.Credits(value)) + TaintCrime.Commit(over);
|
||||
Log.Info($"自营混币器卷款跑路:{value:0},钱包 {pw.Address}");
|
||||
Session.Save(); Open();
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace Decentralized
|
||||
/// 交易终端窗口:首页三个入口(银行、Poinbase、Web3)加报告。银行是真实的信用点(存取、房租);
|
||||
/// Poinbase 是合规交易所;Web3 是去中心化交易和链上钱包。每次操作后按当前页重建窗口。
|
||||
/// </summary>
|
||||
public static class TerminalWindow
|
||||
public static partial class TerminalWindow
|
||||
{
|
||||
public const string Id = "pd_terminal";
|
||||
private const float Bezel = 6f;
|
||||
@@ -29,7 +29,7 @@ namespace Decentralized
|
||||
private static float F => Mathf.Clamp(1f + Ext * 0.00065f, 1f, 1.3f);
|
||||
public static float ChartScale => LeftW >= 634f ? 3f : 2f;
|
||||
private static float[] Sc(float[] b) { float k = LeftW / 420f; return b.Select(x => x * k).ToArray(); }
|
||||
private enum Page { Home, Bank, Poinbase, Web3, Mining, Gray, Wallets }
|
||||
private enum Page { Home, Bank, Poinbase, Web3, Mining, Gray, Wallets, Otc }
|
||||
|
||||
private static Page _page = Page.Home;
|
||||
private static string _amount = "";
|
||||
@@ -76,7 +76,8 @@ namespace Decentralized
|
||||
private static void BuildTop(CustomUIBuilder b)
|
||||
{
|
||||
if (_page == Page.Gray && !GrayAvailable) _page = Page.Web3;
|
||||
TabRows(b, Enum.GetValues(typeof(Page)).Cast<Page>().Where(p => p != Page.Gray || GrayAvailable).Select(p =>
|
||||
if (_page == Page.Otc && OtcClient.Active == null) _page = Page.Home;
|
||||
TabRows(b, Enum.GetValues(typeof(Page)).Cast<Page>().Where(p => (p != Page.Gray || GrayAvailable) && (p != Page.Otc || OtcClient.Active != null)).Select(p =>
|
||||
{
|
||||
var page = p;
|
||||
return new TabDef { Name = L.T("tab." + p.ToString().ToLowerInvariant()), On = page == _page, Click = () => { _page = page; _message = null; Open(); } };
|
||||
@@ -86,8 +87,11 @@ namespace Decentralized
|
||||
|
||||
private static void BuildBody(CustomUIBuilder b)
|
||||
{
|
||||
if ((_page == Page.Web3 || _page == Page.Gray) && WalletWindow.Pending != null && !WalletWindow.Pending.Contract) PayPage(b);
|
||||
else switch (_page)
|
||||
bool pay = (_page == Page.Web3 || _page == Page.Gray) && WalletWindow.Pending != null && !WalletWindow.Pending.Contract;
|
||||
// 换币客户的账单不独占页面:手里往往没有客户要的币,要先在这里换出来再付
|
||||
if (pay) PayPage(b);
|
||||
if (pay && !OtcClient.IsBill(WalletWindow.Pending)) return;
|
||||
switch (_page)
|
||||
{
|
||||
case Page.Home: HomePage(b); break;
|
||||
case Page.Bank: BankPage(b); break;
|
||||
@@ -96,6 +100,7 @@ namespace Decentralized
|
||||
case Page.Mining: ReportPage(b); break;
|
||||
case Page.Gray: GrayPage(b); break;
|
||||
case Page.Wallets: WalletsPage(b); break;
|
||||
case Page.Otc: OtcPage(b); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +173,63 @@ namespace Decentralized
|
||||
|
||||
private static void Go(Page p) { _page = p; _message = null; Open(); }
|
||||
|
||||
/// <summary>换币客户选了"去终端交易":打开终端的柜台交易页,数量默认填客户的全部。</summary>
|
||||
public static void OpenOtc()
|
||||
{
|
||||
var o = OtcClient.Active;
|
||||
if (o == null) return;
|
||||
_page = Page.Otc; _message = null;
|
||||
_amount = WalletWindow.Amt(o.Qty);
|
||||
Open();
|
||||
}
|
||||
|
||||
private static readonly double[] OtcRatios = { 0.25, 0.5, 0.75, 1 };
|
||||
|
||||
/// <summary>柜台交易:客户的来意和报价,按比例或手输定成交数量,预览现金和币,成交或放弃。</summary>
|
||||
private static void OtcPage(CustomUIBuilder b)
|
||||
{
|
||||
var o = OtcClient.Active;
|
||||
b.AddHeader(L.T("otc.h"));
|
||||
if (o == null || !OtcClient.Present()) { b.AddLabel(L.T("otc.msg.gone")); return; }
|
||||
var w = new[] { 200f, 300f };
|
||||
bool take = o.Side == OtcSide.Sell;
|
||||
TableRow(b, w, L.T("otc.k.side"), L.T(take ? "otc.side.sell" : "otc.side.buy", o.Asset));
|
||||
TableRow(b, w, L.T("otc.k.qty"), Fmt.Num(o.Qty) + " " + o.Asset);
|
||||
TableRow(b, w, L.T("otc.k.value"), Fmt.Credits(o.Value));
|
||||
TableRow(b, w, L.T(take ? "otc.k.ask" : "otc.k.bid"), Fmt.Credits(o.Cash));
|
||||
TableRow(b, w, L.T("otc.k.unit"), Fmt.Num(o.Cash / o.Qty) + " / " + o.Asset);
|
||||
b.BeginRow(6f, TextAnchor.MiddleLeft);
|
||||
b.AddLabel(L.T("otc.k.addr", ChainAddress.Short(OtcClient.ActiveAddress)));
|
||||
if (take) b.AddButton(L.T("otc.lookup"), () => { _explorerQuery = OtcClient.ActiveAddress; _page = Page.Wallets; _walletTab = WalletTab.Explorer; _message = null; Open(); });
|
||||
b.End();
|
||||
b.AddSeparator();
|
||||
b.BeginRow(4f);
|
||||
foreach (var r in OtcRatios)
|
||||
{
|
||||
double ratio = r;
|
||||
string v = WalletWindow.Amt(o.Qty * ratio);
|
||||
PledgerSkin.Pick(b, (ratio * 100).ToString("0") + "%", (_amount ?? "").Trim() == v, () => { _amount = v; Open(); }, _picked);
|
||||
}
|
||||
b.End();
|
||||
AmountRow(b, true, o.Asset);
|
||||
if (double.TryParse((_amount ?? "").Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out double q) && q > 0)
|
||||
{
|
||||
var part = Otc.Part(o, q);
|
||||
b.AddLabel(take ? L.T("otc.preview.take", Fmt.Credits(part.Cash), Fmt.Num(part.Qty), o.Asset) : L.T("otc.preview.give", Fmt.Num(part.Qty), o.Asset, Fmt.Credits(part.Cash)));
|
||||
if (!take) b.AddLabel(L.T("mixer.balance", o.Asset, Fmt.Num(Session.Data.Hot.Avail(o.Asset))));
|
||||
}
|
||||
b.BeginRow(6f);
|
||||
b.AddButton(L.T("otc.deal"), () =>
|
||||
{
|
||||
if (!ReadAmount(out double v)) return;
|
||||
string msg = OtcClient.Deal(v);
|
||||
if (msg != null) _message = msg;
|
||||
Open();
|
||||
});
|
||||
b.AddButton(L.T("otc.cancel"), () => { OtcClient.Cancel(); _message = null; _page = Page.Home; Open(); });
|
||||
b.End();
|
||||
}
|
||||
|
||||
/// <summary>钱包那边交易落地后刷新终端(开着的话),带上结果消息。</summary>
|
||||
public static void Refresh(string message)
|
||||
{
|
||||
@@ -1247,13 +1309,12 @@ namespace Decentralized
|
||||
Summary = L.T("predict.sum.sell", PredictGame.Question(m)),
|
||||
Execute = pw =>
|
||||
{
|
||||
var res = d.Predict.SellAll(pw, m, StoreStation.GetDayCounter(), d.Rng, out double got, out double fraud);
|
||||
var res = d.Predict.SellAll(pw, m, StoreStation.GetDayCounter(), Session.Price, out double got, out double taint, out double over);
|
||||
_message = res == PredictResult.Ok ? L.T("predict.sold", Fmt.Num(got)) : L.T("predict.err." + res);
|
||||
if (fraud > 0)
|
||||
if (res == PredictResult.Ok && taint + over > 1e-9)
|
||||
{
|
||||
PlayerStore.Instance.secData.CommitCrime("FRAUD", (int)Math.Round(fraud));
|
||||
_message = L.T("predict.sold.caught", Fmt.Num(got));
|
||||
Log.Info($"内幕卖出被查:只退本金 {got:0},罪证 {fraud:0}");
|
||||
_message = L.T("predict.sold.caught", Fmt.Num(got), Fmt.Credits(taint)) + TaintCrime.Commit(over);
|
||||
Log.Info($"内幕卖出:收回 {got:0},污点 +{taint:0},超出 {over:0}");
|
||||
}
|
||||
if (res == PredictResult.Ok) Session.Save();
|
||||
Open();
|
||||
@@ -1292,18 +1353,16 @@ namespace Decentralized
|
||||
double margin = pos.Margin;
|
||||
CandleChart.Trade(_perpProduct, pos.Notional(PerpSpot(_perpProduct)));
|
||||
double paid = d.Perps.Close(d.Poinbase, _perpProduct, PerpSpot(_perpProduct), StoreStation.GetDayCounter(), out double deficit);
|
||||
// 操纵:平仓盈利,而且盈利方向和玩家自己推价的方向一致,按推价幅度被查:盈利没收,记诈骗罪证,永续账户冻结几天
|
||||
// 操纵:平仓盈利,而且盈利方向和玩家自己推价的方向一致,按推价幅度被查:盈利照常留在 Poinbase 账户,这笔盈利记污点(带上限)
|
||||
double push = d.Market.PlayerPush, profit = paid - margin;
|
||||
bool aligned = _perpProduct == "PSC" && profit > 0 && (pos.Long ? push > 0 : push < 0);
|
||||
if (aligned && d.Rng.Chance(Math.Min(1, Market.ManipChance(push) * StoryMods.Current.Enforce(StoreStation.GetDayCounter()))))
|
||||
{
|
||||
int day = StoreStation.GetDayCounter();
|
||||
d.Poinbase.Add(Assets.CRC, -Math.Min(profit, d.Poinbase.Avail(Assets.CRC)));
|
||||
d.Perps.BannedUntil = day + Tuning.ManipFreezeDays;
|
||||
PlayerStore.Instance.secData.CommitCrime("FRAUD", (int)Math.Round(Math.Min(Tuning.PredictFraudCap, profit * Tuning.PredictFraudShare)));
|
||||
double over = d.Poinbase.AddTaintCapped(profit, Session.Price);
|
||||
News.Show("pd_news_manip_" + day, L.T("news.manip.title"), L.T("news.manip.desc"), 3);
|
||||
_message = L.T("perp.manip", Fmt.Credits(profit), Tuning.ManipFreezeDays);
|
||||
Log.Info($"永续操纵被查:盈利 {profit:0} 没收,推价 {push:0.000}");
|
||||
_message = L.T("perp.manip", Fmt.Credits(profit), Fmt.Credits(profit - over)) + TaintCrime.Commit(over);
|
||||
Log.Info($"永续操纵被查:盈利 {profit:0} 记污点 {profit - over:0},超出 {over:0},推价 {push:0.000}");
|
||||
Session.Save();
|
||||
Open();
|
||||
return;
|
||||
@@ -1478,19 +1537,21 @@ namespace Decentralized
|
||||
b.End();
|
||||
}
|
||||
|
||||
private static bool GrayAvailable => Unlock.MixerUnlocked || Unlock.BlackUnlocked;
|
||||
private enum GrayTab { Mixer, Black }
|
||||
private static bool GrayAvailable => Unlock.MixerUnlocked || Unlock.BlackUnlocked || Unlock.OtcUnlocked;
|
||||
|
||||
private static bool GrayTabOn(GrayTab t) => t == GrayTab.Mixer ? Unlock.MixerUnlocked : t == GrayTab.Black ? Unlock.BlackUnlocked : Unlock.OtcUnlocked;
|
||||
private enum GrayTab { Mixer, Black, Own }
|
||||
private static GrayTab _grayTab = GrayTab.Mixer;
|
||||
|
||||
/// <summary>灰网:混币器和商店,各自在人脉网络里解锁,解锁了哪个就有哪个。</summary>
|
||||
private static void GrayPage(CustomUIBuilder b)
|
||||
{
|
||||
if (_grayTab == GrayTab.Mixer && !Unlock.MixerUnlocked) _grayTab = GrayTab.Black;
|
||||
if (_grayTab == GrayTab.Black && !Unlock.BlackUnlocked) _grayTab = GrayTab.Mixer;
|
||||
if (Unlock.MixerUnlocked && Unlock.BlackUnlocked)
|
||||
TabRows(b, Enum.GetValues(typeof(GrayTab)).Cast<GrayTab>().Select(t => { var tab = t; return new TabDef { Name = L.T("gray.sub." + t.ToString().ToLowerInvariant()), On = tab == _grayTab, Click = () => { _grayTab = tab; _message = null; Open(); } }; }).ToList(), false);
|
||||
var tabs = Enum.GetValues(typeof(GrayTab)).Cast<GrayTab>().Where(GrayTabOn).ToList();
|
||||
if (!GrayTabOn(_grayTab) && tabs.Count > 0) _grayTab = tabs[0];
|
||||
if (tabs.Count > 1)
|
||||
TabRows(b, tabs.Select(t => { var tab = t; return new TabDef { Name = L.T("gray.sub." + t.ToString().ToLowerInvariant()), On = tab == _grayTab, Click = () => { _grayTab = tab; _message = null; Open(); } }; }).ToList(), false);
|
||||
if (!Session.Data.Connected) b.AddLabel(L.T("web3.err.noconn"), "term_note");
|
||||
if (_grayTab == GrayTab.Mixer) MixerPage(b); else BlackPage(b);
|
||||
if (_grayTab == GrayTab.Mixer) MixerPage(b); else if (_grayTab == GrayTab.Own) OwnMixPage(b); else BlackPage(b);
|
||||
}
|
||||
|
||||
/// <summary>Web3:链上钱包与去中心化交易。</summary>
|
||||
@@ -1579,6 +1640,7 @@ namespace Decentralized
|
||||
if (key != null)
|
||||
{
|
||||
if (key.StartsWith("airdrop:") || key.StartsWith("yield:")) return key.Substring(key.IndexOf(':') + 1);
|
||||
if (key.StartsWith("otc:")) return L.T("otc.name");
|
||||
switch (key)
|
||||
{
|
||||
case "mixer": return L.T("explorer.mixer");
|
||||
@@ -1591,6 +1653,7 @@ namespace Decentralized
|
||||
case "intel": return L.T("intel.h");
|
||||
case "ponzi": return L.T("ponzi.h");
|
||||
case "tumbler": return "Tumbler";
|
||||
case "ownmix": return L.T("gray.sub.own");
|
||||
}
|
||||
}
|
||||
var sl = d.Black.Sellers.FirstOrDefault(x => ChainAddress.Same(x.Name, a));
|
||||
@@ -2347,7 +2410,7 @@ namespace Decentralized
|
||||
b.AddLabel(L.T("black.pay.amount", WalletWindow.Amt(p.Amount), p.Asset, Fmt.Credits(p.Amount * Session.Price(p.Asset))));
|
||||
b.BeginRow(6f);
|
||||
b.AddButton(L.T("black.pay.wallet"), () => WalletWindow.OpenForBill(p));
|
||||
b.AddButton(L.T("black.pay.cancel"), () => { WalletWindow.Pending = null; _message = null; Open(); });
|
||||
b.AddButton(L.T("black.pay.cancel"), () => { if (OtcClient.IsBill(p)) OtcClient.Void(); else WalletWindow.Pending = null; _message = null; Open(); });
|
||||
b.End();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Decentralized.Domain;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>
|
||||
/// 涡轮增压器作用在矿架、矿机上:和原版机器一样立刻多跑一轮,这一轮就是立刻挖一晚。
|
||||
/// 原版增压器的效果是调用机器的夜间周期回调(矿架、矿机的回调是"扣电并登记今晚挖矿"),所以在增压器外包一层,
|
||||
/// 作用于矿机时打上 <see cref="Boosting"/>,回调看到它就改为立刻结算一轮:扣一晚的电,按这台机器的算力出块并发到它的收款地址,算一次损耗和暴毙。
|
||||
/// 增压器本身的消耗、充电、可用次数都照原版。
|
||||
/// </summary>
|
||||
public static class TurboMine
|
||||
{
|
||||
/// <summary>原版增压器正在作用于矿机(只在增压器的作用回调里为真)。</summary>
|
||||
public static bool Boosting;
|
||||
|
||||
/// <summary>
|
||||
/// 立刻挖一轮(电已经扣过)。出块按全网份额算:玩家这边的算力取昨晚全部机器的算力(至少是这台),这台机器分其中自己的那份,
|
||||
/// 和夜里一起挖时分到的差不多。
|
||||
/// </summary>
|
||||
public static void Round(GameItem machine, List<KeyValuePair<GameItem, ModuleBonus>> cards)
|
||||
{
|
||||
var d = Session.Data;
|
||||
if (d == null || cards.Count == 0) return;
|
||||
var units = cards.Select(c => (item: c.Key, unit: Items.ToUnit(c.Key), bonus: c.Value)).ToList();
|
||||
double hash = units.Sum(x => x.unit.Hash(x.bonus));
|
||||
if (hash <= 0) return;
|
||||
double player = System.Math.Max(hash, d.LastNight?.Hash ?? 0);
|
||||
double mined = d.Network.Mine(player) * hash / player;
|
||||
bool paid = Night.PayMachine(d, machine, mined);
|
||||
var ps = PlayerStore.Instance;
|
||||
ps.AddNightLog(paid ? L.T("nightlog.turbo", machine.name, Fmt.Num(mined)) : L.T("nightlog.mined.lost", Fmt.Num(mined)));
|
||||
foreach (var (item, unit, bonus) in units)
|
||||
{
|
||||
bool died = unit.Night(bonus, d.Rng);
|
||||
Items.Store(item, unit);
|
||||
if (died) ps.AddNightLog(L.T("nightlog.burnt", item.name), "cc7755");
|
||||
}
|
||||
Log.Info($"涡轮增压:{machine.name} 立刻挖一轮,算力 {hash:0.##},产出 {mined:0.####} PSC{(paid ? "" : "(没设置收款地址,丢失)")}");
|
||||
Session.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,10 @@ namespace Decentralized
|
||||
public static bool MixerUnlocked => PlayerStore.Instance != null && ModHelper.IsNetworkUpgradeUnlocked(MixerId);
|
||||
|
||||
public const string BlackId = "PD_BLACKMARKET";
|
||||
|
||||
/// <summary>场外换币台:小偷灯多一个目标"换币客户",买下时附赠一盏小偷灯(已切到这个目标)。</summary>
|
||||
public const string OtcId = "PD_OTC";
|
||||
public static bool OtcUnlocked => PlayerStore.Instance != null && ModHelper.IsNetworkUpgradeUnlocked(OtcId);
|
||||
public static bool BlackUnlocked => PlayerStore.Instance != null && ModHelper.IsNetworkUpgradeUnlocked(BlackId);
|
||||
|
||||
public static bool IsUnlocked => PlayerStore.Instance != null && ModHelper.IsNetworkUpgradeUnlocked(Id);
|
||||
@@ -27,6 +31,7 @@ namespace Decentralized
|
||||
Add(Id, Price, () => L.T("upgrade.title"), () => L.T("upgrade.desc"), OnPurchased, "terminal", null);
|
||||
Add(MixerId, MixerPrice, () => L.T("mixer.upgrade.title"), () => L.T("mixer.upgrade.desc"), () => Log.Info("混币器已解锁"), "ui_web3", new[] { Id });
|
||||
Add(BlackId, Domain.Tuning.BmUnlockPrice, () => L.T("black.upgrade.title"), () => L.T("black.upgrade.desc"), () => Log.Info("Web3 黑市已解锁"), "ui_web3", new[] { Id });
|
||||
Add(OtcId, Domain.Tuning.OtcUnlockPrice, () => L.T("otc.upgrade.title"), () => L.T("otc.upgrade.desc"), OnOtcPurchased, "ui_web3", new[] { Id });
|
||||
}
|
||||
|
||||
private static void Add(string id, int price, Func<string> title, Func<string> desc, Action onUnlock, string icon, string[] prerequisites)
|
||||
@@ -35,6 +40,14 @@ namespace Decentralized
|
||||
catch (NullReferenceException) { Log.Info($"人脉升级 {id} 已登记(主菜单阶段访问 PlayerStore 失败,已忽略)"); }
|
||||
}
|
||||
|
||||
private static void OnOtcPurchased()
|
||||
{
|
||||
var lamp = ModHelper.SpawnItem(BlackLampHelper.BLACK_LAMP_ID);
|
||||
OtcLamp.SetTarget(lamp, OtcLamp.Target);
|
||||
Items.GiveToFront(lamp);
|
||||
Log.Info("场外换币台已解锁,附赠小偷灯");
|
||||
}
|
||||
|
||||
private static void OnPurchased()
|
||||
{
|
||||
Items.GiveToFront(ModHelper.SpawnItem(Items.Terminal));
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Decentralized
|
||||
public string Address, Asset, Summary;
|
||||
public double Amount;
|
||||
public bool Contract;
|
||||
/// <summary>收款地址直接填好(换币客户就在柜台前,当面给地址),不用玩家手输。</summary>
|
||||
public bool Prefill;
|
||||
/// <summary>合约调用时钱包里实际要花掉的数量(默认等于 Amount;取出质押这类不花币的调用为 0)和付手续费的币(默认用 Asset)。</summary>
|
||||
public double? Spend;
|
||||
public string FeeAsset;
|
||||
@@ -37,8 +39,12 @@ namespace Decentralized
|
||||
public Action<Wallet> Execute;
|
||||
}
|
||||
|
||||
/// <summary>当前待付的账单(同一时间一张,新的覆盖旧的)。任何一台钱包都可以付。</summary>
|
||||
public static Bill Pending;
|
||||
/// <summary>
|
||||
/// 当前待付的账单(终端开的同一时间一张,新的覆盖旧的)。任何一台钱包都可以付。
|
||||
/// 没有终端账单时回落到换币客户的账单(<see cref="OtcClient.Standing"/>):它不会被换币、混币这些终端账单覆盖掉。
|
||||
/// </summary>
|
||||
public static Bill Pending { get => _pending ?? OtcClient.Standing; set => _pending = value; }
|
||||
private static Bill _pending;
|
||||
|
||||
private sealed class Tx
|
||||
{
|
||||
@@ -129,6 +135,7 @@ namespace Decentralized
|
||||
if (IsOpen(dev)) CustomUIManager.Instance.CloseWindow(dev.Id);
|
||||
Devices.Clear();
|
||||
Pending = null;
|
||||
OtcClient.Void();
|
||||
}
|
||||
|
||||
/// <summary>终端"打开钱包转账" / DEX 签名请求:在当前连接的钱包上打开。转账填好币种和金额,地址留给玩家手输。</summary>
|
||||
@@ -143,7 +150,7 @@ namespace Decentralized
|
||||
else
|
||||
{
|
||||
dev.Screen = Screen.Send;
|
||||
dev.To = "";
|
||||
dev.To = bill.Prefill ? bill.Address : "";
|
||||
dev.Asset = bill.Asset;
|
||||
dev.Amount = Amt(bill.Amount);
|
||||
}
|
||||
@@ -522,7 +529,11 @@ namespace Decentralized
|
||||
dev.Tx.Confs = TxRules.Confirmations(ValueOf(dev));
|
||||
dev.Tx.Dropped = d.Rng.Chance(TxRules.DropChance(dev.Tier, cong));
|
||||
dev.Tx.Times = Timeline(dev.Tx.Confs, TxRules.Slowdown(dev.Tier, cong), dev.Tx.Dropped);
|
||||
if (dev.Tx.Bill != null) Pending = null;
|
||||
if (dev.Tx.Bill != null)
|
||||
{
|
||||
if (dev.Tx.Bill == OtcClient.Standing) OtcClient.Standing = null; // 签了名就不再挂着,免得重复付
|
||||
Pending = null;
|
||||
}
|
||||
dev.Screen = Screen.Broadcast;
|
||||
dev.Note = null;
|
||||
Open(dev);
|
||||
@@ -544,7 +555,8 @@ namespace Decentralized
|
||||
if (tx.Dropped)
|
||||
{
|
||||
// 没成交:账单还在,可以重新付
|
||||
if (tx.Bill != null && Pending == null) Pending = tx.Bill;
|
||||
if (tx.Bill != null && OtcClient.IsBill(tx.Bill)) OtcClient.Standing = tx.Bill;
|
||||
else if (tx.Bill != null && Pending == null) Pending = tx.Bill;
|
||||
TerminalWindow.Refresh(L.T("hw.tx.dropped"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,16 +210,19 @@ internal static class Program
|
||||
Check(RigSlots.Shape(2) == "000000" + "000000" + new string('1', 18) && RigSlots.Shape(5) == new string('0', 30) && RigSlots.Shape(3).Length == 30, "形状:宽 3、共 10 行,前 2 × 槽数行可放");
|
||||
});
|
||||
|
||||
Test("模块:折算系数 4,算力 +20%、省电 25%、损耗 −30% 封顶;性能加成提高损耗与暴毙", () =>
|
||||
Test("模块:折算系数 4,不设上限,只有防出错的下限;性能加成提高损耗与暴毙", () =>
|
||||
{
|
||||
var perf = ModuleBonus.From(16, 0, 0);
|
||||
Check(Near(perf.Hash, 1.04, 1e-9) && Near(perf.Wear, 1.04, 1e-9) && Near(perf.Death, 1.04, 1e-9), "一个性能模块(+16):算力 +4%,损耗和暴毙 +4%");
|
||||
var cores = ModuleBonus.From(200 * 3, -100 * 3, 100 * 3);
|
||||
Check(Near(cores.Hash, 1.20, 1e-9), $"塞满神经核心,算力也只 +20%:{cores.Hash:0.00}");
|
||||
Check(Near(cores.Hash, 2.5, 1e-9) && Near(cores.Death, 2.5, 1e-9), $"三个无限制神经核心:算力 ×2.5,暴毙率同样 ×2.5:{cores.Hash:0.00}");
|
||||
Check(Near(cores.Kj, 1.75, 1e-9), $"神经核心的负效率照常增加耗电:×{cores.Kj:0.00}");
|
||||
Check(Near(cores.Wear, 0.70 * 1.20, 1e-9), "品质封顶 −30%,再乘性能带来的 +20%");
|
||||
var eco = ModuleBonus.From(-16, 32 * 5, 0);
|
||||
Check(Near(eco.Kj, 0.75, 1e-9) && Near(eco.Hash, 0.96, 1e-9), "省电封顶 25%;节能模块的负性能照常降低算力");
|
||||
Check(Near(cores.Wear, 0.25 * 2.5, 1e-9), "品质 +300 → 损耗 −75%,再乘性能带来的发热");
|
||||
var nine = ModuleBonus.From(200 * 9, -100 * 9, 100 * 9);
|
||||
Check(Near(nine.Hash, 5.5, 1e-9) && Near(nine.Kj, 3.25, 1e-9) && nine.Wear == Tuning.ModuleWearFloor, "九个核心:算力 ×5.5、耗电 ×3.25,损耗降到下限");
|
||||
var eco = ModuleBonus.From(-16 * 9, 32 * 9, 0);
|
||||
Check(Near(eco.Kj, 1 - 32 * 9 / 400.0, 1e-9) && Near(eco.Hash, 1 - 16 * 9 / 400.0, 1e-9), "九个节能模块:省电 72%,负性能照常降低算力");
|
||||
Check(ModuleBonus.From(0, 400 * 2, 0).Kj == Tuning.ModuleKjFloor && ModuleBonus.From(-400 * 2, 0, 0).Hash == Tuning.ModuleHashFloor, "耗电、算力不低于下限");
|
||||
var none = ModuleBonus.From(0, 0, 0);
|
||||
Check(none.Hash == 1 && none.Kj == 1 && none.Wear == 1 && none.Death == 1, "没有模块时不变");
|
||||
});
|
||||
@@ -1354,32 +1357,115 @@ internal static class Program
|
||||
Check(ps > 12 && ps < 20, $"夜里向 SPARK 参考价靠拢:{ps:0.00}");
|
||||
});
|
||||
|
||||
Test("收黑币:事件对应币种、报价、收下后的污点", () =>
|
||||
Test("换币客户:卖币的事件币种、污点比例与折扣、收下后的污点;买币的随机出价;部分成交;成交统计", () =>
|
||||
{
|
||||
Func<string, double> pr = a => a == Assets.Ponero ? 50 : 1;
|
||||
var none = new List<MarketEvent>();
|
||||
var rng = new Rng(3);
|
||||
int crt = 0, psc = 0, pon = 0;
|
||||
int ev = 0, sides = 0;
|
||||
for (int i = 0; i < 4000; i++)
|
||||
{
|
||||
string a1 = HotCoins.Pick(new[] { MarketEvent.GangWar }, false, rng);
|
||||
if (a1 == Assets.CRT) crt++; else if (a1 != null) psc++;
|
||||
if (HotCoins.Pick(new MarketEvent[0], true, rng) == Assets.Ponero) pon++;
|
||||
var o = Otc.MakeSell(new List<MarketEvent> { MarketEvent.GangWar }, false, pr, 500, rng);
|
||||
if (o.Asset == Assets.CRT && o.TaintRatio == 1) ev++;
|
||||
if (Otc.PickSide(rng) == OtcSide.Sell) sides++;
|
||||
}
|
||||
Check(psc == 0 && Math.Abs(crt / 4000.0 - Tuning.HotEventChance) < 0.03, $"帮派火并期间只有 CRT:{crt}/4000");
|
||||
Check(Math.Abs(pon / 4000.0 - Tuning.HotPoneroChance) < 0.015, $"兑换处开放后的 Ponero:{pon}/4000");
|
||||
Check(HotCoins.Pick(new[] { MarketEvent.RevRaidUpper }, false, new Rng(1)) is string sa ? sa == Assets.PSC : true, "革命军袭击上层是 PSC");
|
||||
Check(HotCoins.Pick(new MarketEvent[0], false, rng) == null, "没有事件、兑换处没开:没人上门");
|
||||
var o = HotCoins.Make(Assets.CRT, 1, 500, false, new Rng(9));
|
||||
Check(o.Value >= 500 * Tuning.HotValueMinRents && o.Value <= 500 * Tuning.HotValueMaxRents && o.Cash >= o.Value * Tuning.HotCutMin - 1 && o.Cash <= o.Value * Tuning.HotCutMax + 1, $"报价:市值 {o.Value:0},现金 {o.Cash}");
|
||||
Check(Math.Abs(ev / 4000.0 - Tuning.OtcEventChance) < 0.03, $"帮派火并期间多是 CRT、全额污点:{ev}/4000");
|
||||
Check(Math.Abs(sides / 4000.0 - Tuning.OtcSellShare) < 0.03, $"卖币、买币各占一半:{sides}/4000");
|
||||
Check(Otc.EventAsset(new List<MarketEvent> { MarketEvent.RevRaidUpper }, new Rng(1)) == Assets.PSC && Otc.EventAsset(none, new Rng(1)) == null, "革命军袭击上层是 PSC;没有事件时没有事件币");
|
||||
// 平时:PSC/CRT/CRA 随机,污点比例在区间内,越脏越便宜
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
var o = Otc.MakeSell(none, false, pr, 500, rng);
|
||||
Check(Array.IndexOf(Otc.SellAssets, o.Asset) >= 0 && o.TaintRatio >= Tuning.OtcTaintMin && o.TaintRatio <= Tuning.OtcTaintMax, "平时的币种与污点比例");
|
||||
Check(o.Value >= 500 * Tuning.OtcValueMinRents && o.Value <= 500 * Tuning.OtcValueMaxRents && Math.Abs(o.Cash - o.Value * Otc.CutFor(o.TaintRatio)) <= 1, $"市值与现金价:{o.Value:0} / {o.Cash}");
|
||||
}
|
||||
Check(Otc.CutFor(0) == Tuning.OtcCutClean && Otc.CutFor(1) == Tuning.OtcCutDirty && Otc.CutFor(0.3) > Otc.CutFor(0.7), "折扣按污点比例线性降低");
|
||||
// 收下:币进钱包,成本是付的现金,污点 = 市值 × 比例(带上限)
|
||||
var oc = new OtcOffer { Side = OtcSide.Sell, Asset = Assets.CRT, Qty = 1000, Value = 1000, TaintRatio = 0.4, Cash = 700 };
|
||||
var w = new Wallet();
|
||||
HotCoins.Receive(w, o);
|
||||
Check(Near(w.Get(Assets.CRT), o.Qty, 1e-9) && Near(w.Taint, o.Value, 1e-9) && Near(w.Basis, o.Cash, 1e-9), "CRT 全额带污点,成本是付的现金");
|
||||
var op = HotCoins.Make(Assets.Ponero, 50, 500, false, new Rng(9));
|
||||
var wp = new Wallet();
|
||||
HotCoins.Receive(wp, op);
|
||||
Check(wp.Taint == 0 && op.Cash >= op.Value * Tuning.HotPoneroCutMin - 1, "Ponero 不带污点、折扣小");
|
||||
Check(Otc.Receive(w, oc, pr) == 0 && Near(w.Get(Assets.CRT), 1000, 1e-9) && Near(w.Taint, 400, 1e-9) && Near(w.Basis, 700, 1e-9), "污点按比例,成本是付的现金");
|
||||
var wf = new Wallet(); wf.Add(Assets.CRC, 100); wf.Taint = 1000;
|
||||
Check(Near(Otc.Receive(wf, oc, pr), 300, 1e-9) && Near(wf.Taint, 1100, 1e-9), "原有污点多时超出的部分返回");
|
||||
// Ponero:兑换处开放后偶尔有,不带污点
|
||||
int pon = 0;
|
||||
for (int i = 0; i < 4000; i++) { var o = Otc.MakeSell(none, true, pr, 500, rng); if (o.Asset == Assets.Ponero) { pon++; Check(o.TaintRatio == 0 && o.Cash >= o.Value * Tuning.OtcPoneroCutMin - 1, "Ponero 不带污点"); } }
|
||||
Check(Math.Abs(pon / 4000.0 - Tuning.OtcPoneroChance) < 0.02, $"兑换处开放后的 Ponero:{pon}/4000");
|
||||
int stings = 0, stingsCd = 0;
|
||||
for (int i = 0; i < 4000; i++) { if (HotCoins.Make(Assets.CRT, 1, 500, false, rng).Sting) stings++; if (HotCoins.Make(Assets.CRT, 1, 500, true, rng).Sting) stingsCd++; }
|
||||
Check(stingsCd > stings * 2, $"镇压期间钓鱼执法更多:{stings} → {stingsCd}");
|
||||
for (int i = 0; i < 4000; i++)
|
||||
{
|
||||
if (Otc.MakeSell(none, false, pr, 500, rng).Sting) stings++;
|
||||
if (Otc.MakeSell(new List<MarketEvent> { MarketEvent.Crackdown }, false, pr, 500, rng).Sting) stingsCd++;
|
||||
}
|
||||
Check(stingsCd > stings * 2, $"镇压期间便衣更多:{stings} → {stingsCd}");
|
||||
// 买币:市值按房租,出价 = 市值 × (1 + 随机溢价),溢价在区间内
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
var ob = Otc.MakeBuy(pr, 500, rng);
|
||||
Check(Array.IndexOf(Otc.BuyAssets, ob.Asset) >= 0 && ob.Value >= 500 * Tuning.OtcBuyMinRents && ob.Value <= 500 * Tuning.OtcBuyMaxRents && Near(ob.Qty * pr(ob.Asset), ob.Value, 1e-6), "买币的币种与数量");
|
||||
Check(ob.Cash >= ob.Value * (1 + Tuning.OtcBidMin) - 1 && ob.Cash <= ob.Value * (1 + Tuning.OtcBidMax) + 1, $"出价在区间内:{ob.Cash} / {ob.Value:0}");
|
||||
}
|
||||
// 部分成交:现金、市值按数量比例折算,超过报价按全部算
|
||||
var whole = new OtcOffer { Side = OtcSide.Sell, Asset = Assets.PSC, Qty = 20, Value = 2000, TaintRatio = 0.5, Cash = 1200, Sting = true };
|
||||
var half = Otc.Part(whole, 10);
|
||||
Check(Near(half.Qty, 10, 1e-9) && Near(half.Value, 1000, 1e-9) && half.Cash == 600 && half.TaintRatio == 0.5 && half.Sting, "收一半:现金、市值减半,污点比例和便衣不变");
|
||||
Check(Near(Otc.Part(whole, 50).Qty, 20, 1e-9) && Otc.Part(whole, 50).Cash == 1200, "超过报价的数量按全部算");
|
||||
Check(Otc.Part(whole, 0) == null && Otc.Part(whole, -1) == null, "数量不合法");
|
||||
// 来历:脏的来源按污点比例出现,数量占比合计为 1
|
||||
var hist = Otc.History(new OtcOffer { TaintRatio = 1 }, new[] { "dirty" }, new[] { "clean" }, new Rng(2));
|
||||
Check(hist.Count >= 1 && hist.Count <= Tuning.OtcHistoryMax && hist.TrueForAll(kv => kv.Key == "dirty") && Near(hist.Sum(kv => kv.Value), 1, 1e-9), "全脏的币来历都是脏来源");
|
||||
var histC = Otc.History(new OtcOffer { TaintRatio = 0 }, new[] { "dirty" }, new[] { "clean" }, new Rng(2));
|
||||
Check(histC.TrueForAll(kv => kv.Key == "clean"), "干净的币来历都是干净来源");
|
||||
var desk = new OtcDesk(); desk.Record(700); desk.Record(300);
|
||||
Check(desk.Volume == 1000 && desk.Deals == 2, "成交统计");
|
||||
});
|
||||
|
||||
Test("自营混币器:注资取回的污点、匿名集与清洗率、客流、出款、查封、卷款跑路", () =>
|
||||
{
|
||||
Func<string, double> pr = a => 1;
|
||||
var w = new Wallet { Address = "w" }; w.Add(Assets.CRT, 30000);
|
||||
var m = new OwnMixer();
|
||||
Check(m.Inject(w, Assets.CRT, 20000, pr) && m.Pool(Assets.CRT).Capital == 20000 && m.Pool(Assets.CRT).CapTaint == 0, "干净的币注资,本金不带污点");
|
||||
Check(!m.Inject(w, Assets.CRT, 1e6, pr) && !m.Inject(w, Assets.SPARK, 1, pr), "余额不够、币种不支持被拒");
|
||||
Check(OwnMixer.RoundRate(40000) > OwnMixer.RoundRate(10000) && OwnMixer.RoundRate(1e9) <= Tuning.MixerCleanRate + 1e-9 && OwnMixer.RoundRate(0) == 0, "匿名集越大清洗率越高,封顶基准清洗率");
|
||||
m.Start(pr);
|
||||
Check(m.Open && Near(m.Rating, OwnMixer.Remain(OwnMixer.RoundRate(20000)), 1e-9), "开张时口碑按匿名集估");
|
||||
double rr = 0.29;
|
||||
var cheap = new OwnMixer { Fee = 0.01, Rating = 0.3 }; var dear = new OwnMixer { Fee = 0.08, Rating = 0.3 }; var dirty = new OwnMixer { Fee = 0.01, Rating = 0.9 };
|
||||
Check(cheap.Share(0.03, rr, true) > dear.Share(0.03, rr, true) && cheap.Share(0.03, rr, true) > dirty.Share(0.03, rr, true), "费率低、出款干净的分到的客流多");
|
||||
Check(cheap.Share(0.03, rr, false) > cheap.Share(0.03, rr, true), "对手关停时客流更多");
|
||||
// 营业几晚:有存入、有手续费,到期的出款
|
||||
var rng = new Rng(4);
|
||||
double fees0 = m.FeesTotal;
|
||||
int deposits = 0, payouts = 0;
|
||||
for (int day = 40; day < 50; day++)
|
||||
foreach (var e in m.Night(day, pr, 60, Tuning.MixerFee, rr, true, 1, false, rng))
|
||||
{
|
||||
if (e.Kind == "deposit") deposits++;
|
||||
if (e.Kind == "payout") payouts++;
|
||||
if (e.Kind == "seized") Check(m.Pools.Count == 0 && m.Pending.Count == 0, "查封清空池子");
|
||||
}
|
||||
Check(deposits > 0 && payouts > 0 && m.FeesTotal > fees0, $"营业中有存入和出款:{deposits} / {payouts},手续费 {m.FeesTotal - fees0:0}");
|
||||
Check(m.Pending.All(x => x.ReadyDay >= 50), "到期的都出款了");
|
||||
// 取回:收入全额带污点,本金按本金的污点
|
||||
var m2 = new OwnMixer(); var w2 = new Wallet { Address = "w2" }; w2.Add(Assets.PSC, 1000); w2.Taint = 500;
|
||||
m2.Inject(w2, Assets.PSC, 1000, pr);
|
||||
Check(Near(m2.Pool(Assets.PSC).CapTaint, 500, 1e-9) && w2.Taint < 1e-9, "脏币注资,污点跟着进本金");
|
||||
m2.Pool(Assets.PSC).Earned = 100;
|
||||
var w3 = new Wallet { Address = "w3" }; w3.Add(Assets.CRC, 10000);
|
||||
Check(m2.Withdraw(w3, Assets.PSC, 100, pr, out double o1) && Near(w3.Taint, 100, 1e-9) && o1 == 0, "先取收入:全额带污点");
|
||||
Check(m2.Withdraw(w3, Assets.PSC, 500, pr, out _) && Near(w3.Taint, 100 + 250, 1e-9), "再取本金:按本金的污点比例");
|
||||
Check(!m2.Withdraw(w3, Assets.PSC, 1000, pr, out _), "不能超过可取回的数量");
|
||||
m2.Pending.Add(new OwnMixDeposit { Asset = Assets.PSC, Amount = 300, Taint = 200, Rounds = 2, ReadyDay = 99 });
|
||||
Check(Near(m2.Free(Assets.PSC), 500, 1e-9) && Near(m2.Total(Assets.PSC), 800, 1e-9), "客户在途的币不能取");
|
||||
// 卷款跑路:连同客户的币全部卷走、全额带污点,永久关闭
|
||||
var w4 = new Wallet { Address = "w4" };
|
||||
var got = m2.Rug(w4, pr, out double o4);
|
||||
Check(Near(w4.Get(Assets.PSC), 800, 1e-9) && Near(w4.Taint, 800, 1e-9) && m2.Closed && !m2.Open && got.Count == 1, "卷走全部、全额污点、关闭");
|
||||
Check(m2.Night(100, pr, 60, Tuning.MixerFee, rr, true, 1, false, new Rng(1)).Count == 0, "关闭后不再有夜间事件");
|
||||
// 查封:风声足够大时被查封,停业若干天
|
||||
var m3 = new OwnMixer { Heat = 1e6 }; m3.Inject(new Wallet { Address = "x", Balances = { [Assets.CRT] = 5000 } }, Assets.CRT, 5000, pr); m3.Start(pr);
|
||||
var ev = m3.Night(60, pr, 60, Tuning.MixerFee, rr, true, 1, false, new Rng(2));
|
||||
Check(ev.Any(e => e.Kind == "seized" && e.Crime > 0 && e.Crime <= Tuning.CrimeEventCap) && m3.Seized(60 + Tuning.OwnMixSeizeDays) && !m3.Seized(61 + Tuning.OwnMixSeizeDays) && !m3.Open, "风声大时被查封、记罪证、停业");
|
||||
});
|
||||
|
||||
Test("预测市场:LMSR 定价、最大亏损、买卖", () =>
|
||||
@@ -1429,16 +1515,16 @@ internal static class Program
|
||||
Check(bk.Buy(acct, m, false, 10, 5, pr, false, out _) == PredictResult.Opposite, "不能同盘反方向");
|
||||
// 卖出:价差为 0,只付手续费
|
||||
double before = acct.Get(Assets.CRC);
|
||||
Check(bk.SellAll(acct, m, 5, out double got) == PredictResult.Ok && Math.Abs(got - 100 * (1 - Tuning.PredictFee)) < 1e-6, $"原价卖回只扣手续费:{got:0.00}");
|
||||
Check(bk.SellAll(acct, m, 5, pr, out double got) == PredictResult.Ok && Math.Abs(got - 100 * (1 - Tuning.PredictFee)) < 1e-6, $"原价卖回只扣手续费:{got:0.00}");
|
||||
Check(Math.Abs(acct.Get(Assets.CRC) - before - got) < 1e-6 && bk.PosOf(m.Id, acct.Address) == null, "回到账户");
|
||||
Check(acct.Taint < 400 && acct.Taint > 359.2, "卖回时污点按退回的比例回来");
|
||||
// 持仓上限
|
||||
var big = new Wallet { Address = "x" }; big.Add(Assets.CRC, 1e7);
|
||||
Check(bk.Buy(big, m, true, 1e6, 5, pr, false, out _) == PredictResult.Cap, "超过份额上限被拒");
|
||||
Check(bk.SellAll(acct, m, 5, out _) == PredictResult.NoPosition, "没持仓不能卖");
|
||||
Check(bk.SellAll(acct, m, 5, pr, out _) == PredictResult.NoPosition, "没持仓不能卖");
|
||||
});
|
||||
|
||||
Test("预测市场:结算、作废、内幕被查、观测", () =>
|
||||
Test("预测市场:结算、作废、内幕记污点、观测", () =>
|
||||
{
|
||||
Func<string, double> pr = a => 1;
|
||||
var rng = new Rng(5);
|
||||
@@ -1446,7 +1532,7 @@ internal static class Program
|
||||
acct.Add(Assets.CRC, 100000);
|
||||
var bk = new PredictBook();
|
||||
// 观测:第一晚没有 Prev,不算 Started
|
||||
bk.Night(4, new[] { "oxymoreWave" }, m => null, _ => acct, rng);
|
||||
bk.Night(4, new[] { "oxymoreWave" }, m => null, _ => acct, pr, rng);
|
||||
Check(!bk.Started.ContainsKey(4), "第一晚没有对照,不记新出现的事件");
|
||||
var win = PredictMarket.Create(++bk.Seq, PredictKind.Event, "powerShortage", "停电", 0, 4, 5, 6, 0.2);
|
||||
var lose = PredictMarket.Create(++bk.Seq, PredictKind.Event, "blackout", "x", 0, 4, 5, 6, 0.2);
|
||||
@@ -1457,9 +1543,9 @@ internal static class Program
|
||||
bk.Buy(acct, lose, true, stake, 4, pr, false, out _);
|
||||
bk.Buy(acct, voided, true, stake, 4, pr, false, out _);
|
||||
double cash = acct.Get(Assets.CRC);
|
||||
bk.Night(5, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, rng);
|
||||
bk.Night(5, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, pr, rng);
|
||||
Check(win.Outcome < 0 && lose.Outcome < 0, "窗口没结束不结算");
|
||||
var evs = bk.Night(6, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, rng);
|
||||
var evs = bk.Night(6, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, pr, rng);
|
||||
Check(win.Outcome == -1 || bk.Markets.All(x => x.Id != win.Id), "到期的盘口移出列表");
|
||||
Check(evs.Any(e => e.Kind == "win" && e.Title == "停电" && Math.Abs(e.Amount - sw) < 1e-6), "押中兑付份数");
|
||||
Check(evs.Any(e => e.Kind == "lose" && e.Title == "x"), "押错没收");
|
||||
@@ -1467,44 +1553,34 @@ internal static class Program
|
||||
Check(bk.Markets.Count == 1 && bk.Markets[0].Id == voided.Id, "后面的窗口还没到");
|
||||
// 缺观测:8 号之前 7、8 的记录缺,到期作废退本金
|
||||
double c2 = acct.Get(Assets.CRC);
|
||||
var ev2 = bk.Night(9, new string[0], bk.Happened, _ => acct, rng);
|
||||
var ev2 = bk.Night(9, new string[0], bk.Happened, _ => acct, pr, rng);
|
||||
Check(ev2.Any(e => e.Kind == "void") && Math.Abs(acct.Get(Assets.CRC) - c2 - 50) < 1e-6, $"缺数据作废并退本金:{acct.Get(Assets.CRC) - c2:0.00}");
|
||||
// 内幕被查:持仓达到上限的 40% 就有概率,按查处概率被查
|
||||
int caught = 0, wins = 0;
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
var b2 = new PredictBook(); var a2 = new Wallet { Address = "p" }; a2.Add(Assets.CRC, 1e6);
|
||||
var mk = PredictMarket.Create(++b2.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b2.Markets.Add(mk);
|
||||
double target = Tuning.PredictInsiderShare * mk.ShareCap * 1.05, spend = 0;
|
||||
spend = (mk.BuyCost(true, target)) * (1 + Tuning.PredictFee);
|
||||
b2.Buy(a2, mk, true, spend, 4, pr, true, out _);
|
||||
var e = b2.Night(5, new string[0], mm => true, _ => a2, new Rng((ulong)(i + 1)));
|
||||
if (e[0].Kind == "caught") { caught++; Check(e[0].Fraud > 0 && e[0].Fraud <= Tuning.PredictFraudCap, "罪证有上限"); }
|
||||
else wins++;
|
||||
}
|
||||
Check(Math.Abs(caught / 400.0 - Tuning.PredictInsiderCatch) < 0.08, $"内幕大单按查处概率被查:{caught}/400");
|
||||
// 小额内幕不会被查
|
||||
// 内幕单:照常兑付全部份数,只有内幕份额对应的兑付记污点
|
||||
var b2 = new PredictBook(); var a2 = new Wallet { Address = "p" }; a2.Add(Assets.CRC, 1e6);
|
||||
var mk = PredictMarket.Create(++b2.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b2.Markets.Add(mk);
|
||||
b2.Buy(a2, mk, true, mk.BuyCost(true, 0.2 * mk.ShareCap) * 1.02, 4, pr, true, out double si);
|
||||
b2.Buy(a2, mk, true, 50, 4, pr, false, out double sn);
|
||||
double c2b = a2.Get(Assets.CRC), t2b = a2.Taint;
|
||||
var e2 = b2.Night(5, new string[0], mm => true, _ => a2, pr, new Rng(1));
|
||||
Check(e2[0].Kind == "insider" && Near(e2[0].Amount, si + sn, 1e-6), $"内幕单照常结算:{e2[0].Kind}");
|
||||
Check(Near(a2.Get(Assets.CRC) - c2b, si + sn, 1e-6), "全部份数照常兑付");
|
||||
Check(Near(a2.Taint - t2b, si, 1e-6) && Near(e2[0].Taint, si, 1e-6) && e2[0].Over == 0 && e2[0].Fraud == 0, $"只有内幕份额的兑付记污点:+{a2.Taint - t2b:0.00} / {si:0.00}");
|
||||
// 不是内幕单:普通结算,不加污点
|
||||
var b3 = new PredictBook(); var a3 = new Wallet { Address = "p" }; a3.Add(Assets.CRC, 1e6);
|
||||
var m3 = PredictMarket.Create(++b3.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b3.Markets.Add(m3);
|
||||
b3.Buy(a3, m3, true, m3.BuyCost(true, 0.2 * m3.ShareCap) * 1.02, 4, pr, true, out _);
|
||||
Check(b3.Night(5, new string[0], mm => true, _ => a3, new Rng(1))[0].Kind == "win", "小额内幕安全");
|
||||
// 被查:只退本金
|
||||
var b4 = new PredictBook(); var a4 = new Wallet { Address = "p" }; a4.Add(Assets.CRC, 1e6);
|
||||
b3.Buy(a3, m3, true, 200, 4, pr, false, out _);
|
||||
Check(b3.Night(5, new string[0], mm => true, _ => a3, pr, new Rng(1))[0].Kind == "win" && a3.Taint == 0, "非内幕单不记污点");
|
||||
// 污点上限:钱包原有污点已超过价值(币价跌过),新加的全部超出,折成罪证
|
||||
var b4 = new PredictBook(); var a4 = new Wallet { Address = "p" }; a4.Add(Assets.CRC, 1e5);
|
||||
var m4 = PredictMarket.Create(++b4.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b4.Markets.Add(m4);
|
||||
double s4 = m4.BuyCost(true, 0.5 * m4.ShareCap) * 1.02;
|
||||
b4.Buy(a4, m4, true, s4, 4, pr, true, out _);
|
||||
double c4 = a4.Get(Assets.CRC);
|
||||
for (ulong sd = 1; sd < 50; sd++)
|
||||
{
|
||||
var bb = new PredictBook(); bb.Markets.Add(m4); bb.Positions.AddRange(b4.Positions.Select(x => new PredictPos { Market = x.Market, Wallet = x.Wallet, Yes = x.Yes, Shares = x.Shares, Cost = x.Cost, Insider = x.Insider }));
|
||||
var aa = new Wallet { Address = "p" };
|
||||
m4.Outcome = -1;
|
||||
var ee = bb.Night(5, new string[0], mm => true, _ => aa, new Rng(sd));
|
||||
if (ee[0].Kind == "caught") { Check(aa.Get(Assets.CRC) < 1e-6, "被查本金和收益全部没收"); break; }
|
||||
}
|
||||
b4.Buy(a4, m4, true, m4.BuyCost(true, 0.1 * m4.ShareCap) * 1.02, 4, pr, true, out double s4);
|
||||
a4.Taint = a4.Value(pr) + 1000;
|
||||
var e4 = b4.Night(5, new string[0], mm => true, _ => a4, pr, new Rng(1));
|
||||
Check(e4[0].Kind == "insider" && e4[0].Taint == 0 && Near(e4[0].Over, s4, 1e-6), $"污点已满时全部超出:{e4[0].Over:0.00}");
|
||||
Check(Near(e4[0].Fraud, Wallet.OverflowFraud(s4), 1e-9) && e4[0].Fraud <= Tuning.PredictFraudCap, "超出的部分按比例记罪证,有上限");
|
||||
});
|
||||
|
||||
Test("预测市场:多钱包持仓各回各的钱包,限额与内幕按盘口合计", () =>
|
||||
Test("预测市场:多钱包持仓各回各的钱包,内幕污点各记各的", () =>
|
||||
{
|
||||
Func<string, double> pr = a => 1;
|
||||
var w1 = new Wallet { Address = "0xa" }; var w2 = new Wallet { Address = "0xb" };
|
||||
@@ -1512,26 +1588,20 @@ internal static class Program
|
||||
Func<string, Wallet> pick = ad => ad == "0xa" ? w1 : w2;
|
||||
var bk = new PredictBook();
|
||||
var m = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); bk.Markets.Add(m);
|
||||
double half = Tuning.PredictInsiderShare * m.ShareCap * 0.6;
|
||||
double half = 0.25 * m.ShareCap;
|
||||
Check(bk.Buy(w1, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "钱包 A 买入");
|
||||
Check(bk.Buy(w2, m, false, 10, 4, pr, false, out _) == PredictResult.Opposite, "另一个钱包也不能买对面");
|
||||
Check(bk.Buy(w2, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "钱包 B 买入同一边");
|
||||
Check(bk.PosAll(m.Id).Count == 2 && bk.PosOf(m.Id, "0xa") != null && bk.PosOf(m.Id, "0xb") != null, "每个钱包各一个持仓");
|
||||
Check(bk.SellAll(w2, m, 4, out double got) == PredictResult.Ok && got > 0 && bk.PosOf(m.Id, "0xb") == null && bk.PosOf(m.Id, "0xa") != null, "卖出只动自己钱包的持仓");
|
||||
Check(bk.SellAll(w2, m, 4, pr, out double got) == PredictResult.Ok && got > 0 && bk.PosOf(m.Id, "0xb") == null && bk.PosOf(m.Id, "0xa") != null, "卖出只动自己钱包的持仓");
|
||||
Check(bk.Buy(w2, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "再买");
|
||||
// 两边各 0.6×查处线,合计超线:拆钱包躲不过
|
||||
int caught = 0;
|
||||
for (ulong sd = 1; sd <= 60; sd++)
|
||||
{
|
||||
var b2 = new PredictBook(); b2.Markets.Add(new PredictMarket { Id = m.Id, Kind = m.Kind, Key = m.Key, Title = m.Title, FromDay = 5, ToDay = 5, P0 = m.P0, B = m.B, Budget = m.Budget, QYes = m.QYes, QNo = m.QNo });
|
||||
foreach (var p in bk.Positions) b2.Positions.Add(new PredictPos { Market = p.Market, Wallet = p.Wallet, Yes = p.Yes, Shares = p.Shares, Cost = p.Cost, Insider = p.Insider });
|
||||
double a0 = w1.Get(Assets.CRC), b0 = w2.Get(Assets.CRC);
|
||||
var ev = b2.Night(5, new string[0], x => true, pick, new Rng(sd));
|
||||
if (ev[0].Kind == "caught") caught++;
|
||||
else Check(w1.Get(Assets.CRC) > a0 && w2.Get(Assets.CRC) > b0, "赢了各自的钱包都收到兑付");
|
||||
w1.Balances[Assets.CRC] = a0; w2.Balances[Assets.CRC] = b0;
|
||||
}
|
||||
Check(Math.Abs(caught / 60.0 - Tuning.PredictInsiderCatch) < 0.2, $"分到两个钱包的内幕持仓合计后按查处概率被查:{caught}/60");
|
||||
// 两个钱包的内幕份额各自记在自己的钱包上
|
||||
double a0 = w1.Get(Assets.CRC), b0 = w2.Get(Assets.CRC), ta = w1.Taint, tb = w2.Taint;
|
||||
double sa = bk.PosOf(m.Id, "0xa").Shares, sb = bk.PosOf(m.Id, "0xb").Shares;
|
||||
double ca = bk.PosOf(m.Id, "0xa").Taint, cb = bk.PosOf(m.Id, "0xb").Taint; // 买入时随资金带进持仓的污点,兑付时原样回来
|
||||
var ev = bk.Night(5, new string[0], x => true, pick, pr, new Rng(1));
|
||||
Check(ev[0].Kind == "insider" && Near(w1.Get(Assets.CRC) - a0, sa, 1e-6) && Near(w2.Get(Assets.CRC) - b0, sb, 1e-6), "各自的钱包收到兑付");
|
||||
Check(Near(w1.Taint - ta - ca, sa, 1e-6) && Near(w2.Taint - tb - cb, sb, 1e-6) && Near(ev[0].Taint, sa + sb, 1e-6), "内幕污点各记各的钱包");
|
||||
});
|
||||
|
||||
Test("预测市场:夜间消息反应、情报、新盘口先验", () =>
|
||||
@@ -1564,7 +1634,7 @@ internal static class Program
|
||||
// 到期后消息一起清掉
|
||||
bk.Tips.Add(new PredictTip { Market = closing.Id });
|
||||
var w = new Wallet { Address = "x" };
|
||||
bk.Night(6, new string[0], mm => true, _ => w, rng);
|
||||
bk.Night(6, new string[0], mm => true, _ => w, a => 1, rng);
|
||||
Check(bk.Tips.Count == 0, "盘口结算后情报作废");
|
||||
Check(bk.Stats.TryGetValue("Event", out var stE) && stE.Count >= 1 && stE.Hits >= 1, "结算计入按类型的历史");
|
||||
// gas / CRA / 时代 先验
|
||||
@@ -1605,8 +1675,8 @@ internal static class Program
|
||||
var bk = new PredictBook(); var w = new Wallet { Address = "w" }; w.Add(Assets.CRC, 1e5);
|
||||
var m = PredictMarket.Create(++bk.Seq, PredictKind.Price, "PSC", "PSC", 100, 4, 5, 5, 0.3); bk.Markets.Add(m);
|
||||
bk.Buy(w, m, yes, 510, 4, a => 1, false, out _);
|
||||
var ev = bk.Night(5, new string[0], x => outcome, _ => w, new Rng(sd), push);
|
||||
if (ev[0].Kind == "manip") { if (yes && push > 0) manip++; else Check(false, "不该被判操纵"); Check(ev[0].Fraud > 0, "记罪证"); Check(w.Get(Assets.CRC) < 1e5 - 400, "本金没收"); }
|
||||
var ev = bk.Night(5, new string[0], x => outcome, _ => w, a => 1, new Rng(sd), push);
|
||||
if (ev[0].Kind == "manip") { if (yes && push > 0) manip++; else Check(false, "不该被判操纵"); Check(ev[0].Fraud == 0 && Near(ev[0].Taint, ev[0].Amount, 1e-6) && Near(w.Taint, ev[0].Amount, 1e-6), "照常兑付,整笔兑付记污点"); Check(w.Get(Assets.CRC) > 1e5 - 510, "本金不没收"); }
|
||||
else if (yes && push > 0) win++; else if (push == 0) noPush++;
|
||||
}
|
||||
}
|
||||
@@ -1728,30 +1798,38 @@ internal static class Program
|
||||
Check(Math.Abs(rugs / 400.0 - Tuning.YieldRugNightly) < 0.05, $"骗局池每晚跑路概率:{rugs / 400.0:0.00}");
|
||||
});
|
||||
|
||||
Test("预测市场:内幕先买后卖也会被查", () =>
|
||||
Test("预测市场:内幕先买后卖,卖出所得的内幕部分记污点", () =>
|
||||
{
|
||||
int caught = 0, n = 400;
|
||||
for (ulong sd = 1; sd <= (ulong)n; sd++)
|
||||
{
|
||||
var bk = new PredictBook(); var w = new Wallet { Address = "w" }; w.Add(Assets.CRC, 1e6);
|
||||
var m = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 4, 7, 7, 0.05); bk.Markets.Add(m);
|
||||
double target = Tuning.PredictInsiderShare * m.ShareCap * 1.02;
|
||||
bk.Buy(w, m, true, m.BuyCost(true, target) * (1 + Tuning.PredictFee), 4, a => 1, true, out _);
|
||||
double cost = bk.PosOf(m.Id, "w").Cost;
|
||||
double p1 = m.PYes, p2 = p1 + (1 - p1) / 2;
|
||||
m.QYes = m.QNo + m.B * Math.Log(p2 / (1 - p2)); // 夜里价格又涨了一截
|
||||
bk.SellAll(w, m, 5, new Rng(sd), out double got, out double fraud);
|
||||
if (fraud > 0) { caught++; Check(got == 0 && fraud <= Tuning.PredictFraudCap, "被查本金和收益全部没收"); }
|
||||
else Check(got > cost, "没被查时赚到价差");
|
||||
}
|
||||
Check(Math.Abs(caught / (double)n - Tuning.PredictInsiderCatch) < 0.08, $"按查处概率被查:{caught}/{n}");
|
||||
// 小额内幕、非内幕卖出不查
|
||||
var bk = new PredictBook(); var w = new Wallet { Address = "w" }; w.Add(Assets.CRC, 1e6);
|
||||
var m = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 4, 7, 7, 0.05); bk.Markets.Add(m);
|
||||
bk.Buy(w, m, true, m.BuyCost(true, 0.3 * m.ShareCap) * (1 + Tuning.PredictFee), 4, a => 1, true, out double si);
|
||||
bk.Buy(w, m, true, 100, 4, a => 1, false, out double sn);
|
||||
double cost = bk.PosOf(m.Id, "w").Cost;
|
||||
double p1 = m.PYes, p2 = p1 + (1 - p1) / 2;
|
||||
m.QYes = m.QNo + m.B * Math.Log(p2 / (1 - p2)); // 夜里价格又涨了一截
|
||||
double t0 = w.Taint;
|
||||
Check(bk.SellAll(w, m, 5, a => 1, out double got, out double taint, out double over) == PredictResult.Ok && got > cost, "照常卖出,赚到价差");
|
||||
Check(Near(taint, got * si / (si + sn), 1e-6) && Near(w.Taint - t0, taint, 1e-9) && over == 0, $"内幕份额对应的卖出所得记污点:{taint:0.00} / {got:0.00}");
|
||||
// 非内幕卖出不加污点
|
||||
var bk2 = new PredictBook(); var w2 = new Wallet { Address = "w" }; w2.Add(Assets.CRC, 1e6);
|
||||
var m2 = PredictMarket.Create(++bk2.Seq, PredictKind.Event, "e", "t", 0, 4, 7, 7, 0.05); bk2.Markets.Add(m2);
|
||||
bk2.Buy(w2, m2, true, 200, 4, a => 1, true, out _);
|
||||
bk2.Buy(w2, m2, true, 200, 4, a => 1, false, out _);
|
||||
m2.QYes = m2.QNo + m2.B * Math.Log(0.6 / 0.4);
|
||||
bk2.SellAll(w2, m2, 5, new Rng(1), out _, out double f2);
|
||||
Check(f2 == 0, "小额内幕卖出安全");
|
||||
bk2.SellAll(w2, m2, 5, a => 1, out _, out double t2, out double o2);
|
||||
Check(t2 == 0 && o2 == 0 && w2.Taint == 0, "非内幕卖出不记污点");
|
||||
});
|
||||
|
||||
Test("钱包:带上限的加污点", () =>
|
||||
{
|
||||
Func<string, double> pr = a => 1;
|
||||
var w = new Wallet { Address = "w" }; w.Add(Assets.CRC, 100);
|
||||
Check(w.AddTaintCapped(60, pr) == 0 && w.Taint == 60, "价值以内全部加上");
|
||||
Check(Near(w.AddTaintCapped(60, pr), 20, 1e-9) && w.Taint == 100, "加到价值为止,返回超出的 20");
|
||||
Check(Near(w.AddTaintCapped(30, pr), 30, 1e-9) && w.Taint == 100, "已满时全部超出");
|
||||
var empty = new Wallet { Address = "e" };
|
||||
Check(Near(empty.AddTaintCapped(5, pr), 5, 1e-9) && empty.Taint == 0, "空钱包加不进污点");
|
||||
Check(w.AddTaintCapped(0, pr) == 0 && w.AddTaintCapped(-3, pr) == 0, "0 和负数不处理");
|
||||
Check(Near(Wallet.OverflowFraud(100), 100 * Tuning.PredictFraudShare, 1e-9) && Wallet.OverflowFraud(1e9) == Tuning.PredictFraudCap && Wallet.OverflowFraud(0) == 0, "超出额按比例折罪证,单次封顶");
|
||||
});
|
||||
|
||||
Test("日 K:开盘、日内高低、成交量、收盘、均线、保留天数", () =>
|
||||
|
||||
Reference in new issue
Block a user