From e88fab3f1b8ab9257e26da2d911bdd4eb492db50 Mon Sep 17 00:00:00 2001 From: ZHU MINCHAO <48154958+MinchaoZhu@users.noreply.github.com> Date: Sun, 8 Nov 2026 18:45:54 +0800 Subject: [PATCH] =?UTF-8?q?Tumbler=20=E6=89=A9=E5=B1=95=E5=AE=9E=E6=B5=8B?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9A=E6=B2=A1=E6=9C=89=E5=87=BA=E6=AC=BE?= =?UTF-8?q?=E5=8F=AF=E8=BF=98=E5=8E=9F=E6=97=B6=E5=8D=95=E7=8B=AC=E4=B8=80?= =?UTF-8?q?=E5=8F=A5=E6=97=A5=E5=BF=97=EF=BC=9B=E6=AF=8F=E6=AC=A1=E4=B8=8A?= =?UTF-8?q?=E9=97=A8=E6=98=AF=E5=90=8C=E4=B8=80=E4=B8=AA=E5=A4=96=E8=A7=82?= =?UTF-8?q?=EF=BC=9B=E6=B5=8B=E8=AF=95=E6=8C=89=E9=92=AE=E2=80=9C=E5=89=A7?= =?UTF-8?q?=E6=83=85=E9=87=8D=E6=9D=A5=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- src/Decentralized.Domain/StoryMods.cs | 2 ++ src/Decentralized/DealerStock.cs | 8 ++++++++ src/Decentralized/ModFiles/Localization/de.csv | 1 + src/Decentralized/ModFiles/Localization/en.csv | 1 + src/Decentralized/ModFiles/Localization/es.csv | 1 + src/Decentralized/ModFiles/Localization/fr.csv | 1 + src/Decentralized/ModFiles/Localization/ja.csv | 1 + src/Decentralized/ModFiles/Localization/pl.csv | 1 + src/Decentralized/ModFiles/Localization/ru.csv | 1 + src/Decentralized/ModFiles/Localization/zh.csv | 1 + src/Decentralized/TumblerStory.cs | 8 ++++++-- 11 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Decentralized.Domain/StoryMods.cs b/src/Decentralized.Domain/StoryMods.cs index 2256571..e2ea0a5 100644 --- a/src/Decentralized.Domain/StoryMods.cs +++ b/src/Decentralized.Domain/StoryMods.cs @@ -127,6 +127,8 @@ namespace Decentralized.Domain public const int Hide = 1, Report = 2, Sell = 3; public int StartDay = -1, Stage, Choice, VisitedDay = -1; public bool Done; + /// Tumbler 的外观(第一次上门时随机定下,之后每次都一样)。 + public string Sprite; /// 第几次上门在哪一天(相对开始日)。 public static readonly int[] Offsets = { 0, 3, 5, 9 }; diff --git a/src/Decentralized/DealerStock.cs b/src/Decentralized/DealerStock.cs index d5acdb4..6655724 100644 --- a/src/Decentralized/DealerStock.cs +++ b/src/Decentralized/DealerStock.cs @@ -152,6 +152,14 @@ namespace Decentralized TumblerStory.ForceVisit(m); PlayerStore.Instance.TryCallNextClient(); })); + ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Tumbler: restart story (test)", () => + { + var st = Session.Data.Story; + Log.Info($"测试:Tumbler 剧情重来(原进度 {st.Tumbler.Stage},选择 {st.Tumbler.Choice},结束 {st.Tumbler.Done})"); + st.Tumbler = new Tumbler(); st.After = new TumblerAfter(); + st.Applied.RemoveAll(k => k.StartsWith("tumbler_")); + st.MixerClosed = st.MixerRebranded = st.MixerHoneypot = false; st.MixerFee = st.MixerVolume = st.MixerRug = 1; + }); ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Tumbler: leak tonight (test)", () => { var a = Session.Data.Story.After; a.Leaked = false; a.LeakDay = StoreStation.GetDayCounter(); diff --git a/src/Decentralized/ModFiles/Localization/de.csv b/src/Decentralized/ModFiles/Localization/de.csv index 37a79f2..81dfbe2 100644 --- a/src/Decentralized/ModFiles/Localization/de.csv +++ b/src/Decentralized/ModFiles/Localization/de.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,"Ich habe gehört, die Security hat deinen Laden durchsucht. tumbler.v4.seized.2,Sie haben jetzt den Schlüssel. Die Aufzeichnungen aller Nutzer werden aufgedeckt. tumbler.v4.seized.3,"Was auch immer du ihnen erzählt hast, ich will es gar nicht mehr wissen." nightlog.tumbler.leak,"Die Security nutzte Tumblers Signaturschlüssel, um die Mixer-Aufzeichnungen zu rekonstruieren: Die bei Auszahlungen ({0}) reingewaschene Kontamination ({1}) wurde den Wallets wieder zugeschrieben." +nightlog.tumbler.leak.none,"Security hat Tumblers Signaturschlüssel verwendet, um die Mixer-Aufzeichnungen zu rekonstruieren. Du hast in letzter Zeit nichts aus dem Mixer abgehoben." nightlog.tumbler.note,"Ein Zettel wurde unter der Tür durchgeschoben: ""Du schuldest mir was, und ich hole es mir zurück. —T""" nightlog.tumbler.tip,Nachricht von Tumbler: Die Security geht morgen womöglich gegen die Mixer-Dienste vor. news.tumbler.leak.title,Security rekonstruiert Mixer-Aufzeichnungen diff --git a/src/Decentralized/ModFiles/Localization/en.csv b/src/Decentralized/ModFiles/Localization/en.csv index a81a2fa..26261d7 100644 --- a/src/Decentralized/ModFiles/Localization/en.csv +++ b/src/Decentralized/ModFiles/Localization/en.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,I heard Security searched your shop. tumbler.v4.seized.2,They have the key now. Every user's records will be dug up. tumbler.v4.seized.3,"Whatever you told them, I don't want to know anymore." nightlog.tumbler.leak,"Security used Tumbler's signing key to rebuild the mixing records: the taint washed off {0} payouts, {1}, was added back to the wallets." +nightlog.tumbler.leak.none,Security used Tumbler's signing key to rebuild the mixing records. You have not withdrawn anything from the mixer recently. nightlog.tumbler.note,"A note was slipped under the door: ""You owe me, and I'll take it back. —T""" nightlog.tumbler.tip,Message from Tumbler: Security may go after the mixing services tomorrow. news.tumbler.leak.title,Security rebuilds mixer records diff --git a/src/Decentralized/ModFiles/Localization/es.csv b/src/Decentralized/ModFiles/Localization/es.csv index d4dccbd..84d404d 100644 --- a/src/Decentralized/ModFiles/Localization/es.csv +++ b/src/Decentralized/ModFiles/Localization/es.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,Me enteré de que Seguridad registró tu tienda. tumbler.v4.seized.2,Ahora tienen la clave. Van a desenterrar los registros de todos los usuarios. tumbler.v4.seized.3,"Lo que sea que les hayas dicho, ya no quiero saberlo." nightlog.tumbler.leak,"Seguridad usó la clave de firma de Tumbler para reconstruir los registros del mezclador: la contaminación lavada en pagos ({0}), {1}, se devolvió a las billeteras." +nightlog.tumbler.leak.none,Seguridad usó la clave de firma de Tumbler para reconstruir los registros de mezcla. No has retirado nada del mezclador recientemente. nightlog.tumbler.note,"Deslizaron una nota por debajo de la puerta: ""Me debes, y lo voy a recuperar. —T""" nightlog.tumbler.tip,Mensaje de Tumbler: puede que Seguridad inspeccione los servicios de mezclador mañana. news.tumbler.leak.title,Seguridad reconstruye registros del mezclador diff --git a/src/Decentralized/ModFiles/Localization/fr.csv b/src/Decentralized/ModFiles/Localization/fr.csv index fa4ca9e..140c6f6 100644 --- a/src/Decentralized/ModFiles/Localization/fr.csv +++ b/src/Decentralized/ModFiles/Localization/fr.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,J'ai appris que la Sécurité a fouillé ta boutique. tumbler.v4.seized.2,Ils ont la clé désormais. Les registres de chaque utilisateur vont être déterrés. tumbler.v4.seized.3,"Peu importe ce que tu leur as dit, je ne veux plus le savoir." nightlog.tumbler.leak,"La Sécurité a utilisé la clé de signature de Tumbler pour reconstituer les registres du mixeur : la contamination blanchie lors de versements (total : {0}), soit {1}, a été réattribuée aux portefeuilles." +nightlog.tumbler.leak.none,La Sécurité a utilisé la clé de signature de Tumbler pour reconstituer les registres de mixage. Vous n'avez rien retiré du mixeur récemment. nightlog.tumbler.note,"Un mot a été glissé sous la porte : ""Tu me dois ça, et je viendrai le reprendre. — T""" nightlog.tumbler.tip,Message de Tumbler : la Sécurité pourrait cibler les services de mixage demain. news.tumbler.leak.title,Sécurité : registres du mixeur reconstitués diff --git a/src/Decentralized/ModFiles/Localization/ja.csv b/src/Decentralized/ModFiles/Localization/ja.csv index 1727626..1cff385 100644 --- a/src/Decentralized/ModFiles/Localization/ja.csv +++ b/src/Decentralized/ModFiles/Localization/ja.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,警察が店を捜索したと聞いた。 tumbler.v4.seized.2,鍵は奴らの手に渡った。全ユーザーの記録が洗い出される。 tumbler.v4.seized.3,あんたが奴らに何を話したか、もう知りたくもない。 nightlog.tumbler.leak,警察はタンブラーの署名鍵を使ってミキサーの記録を復元した:{0} 件の出金で洗浄された汚染 {1} がウォレットに戻された。 +nightlog.tumbler.leak.none,警察はタンブラーの署名鍵を使ってミキシング記録を復元した。最近ミキサーから何も出金していない。 nightlog.tumbler.note,ドアの隙間からメモが差し入れられていた:「借りは必ず取り戻す。—T」 nightlog.tumbler.tip,タンブラーからのメッセージ:明日、警察がミキサーサービスの取り締まりに動くかもしれない。 news.tumbler.leak.title,警察、ミキサー記録を復元 diff --git a/src/Decentralized/ModFiles/Localization/pl.csv b/src/Decentralized/ModFiles/Localization/pl.csv index 6b3bb61..488368c 100644 --- a/src/Decentralized/ModFiles/Localization/pl.csv +++ b/src/Decentralized/ModFiles/Localization/pl.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,"Słyszałem, że Ochrona przeszukała twój sklep." tumbler.v4.seized.2,Mają teraz klucz. Wyciągną rejestry każdego użytkownika. tumbler.v4.seized.3,"Cokolwiek im powiedziałeś, nie chcę już wiedzieć." nightlog.tumbler.leak,Ochrona użyła klucza podpisu Tumblera do odtworzenia rejestrów miksera: skażenie usunięte z wypłat (liczba: {0}) w kwocie {1} powróciło do portfeli. +nightlog.tumbler.leak.none,Ochrona użyła klucza podpisu Tumblera do odtworzenia rejestrów miksowania. Ostatnio nie wypłacono niczego z miksera. nightlog.tumbler.note,"Pod drzwi wsunięto liścik: ""Jesteś mi coś winien i odbiorę to. —T""" nightlog.tumbler.tip,Wiadomość od Tumblera: Ochrona może jutro wziąć na cel usługi mikserów. news.tumbler.leak.title,Ochrona odtwarza rejestry miksera diff --git a/src/Decentralized/ModFiles/Localization/ru.csv b/src/Decentralized/ModFiles/Localization/ru.csv index cdb78e5..099ba3c 100644 --- a/src/Decentralized/ModFiles/Localization/ru.csv +++ b/src/Decentralized/ModFiles/Localization/ru.csv @@ -772,6 +772,7 @@ tumbler.v4.seized.1,"Слышал, Служба безопасности обы tumbler.v4.seized.2,Ключ теперь у них. Они поднимут записи каждого пользователя. tumbler.v4.seized.3,Что ты им сказал — знать больше не хочу. nightlog.tumbler.leak,"Служба безопасности восстановила записи миксера по ключу подписи Тумблера: смытый след с выплат (кол-во: {0}, {1}) возвращён на кошельки." +nightlog.tumbler.leak.none,"Служба безопасности использовала ключ подписи Тумблера, чтобы восстановить записи микширования. В последнее время вы ничего не выводили из миксера." nightlog.tumbler.note,"Под дверь подсунули записку: «Ты мне задолжал, и я своё заберу. — Т»" nightlog.tumbler.tip,Сообщение от Тумблера: завтра Служба безопасности может взяться за миксеры. news.tumbler.leak.title,Служба безопасности восстановила записи миксера diff --git a/src/Decentralized/ModFiles/Localization/zh.csv b/src/Decentralized/ModFiles/Localization/zh.csv index ee57c58..e0388d8 100644 --- a/src/Decentralized/ModFiles/Localization/zh.csv +++ b/src/Decentralized/ModFiles/Localization/zh.csv @@ -771,6 +771,7 @@ tumbler.v4.seized.1,我听说治安部搜了你的店。 tumbler.v4.seized.2,密钥在他们手里,所有用户的记录都会被翻出来。 tumbler.v4.seized.3,你跟他们说过什么,我不想知道了。 nightlog.tumbler.leak,治安部用 Tumbler 的签名密钥还原了混币记录:{0} 笔出款洗掉的污点 {1} 加回了钱包。 +nightlog.tumbler.leak.none,治安部用 Tumbler 的签名密钥还原了混币记录。你最近没有从混币器提回过币。 nightlog.tumbler.note,门缝里塞进来一张纸条:“欠我的,我会拿回来。——T” nightlog.tumbler.tip,Tumbler 发来消息:明天治安部可能要查混币服务。 news.tumbler.leak.title,治安部还原混币记录 diff --git a/src/Decentralized/TumblerStory.cs b/src/Decentralized/TumblerStory.cs index 438a967..7ef60cb 100644 --- a/src/Decentralized/TumblerStory.cs +++ b/src/Decentralized/TumblerStory.cs @@ -67,7 +67,8 @@ namespace Decentralized { a.Leaked = true; var r = d.Mixer.Leak(day, d.Own, Session.Price); - ps.AddNightLog(L.T("nightlog.tumbler.leak", r.Count, Fmt.Credits(r.Taint)) + TaintCrime.Commit(r.Over), "cc7755"); + if (r.Count == 0) ps.AddNightLog(L.T("nightlog.tumbler.leak.none")); + else ps.AddNightLog(L.T("nightlog.tumbler.leak", r.Count, Fmt.Credits(r.Taint)) + TaintCrime.Commit(r.Over), "cc7755"); News.Show("pd_news_tumbler_leak", L.T("news.tumbler.leak.title"), L.T("news.tumbler.leak.desc"), 3, 8); Log.Info($"Tumbler 密钥泄露:还原 {r.Count} 笔出款,污点 +{r.Taint:0},超出 {r.Over:0}"); } @@ -161,9 +162,12 @@ namespace Decentralized private static StoreClient New() { + // 每次上门是同一个人:外观第一次上门时定下来 + var t = Session.Data.Story.Tumbler; + if (string.IsNullOrEmpty(t.Sprite)) t.Sprite = SpriteDict.GetRandomShadySpriteName(); var c = new StoreClient { - identifier = "pd_tumbler", displayName = L.T("tumbler.name"), spriteName = SpriteDict.GetRandomShadySpriteName(), + identifier = "pd_tumbler", displayName = L.T("tumbler.name"), spriteName = t.Sprite, clientIntent = StoreClient.ClientIntent.DIALOGUE, nonShootable = true, dismissable = false, }; ModHelper.SetClientSource(c, ModInfo.Id);