AquaDX/AquaMai.Core/Helpers/NetPacketHook.cs
2025-02-21 21:51:08 +08:00

76 lines
3.0 KiB
C#

using System;
using System.Text;
using Net;
using Net.Packet;
using MelonLoader;
using MelonLoader.TinyJSON;
using HarmonyLib;
using System.IO;
namespace AquaMai.Core.Helpers;
public class NetPacketHook
{
// Returns true if the packet was modified
public delegate Variant NetPacketCompleteHook(string api, Variant request, Variant response);
public static event NetPacketCompleteHook OnNetPacketComplete;
[HarmonyPrefix]
[HarmonyPatch(typeof(Packet), "ProcImpl")]
public static void PreProcImpl(Packet __instance)
{
try
{
if (
__instance.State == PacketState.Process &&
Traverse.Create(__instance).Field("Client").GetValue() is NetHttpClient client &&
client.State == NetHttpClient.StateDone)
{
var netQuery = __instance.Query;
var api = Shim.RemoveApiSuffix(netQuery.Api);
var responseBytes = client.GetResponse().ToArray();
var decryptedResponse = Shim.NetHttpClientDecryptsResponse ? responseBytes : Shim.DecryptNetPacketBody(responseBytes);
var decodedResponse = Encoding.UTF8.GetString(decryptedResponse);
var responseJson = JSON.Load(decodedResponse);
var requestJson = JSON.Load(netQuery.GetRequest());
var modified = false;
foreach (var handler in OnNetPacketComplete?.GetInvocationList())
{
try
{
if (handler.DynamicInvoke(api, requestJson, responseJson) is Variant result)
{
responseJson = result;
modified = true;
}
}
catch (Exception e)
{
MelonLogger.Error($"[NetPacketExtension] Error in handler: {e}");
}
}
if (
modified &&
Traverse.Create(client).Field("_memoryStream").GetValue() is MemoryStream memoryStream &&
!JsonHelper.DeepEqual(responseJson, JSON.Load(decodedResponse)))
{
var modifiedResponse = Encoding.UTF8.GetBytes(responseJson.ToJSON());
if (!Shim.NetHttpClientDecryptsResponse)
{
modifiedResponse = Shim.EncryptNetPacketBody(modifiedResponse);
}
memoryStream.SetLength(0);
memoryStream.Write(modifiedResponse, 0, modifiedResponse.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
MelonLogger.Msg($"[NetPacketExtension] Modified response for {api} ({decryptedResponse.Length} bytes -> {modifiedResponse.Length} bytes)");
}
}
}
catch (Exception e)
{
MelonLogger.Error($"[NetPacketExtension] Failed to process NetPacket: {e}");
}
}
}