# ts-gameframework **Repository Path**: Arcturis/ts-gameframework ## Basic Information - **Project Name**: ts-gameframework - **Description**: typescript游戏联机框架 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 114 - **Created**: 2022-06-13 - **Last Updated**: 2022-06-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TSGF是什么(ts-gameframework) * **开源** 的联机游戏 **全栈式解决方案**:`服务端` + `客户端` 皆由 **TypeScript** 语言编写 * “**黑盒式**” 实现联机游戏:客户端对接SDK,不用关心通信和同步逻辑 * **自定义服务端逻辑**:拓展自己的同步逻辑和各种交互逻辑 * **全分布式的**的架构设计:随在线用户增加而横向拓展服务器集群 # 使用说明 ## 1. 启动服务端 (端口:7100,7101,7102,7801,7901 如果被占用将导致启动失败!) ### 1.1 `servers` 目录下执行 `npm install` (执行过一次即可) ### 1.2 多种方式启动(任选其一) * a. 使用docker一键启动所有服务(包含所有依赖服务) * 安装 **Docker Desktop** * 运行 `./simpleDeploy/run.bat` * b. 开发环境手动启动 注意!依赖:**redis**、**mysql** (需要自行参考官方文档部署这两个服务) * `mysql` 创建数据库 `tsgf_app`, `use tsgf_app` 后执行 `simpleDeploy/mysql/init/` 目录下的所有sql文件 * `servers/gf.server.config.json` 修改 redis 和 mysql 的连接信息 * 增加一条hosts记录: 127.0.0.1 tsgf-servers * 在 `servers` 目录执行 `npm run dev` * c. 手动、分布式部署(生产环境时使用) 注意!依赖:**redis**、**mysql** (需要自行参考官方文档部署这两个服务) * `mysql` 创建数据库 `tsgf_app`, `use tsgf_app` 后执行 `simpleDeploy/mysql/init/` 目录下的所有sql文件 * `servers` 目录下执行 `npm run buildTS`,然后复制出下列目录和文件: deploy/ dist/ node_modules/ gf.server.config.json * 将 `gf.server.config.json` 文件复制多份,每份表示为一种服务的一个实例([配置参考](#gfserverconfigjson配置参考)),如 servers/ deploy/ dist/ node_modules/ gf.hallServer.config.json gf.gameServerCluster.config.json gf.matchServerCluster.config.json gf.gameServer01.config.json gf.matchServer01.config.json gf.demoServer.config.json * 修改每个配置文件中的 **runServer** 节点,确定每个配置文件都要启动哪些服务实例 * 通过启动参数控制当前进程(实例)使用哪个配置文件,如 `node dist/index.js -gfConfigFile="../gf.hallServer.config.json"` * 部署为系统服务 - windows部署,提供了快捷部署服务方式,右键管理员运行 `deploy/install_runasAdmin.cmd` 即可(需修改其中的服务信息) - linux部署,可以使用 `pm2` * **微信小程序需注意**,因微信平台要求访问的域名是固定的,所以就需要让游戏服务器走统一的反向代理。游戏服务器的地址使用url参数形式进行区分,由反向代理组件实现代理规则(如nginx)。比如:游戏服务器地址配置为:`wss://game.a.com/?srv=n1&port=p` (`game.a.com` 为 nginx 服务器地址),nginx是支持根据url参数定义代理规则,实际地址是:`ws://n1.game.a.com:p/`,然后 `n1.game.a.com` 解析为内网IP, 指向游戏服务器 ## 2. 启动客户端demo - `client` 目录执行 `npm i` - 用 Creator 3.5.1 打开 (或导入到CocosDashboard中) - 在 Cocos Creator 中打开 `assets/demo1/demo1Scene.scene` 场景 - 可启动多个预览窗口,用于测试互联,效果: ![对战效果](https://fengssy.gitee.io/zgame/Games/TSGF/PlayShow.gif?v=1.1.0) # 设计说明 ## 结构介绍 ### 服务器结构图 ![拓扑图](https://fengssy.gitee.io/zgame/Games/TSGF/ServerStructure.png?v=1.1.1) ### 玩家使用时序图 ![时序图](https://fengssy.gitee.io/zgame/Games/TSGF/SequenceDiagram.png?v=1.1.0) * **应用** 一个开发者可以有多个应用,一般一个应用对应一个游戏。目前统一使用 **default** 应用标识 * **应用web服务器** 为开发者自己实现用户体系的站点,用于将开发者的用户体系对接到 **TSGF** 的玩家体系 * **大厅服务器** 为 HTTP 服务,可使用常规 web 集群方案进行部署,提供如玩家认证、创建房间、查询房间、匹配操作、分配游戏服务器等功能 * **游戏集群管理服务** 为 websocket 服务,用来管理`游戏服务器`的服务,只能部署一个实例 * **游戏服务器** 为 websocket 服务,可以部署多台(横向拓展),部署实例的数量随着在线玩家数量增加而增加。需要能连接到`游戏集群管理服务`,但实例之间并不进行通讯 * **匹配集群管理服务** 为 websocket 服务,用来管理`匹配服务器`的服务,只能部署一个实例 * **匹配服务器** 为 websocket 服务,可以部署多台(横向拓展),部署实例的数量随着应用增加而增加(单应用场景,只需要部署一个实例即可)。需要能连接到`匹配集群管理服务`,但实例之间并不进行通讯。 * 使用 [TSRPC](https://tsrpc.cn/) 作为通讯框架 *并用 `TSRPC` 框架自带的代码生成/同步模块,导致 `client` 目录名以及相对路径的固定(乱改可能会导致出错)* ## 自定义服务端逻辑 * 匹配器 - 新建类,建议存放在 `src/shared/tsgfServer/match/` - 实现接口 `src/shared/tsgfServer/match/IMatcher.ts` (可参考同目录下的 `MatcherBaseMelee.ts`) - 修改代码 `src/shared/matchServer/BaseMatchServer.ts->onAssignTask` ,加入本匹配器类的实例 ## gf.server.config.json配置参考 * 本配置使用 `jsonschema` 规范约束,因此在 `vscode` 中修改时有智能提示 * `redisConfig`: 配置连接 `redis` 的信息(运行中修改配置文件时,服务实例会自动重新读取配置) * `connString`: 配置连接各个数据库的字符串 * `appDb`: 配置连接到应用库的连接字符串 * `hallServer`: 配置大厅服务 * `port`: 侦听的端口 * `gameServerCluster`: 配置游戏集群管理服务 * `port`: 侦听的端口 * `nodeList`: 本集群下的所有管理节点(运行中修改配置文件时,服务实例会自动重新读取配置) * `clusterNodeId`: 节点ID, 集群内唯一 * `clusterKey`: 本节点连接集群的密钥 * `matchServerCluster`: 配置匹配集群管理服务 * `port`: 侦听的端口 * `nodeList`: 本集群下的所有管理节点(运行中修改配置文件时,服务实例会自动重新读取配置) * `clusterNodeId`: 节点ID, 集群内唯一 * `clusterKey`: 本节点连接集群的密钥 * `gameServer`: 游戏服务(运行中修改配置文件时,服务实例会自动重新读取配置) * `clusterWSUrl`: 游戏集群管理服务的连接地址,如 `ws://tsgf-servers:7101/` * `clusterNodeId`: 游戏集群中的节点id,需要和游戏集群管理服务的配置 `gameServerCluster.nodeList[].clusterNodeId` 一致 * `clusterKey`: 游戏集群中的密钥,需要和游戏集群管理服务的配置 `gameServerCluster.nodeList[].clusterKey` 一致 * `serverName`: 本游戏服务实例的名称,仅用于显示 * `serverWSUrl`: 客户端连接本服务的地址,如 `ws://127.0.0.1:7801/` * `extendData`: 可自定义拓展信息,any类型 * `listenPort`: 侦听的端口(修改本配置需要重启服务实例) * `matchServer`: 匹配服务 * `clusterWSUrl`: 集群管理服务的连接地址,如 `ws://tsgf-servers:7102/` * `clusterNodeId`: 集群中的节点id,需要和集群管理服务的配置 `matchServerCluster.nodeList[].clusterNodeId` 一致 * `clusterKey`: 集群中的密钥,需要和集群管理服务的配置 `matchServerCluster.nodeList[].clusterKey` 一致 * `serverName`: 本服务实例的名称,仅用于显示 * `demoServer`: 模拟应用自己的WEB服务器,用于将应用自己的用户去映射到玩家,获得玩家的认证信息,以连接到 `TSGF` 的服务 * `runServer`: string[] 决定当前实例启动时运行哪些服务 ## 客户端使用说明 ### 应用 * 为 `TSGF开放平台` 的应用,一个开发者可以有多个应用,一般一个应用对应一个游戏 * 应用自己的用户体系需要对接到 `TSGF` 的玩家体系,`openId` 为应用自己用户的唯一标识,通过服务端认证获得 `TSGF` 的玩家ID以及认证令牌(playerId, playerToken) ### 结构说明 * 整体分为两部分: **TSGF服务的客户端封装** 和 **客户端功能封装** * **TSGF服务的客户端封装**,位于 `assets/shared/` 分为: * `hallClient/` 大厅服务器的客户端封装 * `gameClient/` 游戏服务器的客户端封装 * `tsgf/` TSGF服务客户端的公共代码 * `demoClient/` 是`demoServer`的客户端封装 * **客户端功能封装**,位于 `assets/scripts/common/` * 其他功能 * `assets/scripts/env.ts` 使客户端的通讯方式兼容全平台,利用 Creator 插件 [ifdef-creator](https://store.cocos.com/app/detail/3580) 在 Creator 打包时, 根据当前构建平台配置的预定义变量自动使用对应平台的通讯模块 ### 匹配功能说明 * `matchFromType`:匹配发起方类型:玩家匹配、房间招人匹配 * 所有匹配都有 `maxPlayers` 最大玩家数字段,值不相同的匹配、房间之间不会互通 * 玩家匹配: * 不管是单个玩家,还是实现了组队功能再整队发起匹配,都认为来自玩家匹配 * 房间招人匹配: * 创建房间时,`ICreateRoomPara.isPrivate` 和 `ICreateRoomPara.matcherKey` 一起控制,当前房间不人不满时是否允许匹配进入以及使用的匹配器 * 开始玩家匹配时的匹配参数:`IBaseMeleeMatchAttributes.resultsContinueRoomJoinUsMatch` 来控制匹配成功是创建一个新房间时, 如果是创建房间并且人未满,是否允许继续匹配满 * `matcherKey`:匹配器标识定义,不同匹配器的匹配请求之间不会互通。(内置匹配器标识 `MatcherKeys`) * `matcherParams`:匹配器参数,根据不同的匹配器使用对应的类(请看 `MatcherKeys` 的注释) ### 二次开发、使用模块 * 暂时未提供复用性调用方式,只能拷贝源码,进行二次开发或引用模块 * 预计 `v1.2` 版本提供此功能 ## 游戏设计要求 * 输入操作分离:与“我”无关的逻辑实现 *其实只要是联机游戏,就需要做到上面说的设计* ## 实现应用自己的web服务端 * 即 `demoServer` 的角色。主要负责将应用自己的用户体系对接到 `TSGF` 的玩家体系 * 推荐实现方案: * 应用的用户登录后,在应用的web服务器上请求 `TSGF` 大厅的服务端认证接口,获得玩家认证信息(playerId/playerToken等) *可参考 `src/demoServer/api/ApiPlayerAuth.ts`* * 由应用将玩家认证信息返回到客户端,用于客户端的所有需要认证的api # 引用 [TSRPC](https://tsrpc.cn/) Pomu Rainpuff [Nijisanji EN](https://skfb.ly/orVQ7) by scuffward is licensed under [Creative Commons Attribution](http://creativecommons.org/licenses/by/4.0/).