XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEEDToolBox

fix: preserve trade recovery budget across telemetry retries

d70f166
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

11 个文件 +99 -16
Modified README.md +2 -2
@@ -1,6 +1,6 @@
1 1 # XFE ED ToolBox
2 2
3 当前 0.4.26 修复 Bernal 空间站的原生停靠请求,并为连续未执行的请求加入有上限的恢复,正常空管等待继续保留。支持在严格核对空舱静止与连续健康状态后,通过原始菜单更新底层插件;原订单、轮数和收益继续累计。详见 [0.4.26 说明](docs/INTERFACE-0.4.26.md)。
3 当前 0.4.27 将普通飞行数据重试与会话恢复次数分别计算,避免正常跃迁和超巡已消耗降落交接失败后的恢复额度;空载和载货航段都保留最多三次真实会话恢复。降落交接的连续相同状态不再每帧刷日志,并保留原始归零诊断。详见 [0.4.27 说明](docs/INTERFACE-0.4.27.md)。
4 4
5 5 0.4.23 修复当前星系原生 3D 合成层为零尺寸的空白问题,并将跑商改为全范围候选、并行计算、真实进度、采购来源类型筛选和按船型核对停机坪;CG 交付候选使用紫色及文字标识。详见 [0.4.23 说明](docs/INTERFACE-0.4.23.md)。当前星系仍支持真实坐标与左侧目录双向选择,实时商品保留报价详情、来源和完整采集时间;两页依据 Imagegen 设计稿实现。重复诊断会合并,跑商实际运行期间可恢复确切的游戏暂停菜单,手动暂停或停止任务后撤销恢复权限。既有范围见 [0.4.22 说明](docs/INTERFACE-0.4.22.md)及[当前星系与星系内驾驶](docs/CURRENT-SYSTEM-NAVIGATION.md)。
6 6
@@ -14,7 +14,7 @@ Elite Dangerous 的 WinUI 3 指挥官工具箱。当前版本提供实时数据
14 14
15 15 ## 运行
16 16
17 双击仓库根目录的 `Start-Toolbox.cmd`,优先启动 `dist/XFEEDToolBox-0.4.26-win-x64/XFEEDToolBox.exe`。星图与导航已合并;输入星系名称可自动补全,也可选中/双击星点聚焦,长按恒星待外圈填满后由游戏规划,确认成功后点击“开始自动导航”。航路由游戏计算,软件校验并读取。主页与飞船编辑背景采用本地真实船体的旋转科技线稿。发布包面向 Windows x64,包含 .NET 运行时与 Windows App SDK;源码构建需要 PowerShell 7、.NET 10 SDK、Windows SDK 和 Visual Studio 的 C++ x64 构建工具。`--page Navigation --maximized` 可直接打开最大化星图,`--page Refit` 打开飞船编辑。
17 双击仓库根目录的 `Start-Toolbox.cmd`,优先启动 `dist/XFEEDToolBox-0.4.27-win-x64/XFEEDToolBox.exe`。星图与导航已合并;输入星系名称可自动补全,也可选中/双击星点聚焦,长按恒星待外圈填满后由游戏规划,确认成功后点击“开始自动导航”。航路由游戏计算,软件校验并读取。主页与飞船编辑背景采用本地真实船体的旋转科技线稿。发布包面向 Windows x64,包含 .NET 运行时与 Windows App SDK;源码构建需要 PowerShell 7、.NET 10 SDK、Windows SDK 和 Visual Studio 的 C++ x64 构建工具。`--page Navigation --maximized` 可直接打开最大化星图,`--page Refit` 打开飞船编辑。
18 18
19 19 ```powershell
20 20 pwsh -File scripts/Build.ps1
Modified Start-Toolbox.cmd +8 -0
@@ -2,6 +2,14 @@
2 2 setlocal
3 3 cd /d "%~dp0"
4 4 if not defined XFE_TOOLBOX_DATA_DIR if exist "work\toolbox-local-data-dir.txt" set /p "XFE_TOOLBOX_DATA_DIR="<"work\toolbox-local-data-dir.txt"
5 if exist "dist\XFEEDToolBox-0.4.27-win-x64\XFEEDToolBox.exe" (
6 if defined XFE_TOOLBOX_DATA_DIR (
7 start "" "dist\XFEEDToolBox-0.4.27-win-x64\XFEEDToolBox.exe" %* --data-dir "%XFE_TOOLBOX_DATA_DIR%"
8 exit /b
9 )
10 start "" "dist\XFEEDToolBox-0.4.27-win-x64\XFEEDToolBox.exe" %*
11 exit /b
12 )
5 13 if exist "dist\XFEEDToolBox-0.4.26-win-x64\XFEEDToolBox.exe" (
6 14 if defined XFE_TOOLBOX_DATA_DIR (
7 15 start "" "dist\XFEEDToolBox-0.4.26-win-x64\XFEEDToolBox.exe" %* --data-dir "%XFE_TOOLBOX_DATA_DIR%"
Modified XFEEDToolBox.Core/Execution/AutomaticTradeEngine.cs +6 -6
@@ -141,11 +141,11 @@ public sealed class AutomaticTradeEngine(AutomaticTradeConfiguration configurati
141 141 Planning.ShipPadPolicy.RequireFits(destination,player().Ship);
142 142 if(player().Docked&&player().MarketId==destination.MarketId){RefreshCompleted();return;}
143 143 await StateAsync("travelling","正在前往 "+destination.DisplayName,destination,token);
144 for(var attempt=0;;attempt++)
144 for(var recoveries=0;;)
145 145 {
146 146 try{await driver.ExecuteAsync(new(TradeActionKind.Travel,new(){From=player().MarketId==source.MarketId?source:configuration.Destination,To=destination},null),CheckAsync,token).ConfigureAwait(false);RefreshCompleted();return;}
147 catch(DockingHandoffException)when(attempt<3&&recoverToSameMode is not null){await RecoverAsync(token).ConfigureAwait(false);}
148 catch(StationDepartureRecoveryException)when(attempt<3&&recoverToSameMode is not null){await RecoverAsync(token).ConfigureAwait(false);}
147 catch(DockingHandoffException)when(recoveries<3&&recoverToSameMode is not null){recoveries++;await RecoverAsync(token).ConfigureAwait(false);}
148 catch(StationDepartureRecoveryException)when(recoveries<3&&recoverToSameMode is not null){recoveries++;await RecoverAsync(token).ConfigureAwait(false);}
149 149 catch(Exception error)when(FlightThreatPauseException.Present(error)&&!token.IsCancellationRequested){await WaitForSafetyAsync(destination,token).ConfigureAwait(false);}
150 150 catch(Exception error)when(NavigationRecovery.CanRetry(error,token))
151 151 {await StateAsync("travelling","正在衔接下一段航程,自动继续",destination,token);await Task.Delay(100,token).ConfigureAwait(false);}
@@ -231,13 +231,13 @@ public sealed class AutomaticTradeEngine(AutomaticTradeConfiguration configurati
231 231 estimate=supplySelection is {} selection&&selection.Source.MarketId==leg.From.MarketId&&selection.Order==leg.Orders.Single()
232 232 ?new(selection.EstimatedNetProfit,selection.EstimatedMinutes,selection.Basis):AutomaticTradeEstimate.For(leg,root,initial.CurrentShipId);
233 233 active=directory;await StateAsync("cargo-journey","正在采购、运输并出售本批货物",leg.To,token);
234 for(var attempt=0;;attempt++)
234 for(var recoveries=0;;)
235 235 {
236 236 var journey=new NativeTradeJourney(driver,player,CheckAsync,directory){JournalDirectory=journalDirectory};
237 237 journey.Status+=text=>Progress?.Invoke(new(phase,text,next,completed,profit,active){Estimate=estimate,CompletedRounds=completedRounds,SupplySelection=supplySelection});
238 238 try{await journey.RunAsync(leg,token).ConfigureAwait(false);break;}
239 catch(NativeTradeJourneyIncompleteException error)when(error.InnerException is DockingHandoffException&&attempt<3&&recoverToSameMode is not null){await RecoverAsync(token).ConfigureAwait(false);}
240 catch(NativeTradeJourneyIncompleteException error)when(error.InnerException is StationDepartureRecoveryException&&attempt<3&&recoverToSameMode is not null){await RecoverAsync(token).ConfigureAwait(false);}
239 catch(NativeTradeJourneyIncompleteException error)when(error.InnerException is DockingHandoffException&&recoveries<3&&recoverToSameMode is not null){recoveries++;await RecoverAsync(token).ConfigureAwait(false);}
240 catch(NativeTradeJourneyIncompleteException error)when(error.InnerException is StationDepartureRecoveryException&&recoveries<3&&recoverToSameMode is not null){recoveries++;await RecoverAsync(token).ConfigureAwait(false);}
241 241 catch(NativeTradeJourneyIncompleteException error)when(FlightThreatPauseException.Present(error)&&!token.IsCancellationRequested){await WaitForSafetyAsync(leg.To,token).ConfigureAwait(false);}
242 242 catch(NativeTradeJourneyIncompleteException error)when(error.InnerException is {} cause&&NavigationRecovery.CanRetry(cause,token))
243 243 {await StateAsync("cargo-journey","正在衔接下一段航程,保留原货物继续",leg.To,token);await Task.Delay(100,token).ConfigureAwait(false);}
Modified XFEEDToolBox.Core/Execution/NativeTradeNavigation.cs +1 -1
@@ -94,7 +94,7 @@ public sealed class NativeTradeNavigation(int processId,string gameHash,Func<Pla
94 94 var local=await LocalAsync(token);var arrival=new SystemNavigationRunner(player);string? lastIssue=null;
95 95 arrival.Progress+=value=>{lastIssue=value.Message;Status?.Invoke(value.Message);};
96 96 await WithFlightSafetyAsync(()=>arrival.RunAsync(target,local,token));
97 if(arrival.HandoffFailed)throw new DockingHandoffException(lastIssue??"原生自动降落交接未完成。",destination.MarketId);
97 if(arrival.HandoffFailed)throw new DockingHandoffException(lastIssue??"原生自动降落交接未完成。",destination.MarketId,arrival.Failure);
98 98 if(arrival.State!=NavigationRunState.Completed||!player().Docked||player().MarketId!=destination.MarketId)
99 99 throw new InvalidOperationException(lastIssue??"目的站停靠尚未确认完成。",arrival.Failure);
100 100 }
Modified XFEEDToolBox.Core/Navigation/SystemNavigationRunner.cs +10 -6
@@ -13,7 +13,7 @@ public interface ISystemFlightControlDriver
13 13 Task SuspendSystemFlightAsync()=>ReleaseSystemFlightAsync();
14 14 }
15 15 public sealed record SystemNavigationProgress(NavigationRunState State,SystemNavigationTarget Target,SystemNavigationPhase Phase,string Message);
16 public sealed class DockingHandoffException(string message,long marketId):InvalidOperationException(message)
16 public sealed class DockingHandoffException(string message,long marketId,Exception? inner=null):InvalidOperationException(message,inner)
17 17 {public long MarketId{get;}=marketId;}
18 18 public sealed class DockingRequestNotAppliedException():IOException("游戏尚未确认空管请求已执行。");
19 19 public sealed class DockingResetObservationPendingException(string requestId,long marketId,DateTimeOffset requestedAt,Exception inner)
@@ -39,8 +39,12 @@ public sealed class SystemNavigationRunner(Func<PlayerState> player,Func<DateTim
39 39 if(cancellation is not null)throw new InvalidOperationException("星系内导航已在运行。");
40 40 stop=CancellationTokenSource.CreateLinkedTokenSource(token);cancellation=stop;
41 41 }
42 HandoffFailed=false;Failure=null;var phase=SystemNavigationPhase.Preparing;var state=NavigationRunState.Running;var terminal="星系内导航已停止。";
43 void Report(SystemNavigationPhase next,string message){phase=next;State=NavigationRunState.Running;Progress?.Invoke(new(State,target,next,message));}
42 HandoffFailed=false;Failure=null;var phase=SystemNavigationPhase.Preparing;var state=NavigationRunState.Running;var terminal="星系内导航已停止。";string? reportedMessage=null;
43 void Report(SystemNavigationPhase next,string message)
44 {
45 if(State==NavigationRunState.Running&&phase==next&&reportedMessage==message)return;
46 phase=next;reportedMessage=message;State=NavigationRunState.Running;Progress?.Invoke(new(State,target,next,message));
47 }
44 48 try
45 49 {
46 50 var initial=player();var initialShip=initial.CurrentShipId;var initialCommander=initial.CommanderId;var initialSession=initial.LoadGameAt;
@@ -79,13 +83,15 @@ public sealed class SystemNavigationRunner(Func<PlayerState> player,Func<DateTim
79 83 decision=new(SystemNavigationPhase.Stopped,"自动降落未接管,飞船仍在移动,正在保护退出。",null,null,SystemNavigationAction.ExitForFailedHandoff);
80 84 else if(!landingObserved&&!decision.Complete&&now()-pendingReset.RequestedAt>TimeSpan.FromSeconds(30))
81 85 throw new InvalidOperationException("自动降落回执和接管状态仍未确认,原请求未重发。",pendingReset);
86 if(decision.Phase!=SystemNavigationPhase.Stopped&&!decision.Complete)
87 decision=decision with{Phase=SystemNavigationPhase.NativeLanding,Message=landingObserved?"自动降落已接管,正在核对实际停靠。":"正在核对归零回执与自动降落状态,不重发请求。"};
82 88 }
83 89 Report(decision.Phase,decision.Message);
84 90 if(decision.Phase==SystemNavigationPhase.Stopped)
85 91 {
86 92 if(decision.Actions.HasFlag(SystemNavigationAction.ExitForFailedHandoff))
87 93 {
88 HandoffFailed=true;
94 HandoffFailed=true;Failure=pendingReset;
89 95 await driver.ApplySystemFlightAsync(decision,frame,target,frame.ObservedAt.AddMilliseconds(250),stop.Token);
90 96 }
91 97 state=NavigationRunState.Stopped;terminal=decision.Message;break;
@@ -98,8 +104,6 @@ public sealed class SystemNavigationRunner(Func<PlayerState> player,Func<DateTim
98 104 await driver.ApplySystemFlightAsync(decision,frame,target,frame.ObservedAt.AddMilliseconds(250),stop.Token);
99 105 if(decision.Actions.HasFlag(SystemNavigationAction.RequestDocking))requestFailures=0;
100 106 }
101 else if(!decision.Complete)
102 Report(SystemNavigationPhase.NativeLanding,landingObserved?"自动降落已接管,正在核对实际停靠。":"正在核对归零回执与自动降落状态,不重发请求。");
103 107 missingSince=null;
104 108 if(decision.Complete){state=NavigationRunState.Completed;terminal=decision.Message;break;}
105 109 }
Modified XFEEDToolBox.Test/AutomaticTradeMenuIntegrationTests.cs +14 -0
@@ -100,6 +100,20 @@ public sealed class AutomaticTradeMenuIntegrationTests
100 100 Check.That(restartObserved&&safetyPause);Check.Equal(1,visits);Check.That(released>=2);
101 101 Check.That(channel.Calls.All(op=>op is "describe" or "commerce.inventory"));
102 102 }
103 [Test]public async Task ActualSessionRecoveriesRemainBoundedAfterManyTransientReads()
104 {
105 using var temporary=new TemporaryDirectory();var current=Player;var channel=new Commerce();var visits=0;var recoveries=0;
106 var driver=new NativeTradeCommandDriver(channel,()=>current,Path.Combine(temporary.Path,"operations"),(_,_,_)=>
107 {
108 if(++visits%5!=0)throw new FlightTelemetryUnavailableException("fixture fresh-frame retry");
109 throw new DockingHandoffException("fixture handoff still unavailable",2);
110 },_=>Task.CompletedTask);
111 var engine=new AutomaticTradeEngine(Configuration(temporary.Path),driver,channel,()=>current,_=>Task.CompletedTask,temporary.Path,_=>
112 {recoveries++;current=current with{LoadGameAt=current.LoadGameAt!.Value.AddSeconds(1)};return Task.CompletedTask;});
113 var refused=false;try{await engine.RunAsync(default).WaitAsync(TimeSpan.FromSeconds(5));}catch(DockingHandoffException){refused=true;}
114 Check.That(refused);Check.Equal(3,recoveries);Check.Equal(20,visits);
115 Check.That(channel.Calls.All(op=>op is "describe" or "commerce.inventory"));
116 }
103 117 [Test]public async Task EngineInterfaceAndFlightPreparationFailuresNeverCreateARunningScope()
104 118 {
105 119 foreach(var rejectDescribe in new[]{true,false})
Modified XFEEDToolBox.Test/NativeTradeCommandDriverTests.cs +28 -0
@@ -367,6 +367,34 @@ public class NativeTradeCommandDriverTests
367 367 Check.That(refusals>=3);Check.Equal(2,channel.Mutations);Check.Equal(0,channel.Cargo);
368 368 Check.Equal(1,Directory.GetFiles(directory.Path,"settled.json",SearchOption.AllDirectories).Length);
369 369 }
370 [Test] public async Task TransientFlightReadsDoNotSpendEmptyOrLoadedSessionRecoveryAttempts()
371 {
372 foreach(var loaded in new[]{false,true})foreach(var departure in new[]{false,true})
373 {
374 using var directory=new TemporaryDirectory();var channel=new Channel{Credits=10000000,BatchSupported=true,FuelNeeded=false};
375 channel.Player=channel.Player with{CargoCapacity=752,Credits=channel.Credits,Ship="type9",Rebuy=1000};
376 var reads=0;var recovered=0;
377 var driver=new NativeTradeCommandDriver(channel,()=>channel.Player,Path.Combine(directory.Path,"operations"),
378 (station,_,_)=>
379 {
380 if((channel.Cargo>0)==loaded&&++reads<=5)
381 {
382 if(reads<=4)throw new FlightTelemetryUnavailableException("fixture transient during scene transition");
383 channel.Player=channel.Player with{Docked=false};
384 if(departure)throw new StationDepartureRecoveryException((long)channel.ActualMarket,TimeSpan.FromMinutes(3));
385 throw new DockingHandoffException("fixture landing handoff",station.MarketId);
386 }
387 channel.Player=channel.Player with{MarketId=station.MarketId,Docked=true};channel.ActualMarket=(ulong)station.MarketId;return Task.CompletedTask;
388 },_=>Task.CompletedTask,batchPolicy:new(752,1000));
389 driver.WalletObserved+=o=>channel.Player=o.Project(channel.Player);
390 var configuration=new AutomaticTradeConfiguration{Source=new(){MarketId=1,Name="One",SystemName="A",MaxLandingPad=LandingPad.Large},Destination=new(){MarketId=99,Name="Other",SystemName="B",MaxLandingPad=LandingPad.Large},WorkingDirectory=directory.Path};
391 var engine=new AutomaticTradeEngine(configuration,driver,channel,()=>channel.Player,_=>Task.CompletedTask,directory.Path,_=>
392 {recovered++;channel.Player=channel.Player with{Docked=true,LoadGameAt=channel.Player.LoadGameAt!.Value.AddSeconds(1)};return Task.CompletedTask;}){MaximumCycles=1};
393 await engine.RunAsync(default).WaitAsync(TimeSpan.FromSeconds(8));
394 Check.Equal(1,recovered);Check.That(reads>=6);Check.Equal(2,channel.Mutations);Check.Equal(0,channel.Cargo);
395 Check.Equal(1,Directory.GetFiles(directory.Path,"settled.json",SearchOption.AllDirectories).Length);
396 }
397 }
370 398 [Test] public async Task CgEngineUsesUserDestinationAndConfirmsItsActualContribution()
371 399 {
372 400 using var directory=new TemporaryDirectory();var channel=new Channel{Credits=10000000,BatchSupported=true,FuelNeeded=false,Goals=true};
Modified XFEEDToolBox.Test/SystemNavigationRunnerTests.cs +11 -0
@@ -60,6 +60,17 @@ public class SystemNavigationRunnerTests
60 60 if(d.Actions.HasFlag(SystemNavigationAction.ExitForFailedHandoff))exits++;}};
61 61 var runner=new SystemNavigationRunner(()=>Player,()=>at);await runner.RunAsync(Target,driver);
62 62 Check.Equal(NavigationRunState.Stopped,runner.State);Check.That(runner.HandoffFailed);Check.Equal(1,arms);Check.Equal(1,exits);
63 Check.That(runner.Failure is DockingResetObservationPendingException{InnerException:IOException});
64 }
65 [Test]public async Task PendingResetKeepsReadingWithoutAlternatingOrRepeatingProgressEveryFrame()
66 {
67 var at=Now;var arms=0;var messages=new List<string>();
68 var driver=new Fake{Frame=n=>{at=Now.AddMilliseconds((n-1)*100);return n==13?Docked with{Sequence=n,ObservedAt=at}:Landing(n,at,NativeAssistState.Ready);},
69 OnDecision=d=>{if(d.Actions.HasFlag(SystemNavigationAction.EnableDockingAssist)){arms++;throw new DockingResetObservationPendingException("immutable-request",20,Now,new IOException("Lost status reply"));}}};
70 var runner=new SystemNavigationRunner(()=>Player,()=>at);runner.Progress+=p=>messages.Add(p.Message);
71 await runner.RunAsync(Target,driver);
72 Check.Equal(NavigationRunState.Completed,runner.State);Check.Equal(1,arms);Check.Equal(13,driver.Calls.Count(x=>x=="read"));
73 Check.Equal(1,messages.Count(x=>x=="正在核对归零回执与自动降落状态,不重发请求。"));Check.That(messages.Count<=6);
63 74 }
64 75 [Test] public async Task AResetReceiptForAnotherMarketCannotBecomeAnObservedHandoff()
65 76 {
Modified XFEEDToolBox/XFEEDToolBox.csproj +1 -1
@@ -2,7 +2,7 @@
2 2 <PropertyGroup>
3 3 <OutputType>WinExe</OutputType>
4 4 <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5 <Version>0.4.26</Version>
5 <Version>0.4.27</Version>
6 6 <TargetFramework>net10.0-windows10.0.22621.0</TargetFramework>
7 7 <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
8 8 <ApplicationManifest>app.manifest</ApplicationManifest>
Added docs/INTERFACE-0.4.27.md +9 -0
@@ -0,0 +1,9 @@
1 # 0.4.27:飞行数据重试与会话恢复计数
2
3 CG 循环载货抵达 Homer Platform 时,归零请求尚未确认,原有两秒移动保护停止了本次驾驶交接。游戏原生降落随后完成靠港,但工具箱没有自动核对原订单继续出售。原因是航段循环中的计数同时累计普通飞行数据重试和真实会话恢复;此前几次正常瞬时遥测重试已耗尽“最多三次恢复”的额度。
4
5 空载与载货航段现在只在实际开始同模式会话恢复时消耗额度,普通遥测恢复与威胁等待不会占用它。最多三次真实会话恢复仍然有效;取消、身份、货物、健康和资金核对继续约束恢复。
6
7 归零回执未确认时只报告一个当前观察状态,连续相同状态不再每帧重复刷日志;飞行观测和保护检查仍逐帧执行。若最终交接失败,异常保留不可重发请求的原始原因,便于区分请求没有进入原生接口、确认丢失和真实接管失败。
8
9 原有两秒移动保护、原生请求时限和一次性归零语义保持生效。此次更新只涉及托管程序,底层仍为 0.5.21-dev。原 CG 工作目录、交易键、货物和账本继续使用。
Added docs/VALIDATION-0.4.27.md +9 -0
@@ -0,0 +1,9 @@
1 # 0.4.27 验证记录
2
3 - 顺序全量回归:1,523 项,1,517 通过、0 失败、6 跳过,125.145 秒。报告位于本地忽略目录 `work/tests/toolbox-0.4.27-sequential`。新增场景覆盖空载/载货以及进站/离站在四次普通遥测重试后仍能恢复,最多三次真实会话恢复,以及归零观察逐帧继续但不重复刷状态日志。原两秒移动保护、归零不重发与伤害/取消保护继续通过。
4 - 先前一次完整运行中的既有 `ManualVisualDamageStopsInputsWithoutExitOrRestart` 测试超时,保留了失败记录;随后单项复测在 78.372 毫秒通过,无并行发布构建的完整复核也通过。未修改保护逻辑或该测试的时限。
5 - Windows x64 自包含发布成功,958 个部署文件与发布目录逐一核对 SHA256,记录在 `work/release-0.4.27/deployment.json`。底层支持仍经正式项目引用生成并内嵌,接口版本为 0.5.21-dev;游戏进程未重启。
6 - 官方日志确认工具箱停止后,游戏原生降落于 2026-10-25 21:34:52 UTC 实际停靠 Homer Platform。程序更新后从原工作目录接续,原采购键 `81e30853b0ba427482a43de9de3d5e98` 和完整买入回执保持不变;1,104 吨铀以唯一出售键 `7ee329716be644bbb1d8c486db9a0230` 完成服务器与客户端确认。原余额与费用闭合,第 8 轮净收益为 55,323,345 Cr。
7 - CG 864 的服务器响应与原文哈希确认贡献从 22,685 增至 23,789 吨,原有 21 份已完成批次的旅程、结算与贡献文件保持不变。累计已确认净利润为 460,052,599 Cr,程序随后独立选择 Wolf 1453 / Cartier City 并开始下一趟。
8 - `background-visual-check` 在最终进程后台取得 3862×2110 原图,实际查看原图及原比例分块,使用 OCR 交叉核对目标、货源、运行状态与利润。运行文字、布局和原订单恢复三项均通过,证据位于 `work/visual/docking-handoff-0.4.27`,取图前后台窗口未变化。
9 - 行情仍使用中心周边 500 ly 缓存,没有全量下载或完整数据库校验。连续数天运行尚未确认,仍需后续巡检积累证据。旧 SDK 的最后一份归零记录不足以完整分类本次初始请求拒绝,新异常已保留原始诊断;没有通过放宽移动保护或重发未知请求掩盖它。