feat: Upgrade server with HyNB v2.4 modular architecture, minigames, admin GM web panel, companion summons, and car radio

This commit is contained in:
CAtlas0784 committed 2026-10-29 02:44:24 +07:00
1 parent 74e2963a12
commit 3e5adf1dc5
1571 files changed
+336468 -6348

No files matched your search

@@ -19,14 +19,6 @@ namespace Ananta.Server.Handlers.Game;
/// </summary>
internal sealed partial class GameRouter
{
[Handler(MethodId.AskInteractCmd, HandlerPacketKind.Notify)]
private async Task AskInteractCmd(Connection conn, UxRpcMessage msg)
{
var data = msg.GetArgs<SceneMethods.InteractCmdData4229938>();
conn.Log.Info($"[GADGET] interact cmd type={data.CmdType} receiver={data.Receiver} sender={data.Sender}");
await conn.Session.NotifyAsync(MethodId.SyncInteractCmd, UxSerializer.Serialize(
new SceneMethods.SyncInteractCmd4229938 { Data = data }), CancellationToken.None);
}
[Handler(MethodId.AskInteractCmds, HandlerPacketKind.Notify)]
private async Task AskInteractCmds(Connection conn, UxRpcMessage msg)
@@ -37,74 +29,7 @@ internal sealed partial class GameRouter
new SceneMethods.SyncInteractCmds4229938 { Data = data.Data }), CancellationToken.None);
}
[Handler(MethodId.AskSceneDeviceChangeState, HandlerPacketKind.Invoke)]
private async Task AskSceneDeviceChangeState(Connection conn, UxRpcMessage msg)
{
var args = msg.GetArgs<SceneMethods.AskSceneDeviceChangeState4229938>();
conn.Log.Info($"[GADGET] change state type={args.Type} id={args.Info.Id} stateType={args.Info.StateType} state={args.Info.State} check={args.Info.StateCheckIndex}");
// Ack the requested check index so the gadget graph's condition passes, then mirror
// the new state back — the client applies it on the Sync, not on the invoke return.
await conn.ReturnAsync(msg, new SceneMethods.SceneDeviceCheckIndexCallback4229938
{
CheckIndex = args.Info.StateCheckIndex,
Error = 0,
});
await conn.Session.NotifyAsync(MethodId.SyncSceneDeviceStateChange, UxSerializer.Serialize(
new SceneMethods.SyncSceneDeviceStateChange4229938
{
Type = args.Type,
Id = args.Info.Id,
StateType = args.Info.StateType,
State = args.Info.State,
StateCheckIndex = args.Info.StateCheckIndex,
}), CancellationToken.None);
}
[Handler(MethodId.AskSceneDeviceRecordValue, HandlerPacketKind.Invoke)]
private async Task AskSceneDeviceRecordValue(Connection conn, UxRpcMessage msg)
{
var args = msg.GetArgs<SceneMethods.AskSceneDeviceRecordValue4229938>();
conn.Log.Info($"[GADGET] record value type={args.Type} id={args.Info.Id} name={args.Info.ValueName} value='{args.Info.Value}' check={args.Info.ValueCheckIndex}");
await conn.ReturnAsync(msg, new SceneMethods.SceneDeviceCheckIndexCallback4229938
{
CheckIndex = args.Info.ValueCheckIndex,
Error = 0,
});
// Mirror the recorded value so the device graph sees the new value on Sync.
await conn.Session.NotifyAsync(MethodId.SyncSceneDeviceValueChange, UxSerializer.Serialize(
new SceneMethods.SyncSceneDeviceValueChange4229938
{
Type = args.Type,
Id = args.Info.Id,
ValueName = args.Info.ValueName,
Value = args.Info.Value,
ValueCheckIndex = args.Info.ValueCheckIndex,
}), CancellationToken.None);
await conn.Session.NotifyAsync(MethodId.SyncSceneDeviceValueChange, UxSerializer.Serialize(
new SceneMethods.SyncSceneDeviceValueChange4229938
{
Type = args.Type,
Id = args.Info.Id,
ValueName = args.Info.ValueName,
Value = args.Info.Value,
ValueCheckIndex = args.Info.ValueCheckIndex,
}), CancellationToken.None);
}
[Handler(MethodId.AskSceneDeviceSendSignal, HandlerPacketKind.Invoke)]
private async Task AskSceneDeviceSendSignal(Connection conn, UxRpcMessage msg)
{
var args = msg.GetArgs<SceneMethods.AskSceneDeviceSendSignal4229938>();
conn.Log.Info($"[GADGET] send signal type={args.Type} id={args.Id} signal='{args.SignalName}'");
await conn.ReturnEmptyOkAsync(msg);
await conn.Session.NotifyAsync(MethodId.SyncSceneDeviceSignalSend, UxSerializer.Serialize(
new SceneMethods.SyncSceneDeviceSignalSend4229938
{
Type = args.Type,
Id = args.Id,
SignalName = args.SignalName,
}), CancellationToken.None);
}
// Handled in GameRouter.SceneDevices.cs (with loop protection and config toggles)
// ------------------------------------------------------------------
// NPC dialog (F on an NPC): the client resolves the dialog id from its own