iohao / ioGame

无锁异步化、事件驱动架构设计的 java netty 网络编程框架; 轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式; 适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景; 通过 ioGame 你可以很容易的搭建出一个集群无中心节点、集群自动化、分布式的网络服务器;FXGL、Unity、UE、Cocos Creator、Godot、Netty、Protobuf、webSocket、tcp、socket;java Netty 游戏服务器框架;

Home Page:http://game.iohao.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[对接文档] - 新增广播文档构建器,简化生成广播对接文档

iohao opened this issue · comments

新增功能的使用场景

在生成广播对接文档时,支持添加对应的描述、包装类型支持。

使用示例,在业务框架中配置

public class MyLogicServer extends AbstractBrokerClientStartup {
    @Override
    public BarSkeleton createBarSkeleton() {
        // 业务框架构建器
        BarSkeletonBuilder builder = ...
        
        // 错误码、广播、推送对接文档生成
        extractedDco(builder);

        return builder.build();
    }
    
    static void extractedDoc(BarSkeletonBuilder builder) {
        // UserCmd
        builder.addBroadcastDocument(BroadcastDocument.newBuilder(UserCmd.of(UserCmd.enterSquare))
                // 推送的数据类型
                .setDataClass(SquarePlayer.class)
                // 广播(推送)描述
                .setMethodDescription("新玩家加入房间,给房间内的其他玩家广播")
                // 广播方法名,仅在生成客户端代码时使用
                .setMethodName("enterSquare")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(UserCmd.of(UserCmd.move))
                .setDataClass(SquarePlayerMove.class)
                .setMethodDescription("其他玩家的移动")
                .setMethodName("move")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(UserCmd.of(UserCmd.offline))
                .setDataClass(LongValue.class, "userId")
                .setMethodDescription("有玩家下线了")
                .setMethodName("offline")
        );

        // room
        builder.addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.roomUpdateBroadcast))
                .setDataClass(FightRoomNotice.class)
                .setMethodDescription("房间更新通知")
                .setMethodName("roomUpdateBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.playerEnterRoomBroadcast))
                .setDataClass(FightPlayer.class)
                .setMethodDescription("有新玩家加入房间")
                .setMethodName("playerEnterRoomBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.enterRoom))
                .setDataClass(FightEnterRoom.class)
                .setMethodDescription("玩家自己进入房间")
                .setMethodName("enterRoom")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.dissolveRoomBroadcast))
                .setMethodDescription("解散房间")
                .setMethodName("dissolveRoomBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.quitRoom))
                .setDataClass(LongValue.class, "userId")
                .setMethodDescription("有玩家退出房间了")
                .setMethodName("quitRoom")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.ready))
                .setDataClass(PlayerReady.class)
                .setMethodDescription("有玩家准备或取消准备了")
                .setMethodName("ready")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.nextRoundBroadcast))
                .setDataClass(IntValue.class, "round 当前对局数")
                .setMethodDescription("对局开始,通知玩家开始选择")
                .setMethodName("nextRoundBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.operationBroadcast))
                .setDataClass(LongValue.class, "userId")
                .setMethodDescription("通知其他玩家,有玩家做了选择")
                .setMethodName("operationBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.littleSettleBroadcast))
                .setDataClassList(FightRoundPlayerScore.class,"玩家对局分数")
                .setMethodDescription("广播玩家对局分数")
                .setMethodName("littleSettleBroadcast")
        ).addBroadcastDocument(BroadcastDocument.newBuilder(RoomCmd.of(RoomCmd.gameOverBroadcast))
                .setMethodDescription("游戏结束")
                .setMethodName("gameOverBroadcast")
        );
    }
}

错误码

示例中关于错误码可阅读 断言 + 异常机制 = 清晰简洁的代码 (yuque.com)

@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public enum GameCode implements MsgExceptionInfo {
    inRoom(1, "玩家在房间里"),
    roomNotExist(3, "房间不存在"),
    illegalOperation(4, "非法操作"),
    roomMinSpaceSizeEnough(6, "开始游戏需要的最小人数不足"),
    playerNotReady(7, "请等待其他玩家准备"),
    roomSpaceSizeNotEnough(8, "房间空间不足,人数已满"),
    ;

    /** 消息码 */
    final int code;
    /** 消息模板 */
    final String msg;

    GameCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

游戏对接文档生成 (yuque.com)

下面是生成后的对接文档预览(文本文档)

==================== 游戏文档格式说明 ====================
https://www.yuque.com/iohao/game/irth38#cJLdC

==================== FightHallAction 大厅(类似地图) ====================
路由: 1 - 1  --- 【登录】 --- 【FightHallAction:63】【loginVerify】
    方法参数: LoginVerify 登录验证
    方法返回值: UserInfo 玩家信息
 
路由: 1 - 2  --- 【进入大厅】 --- 【FightHallAction:91】【enterSquare】
    方法参数: EnterSquare 进入大厅
    方法返回值: ByteValueList<SquarePlayer> 所有玩家
    广播推送: SquarePlayer ,(新玩家加入房间,给房间内的其他玩家广播)
 
路由: 1 - 4  --- 【玩家移动】 --- 【FightHallAction:127】【move】
    方法参数: SquarePlayerMove 玩家移动
    方法返回值: void 
    广播推送: SquarePlayerMove ,(其他玩家的移动)
 
路由: 1 - 5  --- 【玩家下线】 --- 【FightHallAction:152】【offline】
    方法返回值: void 
    广播推送: LongValue userId,(有玩家下线了)
 
==================== FightRoomAction  ====================
路由: 2 - 1  --- 【玩家创建新房间】 --- 【FightRoomAction:63】【createRoom】
    方法返回值: void 
 
路由: 2 - 2  --- 【玩家进入房间】 --- 【FightRoomAction:95】【enterRoom】
    方法参数: LongValue 房间号
    方法返回值: void 
    广播推送: FightEnterRoom 进入房间,(玩家自己进入房间)
 
路由: 2 - 3  --- 【玩家退出房间】 --- 【FightRoomAction:119】【quitRoom】
    方法返回值: void 
    广播推送: LongValue userId,(有玩家退出房间了)
 
路由: 2 - 4  --- 【玩家准备】 --- 【FightRoomAction:145】【ready】
    方法参数: BoolValue true 表示准备,false 则是取消准备
    方法返回值: void 
    广播推送: PlayerReady 玩家准备信息,(有玩家准备或取消准备了)
 
路由: 2 - 5  --- 【房间列表】 --- 【FightRoomAction:221】【listRoom】
    方法返回值: ByteValueList<FightRoomNotice> 房间列表
 
路由: 2 - 6  --- 【玩家在游戏中的操作】 --- 【FightRoomAction:190】【operation】
    方法参数: FightOperationCommand 玩家操作数据
    方法返回值: void 
 
路由: 2 - 7  --- 【开始游戏】 --- 【FightRoomAction:161】【startGame】
    方法返回值: void 
 
==================== 其它广播推送 ====================
路由: 2 - 50  --- 广播推送: FightPlayer 玩家,(有新玩家加入房间)
路由: 2 - 51  --- 广播推送: FightRoomNotice ,(房间更新通知)
路由: 2 - 52  --- 广播推送: IntValue round 当前对局数,(对局开始,通知玩家开始选择)
路由: 2 - 53  --- 广播推送: LongValue userId,(通知其他玩家,有玩家做了选择)
路由: 2 - 54  --- 广播推送: ByteValueList<FightRoundPlayerScore> 玩家对局分数,(广播玩家对局分数)
路由: 2 - 55  --- 广播推送: {dataClass} {dataDescription},(游戏结束)
路由: 2 - 56  --- 广播推送: {dataClass} {dataDescription},(解散房间)

==================== 错误码 ====================
-1008 : 绑定的游戏逻辑服不存在 : findBindingLogicServerNotExist
-1007 : 强制玩家下线 : forcedOffline
-1006 : 数据不存在 : dataNotExist
-1005 : class 不存在 : classNotExist
-1004 : 请先登录 : verifyIdentity
-1003 : 心跳超时相关 : idleErrorCode
-1002 : 路由错误 : cmdInfoErrorCode
-1001 : 参数验错误 : validateErrCode
-1000 : 系统其它错误 : systemOtherErrCode
1 : 玩家在房间里 : inRoom
3 : 房间不存在 : roomNotExist
4 : 非法操作 : illegalOperation
6 : 开始游戏需要的最小人数不足 : roomMinSpaceSizeEnough
7 : 请等待其他玩家准备 : playerNotReady
8 : 房间空间不足,人数已满 : roomSpaceSizeNotEnough