Files

86 lines
3.5 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.
namespace Ananta.Server.Protocol.Client4229938;
/// <summary>
/// GM 控制台(ALT+F1)下发过的一条职业记录。
///
/// 服务端不持有职业表(职业/等级全在客户端配置里),所以一条职业只在某个 <c>GmJob*</c> 命令
/// 点名它的 jobClassId 之后才存在;这份记录既是命令自身返回值的来源,也是
/// <c>SyncSpiritJobInfo</c> 推送的来源。
/// </summary>
internal sealed class GmJobRecord4229938
{
internal uint JobClassId { get; init; }
internal byte Level { get; set; } = 1;
/// <summary>最后一条到达的职业命令(只用于日志与面板展示)。</summary>
internal GmJobAction4229938 Action { get; set; }
internal DateTime UpdatedUtc { get; set; } = DateTime.UtcNow;
}
/// <summary>
/// 六种 <c>GmJob*</c> 命令。这是服务端自己的记账枚举,<b>不进 wire</b>(wire 上只有 jobClassId /
/// level 两个标量),所以底层类型怎么写都不影响协议。
/// </summary>
internal enum GmJobAction4229938 : byte
{
Take,
Start,
Quit,
Promote,
SetLevel,
End,
}
/// <summary>
/// 一个会话上 GM 职业命令的全部效果。
///
/// 移植自捐赠端 DremkaPS 的 <c>GmTaskState4229938</c>,<b>但只取其中的职业(job)部分</b>:
/// 捐赠端那一份还带着任务 / 事件 / 对话框 / NPC 行为项四组状态,而本服
/// <c>GameRouter.Tasks.cs</c> 已经四次证明任务面板在 4229938 下渲染不出来
/// (<c>TaskPublishEnabled = false</c>),搬那四组只会得到一堆写进去没人读的状态。
/// </summary>
internal sealed class GmJobState4229938
{
/// <summary>
/// 自带锁而不是复用 <c>WorldEntryState.SyncRoot</c>:面板端点跑在 HTTP 线程上,会话被切走或
/// 拆掉之后仍可能摸到这个对象;而且只有 GmJobs 这一条路径会碰它。
/// </summary>
internal object SyncRoot { get; } = new();
/// <summary>jobClassId → 记录。空表示还没收到过任何职业命令。</summary>
internal Dictionary<uint, GmJobRecord4229938> Jobs { get; } = [];
/// <summary>
/// 客户端当前所处的职业。
///
/// ⛑⛑ 默认必须是 <see cref="RuntimePayloadFactory.JoblessUrbanJob4229938"/>(100,Jobless)
/// 而不是 0 —— 0 不是合法的 <c>UrbanJobConfig</c> id,一旦带着职业记录发出去,客户端
/// <c>SpiritJobManager</c> 会去解引用一个不存在的配置。捐赠端这里默认 0、quit/end 之后也回落 0,
/// 那是它的一个坑,<b>本服不照搬</b>。
/// </summary>
internal uint CurrentJob { get; set; } = RuntimePayloadFactory.JoblessUrbanJob4229938;
/// <summary>
/// 是否有过至少一条 <c>GmJob*</c> 命令。用来区分「GM 没动过职业,照旧用配置驱动的那份」
/// 与「GM 动过了,以控制台为准」—— 没有这个标志的话,一次无关命令就会把角色原本的职业顶掉。
/// </summary>
internal bool HasGmOverride { get; set; }
/// <summary>取一条记录,没有就按给定等级建一条。</summary>
internal GmJobRecord4229938 Ensure(uint jobClassId, byte level)
{
if (Jobs.TryGetValue(jobClassId, out var existing))
return existing;
var record = new GmJobRecord4229938
{
JobClassId = jobClassId,
Level = Math.Max((byte)1, level),
};
Jobs[jobClassId] = record;
return record;
}
}