Files
2026-07-10 10:24:29 +08:00

82 lines
2.8 KiB
C#
Raw Permalink 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;
using System.Collections.Generic;
using XWorld.Framework;
namespace XWorld.Server.Host
{
public sealed class Room
{
public string RoomId { get; }
public bool IsActive { get; private set; }
public bool FaultedOut { get; private set; }
private readonly IGameServerRoom _logic;
private readonly ManualClock _clock;
private readonly RoomCtx _ctx;
private readonly ILogger _logger;
private bool _endRequested;
public Room(string roomId, IGameServerRoom logic, ManualClock clock, RoomCtx ctx, ILogger logger)
{
RoomId = roomId; _logic = logic; _clock = clock; _ctx = ctx; _logger = logger;
}
public RoomEndResult EndResult { get; private set; }
// 对外发布用的结算结果:故障房间的 EndResult 不可信(可能是故障前残留),按无结果处理
public RoomEndResult TrustedEndResult => FaultedOut ? null : EndResult;
// 由 RoomCtx.EndRoom 回调(或宿主)触发;下一次 tick 末尾或 Start 后据此结束。
// 多次调用以最后一次的 result 为准。
// publicRoomHost 与测试在装配 RoomCtx 的 endRoom 回调时需引用它(跨程序集)。
public void RequestEnd() => RequestEnd(null);
public void RequestEnd(RoomEndResult result) { _endRequested = true; EndResult = result; }
public void Start(IReadOnlyList<PlayerInfo> players)
{
try
{
_logic.OnRoomStart(players, _ctx);
IsActive = true;
if (_endRequested) End(); // 允许在 OnRoomStart 内即请求结束
}
catch (Exception ex)
{
Fault("OnRoomStart", ex);
}
}
public void Deliver(int playerId, NetMessage message)
{
if (!IsActive) return;
try { _logic.OnMessage(playerId, message); }
catch (Exception ex) { Fault("OnMessage", ex); }
}
public void Tick(float dt)
{
if (!IsActive) return;
_clock.Advance(dt);
try { _logic.OnTick(dt); }
catch (Exception ex) { Fault("OnTick", ex); return; }
if (_endRequested) End();
}
public void End()
{
if (!IsActive) return;
IsActive = false;
try { _logic.OnRoomEnd(); }
catch (Exception ex) { _logger.Error($"room {RoomId} OnRoomEnd 抛异常: {ex.Message}"); }
}
private void Fault(string where, Exception ex)
{
FaultedOut = true;
_logger.Error($"room {RoomId} 在 {where} 故障: {ex}");
IsActive = false;
try { _logic.OnRoomEnd(); } catch { /* 异常路径,吞掉二次异常 */ }
}
}
}