feat: 增加 EnsureOpcodes 自动兜底装载与重载提示,消除手动装载时序依赖
This commit is contained in:
@@ -86,8 +86,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
adaptationReport=game.EvaluateAdaptation(modules);
|
adaptationReport=game.EvaluateAdaptation(modules);
|
||||||
AdaptationManifest.ApplyGate(modules,adaptationReport);
|
AdaptationManifest.ApplyGate(modules,adaptationReport);
|
||||||
});
|
});
|
||||||
var opcodeFile=Path.Combine(directory,"opcodes.json");
|
Try(() => EnsureOpcodes());
|
||||||
if(File.Exists(opcodeFile)) Try(() => opcodes.Load(File.ReadAllText(opcodeFile),gameVersion,"本地缓存"));
|
|
||||||
serviceBar=dtrBar.Get("IC Rebuild · 高度与迷宫");
|
serviceBar=dtrBar.Get("IC Rebuild · 高度与迷宫");
|
||||||
serviceBar.Shown=false;
|
serviceBar.Shown=false;
|
||||||
serviceBar.OnClick=_=>Open();
|
serviceBar.OnClick=_=>Open();
|
||||||
@@ -339,7 +338,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
ImGui.SameLine(); if(ImGui.Button("导出记录") && pending?.IsCompleted!=false)
|
ImGui.SameLine(); if(ImGui.Button("导出记录") && pending?.IsCompleted!=false)
|
||||||
{ var exportRecords=packets.Snapshot(); Try(()=>{ var path=DataPath(file); pending=Background(()=>PacketFiles.ExportAtomic(path,exportRecords)); }); }
|
{ var exportRecords=packets.Snapshot(); Try(()=>{ var path=DataPath(file); pending=Background(()=>PacketFiles.ExportAtomic(path,exportRecords)); }); }
|
||||||
ImGui.SameLine(); if(ImGui.Button("清空记录")) packets.Clear();
|
ImGui.SameLine(); if(ImGui.Button("清空记录")) packets.Clear();
|
||||||
if(ImGui.Button("载入本地 opcodes.json")) Try(()=>opcodes.Load(File.ReadAllText(DataPath("opcodes.json")),gameVersion,"本地文件"));
|
if(ImGui.Button("载入本地 opcodes.json")) Try(()=>{ EnsureOpcodes(true); notice=$"已成功载入 {gameVersion} Opcode 映射({opcodes.Snapshot.Source})"; });
|
||||||
ImGui.SameLine(); if(ImGui.Button("更新在线 Opcode") && pending?.IsCompleted!=false) pending=UpdateOpcodes();
|
ImGui.SameLine(); if(ImGui.Button("更新在线 Opcode") && pending?.IsCompleted!=false) pending=UpdateOpcodes();
|
||||||
ImGui.TextWrapped($"映射版本:{opcodes.Snapshot.GameVersion},来源:{opcodes.Snapshot.Source}");
|
ImGui.TextWrapped($"映射版本:{opcodes.Snapshot.GameVersion},来源:{opcodes.Snapshot.Source}");
|
||||||
var url=config.OpcodeUrl;
|
var url=config.OpcodeUrl;
|
||||||
@@ -372,10 +371,13 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
var dispatcher=network.ActiveSender;
|
var dispatcher=network.ActiveSender;
|
||||||
ImGui.TextWrapped($"原生发送通道:{(network.CanSendNative ? "已就绪 (ReceiverSendPacket + ZoneUp)" : "未就绪(需开启 36 或完成绑定)")} · 队列 {dispatcher.PendingQueueCount} · 等待响应 {dispatcher.InFlightCount}");
|
ImGui.TextWrapped($"原生发送通道:{(network.CanSendNative ? "已就绪 (ReceiverSendPacket + ZoneUp)" : "未就绪(需开启 36 或完成绑定)")} · 队列 {dispatcher.PendingQueueCount} · 等待响应 {dispatcher.InFlightCount}");
|
||||||
ImGui.TextWrapped($"发送会话:{(session.IsValid ? $"就绪 · 区域 {session.Territory} · Entity 0x{session.LocalEntityId:X8}" : "未就绪(需角色在场且非过图/占卜回放)")}");
|
ImGui.TextWrapped($"发送会话:{(session.IsValid ? $"就绪 · 区域 {session.Territory} · Entity 0x{session.LocalEntityId:X8}" : "未就绪(需角色在场且非过图/占卜回放)")}");
|
||||||
|
if(opcodes.Snapshot.GameVersion!=gameVersion)
|
||||||
|
ImGui.TextColored(new Vector4(1,0.4f,0.4f,1),$"提示:Opcode 映射尚未就绪(当前为 {opcodes.Snapshot.GameVersion});发送时将自动载入");
|
||||||
ImGui.InputInt("测试技能 ID (UP_ActionSend)",ref manualSendActionId);
|
ImGui.InputInt("测试技能 ID (UP_ActionSend)",ref manualSendActionId);
|
||||||
ImGui.InputInt("请求序号 RequestId",ref manualSendRequestId);
|
ImGui.InputInt("请求序号 RequestId",ref manualSendRequestId);
|
||||||
if(ImGui.Button("加入技能发送队列 (当前目标)")) Try(()=>
|
if(ImGui.Button("加入技能发送队列 (当前目标)")) Try(()=>
|
||||||
{
|
{
|
||||||
|
EnsureOpcodes();
|
||||||
if(manualSendActionId<=0) throw new ArgumentException("请输入有效技能 ID");
|
if(manualSendActionId<=0) throw new ArgumentException("请输入有效技能 ID");
|
||||||
if(manualSendRequestId is <=0 or >ushort.MaxValue) manualSendRequestId=1;
|
if(manualSendRequestId is <=0 or >ushort.MaxValue) manualSendRequestId=1;
|
||||||
var targetId=game.Targets.Target?.EntityId is >0 and var tid ? (ulong)tid : session.LocalEntityId;
|
var targetId=game.Targets.Target?.EntityId is >0 and var tid ? (ulong)tid : session.LocalEntityId;
|
||||||
@@ -387,6 +389,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if(ImGui.Button("加入 ClientTrigger 队列")) Try(()=>
|
if(ImGui.Button("加入 ClientTrigger 队列")) Try(()=>
|
||||||
{
|
{
|
||||||
|
EnsureOpcodes();
|
||||||
if(manualTriggerCommand<=0 || manualTriggerCommand>ushort.MaxValue) throw new ArgumentException("指令编号超出范围");
|
if(manualTriggerCommand<=0 || manualTriggerCommand>ushort.MaxValue) throw new ArgumentException("指令编号超出范围");
|
||||||
var packet=AuditedPacketEncoder.EncodeClientTrigger(opcodes,gameVersion,(uint)manualTriggerCommand,(uint)Math.Max(0,manualTriggerParam1));
|
var packet=AuditedPacketEncoder.EncodeClientTrigger(opcodes,gameVersion,(uint)manualTriggerCommand,(uint)Math.Max(0,manualTriggerParam1));
|
||||||
var tx=network.EnqueueSend(packet);
|
var tx=network.EnqueueSend(packet);
|
||||||
@@ -412,6 +415,15 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
if(string.IsNullOrWhiteSpace(name) || Path.GetFileName(name)!=name || name.IndexOfAny(Path.GetInvalidFileNameChars())>=0) throw new ArgumentException("请输入当前记录目录中的文件名");
|
if(string.IsNullOrWhiteSpace(name) || Path.GetFileName(name)!=name || name.IndexOfAny(Path.GetInvalidFileNameChars())>=0) throw new ArgumentException("请输入当前记录目录中的文件名");
|
||||||
return Path.Combine(directory,name);
|
return Path.Combine(directory,name);
|
||||||
}
|
}
|
||||||
|
private void EnsureOpcodes(bool force=false)
|
||||||
|
{
|
||||||
|
if(!force && opcodes.Snapshot.GameVersion==gameVersion) return;
|
||||||
|
var path=DataPath("opcodes.json");
|
||||||
|
if(!File.Exists(path) && pi.AssemblyLocation.DirectoryName is { } devDir)
|
||||||
|
path=Path.Combine(devDir,"opcodes.json");
|
||||||
|
if(File.Exists(path))
|
||||||
|
opcodes.Load(File.ReadAllText(path),gameVersion,"本地文件");
|
||||||
|
}
|
||||||
private async Task Background(Action action)
|
private async Task Background(Action action)
|
||||||
{ try { await Task.Run(action,cancellation.Token); if(!disposed) notice="文件操作完成"; } catch(Exception ex) { if(!disposed) notice=ex.Message; } }
|
{ try { await Task.Run(action,cancellation.Token); if(!disposed) notice="文件操作完成"; } catch(Exception ex) { if(!disposed) notice=ex.Message; } }
|
||||||
private async Task SaveCaptureAsync(string path,PacketRecord[] records)
|
private async Task SaveCaptureAsync(string path,PacketRecord[] records)
|
||||||
|
|||||||
Reference in New Issue
Block a user