# 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/)