Files
Ananta-ps/Ananta.Server/Ananta.Handlers/Game/GameRouter.GmFog.cs
T

120 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}