# ShrinkNetwork.ServerHost

这是由 `ShrinkNetwork` 插件生成的独立服务器基础模板。

默认提供：
- 可编译、可启动的宿主入口
- TCP / KCP 双传输监听
- 类似 Minecraft 的 `server.properties` 文本配置
- Unity 项目扫描后的 `Generated/*` 自动装配
- 基础鉴权、会话令牌、协议版本闸门与周期性指标摘要

## 模板结构

- `Program.cs`
  宿主入口，负责加载 `server.properties`、启动模块、打印配置摘要和输出指标。
- `Framework/`
  宿主框架层，包括配置、鉴权状态存储与应用启动器。
- `AuthServerModule.cs`
  内置鉴权模块，提供 `server/auth/login` 与 `server/auth/refresh`。
- `TcpServerTransport.cs`
  TCP 传输层，可选 TLS。
- `KcpServerTransport.cs`
  KCP 传输层。
- `Generated/`
  Unity 扫描后产出的项目专属合约、副本、处理器与模块入口。

## 生成后你要关注的文件

- `Generated/UnityGeneratedNetworkContracts.g.cs`
  当前 Unity 项目扫描得到的消息合约副本。
- `Generated/UnityGeneratedServerHandlers.g.cs`
  自动生成的处理器骨架。
- `Generated/UnityGeneratedServerModule.g.cs`
  自动加载的项目专属服务器模块。

说明：
- `UnityGeneratedServerModule.g.cs` 是项目级生成物，不是通用插件内置玩法模块。
- 如果你有正式业务逻辑，建议把自动生成骨架整理成你自己的正式模块文件。

## 鉴权

## 配置文件

- 默认配置文件名：`server.properties`
- 默认位置：`GeneratedServers/ShrinkNetwork.ServerHost/server.properties`
- 首次启动如果文件不存在，宿主会自动生成一份默认配置。
- 优先级：代码默认值 < `server.properties` < 环境变量
- 可通过环境变量 `SHRINK_SERVER_CONFIG_PATH` 指向自定义配置文件路径。

常用键：
- `server-port`
- `shared-auth-token`
- `enable-session-tokens`
- `session-token-ttl-seconds`
- `session-token-refresh-window-seconds`
- `enable-unity-code-scan`
- `unity-assets-path`
- `scan-output-directory`
- `enable-tcp-tls`
- `tcp-tls-certificate-path`

环境变量：
- `SHRINK_SERVER_AUTH_TOKEN`

行为：
- 默认情况下，如果未设置 `SHRINK_SERVER_AUTH_TOKEN`，`server/auth/login` 会直接拒绝，避免把匿名放行作为线上默认值。
- 如果你明确要跑内网演示，可在 `ServerHostOptions.AllowAnonymousWhenAuthTokenMissing = true` 后再允许匿名登录。
- 设置口令后，客户端应先完成登录，再进入后续项目逻辑。

## 会话令牌

默认行为：
- `server/auth/login` 成功后，宿主会签发一个内存态会话令牌，并把它放进响应包头与响应体。
- 已登录会话的后续消息 / RPC 必须携带当前会话令牌，否则会被宿主拒绝；默认还会直接断开该会话。
- 客户端可通过 `server/auth/refresh` 在续期窗口内轮换新令牌，避免长连接在固定 TTL 后硬过期。

关键配置：
- `ServerHostOptions.EnableSessionTokens`
- `ServerHostOptions.SessionTokenTtlSeconds`
- `ServerHostOptions.SessionTokenRefreshWindowSeconds`
- `ServerHostOptions.DisconnectOnInvalidSessionToken`

对应环境变量：
- `SHRINK_SERVER_ENABLE_SESSION_TOKENS`
- `SHRINK_SERVER_SESSION_TOKEN_TTL_SECONDS`
- `SHRINK_SERVER_SESSION_TOKEN_REFRESH_WINDOW_SECONDS`
- `SHRINK_SERVER_DISCONNECT_ON_INVALID_SESSION_TOKEN`

当前范围：
- 已覆盖“登录签发 / 包头自动携带 / 服务端逐包校验 / 显式刷新”
- 还没有接入外部身份源、分布式会话存储、多实例共享撤销表

## 协议兼容与指标

- 模板宿主默认只接受当前 `ShrinkNetworkProtocol.CurrentProtocolVersion / CurrentSchemaVersion`。
- 可通过 `ServerHostOptions.MinProtocolVersion / MaxProtocolVersion / MinSchemaVersion / MaxSchemaVersion` 调整兼容窗口。
- 检测到协议版本越界时，默认直接断开会话。
- 宿主默认每 `60` 秒输出一次基础指标摘要，也会在 `Ctrl+C` 退出前打印最后一份快照。
- 指标摘要现已包含 `authRejected`，可直接看到会话令牌校验失败次数。

## TCP TLS

- 如果设置了 `SHRINK_SERVER_TLS_CERT_PATH`，宿主会自动为 TCP 监听启用 TLS。
- 可选环境变量：
  - `SHRINK_SERVER_TLS_CERT_PASSWORD`
  - `SHRINK_SERVER_TLS_TARGET_HOST`
- 当前只覆盖“服务端证书 + 客户端校验”主链，还没有扩展到双向证书认证。

## 运行方式

在仓库根目录执行：

```powershell
dotnet run --project .\GeneratedServers\ShrinkNetwork.ServerHost\ShrinkNetwork.ServerHost.csproj
```

如果只想改文本配置，不想改环境变量，直接编辑：

```powershell
notepad .\GeneratedServers\ShrinkNetwork.ServerHost\server.properties
```

如果要启用共享口令鉴权：

```powershell
$env:SHRINK_SERVER_AUTH_TOKEN = "your-token"
dotnet run --project .\GeneratedServers\ShrinkNetwork.ServerHost\ShrinkNetwork.ServerHost.csproj
```

如果要直接跑运行时烟测：

```powershell
$env:SHRINK_SERVER_AUTH_TOKEN = "smoke-token"
$env:SHRINK_SERVER_SESSION_TOKEN_TTL_SECONDS = "120"
$env:SHRINK_SERVER_SESSION_TOKEN_REFRESH_WINDOW_SECONDS = "120"
dotnet run --project .\GeneratedServers\ShrinkNetwork.ServerHost\ShrinkNetwork.ServerHost.csproj
```

另开一个终端执行：

```powershell
dotnet run --project .\GeneratedServers\ShrinkNetwork.RuntimeSmoke\ShrinkNetwork.RuntimeSmoke.csproj -- 127.0.0.1 17777 smoke-token runtime-smoke
```
