Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge vbm #529

Merged
merged 4 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions BossMod/Data/ActorState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,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<Actor> 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);
}
}
}
15 changes: 15 additions & 0 deletions BossMod/Data/WorldState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,19 @@ 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<OpSystemLogMessage> 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)
{
output.EmitFourCC("SLOG"u8).Emit(MessageId);
output.Emit(Args.Length);
foreach (var arg in Args)
output.Emit(arg);
}
}
}
28 changes: 28 additions & 0 deletions BossMod/Framework/WorldStateGameSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ sealed class WorldStateGameSync : IDisposable
private unsafe delegate void ProcessPacketRSVDataDelegate(byte* packet);
private readonly Hook<ProcessPacketRSVDataDelegate> _processPacketRSVDataHook;

private unsafe delegate void ProcessPacketOpenTreasureDelegate(uint actorID, byte* packet);
private readonly Hook<ProcessPacketOpenTreasureDelegate> _processPacketOpenTreasureHook;

private unsafe delegate void* ProcessSystemLogMessageDelegate(uint entityId, uint logMessageId, int* args, byte argCount);
private readonly Hook<ProcessSystemLogMessageDelegate> _processSystemLogMessageHook;

public unsafe WorldStateGameSync(WorldState ws, ActionManagerEx amex)
{
_ws = ws;
Expand Down Expand Up @@ -113,6 +119,14 @@ public unsafe WorldStateGameSync(WorldState ws, ActionManagerEx amex)
_processPacketRSVDataHook = Service.Hook.HookFromSignature<ProcessPacketRSVDataDelegate>("44 8B 09 4C 8D 41 34", ProcessPacketRSVDataDetour);
_processPacketRSVDataHook.Enable();
Service.Log($"[WSG] ProcessPacketRSVData address = 0x{_processPacketRSVDataHook.Address:X}");

_processSystemLogMessageHook = Service.Hook.HookFromSignature<ProcessSystemLogMessageDelegate>("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 0F B6 43 28", ProcessSystemLogMessageDetour);
_processSystemLogMessageHook.Enable();
Service.Log($"[WSG] ProcessSystemLogMessage address = 0x{_processSystemLogMessageHook:X}");

_processPacketOpenTreasureHook = Service.Hook.HookFromSignature<ProcessPacketOpenTreasureDelegate>("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()
Expand All @@ -124,6 +138,8 @@ public void Dispose()
_processPacketNpcYellHook.Dispose();
_processEnvControlHook.Dispose();
_processPacketRSVDataHook.Dispose();
_processSystemLogMessageHook.Dispose();
_processPacketOpenTreasureHook.Dispose();
_subscriptions.Dispose();
_netConfig.Dispose();
_interceptor.Dispose();
Expand Down Expand Up @@ -797,4 +813,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<int>(args, argCount).ToArray()));
return res;
}
}
12 changes: 12 additions & 0 deletions BossMod/Replay/ReplayParserLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,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,
Expand Down Expand Up @@ -384,6 +385,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)
Expand Down Expand Up @@ -526,6 +528,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<Waymark>(_input.ReadString()) : (Waymark)_input.ReadByte(false), set ? _input.ReadVec3() : null);
Expand Down Expand Up @@ -685,6 +696,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());
Expand Down