Commit d521a1cd authored by Chunchi Che's avatar Chunchi Che

Merge branch 'optimize/reflect' into 'main'

Optimize/reflect

See merge request !74
parents 26ff2f20 abad13c3
Pipeline #19500 passed with stages
in 2 minutes and 41 seconds
...@@ -13,12 +13,12 @@ import MsgNewPhaseAdapter from "./newPhase"; ...@@ -13,12 +13,12 @@ import MsgNewPhaseAdapter from "./newPhase";
import MsgHintAdapter from "./hint"; import MsgHintAdapter from "./hint";
import MsgSelectIdleCmdAdapter from "./selectIdleCmd"; import MsgSelectIdleCmdAdapter from "./selectIdleCmd";
import MsgSelectPlaceAdapter from "./selectPlace"; import MsgSelectPlaceAdapter from "./selectPlace";
import MsgMoveAdapter from "./move";
import MsgSelectCardAdapter from "./selectCard"; import MsgSelectCardAdapter from "./selectCard";
import MsgSelectChainAdapter from "./selectChain"; import MsgSelectChainAdapter from "./selectChain";
import MsgSelectEffectYnAdapter from "./selectEffectYn"; import MsgSelectEffectYnAdapter from "./selectEffectYn";
import MsgSelectPositionAdapter from "./selectPosition"; import MsgSelectPositionAdapter from "./selectPosition";
import MsgSelectOptionAdapter from "./selectOption"; import MsgSelectOptionAdapter from "./selectOption";
import PENETRATE from "./penetrate";
/* /*
* STOC GameMsg * STOC GameMsg
...@@ -41,83 +41,80 @@ export default class GameMsgAdapter implements StocAdapter { ...@@ -41,83 +41,80 @@ export default class GameMsgAdapter implements StocAdapter {
const func = dataView.getUint8(0); const func = dataView.getUint8(0);
const gameData = exData.slice(1); const gameData = exData.slice(1);
const gameMsg = new ygopro.StocGameMessage({}); let gameMsg: any = new ygopro.StocGameMessage({}).toObject();
switch (func) { if (!PENETRATE.penetrate(func, gameMsg, gameData)) {
case GAME_MSG.MSG_START: { switch (func) {
gameMsg.start = MsgStartAdapter(gameData); case GAME_MSG.MSG_START: {
gameMsg.start = MsgStartAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_DRAW: { }
gameMsg.draw = MsgDrawAdapter(gameData); case GAME_MSG.MSG_DRAW: {
gameMsg.draw = MsgDrawAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_NEW_TURN: { }
gameMsg.new_turn = MsgNewTurnAdapter(gameData); case GAME_MSG.MSG_NEW_TURN: {
gameMsg.new_turn = MsgNewTurnAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_NEW_PHASE: { }
gameMsg.new_phase = MsgNewPhaseAdapter(gameData); case GAME_MSG.MSG_NEW_PHASE: {
gameMsg.new_phase = MsgNewPhaseAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_HINT: { }
gameMsg.hint = MsgHintAdapter(gameData); case GAME_MSG.MSG_HINT: {
gameMsg.hint = MsgHintAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_IDLE_CMD: { }
gameMsg.select_idle_cmd = MsgSelectIdleCmdAdapter(gameData); case GAME_MSG.MSG_SELECT_IDLE_CMD: {
gameMsg.select_idle_cmd = MsgSelectIdleCmdAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_PLACE: { }
gameMsg.select_place = MsgSelectPlaceAdapter(gameData); case GAME_MSG.MSG_SELECT_PLACE: {
gameMsg.select_place = MsgSelectPlaceAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_MOVE: { }
gameMsg.move = MsgMoveAdapter(gameData); case GAME_MSG.MSG_SELECT_CARD: {
gameMsg.select_card = MsgSelectCardAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_CARD: { }
gameMsg.select_card = MsgSelectCardAdapter(gameData); case GAME_MSG.MSG_SELECT_CHAIN: {
gameMsg.select_chain = MsgSelectChainAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_CHAIN: { }
gameMsg.select_chain = MsgSelectChainAdapter(gameData); case GAME_MSG.MSG_SELECT_EFFECTYN: {
gameMsg.select_effect_yn = MsgSelectEffectYnAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_EFFECTYN: { }
gameMsg.select_effect_yn = MsgSelectEffectYnAdapter(gameData); case GAME_MSG.MSG_SELECT_POSITION: {
gameMsg.select_position = MsgSelectPositionAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_POSITION: { }
gameMsg.select_position = MsgSelectPositionAdapter(gameData); case GAME_MSG.MSG_SELECT_OPTION: {
gameMsg.select_option = MsgSelectOptionAdapter(gameData);
break;
} break;
case GAME_MSG.MSG_SELECT_OPTION: { }
gameMsg.select_option = MsgSelectOptionAdapter(gameData); default: {
console.log("Unhandled GameMessage function=", func);
break;
} break;
default: { }
console.log("Unhandled GameMessage function=", func);
break;
} }
} }
return new ygopro.YgoStocMsg({ return new ygopro.YgoStocMsg({
stoc_game_msg: gameMsg, stoc_game_msg: new ygopro.StocGameMessage(gameMsg),
}); });
} }
} }
{
"50": {
"protoType": "move",
"fields": [
{
"fieldName": "code",
"fieldType": "uint32"
},
{
"fieldName": "from",
"fieldType": "CardLocation"
},
{
"fieldName": "to",
"fieldType": "CardLocation"
},
{
"fieldName": "reason",
"fieldType": "uint8"
}
]
}
}
//! 透传协议
import PenetrateData from "./penetrate.json";
import { BufferReader } from "../../bufferIO";
import { ygopro } from "../../../idl/ocgcore";
type Constructor<T = any> = new (...args: any[]) => T;
const ReadFieldHandlerMap: Map<string, readFieldHandler> = new Map([
["uint8", ((reader) => reader.readUint8()) as readFieldHandler],
["uint16", (reader) => reader.readUint16()],
["uint32", (reader) => reader.readUint32()],
["CardLocation", (reader) => reader.readCardLocation()],
]);
const MsgConstructorMap: Map<string, Constructor> = new Map([
["move", ygopro.StocGameMessage.MsgMove],
]);
export interface penetrateType {
protoType: string;
fields: {
fieldName: string;
fieldType: string;
}[];
}
interface readFieldHandler {
(reader: BufferReader): any;
}
class PenetrateManager {
config: Map<string, penetrateType>;
readFieldHandlerMap: Map<string, readFieldHandler> = ReadFieldHandlerMap;
msgConstructorMap: Map<string, Constructor> = MsgConstructorMap;
constructor(config: any) {
this.config = _objToMap(config);
}
private readField(reader: BufferReader, fieldType: string): any {
const handler = this.readFieldHandlerMap.get(fieldType);
if (handler) {
return handler(reader);
}
return undefined;
}
private constructMsg(protoType: string, object: any): any {
const constructor = this.msgConstructorMap.get(protoType);
if (constructor) {
return new constructor(object);
}
return undefined;
}
penetrate(msgKey: number, gameMsg: any, gameData: Uint8Array): boolean {
const config = this.config.get(msgKey.toString());
const reader = new BufferReader(gameData, true);
if (config) {
const protoType = config.protoType;
const fields = config.fields;
let object: any = {};
for (let field of fields) {
object[field.fieldName] = this.readField(reader, field.fieldType);
}
gameMsg[protoType] = this.constructMsg(protoType, object);
}
return config ? true : false;
}
}
function _objToMap(obj: any): Map<string, penetrateType> {
let map = new Map();
for (let key of Object.keys(obj)) {
map.set(key, obj[key]);
}
return map;
}
const PENETRATE = new PenetrateManager(PenetrateData);
export default PENETRATE;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment