嗨, 大家好! 我要写写我基于 Colyseus 服务器的游戏是如何处理游戏和管理游戏房间的.
我的游戏是一个在<星际公民>风格的单人/多人在线游戏, 即使您退出帐户, 您的游戏也会继续. 在这款 4X/资源管理宇宙风格的游戏中, 即使您处于离线状态, 也可以提取资源, 构建事物, 研究升级.
早先我就决定不让每个 Colyseus 游戏房间都长时间在线永久开放, 而是为每次游戏会话开设一个专用房间. 当一个玩家或一组玩家登录并选择游戏时, 会为他们创建一个游戏房间, 并将房间状态与数据库中的实际游戏数据同步. 当游戏“心跳”或其他事件发生时, 房间状态也会同步, 并且所有连接的客户端都由 Colyseus 自动更新.
我是这么做的, 我自己的 API 中有一个入口, 与 Colyseus 分开, 客户端调用它来预订房间. 使用 Colyseus MatchMaker API, 首先用游戏标识查询房间, 我称其为 gameName, 至少现在是这样. 如果它不存在, 那么我会使用这个标识和 matchMaker.reserveSeatFor 来创建这样的房间. 如果我找到了这样的房间, 那么我会使用 .matchMaker.joinById 来预订席位, 因为我现在知道房间的 ID. 在这两种情况下, 我都会得到一个 reservation 实例, 将该实例使用 Colyseus 客户端 API 发送给客户端, 让客户端加入游戏.
这很好, 但是有一个小问题.
我使用 Auth0 进行身份验证. 使用 Auth0 保护我自己的 API 入口很容易, 但我没有找到用这个身份验证中间件保护 Colyseus 路由的方法. 这让我非常难过. 我就去睡觉了, 早上我想到一个有趣的解决方法. 通过我的入口请求预订席位时一定获得了 auth JWT, 因为它是受身份验证保护的. 而 reservation 实例支持附加属性, 所以我就将整个 JWT 附加到了该实例中.
当客户端预订席位时, 客户端如果没有被篡改, 那么 reservation 中的附加属性会一同到达 GameRoom 类上的 onAuth 处理程序, 万一被篡改, 我再做一次 JWT 验证就能辨明真伪.
这个方法很有用. 我担心的一件事是多个合作玩家的情况, 每个玩家都有自己的 JWT, 我不确定预订是否还能正常工作不出问题. 有时间我会测试一下, 但我认为应该没问题.