feat: Upgrade server with HyNB v2.4 modular architecture, minigames, admin GM web panel, companion summons, and car radio
This commit is contained in:
1 parent
74e2963a12
commit
3e5adf1dc5
1571 files changed
+336468
-6348
No files matched your search
@@ -8,17 +8,12 @@ namespace Ananta.Server.Handlers.Game;
|
||||
|
||||
/// <summary>
|
||||
/// Time + weather. The client runs its clock/atmosphere locally; these handlers make
|
||||
/// the in-game time UI work (accept + remember) and the debug panel can force it:
|
||||
/// time via SyncPlayerCurrentTime (proto-verified shape). Stored per session,
|
||||
/// re-pushed after every load.
|
||||
/// the in-game time UI work (accept + remember) and the admin panel can force both:
|
||||
/// time via SyncPlayerCurrentTime (proto-verified shape), weather via SyncPlayerWeather
|
||||
/// (lua-reader-verified: 3× u32). Stored per session, re-pushed after every load.
|
||||
/// </summary>
|
||||
internal sealed partial class GameRouter
|
||||
{
|
||||
internal static WorldEntryState? GetStateIfExists(TcpSession session)
|
||||
=> session.Items.TryGetValue(WorldStateKey, out var raw) && raw is WorldEntryState existing
|
||||
? existing
|
||||
: null;
|
||||
|
||||
private static void SetSessionTime(WorldEntryState state, uint hour, uint minute, bool fix, uint transition)
|
||||
{
|
||||
lock (state.SyncRoot)
|
||||
@@ -28,6 +23,8 @@ internal sealed partial class GameRouter
|
||||
state.TimeFixed = fix;
|
||||
state.TimeTransitionSeconds = transition;
|
||||
state.HasExplicitTime = true;
|
||||
// ★ 玩家(或 GM/面板)主动推了一把时间 —— 记一次,供「赖在原地的角色该去过日子了」判据用。
|
||||
state.TimeEpoch++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +126,11 @@ internal sealed partial class GameRouter
|
||||
if (args.clear)
|
||||
{
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
state.HasExplicitTime = false;
|
||||
// 「解除固定」同样是玩家主动改时间(回到实时),也要记一次。
|
||||
state.TimeEpoch++;
|
||||
}
|
||||
conn.Log.Info("[TIME] GmFixRaidTime clear");
|
||||
}
|
||||
else
|
||||
@@ -142,115 +143,19 @@ internal sealed partial class GameRouter
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskTimePanelInfo)]
|
||||
private async Task AskTimePanelInfo(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
var state = GetWorldState(msg.Context);
|
||||
GameMethods.TimePanelInfo4229938 response;
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
response = new GameMethods.TimePanelInfo4229938
|
||||
{
|
||||
PersonalTimeSettings = new List<GameMethods.PersonalTimeSetting4229938>(state.PersonalTimeSettings)
|
||||
};
|
||||
}
|
||||
conn.Log.Info($"[TIME] AskTimePanelInfo: returning {response.PersonalTimeSettings.Count} personal time slots");
|
||||
await conn.ReturnAsync(msg, response);
|
||||
}
|
||||
|
||||
[Handler(MethodId.ChangePersonalTimeSetting)]
|
||||
private async Task ChangePersonalTimeSetting(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
if (msg.TryGetArgs<GameMethods.ChangePersonalTimeSettingArgs4229938>(out var args) && args is not null)
|
||||
{
|
||||
var state = GetWorldState(msg.Context);
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
if (args.info is null)
|
||||
{
|
||||
if (args.index >= 0 && args.index < state.PersonalTimeSettings.Count)
|
||||
{
|
||||
state.PersonalTimeSettings.RemoveAt(args.index);
|
||||
conn.Log.Info($"[TIME] personal delete slot={args.index}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args.index >= 0 && args.index < state.PersonalTimeSettings.Count)
|
||||
{
|
||||
state.PersonalTimeSettings[args.index] = args.info;
|
||||
conn.Log.Info($"[TIME] personal update slot={args.index} label={args.info.Label} {args.info.Hour:D2}:{args.info.Minute:D2}");
|
||||
}
|
||||
else
|
||||
{
|
||||
state.PersonalTimeSettings.Add(args.info);
|
||||
conn.Log.Info($"[TIME] personal append slot={args.index} label={args.info.Label} {args.info.Hour:D2}:{args.info.Minute:D2}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
conn.Log.Info($"[TIME] personal slot={args.index} label={args.info?.Label} {args.info?.Hour:D2}:{args.info?.Minute:D2}");
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AddPersonalTimeSetting)]
|
||||
private async Task AddPersonalTimeSetting(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
if (msg.TryGetArgs<GameMethods.AddPersonalTimeSettingArgs4229938>(out var args) && args?.info is not null)
|
||||
{
|
||||
var state = GetWorldState(msg.Context);
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
state.PersonalTimeSettings.Add(args.info);
|
||||
}
|
||||
conn.Log.Info($"[TIME] personal add label={args.info.Label} {args.info.Hour:D2}:{args.info.Minute:D2}");
|
||||
}
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskSetMobileSkinPart)]
|
||||
private async Task AskSetMobileSkinPart(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
if (msg.TryGetArgs<GameMethods.AskSetMobileSkinPartArgs4229938>(out var args) && args is not null)
|
||||
{
|
||||
var state = GetWorldState(msg.Context);
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
state.MobileWallpaperId = args.wallpaper;
|
||||
state.MobileDecorationId = args.decoration;
|
||||
state.MobilePendantId = args.pendant;
|
||||
}
|
||||
conn.Log.Info($"[PHONE] AskSetMobileSkinPart wallpaper={args.wallpaper} decoration={args.decoration} pendant={args.pendant}");
|
||||
}
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskResetMobileSkinPart)]
|
||||
private async Task AskResetMobileSkinPart(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
var state = GetWorldState(msg.Context);
|
||||
lock (state.SyncRoot)
|
||||
{
|
||||
state.MobileWallpaperId = 0;
|
||||
state.MobileDecorationId = 0;
|
||||
state.MobilePendantId = 0;
|
||||
}
|
||||
conn.Log.Info("[PHONE] AskResetMobileSkinPart reset to defaults");
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskInstallMobileApp)]
|
||||
private async Task AskInstallMobileApp(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
if (msg.TryGetArgs<GameMethods.AskInstallMobileAppArgs4229938>(out var args) && args is not null)
|
||||
conn.Log.Info($"[PHONE] AskInstallMobileApp appId={args.appId}");
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskCancelInteractionActionRedPoint)]
|
||||
private async Task AskCancelInteractionActionRedPoint(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
if (msg.TryGetArgs<GameMethods.AskCancelInteractionActionRedPointArgs4229938>(out var args) && args is not null)
|
||||
conn.Log.Info($"[ACTION] AskCancelInteractionActionRedPoint actionId={args.actionId}");
|
||||
if (msg.TryGetArgs<GameMethods.ChangePersonalTimeSettingArgs4229938>(out var args) && args is not null)
|
||||
conn.Log.Info($"[TIME] personal add slot={args.index} label={args.info?.Label}");
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user