# paradogs **Repository Path**: makimaa/paradogs ## Basic Information - **Project Name**: paradogs - **Description**: 一个基于 Java、Netty 的分布式游戏服务端框架,已升级至 paradogs2 | https://gitee.com/makimaa/paradogs2 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2023-07-26 - **Last Updated**: 2025-05-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: SpringBoot, Netty, Java, 游戏服, 分布式 ## README # paradogs ## 项目已经升级至 Paradogs2,请访问 https://gitee.com/makimaa/paradogs2 #### 介绍 一个基于 Java、Netty、的分布式游戏服务端框架,有疑问可以联系 Q410408824 #### 软件架构 - 基础:SpringBoot - 网络:Netty、protobuf (JProtobuf) - 持久化:Mybatis-Plus - Excel 数据:easyExcel - 代码生成:Freemarker #### 快速开始 ##### 启动 1. 修改每个服的 mysql 连接配置为自己的连接地址 ```yaml spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/paradogs_game?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8 username: root password: root ``` 2. **启动中心服**:paradogs-demo-master | DemoMasterApplication 3. **启动登录服**:paradogs-demo-login | DemoMasterApplication 4. **启动逻辑服**:paradogs-demo-logic | DemoMasterApplication 5. **启动网关服**:paradogs-demo-gate | DemoMasterApplication 6. **运行简单客户端测试**:paradogs-demo-client | DemoClientApplication ##### 请求处理操作 - **@PRController** 声明请求处理类 - **@PRMsgMapping** 请求映射地址,可加在类和方法上,下例的请求地址映射为 **"[serverType]|role.hello"** 和 **"[serverType]|role.helloAsync"** - **请求参数**:任意类型对象,需要有 **@ProtobufClass** 或 @Protobuf 修饰 - **返回值**:如果有返回值,会自动将返回值作为回复消息,向发送方进行回复,需要有 **@ProtobufClass** 或 @Protobuf 修饰 - **异步操作**:由于 Netty 基于 NIO,如果消息处理过程中有阻塞操作,需要改为异步执行,**设置 @PRMsgMapping 的 async 为 true** 表示是一个异步操作方法,一般不怎么使用,常用于服务器内部相互调用 ```java @PRController @PRMsgMapping("misc") public class LoginController { @PRMsgMapping("hello") public GCAck hello(LongWrapper wrapper) { log.info("hello game !!!"); return GCAck.success(); } @PRMsgMapping(value = "helloAsync", async = true) public GCAck helloAsync() { log.info("================ helloAsync game !!!"); return GCAck.success(); } } ``` ```java @Data @ProtobufClass public class LongWrapper { // 消息实体类 private Long val; } ``` ##### RPC 请求操作 - **@PRClient** 定义一个 RPC 请求类,指定请求的服务器类型 - **@PRRPCMapping** 指定 RPC 请求的路由地址 ```java @PRClient("logic") public interface LogicClient { @PRRPCMapping("role.hello") GCAck hello(LongWrapper uid); @PRRPCMapping("role.firstSyncData") void firstSyncData(); } ``` - 调用方式 - 注意 RPC 为**阻塞操作**,需要加异步 ```java @Slf4j @PRController public class GateController { @Autowired private LogicClient logicClient; @PRMsgMapping(value = "login", async = true) public GCAck login(CGGateLogin msg) { logicClient.loadPlayer(new LongWrapper(1L)); } } ``` #### 使用说明 ##### 依赖和配置 1. 引入对应的服务器支持依赖(logic 服举例) ```maven com.paradogs paradogs-framework-server-starter ``` 2. 在启动类上添加 @EnableParadogs 注解(logic 服举例) ```java @EnableParadogs @SpringBootApplication public class DemoLogicApplication { public static void main(String[] args) { SpringApplication.run(DemoLogicApplication.class, args); } } ``` 3. 配置 application.yml ```yaml # master: 中心服配置 paradogs: server: port: 8888 type: master name: master-1 master: true # 设置为 true 表示为 master 服 ``` ```yaml # server: 普通服配置 paradogs: server: port: 8090 type: logic # 服务器类型 key: logic-1 # 服务器唯一标识 master: # master 服务器地址 host: localhost port: 8888 ``` ```yaml # gate: 前端服配置(供客户端直接连接) paradogs: server: port: 8001 type: gate # 服务器类型 key: gate-1 # 服务器唯一标识 master: # master 服务器地址 host: localhost port: 8888 clients: # 需要连接的服务器 - host: localhost port: 8090 type: logic # 服务器类型 ``` ##### 消息上下文 PRMsgContextHolder - 通过上下文**可以获取到当前处理请求的相关信息**,如 Channel、消息头、玩家 ID 等 ```java @PRMsgMapping("kill") public void kill() { // 打怪 Long pId = PRMsgContextHolder.getPlayerId(); // 获得当前请求玩家 PlayerTemplate player = playerOnlineHolder.getPlayer(pId); player.getRoleManager().addExp(); // 增加经验 } ``` ##### 循环检测 @PRTick - 所有被 @PRTick 修饰的方法都会在每次 消息处理线程 循环时被调用一次 ```java @Slf4j @Component @Scope("prototype") public class RoleManager extends BaseManager { @PRTick public void checkTaskTimeout() { log.info("检测限时任务是否超时,如果超时则做相应处理"); } } ``` #### 代码生成 ##### 生成 dao、dbEntity | DBEntityGenerator - DBEntityGenerator.main(),根据 mysql 数据库表自动生成 ##### 生成 .proto 文件 | ProtobufIDLGenerator - 运行 ProtobufIDLGenerator.main(),将所有被 @protobufClass 修饰的类转换成 .proto 文件 ##### 配置表生成实体类 | ExcelDataGenerator - 根据 Excel 配置表生成对应的实体类 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)