从新版 noname_new/noname/packages/server 中抽离的多人联机房间服务器,仅保留 WebSocket 房间大厅功能,无冗余的游戏资源文件。
| 文件 | 作用 |
|---|---|
src/index.ts |
房间服务器主逻辑 — WebSocket 服务端,处理房间创建/加入/配置、心跳检测、活动事件、封禁管理等全部功能 |
package.json |
Node.js 依赖声明 — 声明 ws 运行时依赖及 tsx/tsup 等开发工具,运行 npm install 后即可启动 |
deno.json |
Deno 运行时配置 — 映射 ws 到 npm:ws,提供 deno task start 入口,兼容 Deno 用户 |
tsconfig.json |
TypeScript 编译配置 — 供编辑器/tsx 使用,不作实际编译 |
| 文件 | 作用 |
|---|---|
tsup.config.ts |
tsup 构建配置,将 TypeScript 编译为 JS 产物 |
build.ts |
将服务器编译为独立可执行文件(与 noname-server.exe 类似) |
# 安装依赖
npm install
# 运行房间服务器(端口 8082)
npx tsx src/index.ts
# 或设置自定义端口
PORT=8082 npx tsx src/index.tsdeno task start
# 等价于: deno run --allow-net --allow-env --allow-read src/index.tsnpm run build:win # Windows
npm run build:mac # macOS
npm run build:linux # Linux房间服务器监听端口 8082,通信协议为 JSON 数组格式。
所有消息格式:["server", "命令", ...参数]
| 命令 | 参数 | 说明 |
|---|---|---|
key |
[onlineKey] |
身份认证 — 连接后 2 秒内必须发送,否则断开 |
create |
key, nickname, avatar, config, mode |
创建房间 — key 需与 onlineKey 一致 |
enter |
key, nickname, avatar |
加入房间 — 以观战/玩家身份进入已有房间 |
config |
config |
更新房间配置 — 仅房主可调用,参数为游戏配置对象 |
send |
targetId, message |
转发消息 — 房主向指定从属客户端发送消息 |
close |
slaveId |
踢出玩家 — 房主断开指定从属客户端 |
changeAvatar |
nickname, avatar |
更新信息 — 修改昵称/头像 |
status |
str |
更新状态 — 设置状态文本(大厅可见) |
events |
cfg, id, type |
活动管理 — 创建/加入/离开定时活动 |
heartbeat |
(无,纯文本) | 心跳 — 纯字符串 "heartbeat" |
认证 (key)
["server", "key", ["abc12345"]]
onlineKey是浏览器端lib.db.onlineKey生成的值- 超时 2 秒未认证或认证失败会被断开
创建房间 (create)
["server", "create", "abc12345", "玩家名", "caocao", { mode: "standard", ... }, "identity"]
key必须与onlineKey一致config为游戏模式配置对象
加入房间 (enter)
["server", "enter", "roomKey", "玩家名", "caocao"]
roomKey为目标房间的 key- 如果房间已开始游戏且未开启观战,则加入失败
更新配置 (config)
["server", "config", { mode: "standard", gameStarted: true, ... }]
- 仅房主可调用
servermode在首次配置时会自动设为false
转发消息 (send)
["server", "send", "targetWsid", "{\"type\":\"chat\",...}"]
- 房主可通过此命令向从属客户端发送任意数据
活动管理 (events)
// 创建活动
["server", "events", { utc: 1700000000000, day: "周六", hour: "20:00", content: "八人局来人" }, "abc12345", null]
// 加入活动
["server", "events", "eventId", "abc12345", "join"]
// 离开活动
["server", "events", "eventId", "abc12345", "leave"]
- 最多 20 个活动,超过被拒绝
- 活动过期自动清理
心跳 (heartbeat)
// 纯文本,不是 JSON 数组
heartbeat
- 服务器每 60 秒发一次
heartbeat(纯文本) - 客户端回复
heartbeat(纯文本) - 连续未回复会被断开
| 事件 | 数据 | 说明 |
|---|---|---|
roomlist |
[roomList, events, clientList, wsid] |
初始连接 — 连接后立即发送完整状态 |
updaterooms |
[roomList, clientList] |
房间列表更新 — 有房间增删/人数变化时推送 |
updateclients |
[clientList] |
大厅玩家列表更新 |
updateevents |
[events] |
活动列表更新 |
createroom |
[key] |
房间创建成功 — 返回房间 key |
enterroomfailed |
— | 加入房间失败 — 房间不存在或已开始 |
onconnection |
[wsid] |
新玩家加入房间 — 通知房主 |
onmessage |
[wsid, rawMessage] |
收到从属消息 — 通知房主 |
onclose |
[wsid] |
从属断开 — 通知房主 |
selfclose |
— | 房间被关闭 — 房主退出导致 |
reloadroom |
— | 房间空置 — 所有玩家退出,房主应刷新 |
eventsdenied |
[reason] |
活动被拒 — reason: total/time/ban |
denied |
[reason] |
拒绝连接 — reason: key/banned |
heartbeat |
(纯文本) | 心跳 Ping |
roomList
[
["玩家名", "caocao", { "mode": "standard" }, 3, "roomKey"],
"server"
]- 数组项:
[nickname, avatar, config, playerCount, roomKey] - 字符串
"server"表示官方服务器
clientList
[
["玩家名", "caocao", true, "空闲", "wsid123", "onlineKeyABC"]
]- 数组项:
[nickname, avatar, isInLobby, status, wsid, onlineKey]
events
[
{
"id": "eventId",
"creator": "onlineKey",
"nickname": "玩家名",
"avatar": "caocao",
"utc": 1700000000000,
"day": "周六",
"hour": "20:00",
"content": "八人局来人",
"members": ["onlineKey1", "onlineKey2"]
}
]┌─────────────────────────────────────────┐
│ 浏览器 / 游戏客户端 │
│ (apps/core/noname.js) │
└────────────┬────────────────────┬────────┘
│ HTTP (8089) │ WebSocket (8082)
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ noname-server.js │ │ 本房间服务器 │
│ (Deno + Express) │ │ (src/index.ts) │
│ 文件 CRUD + 静态 │ │ 房间/活动/联机 │
└────────────────────┘ └────────────────────┘
同时启动两个服务器即可完整运行新版无名杀:
# 终端 1: 文件服务器(用你现有的)
cd E:\pj2\noname_current\noname
deno task start
# 终端 2: 房间服务器(本目录)
cd E:\pj2\noname_current\server_minimal
deno task start游戏客户端配置中填写 ws://localhost:8082 作为联机服务器地址即可使用房间大厅。