- 采用C/S方式交互,对战过程包含1个服务端和多个客户端,服务端由主办方提供,客户端由参战队伍提供。
- 客户端与服务端之间,通过TCP Socket通讯。
- 客户端Socket通信一次收包可能收不全(需处理粘包、分包问题),参赛队伍请务必考虑此场景,避免因收包未收全直接处理消息而导致掉线。
- 消息内容均为文本格式,使用ASCII字符表示,编码为UTF-8编码。
| 编号 | 英文名 | 中文名 | 备注 |
|---|---|---|---|
| 0 | Space | 空地 | Start消息中data |
| 1 | Mount | 山丘 | Start消息中data |
| 2 | Water | 水 | |
| 3 | Flag | 龙旗据点 | |
| 4 | City | 中立城寨 | |
| 5 | Base | 主基地 |
客户端连接 → 注册消息 → 游戏开始 → 准备完成 → 回合制询问/行动 → 游戏结束
消息内容均为文本字符,字段名为小驼峰格式。消息格式为:消息体长度 + 消息体。
00148{
"msg_data":{
"playerId":1111,
"playerName":"xxx",
"version":"1.0"
},
"msg_name":"registration"
}
- 消息体长度:指示消息体的长度(不包括长度自身),固定为5个字符,不足5位前面补填0
- 消息长度:采用字节长度,而非字符串长度。在UTF-8编码下,一个中文的字符串长度是1,但占用的字节长度是3;一个英文字符的字符串长度和字节长度都是1
- 消息体:JSON格式
注意:若无特殊说明,消息中所有字段均为必选。下面例子中的字段数值均为示意,具体以实际数值为准。
{
"msg_data":{
"playerId":1111,
"playerName":"xxx",
"version":"1.0"
},
"msg_name":"registration"
}说明:registration消息用于客户端向服务端注册自己的队伍Id和队名(客户端应在连接服务端成功后发此消息)。
字段含义:
| 字段名 | 含义 |
|---|---|
| playerId | 玩家Id,程序运行时的输入参数。主办方会为每个参赛队伍分配playerId |
| playerName | 玩家战队名称,玩家自定义,最大长度为40个字节,支持中文,不支持特殊字符 |
| version | 程序版本号,玩家自定义,最大长度为40,支持中文,不支持特殊字符,用于玩家自我版本管理 |
{
"msg_data": {
"map": {
"data": "1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"maxX": 6,
"maxY": 4
},
"players": [{
"playerId": 1111,
"camp": 0
},
{
"playerId": 2222,
"camp": 1
}]
},
"msg_name": "start"
}说明:start消息用于服务端通知所有客户端游戏开始(所有玩家注册完成时,服务端发送此消息)。
字段含义:
| 字段名 | 含义 |
|---|---|
| map | 地图信息 |
| players | 参与游戏的玩家及其所属阵营 |
| 字段名 | 含义 |
|---|---|
| data | 地图数据,从左往右从上往下的地图单元格数据,数字代表的含义请参考"元素编号"章节;地图数据为二维数组,采用逗号分隔 |
| maxX | 地图坐标最大横坐标值 |
| maxY | 地图坐标最大纵坐标值 |
地图数据示例:
data = "1,2,3,4,5,6,7,8,9",maxX = 3, maxY = 3
换行后的地图信息为:
1,2,3
4,5,6
7,8,9
| 字段名 | 含义 |
|---|---|
| playerId | 玩家Id |
| camp | 玩家阵营id:0代表红色阵营,在地图左侧;1代表蓝色阵营,在地图右侧 |
{
"msg_data":{
"playerId":1111
},
"msg_name":"ready"
}说明:ready用于客户端在收到start消息处理完成后,回复准备完成消息给服务端。
字段含义:
| 字段名 | 含义 |
|---|---|
| playerId | 玩家Id |
说明:inquire消息用于服务端向玩家询问行动指令,提供地图上的所有单位的信息。
主要字段:
| 字段名 | 含义 |
|---|---|
| round | 当前的回合数,从1开始计数 |
| players | 地图上的所有的玩家对象列表 |
| cityProps | 地图上中立城寨所在位置列表 |
| stronghold | 地图上龙旗据点所在位置 |
| 字段名 | 类型 | 含义 |
|---|---|---|
| playerId | Int | 玩家id |
| supplies | int | 当前玩家的粮草值(上限1500) |
| morale | int | 当前玩家的士气值(上限300) |
| roles | List | 玩家英雄详细情况-三个 |
| 字段名 | 类型 | 含义 |
|---|---|---|
| roleId | Int | 英雄id,ID与英雄映射关系见附录 |
| attack | Int | 英雄的武力值,即初始攻击力(静态值,不包含加成后的实际值) |
| position | Position | 英雄位置 |
| life | Int | 英雄当前生命值(静态值,不包含加成后的实际值) |
| maxLife | int | 英雄最大生命值 |
| camp | int | 阵营 |
| reviveRound | int | 英雄复活剩余回合数 |
| formationType | int | 英雄带兵阵型(0:无/1:攻击/2:防守) |
| commander | int | 统帅值 |
| statuses | Map<enum, int> | 英雄当前状态,可同时存在多个,状态后面的数字代表状态剩余回合数 |
| skills | List | 技能情况列表 |
| solderProps | List | 表示当前英雄携带的士兵情况 |
| 字段名 | 类型 | 含义 |
|---|---|---|
| x | Int | 横坐标 |
| y | Int | 纵坐标 |
| 字段名 | 类型 | 含义 |
|---|---|---|
| NONE | Enum | 无 |
| RESURRECTION | Enum | 复活中 |
| Silence | Enum | 沉默中(无法释放技能,包括英雄技能闪现) |
| Grounded | Enum | 控制中(无法移动) |
| WEAKNESS | Enum | 虚弱(无法对敌方单位造成伤害) |
| 字段名 | 类型 | 含义 |
|---|---|---|
| skillId | Int | 技能id(英雄技能+号令) |
| cd | int | 技能冷却最大回合数 |
| cdRemainRound | int | 当前技能冷却剩余回合数 |
| damage | int | 技能伤害值 |
| damageReduceRatio | double | 额外伤害免伤比例(护盾) |
| damageAddByAttackRatio | double | 攻击加成比例 |
| roleId | int | 技能归属的英雄id |
| 字段名 | 类型 | 含义 |
|---|---|---|
| roleId | Int | 角色id(7:弓兵/8:盾兵) |
| attack | Int | 攻击力 |
| heroId | Int | 所属英雄id |
| life | Int | 生命值 |
| 字段名 | 含义 |
|---|---|
| roleId | 城寨的角色id(50/51/52) |
| position | 城寨所在单元格坐标 |
| life | 当前城防值 |
| 字段名 | 含义 |
|---|---|
| roleId | 据点的角色id(3) |
| camp | 所属阵营(0/1/2),未被占领时阵营为2 |
| occupiedRound | 占领进度(数组,下标为0表示红方占领的回合数,下标为1表示蓝方占领的回合数) |
| position | 据点所在单元格坐标,([-1, -1]表示龙旗据点不可占领) |
备注:龙旗据点会在游戏开始后100回合允许占领
结算顺序: PICK > BUFF > MAKE > FORM > SK > AD & SG > SP > MOVE > AC SK与AD、SG冲突 SP与MOVE冲突
{
"msg_name": "action",
"msg_data": {
"round": 1,
"playerId": 1111,
"actions": [
{
"roleId": 40,
"action": "MOVE",
"position": {
"x": 3,
"y": 2
}
},
{
"roleId": 41,
"action": "SP",
"position": {
"x": 3,
"y": 2
}
},
{
"playerId": 2222,
"action": "PICK",
"roles": [41, 44, 47]
},
{
"action": "MAKE",
"details": [
{
"roleId": 48,
"solders": [7, 7, 8]
},
{
"roleId": 41,
"solders": [8]
}
]
},
{
"roleId": 40,
"action": "FORM",
"formationType": 1
},
{
"action": "BUFF",
"buffType": 1001,
"roleId": 40
},
{
"action": "AC"
},
{
"roleId": 41,
"action": "SG",
"position": {
"x": 3,
"y": 2
}
},
{
"roleId": 41,
"action": "AD",
"position": {
"x": 3,
"y": 2
}
},
{
"roleId": 40,
"action": "SK",
"skillId": 4001,
"position": {
"x": 3,
"y": 2
},
"formType": 1,
"teleportPosition": {
"x": 5,
"y": 3
}
}
]
}
}说明:action消息用于玩家向服务端发出行动指令
注意:角色ID只能是己方角色
主要字段:
| 字段名 | 类型 | 含义 |
|---|---|---|
| round | int | 当前的回合数,从1开始计数 |
| playerId | int | 玩家ID |
| actions | List | 行动指令数组,action顺序表示角色攻击先后 |
- position:以玩家为中心,指定九宫格米字型位置。该位置就是移动后的位置
- 限制:1回合移动最大1个距离,需移动的目标点可达该指令才会生效
- 互斥:与SP指令互斥,同时出现则以SP指令优先执行
- roleId:英雄ID
- position:传送位置,该位置为以英雄为中心10个距离范围,且非障碍(山丘、水域)位置
- 互斥:与MOVE互斥,同一回合只生效SP指令
- roles:指定要选择的英雄ID,数组固定长度为3
- 条件:需要判断当前死亡英雄的剩余复活回合数为1时发送该指令才会切换阵容
- details:生产详情数组
- roleId:英雄ID
- solders:士兵类型数组
- roleId:英雄ID
- formationType:阵型类型枚举(1:攻击/2:防守)
- buffType:buff类型的固定枚举值
- roleId:当且仅当buff类型为1001(传国玉玺)时,需要使用该字段指定一名我方英雄
- 时机:在每局游戏的第100,150,200回合可以发送该指令选择一个buff
- 条件:当满足占点条件时,该指令生效
- roleId:英雄ID
- position:攻打位置
- roleId:英雄ID
- position:攻击位置
- 互斥:与技能攻击互斥,若与技能攻击同时发送,则以技能攻击生效
- roleId:释放方英雄的roleId
- skillId:技能ID
- position:技能释放的位置,无须指定释放位置的技能该字段可传可不传
- formType:诸葛亮二技能指定的阵型,当且仅当skillId为4601时有效
- teleportPosition:刘备二技能指定的传送目标位置,当且仅当skillId为4301时有效
- 互斥:与普通攻击互斥,若与普通攻击同时发送,则以技能攻击生效
{
"msg_data": {
"players": [{
"destroyTowerNum": 0,
"heroes": [{
"bowmen": 6,
"id": 1500,
"killedNum": 3,
"name": "吕布",
"roleId": 40,
"shieldmen": 0
},
{
"bowmen": 12,
"id": 1504,
"killedNum": 4,
"name": "曹操",
"roleId": 44,
"shieldmen": 0
},
{
"bowmen": 7,
"id": 1506,
"killedNum": 0,
"name": "诸葛亮",
"roleId": 46,
"shieldmen": 0
}],
"killedNum": 7,
"occupyRound": 60,
"online": true,
"overRound": 490,
"playerId": 1111,
"playerName": "Labubu",
"progress": 1.0,
"soldierNum": 25,
"totalGold": 336
},
{
"destroyTowerNum": 0,
"heroes": [{
"bowmen": 0,
"id": 1510,
"killedNum": 0,
"name": "吕布",
"roleId": 40,
"shieldmen": 3
},
{
"bowmen": 0,
"id": 1515,
"killedNum": 1,
"name": "孙权",
"roleId": 45,
"shieldmen": 2
},
{
"bowmen": 0,
"id": 1518,
"killedNum": 1,
"name": "周瑜",
"roleId": 48,
"shieldmen": 8
}],
"killedNum": 2,
"occupyRound": 2,
"online": true,
"overRound": 490,
"playerId": 2222,
"playerName": "Tycoco",
"progress": 0.0333,
"soldierNum": 13,
"totalGold": 7
}]
},
"msg_name": "over"
}说明:over用于游戏结束时,服务端广播给所有客户端的消息。
字段含义:
| 字段名 | 类型 | 含义 |
|---|---|---|
| playerId | Int | 玩家id |
| playerName | string | 玩家名称 |
| online | Boolean | 玩家是否掉线 |
| overRound | int | 结束回合 |
| progress | double | 占点进度(1.0表示100%) |
| soldierNum | int | 存活士兵总量 |
| totalGold | int | 剩余粮草 |
| heroes | List | 英雄情况 |
| 字段名 | 类型 | 含义 |
|---|---|---|
| id | Int | 英雄id(红方英雄id1500-1508),(蓝方英雄id1510-1518) |
| roleId | int | 英雄id(40-48) |
| name | string | 英雄名称 |
| bowmen | Int | 结束回合存活弓兵数量 |
| shieldmen | int | 结束回合存活盾兵数量 |
| killedNum | int | 本局游戏当前角色所属职业的击杀总量 |
- 粘包处理:客户端必须正确处理TCP粘包、分包问题
- 字符编码:所有消息采用UTF-8编码
- 消息长度:消息长度字段表示字节长度,不是字符串长度
- 必选字段:除非特别说明,所有字段均为必选
- 指令互斥:注意各种行动指令的互斥关系和优先级
- 角色限制:行动指令中的角色ID只能是己方角色