From 7010140b10ba373e67ddf8f00233ebbac1cb449c Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:20:26 -0500 Subject: [PATCH 1/2] syslog and open treasure packets --- BossMod/Data/ActorState.cs | 10 +++++++++ BossMod/Data/WorldState.cs | 13 ++++++++++++ BossMod/Framework/WorldStateGameSync.cs | 28 +++++++++++++++++++++++++ BossMod/Replay/ReplayParserLog.cs | 12 +++++++++++ 4 files changed, 63 insertions(+) diff --git a/BossMod/Data/ActorState.cs b/BossMod/Data/ActorState.cs index f54a50dee..5c4730091 100644 --- a/BossMod/Data/ActorState.cs +++ b/BossMod/Data/ActorState.cs @@ -409,4 +409,14 @@ public sealed record class OpEventNpcYell(ulong InstanceID, ushort Message) : Op protected override void ExecActor(WorldState ws, Actor actor) => ws.Actors.EventNpcYell.Fire(actor, Message); public override void Write(ReplayRecorder.Output output) => output.EmitFourCC("NYEL"u8).EmitActor(InstanceID).Emit(Message); } + + public Event EventOpenTreasure = new(); + public sealed record class OpEventOpenTreasure(ulong InstanceID) : Operation(InstanceID) + { + protected override void ExecActor(WorldState ws, Actor actor) => ws.Actors.EventOpenTreasure.Fire(actor); + public override void Write(ReplayRecorder.Output output) + { + output.EmitFourCC("OPNT"u8).EmitActor(InstanceID); + } + } } diff --git a/BossMod/Data/WorldState.cs b/BossMod/Data/WorldState.cs index 0f12a2e77..413bc0206 100644 --- a/BossMod/Data/WorldState.cs +++ b/BossMod/Data/WorldState.cs @@ -143,4 +143,17 @@ public sealed record class OpEnvControl(byte Index, uint State) : Operation protected override void Exec(WorldState ws) => ws.EnvControl.Fire(this); public override void Write(ReplayRecorder.Output output) => output.EmitFourCC("ENVC"u8).Emit(Index, "X2").Emit(State, "X8"); } + + public Event SystemLogMessage = new(); + public sealed record class OpSystemLogMessage(uint MessageId, int[] Args) : Operation + { + protected override void Exec(WorldState ws) => ws.SystemLogMessage.Fire(this); + public override void Write(ReplayRecorder.Output output) + { + output.EmitFourCC("SLOG"u8).Emit(MessageId); + output.Emit(Args.Length); + foreach (var arg in Args) + output.Emit(arg); + } + } } diff --git a/BossMod/Framework/WorldStateGameSync.cs b/BossMod/Framework/WorldStateGameSync.cs index 4149a8169..0d343a364 100644 --- a/BossMod/Framework/WorldStateGameSync.cs +++ b/BossMod/Framework/WorldStateGameSync.cs @@ -64,6 +64,12 @@ sealed class WorldStateGameSync : IDisposable private unsafe delegate void ProcessPacketRSVDataDelegate(byte* packet); private readonly Hook _processPacketRSVDataHook; + private unsafe delegate void ProcessPacketOpenTreasureDelegate(uint actorID, byte* packet); + private readonly Hook _processPacketOpenTreasureHook; + + private unsafe delegate void* ProcessSystemLogMessageDelegate(uint entityId, uint logMessageId, int* args, byte argCount); + private readonly Hook _processSystemLogMessageHook; + public unsafe WorldStateGameSync(WorldState ws, ActionManagerEx amex) { _ws = ws; @@ -112,6 +118,14 @@ public unsafe WorldStateGameSync(WorldState ws, ActionManagerEx amex) _processPacketRSVDataHook = Service.Hook.HookFromSignature("44 8B 09 4C 8D 41 34", ProcessPacketRSVDataDetour); _processPacketRSVDataHook.Enable(); Service.Log($"[WSG] ProcessPacketRSVData address = 0x{_processPacketRSVDataHook.Address:X}"); + + _processSystemLogMessageHook = Service.Hook.HookFromSignature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 0F B6 43 28", ProcessSystemLogMessageDetour); + _processSystemLogMessageHook.Enable(); + Service.Log($"[WSG] ProcessSystemLogMessage address = 0x{_processSystemLogMessageHook:X}"); + + _processPacketOpenTreasureHook = Service.Hook.HookFromSignature("40 53 48 83 EC 20 48 8B DA 48 8D 0D ?? ?? ?? ?? 8B 52 10 E8 ?? ?? ?? ?? 48 85 C0 74 1B", ProcessPacketOpenTreasureDetour); + _processPacketOpenTreasureHook.Enable(); + Service.Log($"[WSG] ProcessPacketOpenTreasure address = 0x{_processPacketOpenTreasureHook.Address:X}"); } public void Dispose() @@ -123,6 +137,8 @@ public void Dispose() _processPacketNpcYellHook.Dispose(); _processEnvControlHook.Dispose(); _processPacketRSVDataHook.Dispose(); + _processSystemLogMessageHook.Dispose(); + _processPacketOpenTreasureHook.Dispose(); _subscriptions.Dispose(); _netConfig.Dispose(); _interceptor.Dispose(); @@ -796,4 +812,16 @@ private unsafe void ProcessPacketRSVDataDetour(byte* packet) _processPacketRSVDataHook.Original(packet); _globalOps.Add(new WorldState.OpRSVData(MemoryHelper.ReadStringNullTerminated((nint)(packet + 4)), MemoryHelper.ReadString((nint)(packet + 0x34), *(int*)packet))); } + private unsafe void ProcessPacketOpenTreasureDetour(uint actorID, byte* packet) + { + _processPacketOpenTreasureHook.Original(actorID, packet); + _actorOps.GetOrAdd(actorID).Add(new ActorState.OpEventOpenTreasure(actorID)); + } + + private unsafe void* ProcessSystemLogMessageDetour(uint entityId, uint messageId, int* args, byte argCount) + { + var res = _processSystemLogMessageHook.Original(entityId, messageId, args, argCount); + _globalOps.Add(new WorldState.OpSystemLogMessage(messageId, new Span(args, argCount).ToArray())); + return res; + } } diff --git a/BossMod/Replay/ReplayParserLog.cs b/BossMod/Replay/ReplayParserLog.cs index aac9f76c8..178741145 100644 --- a/BossMod/Replay/ReplayParserLog.cs +++ b/BossMod/Replay/ReplayParserLog.cs @@ -282,6 +282,7 @@ private ReplayParserLog(Input input, ReplayBuilder builder) [new("ZONE"u8)] = ParseZoneChange, [new("DIRU"u8)] = ParseDirectorUpdate, [new("ENVC"u8)] = ParseEnvControl, + [new("SLOG"u8)] = ParseSystemLog, [new("WAY+"u8)] = () => ParseWaymarkChange(true), [new("WAY-"u8)] = () => ParseWaymarkChange(false), [new("ACT+"u8)] = ParseActorCreate, @@ -318,6 +319,7 @@ private ReplayParserLog(Input input, ReplayBuilder builder) [new("EANM"u8)] = ParseActorEventObjectAnimation, [new("PATE"u8)] = ParseActorPlayActionTimelineEvent, [new("NYEL"u8)] = ParseActorEventNpcYell, + [new("OPNT"u8)] = ParseActorEventOpenTreasure, [new("PAR "u8)] = ParsePartyModify, [new("PAR+"u8)] = ParsePartyModify, // legacy (up to v3) [new("PAR-"u8)] = ParsePartyLeave, // legacy (up to v3) @@ -428,6 +430,15 @@ private WorldState.OpEnvControl ParseEnvControl() _input.ReadUInt(true); return new(_input.ReadByte(true), _input.ReadUInt(true)); } + private WorldState.OpSystemLogMessage ParseSystemLog() + { + var id = _input.ReadUInt(false); + var argCount = _input.ReadInt(); + var args = new int[argCount]; + for (var i = 0; i < argCount; i++) + args[i] = _input.ReadInt(); + return new(id, args); + } private WaymarkState.OpWaymarkChange ParseWaymarkChange(bool set) => new(_version < 10 ? Enum.Parse(_input.ReadString()) : (Waymark)_input.ReadByte(false), set ? _input.ReadVec3() : null); @@ -587,6 +598,7 @@ private ActorState.OpCastEvent ParseActorCastEvent() private ActorState.OpEventObjectAnimation ParseActorEventObjectAnimation() => new(_input.ReadActorID(), _input.ReadUShort(true), _input.ReadUShort(true)); private ActorState.OpPlayActionTimelineEvent ParseActorPlayActionTimelineEvent() => new(_input.ReadActorID(), _input.ReadUShort(true)); private ActorState.OpEventNpcYell ParseActorEventNpcYell() => new(_input.ReadActorID(), _input.ReadUShort(false)); + private ActorState.OpEventOpenTreasure ParseActorEventOpenTreasure() => new(_input.ReadActorID()); private PartyState.OpModify ParsePartyModify() => new(_input.ReadInt(), new(_input.ReadULong(true), _input.ReadULong(true), _version >= 15 && _input.ReadBool(), _version < 15 ? "" : _input.ReadString())); private PartyState.OpModify ParsePartyLeave() => new(_input.ReadInt(), new(0, 0, false, "")); private PartyState.OpLimitBreakChange ParsePartyLimitBreak() => new(_input.ReadInt(), _input.ReadInt()); From af99dbda378807f0ff98068529a01cb547299582 Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:36:48 -0500 Subject: [PATCH 2/2] compile error --- BossMod/Data/WorldState.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BossMod/Data/WorldState.cs b/BossMod/Data/WorldState.cs index 413bc0206..759444807 100644 --- a/BossMod/Data/WorldState.cs +++ b/BossMod/Data/WorldState.cs @@ -147,6 +147,8 @@ public sealed record class OpEnvControl(byte Index, uint State) : Operation public Event SystemLogMessage = new(); public sealed record class OpSystemLogMessage(uint MessageId, int[] Args) : Operation { + public readonly int[] Args = Args; + protected override void Exec(WorldState ws) => ws.SystemLogMessage.Fire(this); public override void Write(ReplayRecorder.Output output) {