120 lines
4.9 KiB
C#
120 lines
4.9 KiB
C#
using System.Buffers.Binary;
|
||
using Ananta.SDK.Rpc;
|
||
using Ananta.Server.Protocol.Client4229938;
|
||
using GameMethods = Ananta.Server.RpcTypes.Client4229938.Methods.Game;
|
||
using SceneMethods = Ananta.Server.RpcTypes.Client4229938.Methods.GameScene;
|
||
|
||
namespace Ananta.Server.Handlers.Game;
|
||
|
||
/// <summary>
|
||
/// 迷雾 / 探索 POI / Aether 氛围层 —— <c>SyncEnterFogMapPoiId</c>(63491307)、
|
||
/// <c>GmUnlockAllFogMap</c>(65914419)、<c>GmSetAmbianceEnabled</c>(69166506)、
|
||
/// <c>GmGetAmbianceEnabled</c>(69384152)。
|
||
///
|
||
/// 移植自捐赠端 DremkaPS(2026-09-24)。
|
||
///
|
||
/// ★★ 这一组是<b>抓包筛出来的</b>,不是照单全收。捐赠端比本服多的 handler 一共有 66 个,
|
||
/// 拿 16.5 万行 <c>unknown-methods.log</c> 逐个数下来,<b>只有 6 个真的被客户端发过</b>:
|
||
/// <c>SyncEnterFogMapPoiId</c> 49 次(活跃到 09-23)、<c>GmUnlockAllFogMap</c> 5 次、
|
||
/// <c>ForceSubmitTask</c> 5 次、<c>GmSwitchSpiritHere</c> 3 次、<c>GmSubmitEvent</c> 2 次、
|
||
/// <c>GmGetAmbianceEnabled</c> 2 次。剩下 <b>60 个零次</b>,注册它们只是增加维护面 —— 已剔除。
|
||
///
|
||
/// 剔除的三条(虽然日志里出现过):
|
||
/// · <c>ForceSubmitTask</c> / <c>GmSubmitEvent</c> —— 任务族。本服
|
||
/// <c>GameRouter.Tasks.cs</c> 已经四次证明任务面板在 4229938 下渲染不出来
|
||
/// (<c>TaskPublishEnabled = false</c>),捐赠端自己也只拿它们记账,搬过来是死代码。
|
||
/// · <c>GmSwitchSpiritHere</c> —— 切角色。本服已有 <c>AskSwitchSpirit</c> 这条正规路径,
|
||
/// GM 版只是控制台的快捷方式,09-16 之后再没被用过。
|
||
///
|
||
/// ⛑ <c>GmGetAmbianceEnabled</c> 是 <b>0 字节的 INVOKE</b>:客户端在 await 一个返回值。
|
||
/// 不接它,控制台按下去会一直卡到超时(规则 94)。这里回一个 bool。
|
||
/// </summary>
|
||
internal sealed partial class GameRouter
|
||
{
|
||
[Handler(MethodId.SyncEnterFogMapPoiId, HandlerPacketKind.Notify)]
|
||
private Task EnterFogMapPoiId(Connection conn, UxRpcMessage msg)
|
||
{
|
||
var poiId = msg.TryGetArgs<GameMethods.SyncEnterFogMapPoiId4229938>(out var args) && args is not null
|
||
? args.PoiId
|
||
: (msg.Body.Length >= 4 ? BinaryPrimitives.ReadUInt32LittleEndian(msg.Body) : 0u);
|
||
|
||
if (poiId == 0)
|
||
{
|
||
conn.Log.Warn($"[FOG] enter-poi without an id bytes={msg.Body.Length}");
|
||
return Task.CompletedTask;
|
||
}
|
||
|
||
var state = GetWorldState(msg.Context);
|
||
bool fresh;
|
||
int total;
|
||
lock (state.SyncRoot)
|
||
{
|
||
fresh = state.FogMapPoiIds.Add(poiId);
|
||
total = state.FogMapPoiIds.Count;
|
||
}
|
||
|
||
// 同一个 POI 玩家会反复踏入(抓包里 49 条几乎全是 id=11),所以只在新增时记 Info。
|
||
if (fresh)
|
||
conn.Log.Info($"[FOG] enter-poi id={poiId} total={total}");
|
||
return Task.CompletedTask;
|
||
}
|
||
|
||
[Handler(MethodId.GmUnlockAllFogMap, HandlerPacketKind.Invoke)]
|
||
private async Task GmUnlockAllFogMap(Connection conn, UxRpcMessage msg)
|
||
{
|
||
var unlock = msg.TryGetArgs<GameMethods.GmUnlockAllFogMap4229938>(out var args) && args is not null
|
||
? args.Unlock
|
||
: (msg.Body.Length > 0 && msg.Body[0] != 0);
|
||
|
||
var state = GetWorldState(msg.Context);
|
||
lock (state.SyncRoot)
|
||
state.FogMapAllUnlocked = unlock;
|
||
|
||
conn.Log.Info($"[FOG] gm-unlock-all unlock={unlock} poi={state.FogMapPoiIds.Count} "
|
||
+ $"raid={state.ActiveRaidId} (recorded: pushing SyncSceneFogMapAllUnlock needs the current sceneId, not wired yet)");
|
||
|
||
await conn.ReturnEmptyOkAsync(msg);
|
||
}
|
||
|
||
[Handler(MethodId.GmSetAmbianceEnabled, HandlerPacketKind.Invoke)]
|
||
private async Task GmSetAmbianceEnabled(Connection conn, UxRpcMessage msg)
|
||
{
|
||
bool enabled;
|
||
int type = 0;
|
||
if (msg.TryGetArgs<SceneMethods.GmSetAmbianceEnabled>(out var args) && args is not null)
|
||
{
|
||
enabled = args.Enabled;
|
||
type = args.Type;
|
||
}
|
||
else
|
||
{
|
||
enabled = msg.Body.Length > 0 && msg.Body[0] != 0;
|
||
}
|
||
|
||
var state = GetWorldState(msg.Context);
|
||
lock (state.SyncRoot)
|
||
{
|
||
state.AmbianceEnabled = enabled;
|
||
state.AmbianceType = type;
|
||
}
|
||
|
||
conn.Log.Info($"[GM] ambiance set enabled={enabled} type={type}");
|
||
await conn.ReturnEmptyOkAsync(msg);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 0 字节 INVOKE —— 必须回一个 bool,否则客户端这次调用会 await 到超时。
|
||
/// </summary>
|
||
[Handler(MethodId.GmGetAmbianceEnabled, HandlerPacketKind.Invoke)]
|
||
private Task GmGetAmbianceEnabled(Connection conn, UxRpcMessage msg)
|
||
{
|
||
var state = GetWorldState(msg.Context);
|
||
bool enabled;
|
||
lock (state.SyncRoot)
|
||
enabled = state.AmbianceEnabled;
|
||
|
||
conn.Log.Info($"[GM] ambiance query -> {enabled}");
|
||
return conn.ReturnAsync(msg, enabled);
|
||
}
|
||
}
|