浏览代码

1.调整服务端目录;2.增加Game服启动示例

johnclot69 1 月之前
父节点
当前提交
0bcc780bd2
共有 24 个文件被更改,包括 168 次插入139 次删除
  1. 1 1
      .gitignore
  2. 2 2
      incubator-app/build.gradle
  3. 0 66
      incubator-app/src/main/java/App.java
  4. 24 0
      incubator-app/src/main/java/com/incubator/app/App.java
  5. 1 1
      incubator-core/src/main/java/com/incubator/core/events/EventListener.java
  6. 9 0
      incubator-core/src/main/java/com/incubator/core/events/WebSocketConnectedEvent.java
  7. 9 0
      incubator-core/src/main/java/com/incubator/core/events/WebSocketDisconnectedEvent.java
  8. 2 2
      incubator-core/src/main/java/com/incubator/core/events/WebSocketMessageEvent.java
  9. 4 3
      incubator-core/src/main/java/com/incubator/core/message/MessageHandler.java
  10. 11 7
      incubator-core/src/main/java/com/incubator/core/message/MessageHandlerSystem.java
  11. 3 2
      incubator-core/src/main/java/com/incubator/core/message/WebSocketEventDispatcherSystem.java
  12. 1 1
      incubator-core/src/main/java/com/incubator/core/network/NettySystem.java
  13. 6 6
      incubator-core/src/main/java/com/incubator/core/network/WebSocketHandler.java
  14. 3 3
      incubator-core/src/main/java/com/incubator/core/network/WebSocketHandshakeHandler.java
  15. 1 1
      incubator-core/src/main/java/com/incubator/core/protocol/BinaryWebSocketFrameCodec.java
  16. 1 1
      incubator-core/src/main/java/com/incubator/core/protocol/Message.java
  17. 3 3
      incubator-core/src/main/java/com/incubator/core/protocol/MsgPackCodec.java
  18. 1 1
      incubator-core/src/main/java/com/incubator/core/thread/AbstractRunnable.java
  19. 1 1
      incubator-core/src/main/java/com/incubator/core/thread/NamedThreadFactory.java
  20. 0 18
      incubator-core/src/main/java/events/WebSocketConnectedEvent.java
  21. 0 18
      incubator-core/src/main/java/events/WebSocketDisconnectedEvent.java
  22. 19 0
      incubator-game/build.gradle
  23. 63 0
      incubator-game/src/main/java/com/incubator/game/Game.java
  24. 3 2
      settings.gradle

+ 1 - 1
.gitignore

@@ -33,7 +33,7 @@ hs_err_pid*
 .loadpath
 /release
 
-# Google App Engine
+# Google com.incubator.app.App Engine
 *.appengine-generated/
 !*/src/main/**/gen/**/generated-sources/
 .DS_Store

+ 2 - 2
incubator-app/build.gradle

@@ -46,7 +46,7 @@ tasks.named('jar') {
 tasks.shadowJar {
     zip64 = true
     // 设置 JAR 包的基本名称
-    archiveBaseName = 'incubator-game'
+    archiveBaseName = 'incubator-app'
     // 使用项目的版本号作为 JAR 的版本
     archiveVersion = project.version
     // 移除分类器,生成的 JAR 没有后缀
@@ -73,7 +73,7 @@ tasks.shadowJar {
 // 项目依赖
 dependencies {
     // 子模块依赖
-    implementation project(':incubator-core')
+    implementation project(':incubator-game')
 
     // 测试依赖
     testImplementation platform("org.junit:junit-bom:5.10.0")

+ 0 - 66
incubator-app/src/main/java/App.java

@@ -1,66 +0,0 @@
-import com.artemis.Entity;
-import com.artemis.World;
-import com.artemis.WorldConfiguration;
-import com.artemis.WorldConfigurationBuilder;
-import message.MessageHandlerSystem;
-import message.WebSocketEventDispatcherSystem;
-import network.NettySystem;
-
-import java.time.Duration;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Main 入口
- */
-public class App {
-
-    private static World world;
-
-    public static void main(String[] args) {
-
-        try {
-            // 构建 WorldConfiguration,注册 RealmSystem 和 GameSystem
-            WorldConfiguration config = new WorldConfigurationBuilder()
-                    .with(new WebSocketEventDispatcherSystem())
-                    .with(new MessageHandlerSystem())
-                    .with(new NettySystem())
-                    .build();
-
-            // 创建 World 对象(服务端主实体)
-            world = new World(config);
-
-            // 根据类型创建 Game 实体
-            Entity gameEntity = world.createEntity();
-            // 可以在 gameEntity 上挂载其它组件,示例略
-
-            // 使用虚拟线程创建 ScheduledExecutorService(JDK23 新特性)
-            ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(Thread.ofVirtual().factory());
-            // 每 16 毫秒更新一次,大约 60 次/秒,使用 Duration 表达时间间隔
-            executor.scheduleAtFixedRate(() -> {
-                world.setDelta(0.016f); // 单位为秒
-                world.process();        // 更新所有系统
-            }, 0, Duration.ofMillis(16).toMillis(), TimeUnit.MILLISECONDS);
-
-            // 添加 JVM 关闭钩子,确保退出时释放资源
-            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
-                System.out.println("Shutdown hook triggered, releasing resources...");
-                executor.shutdown();
-                world.dispose();
-            }));
-
-            // 阻塞 main 线程,保持服务运行(使用 CountDownLatch 更语义化)
-            try {
-                new CountDownLatch(1).await();
-            } catch (InterruptedException e) {
-                System.err.println("Main thread interrupted: " + e.getMessage());
-                Thread.currentThread().interrupt();
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}

+ 24 - 0
incubator-app/src/main/java/com/incubator/app/App.java

@@ -0,0 +1,24 @@
+package com.incubator.app;
+
+import com.incubator.game.Game;
+
+/**
+ * Main 入口
+ */
+public class App {
+
+    public static void main(String[] args) {
+
+        Game game = new Game();
+        game.start();
+
+        // 阻塞 main 线程,保持服务运行(使用 CountDownLatch 更语义化)
+        try {
+            Thread.currentThread().join();
+        } catch (InterruptedException e) {
+            System.err.println("Main thread interrupted: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+}

+ 1 - 1
incubator-core/src/main/java/events/EventListener.java → incubator-core/src/main/java/com/incubator/core/events/EventListener.java

@@ -1,4 +1,4 @@
-package events;
+package com.incubator.core.events;
 
 public interface EventListener {
     void handle(WebSocketMessageEvent event);

+ 9 - 0
incubator-core/src/main/java/com/incubator/core/events/WebSocketConnectedEvent.java

@@ -0,0 +1,9 @@
+package com.incubator.core.events;
+
+import io.netty.channel.Channel;
+
+/**
+ * WebSocket 消息连接事件
+ */
+public record WebSocketConnectedEvent(Channel channel) {
+}

+ 9 - 0
incubator-core/src/main/java/com/incubator/core/events/WebSocketDisconnectedEvent.java

@@ -0,0 +1,9 @@
+package com.incubator.core.events;
+
+import io.netty.channel.Channel;
+
+/**
+ * WebSocket 消息连接连接关闭事件
+ */
+public record WebSocketDisconnectedEvent(Channel channel) {
+}

+ 2 - 2
incubator-core/src/main/java/events/WebSocketMessageEvent.java → incubator-core/src/main/java/com/incubator/core/events/WebSocketMessageEvent.java

@@ -1,7 +1,7 @@
-package events;
+package com.incubator.core.events;
 
 import io.netty.channel.Channel;
-import protocol.Message;
+import com.incubator.core.protocol.Message;
 
 /**
  * WebSocket 消息事件(包含通道和消息内容)

+ 4 - 3
incubator-core/src/main/java/message/MessageHandler.java → incubator-core/src/main/java/com/incubator/core/message/MessageHandler.java

@@ -1,6 +1,7 @@
-package message;
+package com.incubator.core.message;
 
-import protocol.Message;
+import com.incubator.core.protocol.Message;
+import io.netty.channel.Channel;
 
 /**
  * 消息处理器基类(需保持独立文件)
@@ -17,5 +18,5 @@ public abstract class MessageHandler {
      * 抽象处理方法
      * @param message 接收到的消息对象
      */
-    public abstract void handle(Message message);
+    public abstract void handle(Channel channel, Message message);
 }

+ 11 - 7
incubator-core/src/main/java/message/MessageHandlerSystem.java → incubator-core/src/main/java/com/incubator/core/message/MessageHandlerSystem.java

@@ -1,16 +1,18 @@
-package message;
+package com.incubator.core.message;
 
 import com.artemis.BaseSystem;
 import com.artemis.annotations.Wire;
-import events.EventListener;
-import events.WebSocketMessageEvent;
-import protocol.Message;
+import com.incubator.core.events.EventListener;
+import com.incubator.core.events.WebSocketConnectedEvent;
+import com.incubator.core.events.WebSocketDisconnectedEvent;
+import com.incubator.core.events.WebSocketMessageEvent;
+import com.incubator.core.protocol.Message;
 
 import java.util.HashMap;
 import java.util.Map;
 
 /**
- * 消息处理系统(整合注册与事件处理)
+ * 消息事件处理系统
  * 职责:
  * 1. 管理消息处理器注册
  * 2. 监听并处理网络消息事件
@@ -23,10 +25,12 @@ public class MessageHandlerSystem extends BaseSystem implements EventListener {
 
     @Override
     protected void initialize() {
-        // 事件分发器(由Artemis自动注入)
+        // websocket事件分发器(由Artemis自动注入)
         WebSocketEventDispatcherSystem eventDispatcher = this.world.getSystem(WebSocketEventDispatcherSystem.class);
         // 注册事件监听器
+        eventDispatcher.addListener(this, WebSocketConnectedEvent.class);
         eventDispatcher.addListener(this, WebSocketMessageEvent.class);
+        eventDispatcher.addListener(this, WebSocketDisconnectedEvent.class);
 
         // 示例注册(实际项目中应使用自动扫描或手动注册)
         // registerHandler(new LoginHandler());
@@ -53,7 +57,7 @@ public class MessageHandlerSystem extends BaseSystem implements EventListener {
 
         if (handler != null) {
             try {
-                handler.handle(message);
+                handler.handle(event.channel(), message);
             } catch (Exception e) {
                 System.err.printf("Error processing cmd=%d: %s%n",
                         message.cmd, e);

+ 3 - 2
incubator-core/src/main/java/message/WebSocketEventDispatcherSystem.java → incubator-core/src/main/java/com/incubator/core/message/WebSocketEventDispatcherSystem.java

@@ -1,10 +1,10 @@
-package message;
+package com.incubator.core.message;
 
 import com.artemis.BaseSystem;
 
 import com.artemis.utils.reflect.ClassReflection;
 import com.artemis.utils.reflect.ReflectionException;
-import events.EventListener;
+import com.incubator.core.events.EventListener;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -16,6 +16,7 @@ import java.util.Map;
  * 自定义事件分发系统(需注册到Artemis世界)
  */
 public class WebSocketEventDispatcherSystem extends BaseSystem {
+
     private final Map<Class<?>, List<EventListener>> listeners = new HashMap<>();
 
     /**

+ 1 - 1
incubator-core/src/main/java/network/NettySystem.java → incubator-core/src/main/java/com/incubator/core/network/NettySystem.java

@@ -1,4 +1,4 @@
-package network;
+package com.incubator.core.network;
 
 import com.artemis.BaseSystem;
 import com.artemis.World;

+ 6 - 6
incubator-core/src/main/java/network/WebSocketHandler.java → incubator-core/src/main/java/com/incubator/core/network/WebSocketHandler.java

@@ -1,12 +1,12 @@
-package network;
+package com.incubator.core.network;
 
 import com.artemis.World;
-import events.WebSocketConnectedEvent;
-import events.WebSocketDisconnectedEvent;
-import events.WebSocketMessageEvent;
+import com.incubator.core.events.WebSocketConnectedEvent;
+import com.incubator.core.events.WebSocketDisconnectedEvent;
+import com.incubator.core.events.WebSocketMessageEvent;
 import io.netty.channel.Channel;
-import message.WebSocketEventDispatcherSystem;
-import protocol.Message;
+import com.incubator.core.message.WebSocketEventDispatcherSystem;
+import com.incubator.core.protocol.Message;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 

+ 3 - 3
incubator-core/src/main/java/network/WebSocketHandshakeHandler.java → incubator-core/src/main/java/com/incubator/core/network/WebSocketHandshakeHandler.java

@@ -1,12 +1,12 @@
-package network;
+package com.incubator.core.network;
 
 import com.artemis.World;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPipeline;
 import io.netty.channel.SimpleChannelInboundHandler;
 import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
-import protocol.BinaryWebSocketFrameCodec;
-import protocol.MsgPackCodec;
+import com.incubator.core.protocol.BinaryWebSocketFrameCodec;
+import com.incubator.core.protocol.MsgPackCodec;
 
 /**
  * 用于监控 WebSocket 握手事件并调用自定义处理逻辑。

+ 1 - 1
incubator-core/src/main/java/protocol/BinaryWebSocketFrameCodec.java → incubator-core/src/main/java/com/incubator/core/protocol/BinaryWebSocketFrameCodec.java

@@ -1,4 +1,4 @@
-package protocol;
+package com.incubator.core.protocol;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;

+ 1 - 1
incubator-core/src/main/java/protocol/Message.java → incubator-core/src/main/java/com/incubator/core/protocol/Message.java

@@ -1,4 +1,4 @@
-package protocol;
+package com.incubator.core.protocol;
 
 import java.io.Serializable;
 import java.util.Map;

+ 3 - 3
incubator-core/src/main/java/protocol/MsgPackCodec.java → incubator-core/src/main/java/com/incubator/core/protocol/MsgPackCodec.java

@@ -1,4 +1,4 @@
-package protocol;
+package com.incubator.core.protocol;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;
@@ -25,7 +25,7 @@ public class MsgPackCodec extends MessageToMessageCodec<ByteBuf, Message> {
             packer.packMapHeader(4)
                     .packString("cmd").packInt(msg.cmd)
                     .packString("code").packInt(msg.code)
-                    .packString("message").packString(msg.message)
+                    .packString("com/incubator/core/message").packString(msg.message)
                     .packString("data").packMapHeader(msg.data.size());
 
             msg.data.forEach((k, v) -> {
@@ -105,7 +105,7 @@ public class MsgPackCodec extends MessageToMessageCodec<ByteBuf, Message> {
                 switch (key) {
                     case "cmd" -> message.cmd = unpacked.unpackInt();
                     case "code" -> message.code = unpacked.unpackInt();
-                    case "message" -> message.message = unpacked.unpackString();
+                    case "com/incubator/core/message" -> message.message = unpacked.unpackString();
                     case "data" -> {
                         if (unpacked.tryUnpackNil()) {
                             message.data.clear();

+ 1 - 1
incubator-core/src/main/java/thread/AbstractRunnable.java → incubator-core/src/main/java/com/incubator/core/thread/AbstractRunnable.java

@@ -1,4 +1,4 @@
-package thread;
+package com.incubator.core.thread;
 
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;

+ 1 - 1
incubator-core/src/main/java/thread/NamedThreadFactory.java → incubator-core/src/main/java/com/incubator/core/thread/NamedThreadFactory.java

@@ -1,4 +1,4 @@
-package thread;
+package com.incubator.core.thread;
 
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;

+ 0 - 18
incubator-core/src/main/java/events/WebSocketConnectedEvent.java

@@ -1,18 +0,0 @@
-package events;
-
-import io.netty.channel.Channel;
-
-/**
- * WebSocket 消息连接事件
- */
-public class WebSocketConnectedEvent {
-    private final Channel channel;
-
-    public WebSocketConnectedEvent(Channel channel) {
-        this.channel = channel;
-    }
-
-    public Channel getChannel() {
-        return channel;
-    }
-}

+ 0 - 18
incubator-core/src/main/java/events/WebSocketDisconnectedEvent.java

@@ -1,18 +0,0 @@
-package events;
-
-import io.netty.channel.Channel;
-
-/**
- * WebSocket 消息连接连接关闭事件
- */
-public class WebSocketDisconnectedEvent {
-    private final Channel channel;
-
-    public WebSocketDisconnectedEvent(Channel channel) {
-        this.channel = channel;
-    }
-
-    public Channel getChannel() {
-        return channel;
-    }
-}

+ 19 - 0
incubator-game/build.gradle

@@ -0,0 +1,19 @@
+plugins {
+    id("java-library")
+}
+
+group = "com.incubator.game"
+version = "1.0-SNAPSHOT"
+
+dependencies {
+    testImplementation(platform("org.junit:junit-bom:5.10.0"))
+    testImplementation("org.junit.jupiter:junit-jupiter")
+
+    api project(path: ':incubator-core')
+}
+
+configurations.configureEach {
+    exclude group: 'ch.qos.logback', module: 'logback-classic'
+}
+
+build.dependsOn(copyAllDependencies)

+ 63 - 0
incubator-game/src/main/java/com/incubator/game/Game.java

@@ -0,0 +1,63 @@
+package com.incubator.game;
+
+import com.artemis.Entity;
+import com.artemis.World;
+import com.artemis.WorldConfiguration;
+import com.artemis.WorldConfigurationBuilder;
+import com.incubator.core.message.MessageHandlerSystem;
+import com.incubator.core.message.WebSocketEventDispatcherSystem;
+import com.incubator.core.network.NettySystem;
+
+import java.time.Duration;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 游戏服
+ */
+public class Game {
+
+    // 游戏服world
+    public World world;
+    // 使用虚拟线程创建 ScheduledExecutorService(JDK23 新特性)
+    private ScheduledExecutorService executor;
+
+    public Game() {
+        // 构建 WorldConfiguration,注册 RealmSystem 和 GameSystem
+        WorldConfiguration config = new WorldConfigurationBuilder()
+                .with(new WebSocketEventDispatcherSystem())
+                .with(new MessageHandlerSystem())
+                .with(new NettySystem())
+                .build();
+
+        // 创建 World 对象(服务端主实体)
+        this.world = new World(config);
+    }
+
+    /**
+     * 启动游戏服务,包含主循环
+     */
+    public void start() {
+        // 根据类型创建 Game 实体
+        Entity gameEntity = this.world.createEntity();
+        // 可以在 gameEntity 上挂载其它组件,示例略
+
+        // 使用虚拟线程创建 ScheduledExecutorService(JDK23 新特性)
+        this.executor = Executors.newSingleThreadScheduledExecutor(Thread.ofVirtual().factory());
+        // 每 16 毫秒更新一次,大约 60 次/秒,使用 Duration 表达时间间隔
+        this.executor.scheduleAtFixedRate(() -> {
+            this.world.setDelta(0.016f); // 单位为秒
+            this.world.process();        // 更新所有系统
+        }, 0, Duration.ofMillis(16).toMillis(), TimeUnit.MILLISECONDS);
+
+        // 添加 JVM 关闭钩子,确保退出时释放资源
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("Shutdown hook triggered, releasing resources...");
+            this.world.dispose();
+            this.executor.shutdown();
+        }));
+
+    }
+
+}

+ 3 - 2
settings.gradle

@@ -1,4 +1,5 @@
 rootProject.name = 'IncubatorGame'
-include('incubator-core')
-include('incubator-app')
+include 'incubator-core'
+include 'incubator-game'
+include 'incubator-app'