diff --git a/.gitignore b/.gitignore
index 434f26077c90e38a92b351d32d51337dc4de65d0..35d1e72d5bf4043cfaeb7176ef08a8ba8e1a505e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,7 @@
hs_err_pid*
# target
-target/
\ No newline at end of file
+target/
+
+# protobuf-itl
+proto/
\ No newline at end of file
diff --git a/README.md b/README.md
index b94d7319d8fe29571b02923aded5205b9b001be5..89dc6cbebaf2740cb437000794a02c7a36e654de 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,150 @@
# paradogs
#### 介绍
-一个基于 Java、Netty、发布订阅驱动的分布式游戏服务端框架
+一个基于 Java、Netty、的分布式游戏服务端框架,有疑问可以联系 Q410408824
#### 软件架构
-软件架构说明
+- 基础:SpringBoot
+- 网络:Netty、protobuf (JProtobuf)
+- 持久化:Mybatis-PlusS
+- 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]|misc.hello"** 和 **"[serverType]|misc.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("misc.loadPlayer")
+ GCAck loadPlayer(LongWrapper uid);
+
+ @PRRPCMapping("misc.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. xxxx
-2. xxxx
-3. xxxx
#### 使用说明
+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
+- master: 中心服配置
+```yaml
+paradogs:
+server:
+port: 8888
+type: master
+name: master-1
+master: true # 设置为 true 表示为 master 服
+```
+- server: 普通服配置
+```yaml
+paradogs:
+ server:
+ port: 8090
+ type: logic # 服务器类型
+ key: logic-1 # 服务器唯一标识
+ master: # master 服务器地址
+ host: localhost
+ port: 8888
+```
+- gate: 前端服配置(供客户端直接连接)
+```yaml
+paradogs:
+ server:
+ port: 8001
+ type: gate # 服务器类型
+ key: gate-1 # 服务器唯一标识
+ master: # master 服务器地址
+ host: localhost
+ port: 8888
+ clients: # 需要连接的服务器
+ - host: localhost
+ port: 8090
+ type: logic # 服务器类型
+```
-1. xxxx
-2. xxxx
-3. xxxx
#### 参与贡献
diff --git a/paradogs-demo/paradogs-demo-client/src/main/java/com/paradogs/demo/client/DemoClientApplication.java b/paradogs-demo/paradogs-demo-client/src/main/java/com/paradogs/demo/client/DemoClientApplication.java
index 9e12c9b9c30bf3f2e4d97dcd275b3b3e5907967e..deaaa13770bc63644120eac317b7948ac8296fff 100644
--- a/paradogs-demo/paradogs-demo-client/src/main/java/com/paradogs/demo/client/DemoClientApplication.java
+++ b/paradogs-demo/paradogs-demo-client/src/main/java/com/paradogs/demo/client/DemoClientApplication.java
@@ -2,10 +2,10 @@ package com.paradogs.demo.client;
import com.paradogs.demo.client.demo.Client;
import com.paradogs.demo.client.pojo.CGLogin;
-import com.paradogs.framework.common.pojo.cg.CGGatewayLogin;
-import com.paradogs.framework.common.pojo.gc.GCAllocGateway;
+import com.paradogs.framework.common.pojo.cg.CGGateLogin;
import com.paradogs.framework.common.pojo.gc.GCApplyGate;
import com.paradogs.framework.core.msg.ByteData;
+import com.paradogs.framework.core.msg.R;
import com.paradogs.framework.core.netty.PRCodec;
import com.paradogs.framework.core.utils.ProtoUtils;
import io.netty.bootstrap.Bootstrap;
@@ -17,6 +17,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -77,15 +78,31 @@ public class DemoClientApplication {
channel.pipeline().addLast(new SimpleChannelInboundHandler() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteData msg) throws Exception {
- log.info("Receive: {}", msg);
- Client.send(ctx.channel(), "logic|misc.hello", new CGGatewayLogin("123"));
+ if (msg.getMsgHeader().getRoute().equals("syncData")) {
+ R result = ProtoUtils.decode(msg.getDataBytes(), R.class);
+ log.info("Receive: {}", result);
+ } else {
+ log.info("Receive: {}", msg);
+ }
}
});
}
});
Channel gateChannel = client.connect(result.getHost(), result.getPort()).sync().channel();
log.info("Connect Gate success");
- Client.send(gateChannel, "gate|login", new CGGatewayLogin(result.getToken()));
+ Client.send(gateChannel, "gate|login", new CGGateLogin(result.getToken()));
+
+ Thread.sleep(1000);
+ new Thread(new Runnable() {
+ @SneakyThrows
+ @Override
+ public void run() {
+ while (true) {
+ Client.send(gateChannel, "logic|misc.updateData", new CGGateLogin("123"));
+ Thread.sleep(199999000);
+ }
+ }
+ }).start();
}
});
@@ -94,6 +111,6 @@ public class DemoClientApplication {
Channel channel = client.connect("localhost", 80).sync().channel();
- Client.send(channel, "login|applyGate", new CGLogin("yumi", "123"));
+ Client.send(channel, "login|login", new CGLogin("yumi", "123"));
}
}
diff --git a/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/controller/GateController.java b/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/controller/GateController.java
index 12499bce91c49f5f1358e829fa95c0b80395022b..f0b399987e5a6098acd8943485c2e8b47ce242e4 100644
--- a/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/controller/GateController.java
+++ b/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/controller/GateController.java
@@ -2,20 +2,19 @@ package com.paradogs.demo.gate.controller;
import com.paradogs.demo.gate.misc.PlayerOnlineHolder;
import com.paradogs.demo.gate.rpc.LogicClient;
-import com.paradogs.framework.common.pojo.cg.CGGatewayLogin;
+import com.paradogs.framework.common.pojo.cg.CGGateLogin;
import com.paradogs.framework.common.pojo.cg.CGPrepareLogin;
import com.paradogs.framework.common.pojo.misc.LongWrapper;
import com.paradogs.framework.core.annoations.request.PRController;
import com.paradogs.framework.core.annoations.request.PRMsgMapping;
import com.paradogs.framework.core.msg.GCAck;
-import com.paradogs.framework.core.utils.PRAsync;
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
+import com.paradogs.framework.core.msg.R;
+import com.paradogs.framework.core.utils.MsgUtils;
+import com.paradogs.framework.gate.GateChannelHolder;
+import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
/**
* @author: yumi
@@ -48,13 +47,27 @@ public class GateController {
* @return
*/
@PRMsgMapping(value = "login", async = true)
- public GCAck login(CGGatewayLogin msg) {
+ public GCAck login(CGGateLogin msg) {
PlayerOnlineHolder.WillLoginInfo info = playerOnlineHolder.get(msg.getToken());
if (info != null) {
+ // 绑定 Channel 所属玩家信息,待优化:登录功能可以放在 gate-starter 模块里
+ GateChannelHolder.bindSession(PRMsgContextHolder.getChannel(), new GateChannelHolder.Session(info.getUid()));
logicClient.loadPlayer(new LongWrapper(info.getUid()));
+ playerOnlineHolder.removeToken(msg.getToken());
return GCAck.success();
}
return GCAck.fail();
}
+ /**
+ * 同步玩家自身数据
+ */
+ @PRMsgMapping("syncData")
+ public void syncData(R syncData) {
+ Channel channel = GateChannelHolder.getPlayerChannel(syncData.getPlayerId());
+ if (channel != null) {
+ MsgUtils.send("syncData", syncData, channel);
+ }
+ }
+
}
diff --git a/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/rpc/LogicClient.java b/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/rpc/LogicClient.java
index 0ff2a287b90cd34b0c4836a0bfffce712f8634de..3fc2acc195a7ff9c8f563c0270228079145cd960 100644
--- a/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/rpc/LogicClient.java
+++ b/paradogs-demo/paradogs-demo-gate/src/main/java/com/paradogs/demo/gate/rpc/LogicClient.java
@@ -15,4 +15,7 @@ public interface LogicClient {
@PRRPCMapping("misc.loadPlayer")
GCAck loadPlayer(LongWrapper uid);
+
+ @PRRPCMapping("misc.firstSyncData")
+ void firstSyncData();
}
diff --git a/paradogs-demo/paradogs-demo-logic/pom.xml b/paradogs-demo/paradogs-demo-logic/pom.xml
index 2f654767309c5cd830e2a4bf457cce65652041a8..d480ba78bb5127378c1a3e6de2d6a8aa169fe830 100644
--- a/paradogs-demo/paradogs-demo-logic/pom.xml
+++ b/paradogs-demo/paradogs-demo-logic/pom.xml
@@ -21,6 +21,10 @@
com.paradogs
paradogs-framework-server-starter
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
\ No newline at end of file
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/controller/LoginController.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/controller/LoginController.java
index ca18e5d570616801023e8fee77076c13033fb768..ccf59144017ee512f092c0c5f6eac0d6dd1010bd 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/controller/LoginController.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/controller/LoginController.java
@@ -1,16 +1,18 @@
package com.paradogs.demo.logic.controller;
import com.paradogs.demo.logic.event.PlayerLoginEvent;
-import com.paradogs.demo.logic.manager.base.PlayerTemplate;
+import com.paradogs.demo.logic.misc.PlayerOnlineHolder;
+import com.paradogs.demo.logic.misc.PlayerTemplate;
+import com.paradogs.framework.common.entity.Role;
import com.paradogs.framework.common.pojo.misc.LongWrapper;
import com.paradogs.framework.core.annoations.request.PRController;
import com.paradogs.framework.core.annoations.request.PRMsgMapping;
import com.paradogs.framework.core.msg.GCAck;
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
import com.paradogs.framework.core.utils.EventUtils;
-import com.paradogs.framework.core.utils.PRAsync;
+import com.paradogs.framework.core.utils.MsgUtils;
import lombok.extern.slf4j.Slf4j;
-
-import java.util.concurrent.CompletableFuture;
+import org.springframework.beans.factory.annotation.Autowired;
/**
* @author: yumi
@@ -22,6 +24,9 @@ import java.util.concurrent.CompletableFuture;
@PRMsgMapping("misc")
public class LoginController {
+ @Autowired
+ private PlayerOnlineHolder playerOnlineHolder;
+
@PRMsgMapping(value = "loadPlayer", async = true)
public GCAck loadPlayer(LongWrapper wrapper) {
// 初始化玩家数据
@@ -38,5 +43,25 @@ public class LoginController {
return GCAck.success();
}
+ @PRMsgMapping(value = "helloAsync", async = true)
+ public GCAck helloAsync() {
+ log.info("================ helloAsync game !!!");
+ return GCAck.success();
+ }
+
+ @PRMsgMapping("firstSyncData")
+ public void firstSyncData() {
+ System.out.println("1");
+ }
+
+ /**
+ * 打怪测试
+ */
+ @PRMsgMapping("addExp")
+ public void kill() {
+ PlayerTemplate player = playerOnlineHolder.getPlayer(PRMsgContextHolder.getPlayerId());
+ player.getRoleManager().addExp();
+ }
+
}
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/event/PlayerLoginEvent.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/event/PlayerLoginEvent.java
index ca638a9836ce42ebd9fca88865621b3cc3f185ca..c85f87d2b71fe5dada4c74f5b1589f66dc7a7052 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/event/PlayerLoginEvent.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/event/PlayerLoginEvent.java
@@ -1,6 +1,6 @@
package com.paradogs.demo.logic.event;
-import com.paradogs.demo.logic.manager.base.PlayerTemplate;
+import com.paradogs.demo.logic.misc.PlayerTemplate;
import com.paradogs.framework.common.events.base.AnonEvent;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/PlayerManager.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/InventoryManager.java
similarity index 56%
rename from paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/PlayerManager.java
rename to paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/InventoryManager.java
index 8b3bd7eebd6e1b48aa8eaa17c524b10ebba5b640..8dcc1d62e7e81b67ce9b3abca0db71a9fe205965 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/PlayerManager.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/InventoryManager.java
@@ -1,18 +1,17 @@
package com.paradogs.demo.logic.manager;
-import com.paradogs.framework.common.dao.PlayerDao;
-import com.paradogs.framework.common.entity.Player;
import com.paradogs.demo.logic.manager.base.BaseManager;
+import com.paradogs.framework.common.dao.InventoryDao;
+import com.paradogs.framework.common.entity.Inventory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* @author: yumi
- * @date: 2023/11/23 14:01
+ * @date: 2023/11/30 15:21
* @Description: TODO
*/
-@Scope("prototype")
@Component
-public class PlayerManager extends BaseManager {
-
+@Scope("prototype")
+public class InventoryManager extends BaseManager {
}
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/RoleManager.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/RoleManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..c78e53ce3dcd7f838f05e7ae02210aff918e6794
--- /dev/null
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/RoleManager.java
@@ -0,0 +1,28 @@
+package com.paradogs.demo.logic.manager;
+
+import com.paradogs.demo.logic.manager.base.BaseManager;
+import com.paradogs.framework.common.dao.RoleDao;
+import com.paradogs.framework.common.entity.Role;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author: yumi
+ * @date: 2023/11/30 15:22
+ * @Description: TODO
+ */
+@Component
+@Scope("prototype")
+public class RoleManager extends BaseManager {
+
+ public void addExp() {
+ Role role = getData();
+ role.setExp(role.getExp() + 100);
+ if (role.getExp() > 499) {
+ role.setExp(role.getExp() - 499);
+ role.setLevel(role.getLevel() + 1);
+ }
+ updateData(role);
+ }
+
+}
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/BaseManager.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/BaseManager.java
index ff08883dbc2ae1e7a1fdd083dd9780b5c284ccff..bea9765acccb3bad4ca41109d9f6b76a655d8fa7 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/BaseManager.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/BaseManager.java
@@ -2,9 +2,13 @@ package com.paradogs.demo.logic.manager.base;
import com.baomidou.mybatisplus.extension.service.IService;
import com.paradogs.framework.common.entity.base.BaseEntity;
+import com.paradogs.framework.core.queue.DBUpdatMsg;
+import com.paradogs.framework.core.queue.PRQueueHolder;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -13,31 +17,85 @@ import org.springframework.beans.factory.annotation.Autowired;
* @Description: TODO
*/
@Slf4j
-public abstract class BaseManager> {
+public abstract class BaseManager> {
@Autowired
private D dao;
+ @Setter
+ private E data;
+
+ public E getData() {
+ E e = null;
+ try {
+ e = dao.getEntityClass().newInstance();
+ } catch (InstantiationException instantiationException) {
+ instantiationException.printStackTrace();
+ } catch (IllegalAccessException illegalAccessException) {
+ illegalAccessException.printStackTrace();
+ }
+ BeanUtils.copyProperties(data, e);
+ return e;
+ }
+
+ /**
+ * 数据是否被修改并且未同步到客户端
+ */
@Getter
@Setter
- private T entity;
+ private boolean dirty;
/**
* 加载玩家数据
* @param uid
*/
public void loadData(Long uid) {
- this.entity = dao.getById(uid);
- if (this.entity == null) {
+ this.data = dao.getById(uid);
+ this.dirty = true;
+ if (this.data == null) {
try {
- this.entity = dao.getEntityClass().newInstance();
+ this.data = dao.getEntityClass().newInstance();
+ this.data.setUid(uid);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
- log.debug("Load {}: {}", this.getClass().getSimpleName(), this.entity);
+ log.debug("Load {}: {}", this.getClass().getSimpleName(), this.data);
+ }
+
+ /**
+ * 复制一份数据
+ * @return
+ */
+ public E copyData() {
+ if (this.data == null) {
+ return null;
+ }
+ E copy = null;
+ try {
+ copy = dao.getEntityClass().newInstance();
+ BeanUtils.copyProperties(this.data, copy);
+ } catch (InstantiationException | IllegalAccessException e) {
+ log.error("Error copying data", e);
+ }
+ return copy;
+ }
+
+ /**
+ * 更新数据,待优化:数据值真实变化时再改变状态位
+ * @param data
+ */
+ public void updateData(E data) {
+ if (!this.data.equals(data)) {
+ this.data = data;
+ this.dirty = true;
+ PRQueueHolder.putMsg(PRQueueHolder.QueueType.DB, new DBUpdatMsg(data.getUid(), dao, data));
+ }
+ }
+ public void setData(E data) {
+ updateData(data);
}
/**
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerOnlineHolder.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerOnlineHolder.java
index 4a7d46b2d2e2b772e153d51c41d23463b2059547..09d96252cde94efab33c711d9de3fb2ccfe49b97 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerOnlineHolder.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerOnlineHolder.java
@@ -2,7 +2,6 @@ package com.paradogs.demo.logic.misc;
import com.paradogs.demo.logic.event.PlayerLoginEvent;
import com.paradogs.demo.logic.event.PlayerLogoutEvent;
-import com.paradogs.demo.logic.manager.base.PlayerTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@@ -24,6 +23,11 @@ public class PlayerOnlineHolder {
*/
private Map onlinePlayerMap = new HashMap<>();
+
+ public PlayerTemplate getPlayer(Long uid) {
+ return onlinePlayerMap.get(uid);
+ }
+
@EventListener(PlayerLoginEvent.class)
public void PlayerLoginEventHandler(PlayerLoginEvent event) {
onlinePlayerMap.put(event.getUid(), event.getPlayerTemplate());
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/PlayerTemplate.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerTemplate.java
similarity index 51%
rename from paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/PlayerTemplate.java
rename to paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerTemplate.java
index 28ea8b70f258f38ffea5a86f1d666133b8cc6ecd..bba63a00407d902cff0cfad67f0554b2c5c40c5d 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/manager/base/PlayerTemplate.java
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/PlayerTemplate.java
@@ -1,10 +1,18 @@
-package com.paradogs.demo.logic.manager.base;
+package com.paradogs.demo.logic.misc;
-import com.paradogs.demo.logic.manager.PlayerManager;
+import com.paradogs.demo.logic.manager.InventoryManager;
+import com.paradogs.demo.logic.manager.RoleManager;
+import com.paradogs.demo.logic.manager.base.BaseManager;
+import com.paradogs.framework.common.entity.base.BaseEntity;
+import com.paradogs.framework.core.utils.BeanUtils;
import com.paradogs.framework.core.utils.SpringUtils;
import lombok.Data;
+import lombok.EqualsAndHashCode;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
/**
* @author: yumi
@@ -19,7 +27,18 @@ public class PlayerTemplate {
*/
private Long uid;
- private PlayerManager playerManager;
+ /**
+ * 角色相关
+ */
+ private RoleManager roleManager;
+
+ /**
+ * 库存系统
+ */
+ private InventoryManager inventoryManager;
+
+
+ private List managers = new ArrayList<>();
public PlayerTemplate(Long uid) {
/**
@@ -33,6 +52,7 @@ public class PlayerTemplate {
// 加载数据
manager.loadData(uid);
field.set(this, manager);
+ managers.add(manager);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
@@ -40,4 +60,9 @@ public class PlayerTemplate {
}
}
+ public List copyData() {
+ List dataList = managers.stream().map(manager -> manager.copyData()).collect(Collectors.toList());
+ return dataList;
+ }
+
}
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/SyncAspect.java b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/SyncAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c761fca251d1709d4bbe80d664cd176f314a1fd
--- /dev/null
+++ b/paradogs-demo/paradogs-demo-logic/src/main/java/com/paradogs/demo/logic/misc/SyncAspect.java
@@ -0,0 +1,72 @@
+package com.paradogs.demo.logic.misc;
+
+import com.paradogs.demo.logic.manager.base.BaseManager;
+import com.paradogs.framework.core.annoations.request.PRMsgMapping;
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
+import com.paradogs.framework.core.msg.R;
+import com.paradogs.framework.core.utils.MsgUtils;
+import com.paradogs.framework.core.utils.ReflectUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author: yumi
+ * @date: 2023/11/30 17:55
+ * @Description: 检查和同步玩家数据变化的切面
+ */
+@Slf4j
+@Aspect
+@Order(Integer.MAX_VALUE)
+@Component
+public class SyncAspect {
+
+ @Autowired
+ private PlayerOnlineHolder onlineHolder;
+
+ /**
+ * 对 @PRMsgMapping 注解方法切面,用于检查和同步玩家数据变化
+ * - @within(com.paradogs.framework.core.annoations.request.PRController) &&
+ * @param joinPoint
+ * @param msgMapping
+ * @return
+ * @throws Throwable
+ */
+ @Around("@annotation(msgMapping)")
+ public Object aroundPRMsgMappingMethods(ProceedingJoinPoint joinPoint, PRMsgMapping msgMapping) throws Throwable {
+ Object result = joinPoint.proceed(); // 执行目标方法
+ Long uId = PRMsgContextHolder.getPlayerId();
+ PlayerTemplate template = onlineHolder.getPlayer(uId);
+ /**
+ * 玩家数据发生变化时,同步数据(先发送同步消息再发送回复消息)
+ * 待优化:
+ * 1. 目前变化时同步整个类,可以改成同步类中单个字段
+ * 2. syncData 消息和 reply 消息合并发送:合并成同一个类或 write() 不 flush ?
+ */
+ if (template != null) {
+ R syncData = R.success(result);
+ boolean needSync = false;
+ for (BaseManager manager : template.getManagers()) {
+ if (manager.isDirty()) {
+ ReflectUtils.callSetter(syncData, manager.getData().getClass().getSimpleName(), manager.getData());
+ needSync = true;
+ }
+ }
+ // 如果玩家数据变化,则同步玩家数据
+ if (needSync) {
+ syncData.setPlayerId(uId);
+ MsgUtils.send("gate|syncData", syncData, PRMsgContextHolder.getChannel());
+ log.debug("数据变化,同步玩家数据: {}", syncData);
+ }
+ // 更新数据状态
+ template.getManagers().forEach(manager -> manager.setDirty(false));
+ }
+
+ return result;
+ }
+
+}
diff --git a/paradogs-demo/paradogs-demo-logic/src/main/resources/application.yml b/paradogs-demo/paradogs-demo-logic/src/main/resources/application.yml
index 0d96fe13a8c5c11ee77ccb9a0d1639f29f971932..9296e8c438d9a5143d61b4f653d58eb311ad88c6 100644
--- a/paradogs-demo/paradogs-demo-logic/src/main/resources/application.yml
+++ b/paradogs-demo/paradogs-demo-logic/src/main/resources/application.yml
@@ -22,7 +22,7 @@ mybatis-plus:
field-strategy: not_empty
table-underline: true
configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+ log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
# 日志级别配置
logging:
diff --git a/paradogs-demo/paradogs-demo-login/src/main/java/com/paradogs/demo/login/controller/LoginController.java b/paradogs-demo/paradogs-demo-login/src/main/java/com/paradogs/demo/login/controller/LoginController.java
index d6fd32b7c9b606b5767d98c5b625476b63abb7ce..72b0b7bcd3a647e13d394d10cadecb684029eaf2 100644
--- a/paradogs-demo/paradogs-demo-login/src/main/java/com/paradogs/demo/login/controller/LoginController.java
+++ b/paradogs-demo/paradogs-demo-login/src/main/java/com/paradogs/demo/login/controller/LoginController.java
@@ -38,7 +38,7 @@ public class LoginController {
@Autowired
private PlayerDao playerDao;
- @PRMsgMapping(value = "applyGate", async = true)
+ @PRMsgMapping(value = "login", async = true)
public GCApplyGate login(CGLogin dto) {
Player player = playerDao.getOne(Wrap.lbq()
.eq(Player::getAccount, dto.getAccount())
diff --git a/paradogs-framework/paradogs-framework-common/pom.xml b/paradogs-framework/paradogs-framework-common/pom.xml
index 1732bc1d94a79969c65358609936c6e899f83ebe..3a1ba23bcea85061870fc602166fa7ef0b585bd1 100644
--- a/paradogs-framework/paradogs-framework-common/pom.xml
+++ b/paradogs-framework/paradogs-framework-common/pom.xml
@@ -33,6 +33,10 @@
io.netty
netty-all
+
+ com.alibaba
+ easyexcel
+
\ No newline at end of file
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/InventoryDao.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/InventoryDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f292c0fca6c6cce43a07d1e83e400d558fe3a37
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/InventoryDao.java
@@ -0,0 +1,16 @@
+package com.paradogs.framework.common.dao;
+
+import com.paradogs.framework.common.entity.Inventory;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+public interface InventoryDao extends IService {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/PlayerDao.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/PlayerDao.java
index 1d5b9128f6ac220b45cf6c59e46b67efc33bcd65..daa43dd181af5e40630f8162496921f64922ceba 100644
--- a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/PlayerDao.java
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/PlayerDao.java
@@ -9,7 +9,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
*
*
* @author yumi
- * @since 2023-11-20
+ * @since 2023-11-30
*/
public interface PlayerDao extends IService {
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/RoleDao.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/RoleDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..c74f16e47ffa75970c85d86cffdc78eac44072ad
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/RoleDao.java
@@ -0,0 +1,16 @@
+package com.paradogs.framework.common.dao;
+
+import com.paradogs.framework.common.entity.Role;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+public interface RoleDao extends IService {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/InventoryDaoImpl.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/InventoryDaoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bc65f8ab32b5fdd755f217e87545a7e7efb93b8
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/InventoryDaoImpl.java
@@ -0,0 +1,20 @@
+package com.paradogs.framework.common.dao.impl;
+
+import com.paradogs.framework.common.entity.Inventory;
+import com.paradogs.framework.common.mapper.InventoryMapper;
+import com.paradogs.framework.common.dao.InventoryDao;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+@Service
+public class InventoryDaoImpl extends ServiceImpl implements InventoryDao {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/PlayerDaoImpl.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/PlayerDaoImpl.java
index d7650f97cebeb99b0d0cd936ecb3242f0704aa82..9399c3b872044e5a6dd10b0551b6649f5c75b8e1 100644
--- a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/PlayerDaoImpl.java
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/PlayerDaoImpl.java
@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
*
*
* @author yumi
- * @since 2023-11-20
+ * @since 2023-11-30
*/
@Service
public class PlayerDaoImpl extends ServiceImpl implements PlayerDao {
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/RoleDaoImpl.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/RoleDaoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..32e1cb6596b17469e8498cfcdf1c03573c5c6a4b
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/dao/impl/RoleDaoImpl.java
@@ -0,0 +1,20 @@
+package com.paradogs.framework.common.dao.impl;
+
+import com.paradogs.framework.common.entity.Role;
+import com.paradogs.framework.common.mapper.RoleMapper;
+import com.paradogs.framework.common.dao.RoleDao;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+@Service
+public class RoleDaoImpl extends ServiceImpl implements RoleDao {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/data/RoleLevel.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/data/RoleLevel.java
new file mode 100644
index 0000000000000000000000000000000000000000..5617ce272ba516a6923f2d3c9262df4b840169d1
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/data/RoleLevel.java
@@ -0,0 +1,114 @@
+package com.paradogs.framework.common.data;
+
+import com.paradogs.framework.common.utils.ExcelUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RoleLevel class generated by Freemarker.
+ * @Description: roleLevel(玩家等级).xlsx
+ */
+@Slf4j
+@Component
+public class RoleLevel {
+
+ private final static String fileName = "roleLevel(玩家等级).xlsx";
+
+ /**
+ * -1 项
+ */
+ private final static Config config;
+
+ /**
+ * 数据 map[id] = data
+ */
+ private final static Map dataMap;
+
+ /**
+ * 项目启动时初始化加载 Excel 配置
+ */
+ static {
+ try {
+ dataMap = new LinkedHashMap<>();
+ Config _config = new Config();
+ File file = new File("G:/project/me/git/paradogs/paradogs-framework/paradogs-framework-common/src/main/resources/data/roleLevel(玩家等级).xlsx");
+ List list = ExcelUtils.readGameData(file, Template.class);
+ for (Template template : list) {
+ if (template.getId() != null) {
+ if (template.getId().equals(-1)) {
+ BeanUtils.copyProperties(template, _config);
+ continue;
+ }
+ Data data = new Data();
+ BeanUtils.copyProperties(template, data);
+ dataMap.put(template.getId(), data);
+ }
+ }
+ config = _config;
+ log.info("Load Data: {}", fileName);
+ } catch (Exception e) {
+ throw new RuntimeException("Init [" + fileName + "] error");
+ }
+ }
+
+ public static Data getData(Long id) {
+ return dataMap.get(id);
+ }
+
+ public static Config getConfig() {
+ return config;
+ }
+
+ public static List listData() {
+ return (List) dataMap.values();
+ }
+
+ @lombok.Data
+ public static class Data {
+
+ /**
+ * id
+ */
+ private Long id;
+ /**
+ * 升级所需经验
+ */
+ private Long exp;
+ }
+
+ @lombok.Data
+ public static class Config {
+
+ /**
+ * id
+ */
+ private Long id;
+ /**
+ * 最大等级
+ */
+ private Long maxLevel;
+ }
+
+ @lombok.Data
+ public static class Template {
+ /**
+ * id
+ */
+ private Long id;
+ /**
+ * 升级所需经验
+ */
+ private Long exp;
+ /**
+ * 最大等级
+ */
+ private Long maxLevel;
+ }
+
+}
\ No newline at end of file
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Inventory.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Inventory.java
new file mode 100644
index 0000000000000000000000000000000000000000..b02b6cc100065380656a9d925ec5312e0468edf8
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Inventory.java
@@ -0,0 +1,38 @@
+package com.paradogs.framework.common.entity;
+
+import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.paradogs.framework.common.entity.base.BaseEntity;
+import java.io.Serializable;
+import java.util.Map;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ *
+ *
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = true)
+@TableName("g_inventory")
+@ProtobufClass
+public class Inventory extends BaseEntity {
+
+ /**
+ * 库存列表
+ */
+ @TableField("inventory")
+ private Map inventory;
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Player.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Player.java
index d3a3d31688e7d43e6ddae6a10a661807050c6cb8..b59b70c7e615b8c48146b10d7a9d8c2da91255af 100644
--- a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Player.java
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Player.java
@@ -1,12 +1,12 @@
package com.paradogs.framework.common.entity;
+import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-
import com.paradogs.framework.common.entity.base.BaseEntity;
-import lombok.AllArgsConstructor;
+import java.io.Serializable;
import lombok.Getter;
-import lombok.NoArgsConstructor;
import lombok.Setter;
/**
@@ -15,17 +15,13 @@ import lombok.Setter;
*
*
* @author yumi
- * @since 2023-11-20
+ * @since 2023-11-30
*/
@Getter
@Setter
-@AllArgsConstructor
-@NoArgsConstructor
@TableName("g_player")
public class Player extends BaseEntity {
- private static final long serialVersionUID = 1L;
-
@TableField("account")
private String account;
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Role.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2cb0309b636d08aeab4cd46eeb0786125a4d876
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/Role.java
@@ -0,0 +1,47 @@
+package com.paradogs.framework.common.entity;
+
+import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.paradogs.framework.common.entity.base.BaseEntity;
+import java.util.Map;
+
+import lombok.*;
+
+/**
+ *
+ *
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+@TableName("g_role")
+@ProtobufClass
+public class Role extends BaseEntity {
+
+ /**
+ * 等级
+ */
+ @TableField("level")
+ private Long level = 0L;
+
+ /**
+ * 经验值
+ */
+ @TableField("exp")
+ private Long exp = 0L;
+
+ /**
+ * 持有道具 map[道具 ID] = 数量
+ */
+ @TableField("bag")
+ private Map bag;
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/base/BaseEntity.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/base/BaseEntity.java
index 58ba82d3c14913412125fd5fb09bab7c43f84b0d..ebf13b29762b6cf27d458dbea9f731c6b059bb10 100644
--- a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/base/BaseEntity.java
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/entity/base/BaseEntity.java
@@ -1,19 +1,25 @@
package com.paradogs.framework.common.entity.base;
+import com.baidu.bjf.remoting.protobuf.FieldType;
+import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
+import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
+import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
+import java.util.Date;
/**
* @author: yumi
* @date: 2023/11/20 11:01
* @Description: TODO
*/
+@EqualsAndHashCode
@Data
public class BaseEntity implements Serializable {
@@ -27,12 +33,12 @@ public class BaseEntity implements Serializable {
* 创建时间
*/
@TableField(value = "createTime", fill = FieldFill.INSERT)
- private LocalDateTime createTime;
+ private Date createTime;
/**
* 更新时间
*/
@TableField(value = "updateTime", fill = FieldFill.UPDATE)
- private LocalDateTime updateTime;
+ private Date updateTime;
}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/InventoryMapper.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/InventoryMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd465702c0181b4751f391d4fb2ddfcf30255d32
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/InventoryMapper.java
@@ -0,0 +1,16 @@
+package com.paradogs.framework.common.mapper;
+
+import com.paradogs.framework.common.entity.Inventory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+public interface InventoryMapper extends BaseMapper {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/RoleMapper.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/RoleMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..d01588bca12604c57a7c506ea2c887e604a79039
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/mapper/RoleMapper.java
@@ -0,0 +1,16 @@
+package com.paradogs.framework.common.mapper;
+
+import com.paradogs.framework.common.entity.Role;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author yumi
+ * @since 2023-11-30
+ */
+public interface RoleMapper extends BaseMapper {
+
+}
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGatewayLogin.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGateLogin.java
similarity index 93%
rename from paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGatewayLogin.java
rename to paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGateLogin.java
index 0774ef97f5239b32d832e6097ee336c8de3a6fd1..eb78d0cb81a78b2dda3ab073972983f1ddb27735 100644
--- a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGatewayLogin.java
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/pojo/cg/CGGateLogin.java
@@ -16,7 +16,7 @@ import lombok.ToString;
@NoArgsConstructor
@ToString(callSuper = true)
@ProtobufClass
-public class CGGatewayLogin {
+public class CGGateLogin {
private String token;
diff --git a/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/utils/ExcelUtils.java b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/utils/ExcelUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..dabaa51d23c0d9bcc8177f9ed8cc1efd7ea694f9
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/utils/ExcelUtils.java
@@ -0,0 +1,105 @@
+package com.paradogs.framework.common.utils;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/5 21:48
+ * @Description: TODO
+ */
+public class ExcelUtils {
+
+ /**
+ * 读取 Excel 并返回数据集合
+ * @param excelFile Excel 文件
+ * @param targetClass 数据类型
+ * @param
+ * @return
+ */
+ public static List read(File excelFile, Class targetClass) {
+ ExcelDataTransformListener reader = new ExcelDataTransformListener<>();
+ /**
+ * 注意要调用 .sheet().doRead() 才会开始读取
+ */
+ EasyExcel.read(excelFile, targetClass, reader)
+ .sheet()
+ .doRead();
+
+ return reader.getData();
+ }
+
+ public static List readGameData(File excelFile, Class targetClass) {
+ GameDataTransformListener reader = new GameDataTransformListener<>();
+ /**
+ * 注意要调用 .sheet().doRead() 才会开始读取
+ */
+ EasyExcel.read(excelFile, targetClass, reader)
+ .sheet()
+ .doRead();
+
+ return reader.getData();
+ }
+
+ public static List read(File excelFile, String sheet, Class targetClass) {
+
+ ExcelDataTransformListener reader = new ExcelDataTransformListener<>();
+
+ /**
+ * 注意要调用 .sheet().doRead() 才会开始读取
+ */
+ EasyExcel.read(excelFile, targetClass, reader)
+ .sheet(sheet)
+ .doRead();
+
+ return reader.getData();
+ }
+
+ public static class ExcelDataTransformListener extends AnalysisEventListener {
+ @Getter
+ private List data = new ArrayList<>();
+ /**
+ * Excel 获取到每一条数据都会执行一次
+ */
+ @Override
+ public void invoke(T bean, AnalysisContext analysisContext) {
+ data.add(bean);
+ }
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+ }
+ }
+
+ public static class GameDataTransformListener extends AnalysisEventListener {
+ @Getter
+ private List data = new ArrayList<>();
+ /**
+ * Excel 获取到每一条数据都会执行一次
+ */
+ @Override
+ public void invoke(T bean, AnalysisContext context) {
+ int currentRowIndex = context.readRowHolder().getRowIndex();
+ if (currentRowIndex <= 1) {
+ return;
+ }
+ data.add(bean);
+ }
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+ }
+
+ @Override
+ public void onException(Exception exception, AnalysisContext context) throws Exception {
+ // 忽略第二行的参数类型 bean 转换报错
+ }
+ }
+
+}
diff --git "a/paradogs-framework/paradogs-framework-common/src/main/resources/data/roleLevel(\347\216\251\345\256\266\347\255\211\347\272\247).xlsx" "b/paradogs-framework/paradogs-framework-common/src/main/resources/data/roleLevel(\347\216\251\345\256\266\347\255\211\347\272\247).xlsx"
new file mode 100644
index 0000000000000000000000000000000000000000..f20842d5e0e24d849782a1a583309303f3fc7bf1
Binary files /dev/null and "b/paradogs-framework/paradogs-framework-common/src/main/resources/data/roleLevel(\347\216\251\345\256\266\347\255\211\347\272\247).xlsx" differ
diff --git a/paradogs-framework/paradogs-framework-common/src/main/resources/mapper/PlayerMapper.xml b/paradogs-framework/paradogs-framework-common/src/main/resources/mapper/PlayerMapper.xml
deleted file mode 100644
index 2378f5dfaeabc12252d93159b5b927ab9504f163..0000000000000000000000000000000000000000
--- a/paradogs-framework/paradogs-framework-common/src/main/resources/mapper/PlayerMapper.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/EnableParadogs.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/EnableParadogs.java
index 5422afed528d04395b8964a6a3c717b0259401fd..9e947540a2f7b0c8d780d7ea8e404fed412032ae 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/EnableParadogs.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/EnableParadogs.java
@@ -30,7 +30,8 @@ import java.lang.annotation.Target;
NettyConfiguration.class,
QueueConfiguration.class,
RPCConfiguration.class,
- MybatisPlusConfiguration.class
+ MybatisPlusConfiguration.class,
+ DataConfiguration.class
})
public @interface EnableParadogs {
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/request/PRMsgMapping.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/request/PRMsgMapping.java
index 6c60992d5e37d0afe633800d0d245d0fff19f852..17a76472ff0756bf25b1edd950cd88e854c5f32e 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/request/PRMsgMapping.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/request/PRMsgMapping.java
@@ -21,6 +21,10 @@ public @interface PRMsgMapping {
*/
String value();
+ /**
+ * 是否异步执行,为 true 会将方法放在 CompleteFuture 中执行
+ * @return
+ */
boolean async() default false;
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/rpc/PRRPCProxyInterceptor.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/rpc/PRRPCProxyInterceptor.java
index dcccd6600c7699f05b995db821a2d52569269915..822e4158a4c8b1a8cad5da500dd97c3912debd10 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/rpc/PRRPCProxyInterceptor.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/annoations/rpc/PRRPCProxyInterceptor.java
@@ -71,10 +71,6 @@ public class PRRPCProxyInterceptor implements MethodInterceptor {
// 获得返回值类型
Class> returnType = method.getReturnType();
- if (returnType.equals(Void.TYPE)) {
- return null;
- }
-
/**
* 监听回调
*/
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/DataConfiguration.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/DataConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9fae2d5c1743a5563e887020076a8053fa2dfb3
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/DataConfiguration.java
@@ -0,0 +1,14 @@
+package com.paradogs.framework.core.config;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/6 14:32
+ * @Description: TODO
+ */
+@AutoConfiguration
+@ComponentScan(basePackages = {"com.paradogs.framework.common.data"}) // 指定的是目录
+public class DataConfiguration {
+}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/MybatisPlusConfiguration.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/MybatisPlusConfiguration.java
index d21a324db125922e5a362244f927c64ed8e591bd..42044dba60ca89b028f2d53c065cbacce71907d1 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/MybatisPlusConfiguration.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/MybatisPlusConfiguration.java
@@ -3,6 +3,7 @@ package com.paradogs.framework.core.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -14,12 +15,12 @@ import java.time.LocalDateTime;
* @date: 2023/11/20 11:17
* @Description: TODO
*/
-@Configuration
/**
* mybatis-plus 扫描要精确到 dao 或 mapper,否则自动装配会有问题(dao(service)找不到正确 mapper)
* 可能原因是扫描重叠了,dao(service)也被当成 mapper 自动生成代理实现类了
* !!! 虽然是微服务,但是所有业务的 dao 都放在一起了,!! 方便单人开发 !!,如果需要正常的微服务操作,可以取消这里的注册,自行在对应服务中编写 dao 和 pojo
*/
+@AutoConfiguration
@ComponentScan(basePackages = {"com.paradogs.framework.common.dao.*"}) // 要精确到 dao
@MapperScan("com.paradogs.framework.common.mapper") // 不能加 *
public class MybatisPlusConfiguration {
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/QueueConfiguration.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/QueueConfiguration.java
index 45d2599211f1c4dda7e2b9f100ee5ec00ba1f120..bedd79f7e0fca87863ad83bcea19ad8b9d7a5a42 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/QueueConfiguration.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/config/QueueConfiguration.java
@@ -1,9 +1,6 @@
package com.paradogs.framework.core.config;
-import com.paradogs.framework.core.queue.AbstractMsgConsumer;
-import com.paradogs.framework.core.queue.MsgDefaultConsumer;
-import com.paradogs.framework.core.queue.PRQueueHolder;
-import com.paradogs.framework.core.queue.QueueProperties;
+import com.paradogs.framework.core.queue.*;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@@ -24,6 +21,12 @@ public class QueueConfiguration {
public AbstractMsgConsumer defaultMsgConsumer() {
return new MsgDefaultConsumer();
}
+ @Bean
+ @Scope("prototype")
+ @ConditionalOnMissingBean(DBConsumer.class)
+ public DBConsumer dbConsumer() {
+ return new DBConsumer();
+ }
@Bean
public QueueProperties queueProperties() {
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/ByteData.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/ByteData.java
index 038706a83dd14e706e20041cf035f43c9c745d5b..85f7ef0c8a59087e09e07fb542cc39358c4dfa96 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/ByteData.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/ByteData.java
@@ -23,6 +23,9 @@ public class ByteData implements IMsgSerializable {
@Protobuf(fieldType = FieldType.BYTES, order = 2)
private byte[] dataBytes;
+
+ private PRMsgContextHolder.Snapshot context;
+
@Override
public void serialization(ByteBuf out) {
out.writeBytes(this.dataBytes);
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/MsgHeader.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/MsgHeader.java
index f215ee773e453e3720f7dbbb79cec1f182f83290..8223dcb33fd79ac6c09bd10e57778cf13c4eab1b 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/MsgHeader.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/MsgHeader.java
@@ -15,6 +15,7 @@ import lombok.ToString;
import java.io.IOException;
import java.time.LocalDateTime;
+import java.util.Arrays;
/**
@@ -56,25 +57,18 @@ public class MsgHeader implements IMsgSerializable {
@Protobuf(fieldType = FieldType.INT64, order = 4, required = false)
private Long replyMsgId;
+ /**
+ * 玩家 ID
+ */
+ @Protobuf(fieldType = FieldType.INT64, order = 5, required = false)
+ private Long pId;
+
// /**
// * 消息生成的时间戳
// */
// @Protobuf(fieldType = FieldType.INT64, order = 3, required = false)
// private Long timestamp;
- /**
- * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 额外 Props
- */
-
- /**
- * 玩家 ID
- */
- private Long pId;
-
- /**
- * 创建时间
- */
- private LocalDateTime createTime = LocalDateTime.now();
/**
* 序列化(编码)
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/PRMsgContextHolder.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/PRMsgContextHolder.java
index 59900358f6033db98caba1895b1c0c5e9c3d6dd3..52bb2c7e0791801779d9d2797dace6973bf07f61 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/PRMsgContextHolder.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/PRMsgContextHolder.java
@@ -12,24 +12,23 @@ import lombok.*;
@Data
public class PRMsgContextHolder {
- @Getter
- private static ChannelHandlerContext ctx;
-
- @Getter
- private static Long playerId;
+ /**
+ * 上下文信息
+ */
+ private static ThreadLocal context = new ThreadLocal<>();
- @Getter
- private static Channel channel;
+ public static void releaseContext() {
+ context.remove();
+ }
- public static void setContext(ChannelHandlerContext ctx, Long playerId) {
- PRMsgContextHolder.ctx = ctx;
- PRMsgContextHolder.playerId = playerId;
+ public static void setContext(ChannelHandlerContext ctx, Long playerId, MsgHeader header) {
+ Snapshot snapshot = new Snapshot(ctx, playerId, header);
+ context.set(snapshot);
}
public static void setContext(Snapshot snapshot) {
- PRMsgContextHolder.ctx = snapshot.ctx;
- PRMsgContextHolder.playerId = snapshot.playId;
+ context.set(snapshot);
}
@@ -37,14 +36,35 @@ public class PRMsgContextHolder {
* 返回当前上下文快照
*/
public static PRMsgContextHolder.Snapshot getSnapshot() {
- return new PRMsgContextHolder.Snapshot(PRMsgContextHolder.ctx, playerId);
+ return context.get();
}
public static Channel getChannel() {
- if (PRMsgContextHolder.getCtx() != null) {
- return PRMsgContextHolder.getCtx().channel();
+ return getCtx().channel();
+ }
+
+ public static ChannelHandlerContext getCtx() {
+ Snapshot snapshot = getSnapshot();
+ if (snapshot == null) {
+ return null;
+ }
+ return snapshot.getCtx();
+ }
+
+ public static Long getPlayerId() {
+ Snapshot snapshot = getSnapshot();
+ if (snapshot == null) {
+ return null;
+ }
+ return snapshot.getPlayId();
+ }
+
+ public static MsgHeader getMsgHeader() {
+ Snapshot snapshot = getSnapshot();
+ if (snapshot == null) {
+ return null;
}
- return null;
+ return snapshot.getHeader();
}
/**
@@ -56,6 +76,7 @@ public class PRMsgContextHolder {
public static class Snapshot {
private ChannelHandlerContext ctx;
private Long playId;
+ private MsgHeader header;
}
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/R.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/R.java
new file mode 100644
index 0000000000000000000000000000000000000000..15935a2ff90684f9ba8a5359721f0a066bf1e949
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/msg/R.java
@@ -0,0 +1,44 @@
+package com.paradogs.framework.core.msg;
+
+import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass;
+import com.paradogs.framework.common.entity.Inventory;
+import com.paradogs.framework.common.entity.Role;
+import com.paradogs.framework.core.utils.ProtoUtils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author: yumi
+ * @date: 2023/11/30 16:46
+ * @Description: SyncData 客户端统一返回
+ */
+@Data
+@ProtobufClass
+public class R {
+
+ private Long playerId;
+
+ /**
+ * 回复数据
+ */
+ private byte[] replyData;
+
+ /**
+ * 数据变化时的同步数据
+ */
+ private Role role;
+
+ private Inventory inventory;
+
+
+ public R() {}
+ public R(byte[] data) {
+ this.replyData = data;
+ }
+
+
+ public static R success(T data) {
+ return new R(ProtoUtils.encode(data));
+ }
+
+}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRAbMsgHandler.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRAbMsgHandler.java
index 65712163451c7dc33c0b9476c70ed348015be97e..f0fb9a1bc842389a7023d9fb6d451e395eb7b22a 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRAbMsgHandler.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRAbMsgHandler.java
@@ -35,7 +35,8 @@ public abstract class PRAbMsgHandler extends SimpleChannelInboundHandler {
* @param msg
*/
protected void setContext(ChannelHandlerContext ctx, ByteData msg) {
- PRMsgContextHolder.setContext(ctx, msg.getMsgHeader().getPId());
+ PRMsgContextHolder.setContext(ctx, msg.getMsgHeader().getPId(), msg.getMsgHeader());
+ msg.setContext(PRMsgContextHolder.getSnapshot()); // 队列线程和 netty 线程不一样,要保存转移设置
}
/**
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRCodec.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRCodec.java
index 5b7e717cd65a34017d78d1ee452f5aabaf22497c..c3383e7ce4a8586aa3f6360388f92f841fdcd718 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRCodec.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/PRCodec.java
@@ -29,9 +29,12 @@ public class PRCodec extends ByteToMessageCodec {
@Override
protected void encode(ChannelHandlerContext ctx, PRMsg msg, ByteBuf out) throws Exception {
- msg.getMsgHeader().serialization(out);
-
- msg.serialization(out);
+ try {
+ msg.getMsgHeader().serialization(out);
+ msg.serialization(out);
+ } catch (Exception e) {
+ log.error("Encode error: {}", e.getMessage(), e);
+ }
}
@@ -51,4 +54,9 @@ public class PRCodec extends ByteToMessageCodec {
}
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ log.error("{}", cause.getMessage(), cause);
+ super.exceptionCaught(ctx, cause);
+ }
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/server/PRConnection.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/server/PRConnection.java
index 804f96b5bea802ad4e775d73a5bc62524416080e..fe737a11514b8df9ea616e3e21fc309b27859d39 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/server/PRConnection.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/netty/server/PRConnection.java
@@ -17,12 +17,6 @@ import java.time.LocalDateTime;
@NoArgsConstructor
public class PRConnection {
- public PRConnection(Channel channel, ServerProperties properties) {
- this.channel = channel;
- this.type = properties.getType();
- this.properties = properties;
- }
-
/**
* player、gate、master、login、...
*/
@@ -32,6 +26,12 @@ public class PRConnection {
private ServerProperties properties;
+ public PRConnection(Channel channel, ServerProperties properties) {
+ this.channel = channel;
+ this.type = properties.getType();
+ this.properties = properties;
+ }
+
public boolean isInit() {
return properties != null;
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/AbstractMsgConsumer.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/AbstractMsgConsumer.java
index a826c376b5e829fe4c6671b72502cfecdf0c4e4a..7f79db5f800010530099a06121c1833bae7a8a86 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/AbstractMsgConsumer.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/AbstractMsgConsumer.java
@@ -1,6 +1,7 @@
package com.paradogs.framework.core.queue;
import com.paradogs.framework.core.msg.ByteData;
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
import com.paradogs.framework.core.netty.events.MainLoopEvent;
import com.paradogs.framework.core.utils.EventUtils;
@@ -18,4 +19,9 @@ public abstract class AbstractMsgConsumer extends QueueConsumerThread
EventUtils.publishEvent(mainLoopEvent);
}
+ @Override
+ public void handleBefore(ByteData msg) {
+ super.handleBefore(msg);
+ PRMsgContextHolder.setContext(msg.getContext());
+ }
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBConsumer.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBConsumer.java
new file mode 100644
index 0000000000000000000000000000000000000000..04ed0f2a954bcec11f22bae3b835dd33fc560c19
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBConsumer.java
@@ -0,0 +1,32 @@
+package com.paradogs.framework.core.queue;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/9 20:20
+ * @Description: TODO
+ */
+@Slf4j
+public class DBConsumer extends QueueConsumerThread {
+
+ /**
+ * 保存到 DB,如果出现异常很危险
+ * @param msg
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ */
+ @Override
+ public void handle(DBUpdatMsg msg) throws InvocationTargetException, IllegalAccessException {
+ IService dao = msg.getDao();
+ dao.saveOrUpdate(msg.getData());
+ log.debug("保存 DB 成功:{}", msg.getData());
+ }
+
+ @Override
+ public void loop() {
+ }
+}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBUpdatMsg.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBUpdatMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..9cf63229462d1988b7ea6a46646bb14e1601fb25
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/DBUpdatMsg.java
@@ -0,0 +1,34 @@
+package com.paradogs.framework.core.queue;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/9 20:27
+ * @Description: 暂时事务更新
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DBUpdatMsg {
+
+ /**
+ * 玩家 ID
+ */
+ private Long pId;
+
+ /**
+ * 操作的 dao
+ */
+ private IService dao;
+
+ /**
+ * dao 对应的 data
+ */
+ private T data;
+
+}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/PRQueueHolder.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/PRQueueHolder.java
index bf36baa30c31e63b78bbf6e2283fb40cfc289f77..7ec00bf80ec1a3ab0d0080bcdaa3356cdc92eed1 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/PRQueueHolder.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/PRQueueHolder.java
@@ -39,6 +39,7 @@ public class PRQueueHolder implements ApplicationRunner {
*/
public void init() {
initQueue(QueueType.MAIN, queueProperties.getMainSize());
+ initQueue(QueueType.DB, queueProperties.getDbSize());
}
public void initQueue(QueueType type, int size) {
@@ -50,7 +51,11 @@ public class PRQueueHolder implements ApplicationRunner {
queueConsumer.setLoop(true);
}
queueConsumer.setKey(type.key + "-" + (i + 1));
- queueConsumer.start();
+ try {
+ queueConsumer.start();
+ } catch (IllegalThreadStateException e) {
+ throw new RuntimeException("Consumer[" + queueConsumer.getClass().getName() + "] is singleton, please use @Scope(\"prototype\")");
+ }
if (!consumerMap.containsKey(type)) {
consumerMap.put(type, new ArrayList<>());
}
@@ -68,7 +73,11 @@ public class PRQueueHolder implements ApplicationRunner {
/**
* 消息逻辑处理
*/
- MAIN(AbstractMsgConsumer.class, "MainMsgConsumer");
+ MAIN(AbstractMsgConsumer.class, "MainMsgConsumer"),
+ /**
+ * DB 持久化处理
+ */
+ DB(DBConsumer.class, "DBConsumer");
/**
* 消费对象类型
@@ -88,6 +97,9 @@ public class PRQueueHolder implements ApplicationRunner {
public static void putMsg(QueueType queueType, ByteData msg) throws InterruptedException {
balance(consumerMap.get(queueType), msg).produce(msg);
}
+ public static void putMsg(QueueType queueType, DBUpdatMsg msg) {
+ balance(consumerMap.get(queueType), msg).produce(msg);
+ }
/**
* 待优化,负载均衡规则,可以换成一个接口
@@ -99,6 +111,13 @@ public class PRQueueHolder implements ApplicationRunner {
}
return list.get((int) (msg.getMsgHeader().getPId() % list.size()));
}
+ private static QueueConsumerThread balance(List list, DBUpdatMsg msg) {
+ if (msg.getPId() == null) {
+ return list.get(0);
+ }
+ return list.get((int) (msg.getPId() % list.size()));
+ }
+
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueConsumerThread.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueConsumerThread.java
index 09ca20fd688afbe53e73ae079346d6b7f9b8df7a..4d3c2843de99dced6aeaa3e03e657f6da0bdd20c 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueConsumerThread.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueConsumerThread.java
@@ -1,6 +1,7 @@
package com.paradogs.framework.core.queue;
import com.paradogs.framework.core.exceptions.GlobalExceptionDispatch;
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
import com.paradogs.framework.core.utils.SpringUtils;
import com.paradogs.framework.core.utils.StringUtils;
import lombok.Getter;
@@ -53,6 +54,11 @@ public abstract class QueueConsumerThread extends Thread {
@Setter
private boolean isLoop = false;
+ /**
+ * 线程是否正在运行,用于单例防错
+ */
+ private boolean isRunning = false;
+
/**
* 全局异常处理转发器
*/
@@ -70,6 +76,9 @@ public abstract class QueueConsumerThread extends Thread {
*/
public abstract void handle(T msg) throws InvocationTargetException, IllegalAccessException;
+ public void handleBefore(T msg) {}
+ public void handleAfter(T msg) {}
+
/**
* 循环检测
*/
@@ -82,14 +91,17 @@ public abstract class QueueConsumerThread extends Thread {
while (true) {
+ /**
+ * 循环检测事件
+ */
if (isLoop) {
- // 循环检测事件
loop();
}
+ /**
+ * 处理消息,消息队列为空时,等待一段时间再处理,如果有消息则处理完直接找下一个
+ */
T msg = queue.poll();
-
- // 消息队列为空时,等待一段时间再处理,如果有消息则处理完直接找下一个
if (msg == null) {
try {
Thread.sleep(100);
@@ -103,9 +115,15 @@ public abstract class QueueConsumerThread extends Thread {
this.handleCount++;
try {
+ handleBefore(msg);
+ PRMsgContextHolder.getSnapshot();
+
handle(msg);
+
+ handleAfter(msg);
+
} catch (Exception e) {
- // 转发到全局异常处理
+ // 出现异常时,转发到全局异常处理
globalExceptionDispatch.forward(e);
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueProperties.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueProperties.java
index 798e84c96e96aca1d0d6ad974af59528632982d4..baf03262a664abfde061af18891ec2ea7b9ff006 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueProperties.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/queue/QueueProperties.java
@@ -21,4 +21,9 @@ public class QueueProperties {
*/
private int mainSize = 1;
+ /**
+ * DB 持久化消息处理队列
+ */
+ private int dbSize = 0;
+
}
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/MsgUtils.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/MsgUtils.java
index f23cf76833322f8495e4e575c85cdace2c30155c..e816d19b81b54c390ca8398aff325db0ea058c4d 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/MsgUtils.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/MsgUtils.java
@@ -12,6 +12,7 @@ import com.paradogs.framework.core.msg.PRMsg;
import com.paradogs.framework.core.msg.ByteData;
import com.paradogs.framework.core.msg.MsgHeader;
import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
@@ -43,12 +44,18 @@ public class MsgUtils {
/**
* 发起 rpc 请求
* @param event
+ * 待优化:先发送再监听可能会赶不上,概率较小
*/
@EventListener(RPCRequestEvent.class)
public void onRPCRequestEvent(RPCRequestEvent event) {
// 发起请求
+ MsgHeader msgHeader = PRMsgContextHolder.getMsgHeader();
+
PRMsg msg = send(event.getRoute(), event.getData());
// 开启响应监听
+ if (event.getReturnClass() == null || event.getReturnClass().equals(Void.TYPE)) {
+ return;
+ }
EventUtils.on4Once(event.getRoute(), msg.getMsgHeader().getId(), event.getReturnClass(), event.getPromise());
}
@@ -88,8 +95,12 @@ public class MsgUtils {
/**
* 异步执行
*/
+ final PRMsgContextHolder.Snapshot mainThreadContextSnapshot = PRMsgContextHolder.getSnapshot();
PRAsync.run(() -> {
try {
+ // 将主线程上下文设置到异步线程上下文
+ PRMsgContextHolder.setContext(mainThreadContextSnapshot);
+ // 执行方法
Object result = method.invoke(
pdgController,
Stream.of(method.getParameterTypes())
@@ -116,6 +127,9 @@ public class MsgUtils {
reply(header.getSendServer(), result, msg.getMsgHeader().getId(), PRMsgContextHolder.getChannel());
} catch (Exception e) {
throw new MessageException(e);
+ } finally {
+ // 释放上下文,切面可能会受影响取不到? 待优化
+ PRMsgContextHolder.releaseContext();
}
});
} else {
@@ -158,8 +172,9 @@ public class MsgUtils {
*/
public static PRMsg send(String route, T data, Channel channel) {
PRMsg msg = new PRMsg(route, data);
+ msg.getMsgHeader().setPId(PRMsgContextHolder.getPlayerId());
channel.writeAndFlush(msg);
- log.debug(">>>>> {}, {}", route, data);
+ log.debug(">>>>> {}, {}, {}", route, data, msg.getMsgHeader().getId());
return msg;
}
protected static PRMsg send(String route, T data) {
@@ -173,7 +188,7 @@ public class MsgUtils {
* @param data 数据
* @param replyId 回复的消息 ID
*/
- protected static void reply(String server, T data, Long replyId, Channel channel) {
+ public static void reply(String server, T data, Long replyId, Channel channel) {
// 返回消息
MsgHeader header = new MsgHeader();
header.setRoute(server + RouteUtils.SERVER_SEPARATOR + "_paradogs.callback");
@@ -182,7 +197,7 @@ public class MsgUtils {
// 发送 GC
// Channel channel = getChannel(server);
channel.writeAndFlush(gcMsg);
- log.debug("[reply] >>>>> {}, {}", server, data);
+ log.debug("[reply] >>>>> {}, {}, {}", server, header, data);
}
/**
@@ -200,17 +215,17 @@ public class MsgUtils {
/**
* Gate 服转发消息: 特殊处理,直接发送到对应服
*/
- public static void gateRequest(String route, T data, Class> returnClass, CompletableFuture promise) {
- PRMsg msg = new PRMsg(route, data);
- String server = RouteUtils.getServer(route);
+ public static void gateRequest(MsgHeader header, T data, Class> returnClass, CompletableFuture promise) {
+ PRMsg msg = new PRMsg(header, data);
+ String server = RouteUtils.getServer(header.getRoute());
PRConnection conn = PRConnHolder.getConn(server);
if (conn == null) {
throw new MessageException("Not Found Connection, server: " + server);
}
// 开启响应监听
- EventUtils.on4Once(route, msg.getMsgHeader().getId(), returnClass, promise);
+ EventUtils.on4Once(header.getRoute(), msg.getMsgHeader().getId(), returnClass, promise);
conn.getChannel().writeAndFlush(msg);
- log.debug("[request] >>>>> {}, {}", route, msg);
+ log.debug("[request] >>>>> {}, {}", header.getRoute(), msg);
}
protected static Channel getChannel(String server) {
diff --git a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/ReflectUtils.java b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/ReflectUtils.java
index c2190e77740715fdc28f69ca97ddaf8743913dfd..b28c2ac0d5ff95a8f30581121a27388301bbf5e7 100644
--- a/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/ReflectUtils.java
+++ b/paradogs-framework/paradogs-framework-core/src/main/java/com/paradogs/framework/core/utils/ReflectUtils.java
@@ -1,5 +1,7 @@
package com.paradogs.framework.core.utils;
+import lombok.extern.slf4j.Slf4j;
+
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -9,6 +11,7 @@ import java.lang.reflect.Type;
* @date: 2023/9/23 9:57
* @Description: 反射工具类
*/
+@Slf4j
public class ReflectUtils {
/**
@@ -32,4 +35,30 @@ public class ReflectUtils {
return null;
}
+ /**
+ * 调用 setter 方法
+ * @param obj
+ * @param fieldName
+ * @param value
+ */
+ public static void callSetter(Object obj, String fieldName, Object value) {
+ try {
+ String methodName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
+ Method method = findMethod(obj.getClass(), methodName, value.getClass());
+ if (method != null) {
+ method.invoke(obj, value);
+ }
+ } catch (Exception e) {
+ // 处理异常
+ log.error("setter error, field: {}, value: {}, {}", fieldName, value, e.getMessage(), e);
+ }
+ }
+ private static Method findMethod(Class> clazz, String methodName, Class> parameterType) {
+ try {
+ return clazz.getMethod(methodName, parameterType);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
}
diff --git a/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/GateChannelHolder.java b/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/GateChannelHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad15415ff17168b43ee6640eec541fb806a8e0a2
--- /dev/null
+++ b/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/GateChannelHolder.java
@@ -0,0 +1,78 @@
+package com.paradogs.framework.gate;
+
+import com.paradogs.framework.core.msg.PRMsgContextHolder;
+import io.netty.channel.Channel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/1 11:27
+ * @Description: 玩家连接管理
+ */
+public class GateChannelHolder {
+
+ /**
+ * map[channel] = session
+ */
+ private static Map channelMap = new HashMap<>();
+ /**
+ * map[playerId] = channel
+ */
+ private static Map playerMap = new HashMap<>();
+
+
+ public static void init(Channel channel) {
+ channelMap.put(channel, null);
+ }
+ public static void remove(Channel channel) {
+ Session session = channelMap.remove(channel);
+ if (session != null && session.getPlayerId() != null) {
+ playerMap.remove(session.getPlayerId());
+ }
+ }
+
+ /**
+ * 获得 Channel 对应数据
+ * @param channel
+ * @return
+ */
+ public static Session getSession(Channel channel) {
+ return channelMap.get(channel);
+ }
+
+ /**
+ * 绑定 Channel 数据
+ * @param channel
+ * @param session
+ */
+ public static void bindSession(Channel channel, Session session) {
+ channelMap.put(channel, session);
+ playerMap.put(session.getPlayerId(), channel);
+ // 重新设置当前上下文
+ PRMsgContextHolder.Snapshot snapshot = PRMsgContextHolder.getSnapshot();
+ snapshot.setPlayId(session.getPlayerId());
+ PRMsgContextHolder.setContext(snapshot);
+ }
+
+ /**
+ * 获取玩家 ID 的 Channel
+ * @param playerId
+ * @return
+ */
+ public static Channel getPlayerChannel(Long playerId) {
+ return playerMap.get(playerId);
+ }
+
+ @Data
+ @AllArgsConstructor
+ @NoArgsConstructor
+ public static class Session {
+ private Long playerId;
+ }
+
+}
diff --git a/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/PRGateServerMsgHandler.java b/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/PRGateServerMsgHandler.java
index cc2b042660ebd582e461b2d80f1bf245fd470f44..982389e9dca2e31b7ce91b900ee32e1106967a6b 100644
--- a/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/PRGateServerMsgHandler.java
+++ b/paradogs-framework/paradogs-framework-gate-starter/src/main/java/com/paradogs/framework/gate/PRGateServerMsgHandler.java
@@ -36,8 +36,12 @@ public class PRGateServerMsgHandler extends PRAbServerMsgHandler {
@Override
protected void setProps(ChannelHandlerContext ctx, ByteData msg) {
super.setProps(ctx, msg);
+ GateChannelHolder.Session session = GateChannelHolder.getSession(ctx.channel());
+ if (session != null) {
+ msg.getMsgHeader().setPId(session.getPlayerId());
+ }
if (StringUtils.isBlank(msg.getMsgHeader().getSendServer())) {
- msg.getMsgHeader().setSendServer("gate");
+ msg.getMsgHeader().setSendServer("player");
}
}
@@ -56,9 +60,11 @@ public class PRGateServerMsgHandler extends PRAbServerMsgHandler {
// 待优化:如果 logic 方法没有返回值,这里会无限等待,内存溢出
CompletableFuture promise = new CompletableFuture<>();
promise.thenAccept(data -> {
+ // 回复客户端
MsgUtils.send("player", data, PRMsgContextHolder.getChannel());
});
- MsgUtils.gateRequest(msg.getMsgHeader().getRoute(), msg.getDataBytes(), byte[].class, promise);
+ // 转发到对应服务器
+ MsgUtils.gateRequest(msg.getMsgHeader(), msg.getDataBytes(), byte[].class, promise);
}
/**
@@ -69,6 +75,7 @@ public class PRGateServerMsgHandler extends PRAbServerMsgHandler {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
+ GateChannelHolder.init(ctx.channel());
EventUtils.publishEvent(new PlayerClientActiveEvent(ctx));
log.info("PlayerClient connect: {}", IPUtils.getAddr(ctx.channel()));
}
@@ -81,6 +88,7 @@ public class PRGateServerMsgHandler extends PRAbServerMsgHandler {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
+ GateChannelHolder.remove(ctx.channel());
EventUtils.publishEvent(new PlayerClientInactiveEvent(ctx));
log.info("PlayerClient disconnect: {}", IPUtils.getAddr(ctx.channel()));
}
diff --git a/paradogs-framework/paradogs-framework-gate-starter/src/main/resources/config/application.yml b/paradogs-framework/paradogs-framework-gate-starter/src/main/resources/config/application.yml
index cfc460e9f4b289a18f0b81ab212f825eff7bac38..02079458bfb7c4e4a5f7cb43fc74aa43fbe86c4d 100644
--- a/paradogs-framework/paradogs-framework-gate-starter/src/main/resources/config/application.yml
+++ b/paradogs-framework/paradogs-framework-gate-starter/src/main/resources/config/application.yml
@@ -1,6 +1,3 @@
paradogs:
queue:
- enable: false
- main-size: 1
- db-size: 1
-
+ main-size: 1
\ No newline at end of file
diff --git a/paradogs-framework/paradogs-framework-master-starter/src/main/java/com/paradogs/framework/master/netty/MasterMsgHandler.java b/paradogs-framework/paradogs-framework-master-starter/src/main/java/com/paradogs/framework/master/netty/MasterMsgHandler.java
index 034a85705003bde48e59eb7a5b0fc47ebe012981..f187f887ec5e29147ae1e35639f5589fd049175e 100644
--- a/paradogs-framework/paradogs-framework-master-starter/src/main/java/com/paradogs/framework/master/netty/MasterMsgHandler.java
+++ b/paradogs-framework/paradogs-framework-master-starter/src/main/java/com/paradogs/framework/master/netty/MasterMsgHandler.java
@@ -61,7 +61,7 @@ public class MasterMsgHandler extends PRAbServerMsgHandler {
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
PRConnection conn = PRConnHolder.removeConn(ctx.channel());
- log.info("Client disconnect: {}", conn);
+
EventUtils.publishEvent(new ServerClientInactiveEvent(ctx));
}
}
diff --git a/paradogs-framework/paradogs-framework-server-starter/src/main/java/com/paradogs/framework/server/ServerMsgConsumer.java b/paradogs-framework/paradogs-framework-server-starter/src/main/java/com/paradogs/framework/server/ServerMsgConsumer.java
index 15f94e1dd9b7ad5d1c200b6d0c541394593a7f2f..c60be83c138466c900a34e9be888256fc656cea8 100644
--- a/paradogs-framework/paradogs-framework-server-starter/src/main/java/com/paradogs/framework/server/ServerMsgConsumer.java
+++ b/paradogs-framework/paradogs-framework-server-starter/src/main/java/com/paradogs/framework/server/ServerMsgConsumer.java
@@ -6,7 +6,9 @@ import com.paradogs.framework.core.queue.AbstractMsgConsumer;
import com.paradogs.framework.core.utils.MsgUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
@@ -17,8 +19,10 @@ import java.lang.reflect.InvocationTargetException;
* @Description: TODO
*/
@Slf4j
+@Scope("prototype")
@Primary
@Component
+@ConditionalOnMissingBean(ServerMsgConsumer.class)
public class ServerMsgConsumer extends AbstractMsgConsumer {
diff --git a/paradogs-framework/paradogs-framework-server-starter/src/main/resources/config/application.yml b/paradogs-framework/paradogs-framework-server-starter/src/main/resources/config/application.yml
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..240760f51b31b6fa173bb66ad564aeb26c31567a 100644
--- a/paradogs-framework/paradogs-framework-server-starter/src/main/resources/config/application.yml
+++ b/paradogs-framework/paradogs-framework-server-starter/src/main/resources/config/application.yml
@@ -0,0 +1,4 @@
+paradogs:
+ queue:
+ main-size: 3
+ db-size: 3
\ No newline at end of file
diff --git a/paradogs-framework/pom.xml b/paradogs-framework/pom.xml
index cefa03056d1c57f83172e79807f9c0abdaa1a1eb..4aa83d34afa87bf0d4cbe4def7fc120b42e97fe9 100644
--- a/paradogs-framework/pom.xml
+++ b/paradogs-framework/pom.xml
@@ -11,11 +11,11 @@
paradogs-framework
pom
+ paradogs-framework-common
paradogs-framework-core
paradogs-framework-gate-starter
paradogs-framework-server-starter
paradogs-framework-master-starter
- paradogs-framework-common
\ No newline at end of file
diff --git a/paradogs-generator/pom.xml b/paradogs-generator/pom.xml
index f363f258e2ed69fe0e992fd49327ea844b3ea9e4..ca223a7ce29bdae556007cd789c41f61e99002d6 100644
--- a/paradogs-generator/pom.xml
+++ b/paradogs-generator/pom.xml
@@ -37,6 +37,10 @@
com.paradogs
paradogs-framework-core
+
+ com.alibaba
+ easyexcel
+
\ No newline at end of file
diff --git a/paradogs-generator/src/main/java/com/paradogs/generator/DBEntityGenerator.java b/paradogs-generator/src/main/java/com/paradogs/generator/DBEntityGenerator.java
index c1cde167f3a1f02cdd9937ec3daf662f1681a87e..47ee4a69c84a00b359a36dc92692e3135d0532cd 100644
--- a/paradogs-generator/src/main/java/com/paradogs/generator/DBEntityGenerator.java
+++ b/paradogs-generator/src/main/java/com/paradogs/generator/DBEntityGenerator.java
@@ -11,7 +11,7 @@ import java.util.Collections;
/**
* @author: yumi
* @date: 2023/11/14 10:00
- * @Description: TODO
+ * @Description: DB 实体类生成器,待优化,代码生成等项目完善之后再做完整的代码生成 !!!
*/
public class DBEntityGenerator {
public static void main(String[] args) {
@@ -22,8 +22,7 @@ public class DBEntityGenerator {
.globalConfig(builder -> {
builder.author("yumi") // 设置作者
.commentDate("yyyy-MM-dd")
- .outputDir(System.getProperty("user.dir") + "/paradogs-framework/paradogs-framework-common/src/main/java") // 设置输出目录为项目的src/main/java目录
- .fileOverride(); // 覆盖已生成文件
+ .outputDir(System.getProperty("user.dir") + "/paradogs-framework/paradogs-framework-common/src/main/java"); // 设置输出目录为项目的src/main/java目录
})
.packageConfig(builder -> {
builder.parent("com.paradogs.framework.common") // 设置父包名
@@ -36,12 +35,16 @@ public class DBEntityGenerator {
builder
// .addInclude("table_name") // 设置需要生成的表名,如果要生成所有表,可以省略此行
.addTablePrefix("g_")
+
.entityBuilder()
+ .enableFileOverride() // // 覆盖已生成文件
.enableLombok()
.superClass(BaseEntity.class)
.enableTableFieldAnnotation() // 增加 @TableField
.idType(IdType.AUTO)
+
.serviceBuilder()
+ .enableFileOverride() // // 覆盖已生成文件
.formatServiceFileName("%sDao") // 去掉 'I' 前缀,Service 改为 Dao 名称
.formatServiceImplFileName("%sDaoImpl")
.build();
@@ -50,6 +53,7 @@ public class DBEntityGenerator {
builder
// .disable(TemplateType.SERVICE) // 禁用 Service 生成
// .disable(TemplateType.SERVICE_IMPL) // 禁用 ServiceImpl 生成
+ .disable(TemplateType.MAPPER)
.disable(TemplateType.CONTROLLER); // 禁用 Controller 生成
})
diff --git a/paradogs-generator/src/main/java/com/paradogs/generator/ExcelDataGenerator.java b/paradogs-generator/src/main/java/com/paradogs/generator/ExcelDataGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa8dcfd780595412a7bdb5b1f18e26d4a430f6ff
--- /dev/null
+++ b/paradogs-generator/src/main/java/com/paradogs/generator/ExcelDataGenerator.java
@@ -0,0 +1,146 @@
+package com.paradogs.generator;
+
+import com.alibaba.excel.EasyExcel;
+import com.paradogs.framework.core.utils.StringUtils;
+import com.paradogs.generator.misc.ExcelDataGeneratorListener;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.Version;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * @author: yumi
+ * @date: 2023/12/5 21:58
+ * @Description: 配置表实体类生成器
+ */
+@Slf4j
+public class ExcelDataGenerator {
+
+ public static void main(String[] args) throws IOException, TemplateException {
+ String path = System.getProperty("user.dir") + "/paradogs-framework/paradogs-framework-common/src/main/resources/data";
+ File folder = new File(path);
+
+ for (File file : folder.listFiles()) {
+ ExcelDataGeneratorListener reader = new ExcelDataGeneratorListener();
+ EasyExcel.read(file, reader)
+ .headRowNumber(0) // 表头也读取
+ .sheet(0)
+ .doRead();
+ String fileDataName = StringUtils.firstChar2UpperCase(file.getName().substring(0, file.getName().lastIndexOf("(")));
+
+ // 创建 Freemarker 配置
+ Configuration cfg = new Configuration(new Version("2.3.31"));
+ cfg.setClassLoaderForTemplateLoading(ExcelDataGenerator.class.getClassLoader(), "ftls");
+ cfg.setDefaultEncoding("UTF-8");
+
+ // 加载模板
+ Template template = cfg.getTemplate("data.ftl");
+
+ // 创建数据模型
+ Map dataModel = new HashMap<>();
+ dataModel.put("package", "com.paradogs.framework.common.data");
+
+ List> dataMaps = reader.getData();
+ if (dataMaps.size() < 2) {
+ log.error("{} row < 2", file.getName());
+ continue;
+ }
+
+ // 生成数据项
+ List