Commit 8c03717a authored by nanahira's avatar nanahira

Merge branch 'msg-encode' of ../srvpro into develop

parents 63f188ef ec34713f
Pipeline #42905 passed with stages
in 7 minutes and 48 seconds
...@@ -46,3 +46,4 @@ $RECYCLE.BIN/ ...@@ -46,3 +46,4 @@ $RECYCLE.BIN/
/lflist.conf /lflist.conf
config.user.bak config.user.bak
/scripts
...@@ -3,17 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) { ...@@ -3,17 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.YGOProMessagesHelper = void 0; exports.YGOProMessagesHelper = exports.LegacyStruct = exports.LegacyStructInst = void 0;
const struct_1 = require("./struct");
const underscore_1 = __importDefault(require("underscore")); const underscore_1 = __importDefault(require("underscore"));
const structs_json_1 = __importDefault(require("./data/structs.json")); const load_constants_1 = __importDefault(require("./load-constants"));
const typedefs_json_1 = __importDefault(require("./data/typedefs.json")); const ygopro_msg_encode_1 = require("ygopro-msg-encode");
const ygopro_msg_struct_compat_1 = require("./ygopro-msg-struct-compat");
const proto_structs_json_1 = __importDefault(require("./data/proto_structs.json")); const proto_structs_json_1 = __importDefault(require("./data/proto_structs.json"));
const constants_json_1 = __importDefault(require("./data/constants.json"));
class Handler { class Handler {
constructor(handler, synchronous) { constructor(handler, synchronous) {
this.handler = handler; this.handler = handler;
this.synchronous = synchronous || false; this.synchronous = synchronous;
} }
async handle(buffer, info, datas, params) { async handle(buffer, info, datas, params) {
if (this.synchronous) { if (this.synchronous) {
...@@ -27,8 +26,50 @@ class Handler { ...@@ -27,8 +26,50 @@ class Handler {
} }
} }
} }
class LegacyStructInst {
constructor(cls) {
this.cls = cls;
}
_setBuff(buff) {
this.buffer = buff;
}
set(field, value) {
if (!this.buffer || !this.cls)
return;
const inst = (0, ygopro_msg_struct_compat_1.applyYGOProMsgStructCompat)(new this.cls().fromPayload(this.buffer));
inst[field] = value;
const parsed = Buffer.from(inst.toPayload());
if (parsed.length >= this.buffer.length) {
// slice it down
parsed.copy(this.buffer, 0, 0, this.buffer.length);
}
else {
// copy a small part only
parsed.copy(this.buffer, 0, 0, parsed.length);
}
}
}
exports.LegacyStructInst = LegacyStructInst;
class LegacyStruct {
constructor(helper) {
this.helper = helper;
this.protoClasses = new Map();
for (const [direction, list] of Object.entries(proto_structs_json_1.default)) {
for (const [protoStr, structName] of Object.entries(list)) {
if (!structName)
continue;
this.protoClasses.set(structName, this.helper.getProtoClass(protoStr, direction));
}
}
}
get(structName) {
return new LegacyStructInst(this.protoClasses.get(structName));
}
}
exports.LegacyStruct = LegacyStruct;
class YGOProMessagesHelper { class YGOProMessagesHelper {
constructor(singleHandleLimit) { constructor(singleHandleLimit = 1000) {
this.singleHandleLimit = singleHandleLimit;
this.handlers = { this.handlers = {
STOC: [new Map(), STOC: [new Map(),
new Map(), new Map(),
...@@ -43,56 +84,8 @@ class YGOProMessagesHelper { ...@@ -43,56 +84,8 @@ class YGOProMessagesHelper {
new Map(), new Map(),
] ]
}; };
this.initDatas(); this.constants = (0, load_constants_1.default)();
this.initStructs(); this.structs = new LegacyStruct(this);
if (singleHandleLimit) {
this.singleHandleLimit = singleHandleLimit;
}
else {
this.singleHandleLimit = 1000;
}
}
initDatas() {
this.structs_declaration = structs_json_1.default;
this.typedefs = typedefs_json_1.default;
this.proto_structs = proto_structs_json_1.default;
this.constants = constants_json_1.default;
}
initStructs() {
this.structs = new Map();
for (let name in this.structs_declaration) {
const declaration = this.structs_declaration[name];
let result = (0, struct_1.Struct)();
for (let field of declaration) {
if (field.encoding) {
switch (field.encoding) {
case "UTF-16LE":
result.chars(field.name, field.length * 2, field.encoding);
break;
default:
throw `unsupported encoding: ${field.encoding}`;
}
}
else {
let type = field.type;
if (this.typedefs[type]) {
type = this.typedefs[type];
}
if (field.length) {
result.array(field.name, field.length, type); //不支持结构体
}
else {
if (this.structs.has(type)) {
result.struct(field.name, this.structs.get(type));
}
else {
result[type](field.name);
}
}
}
}
this.structs.set(name, result);
}
} }
getDirectionAndProto(protoStr) { getDirectionAndProto(protoStr) {
const protoStrMatch = protoStr.match(/^(STOC|CTOS)_([_A-Z]+)$/); const protoStrMatch = protoStr.match(/^(STOC|CTOS)_([_A-Z]+)$/);
...@@ -117,11 +110,27 @@ class YGOProMessagesHelper { ...@@ -117,11 +110,27 @@ class YGOProMessagesHelper {
} }
return parseInt(translatedProto); return parseInt(translatedProto);
} }
getProtoClass(proto, direction) {
const identifier = typeof proto === 'number' ? proto : this.translateProto(proto, direction);
const registry = direction === 'CTOS' ? ygopro_msg_encode_1.YGOProCtos : direction === 'STOC' ? ygopro_msg_encode_1.YGOProStoc : null;
if (!registry) {
throw `Invalid direction: ${direction}`;
}
return registry.get(identifier);
}
classToProtoStr(cls) {
const registry = cls.prototype instanceof ygopro_msg_encode_1.YGOProCtosBase ? ygopro_msg_encode_1.YGOProCtos : cls.prototype instanceof ygopro_msg_encode_1.YGOProStocBase ? ygopro_msg_encode_1.YGOProStoc : null;
if (!registry) {
throw `Invalid class: ${cls.name}`;
}
const identifier = cls.identifier;
const direction = cls.prototype instanceof ygopro_msg_encode_1.YGOProCtosBase ? 'CTOS' : 'STOC';
return `${direction}_${this.constants[direction][identifier]}`;
}
prepareMessage(protostr, info) { prepareMessage(protostr, info) {
const { direction, proto } = this.getDirectionAndProto(protostr); const { direction, proto } = this.getDirectionAndProto(protostr);
const translatedProto = this.translateProto(proto, direction);
let buffer; let buffer;
//console.log(proto, this.proto_structs[direction][proto]);
//const directionProtoList = this.constants[direction];
if (typeof info === 'undefined') { if (typeof info === 'undefined') {
buffer = null; buffer = null;
} }
...@@ -129,12 +138,12 @@ class YGOProMessagesHelper { ...@@ -129,12 +138,12 @@ class YGOProMessagesHelper {
buffer = info; buffer = info;
} }
else { else {
let struct = this.structs.get(this.proto_structs[direction][proto]); const protoCls = this.getProtoClass(translatedProto, direction);
struct.allocate(); if (!protoCls) {
struct.set(info); throw `No proto class for ${protostr}`;
buffer = struct.buffer(); }
buffer = Buffer.from((0, ygopro_msg_struct_compat_1.fromPartialCompat)(protoCls, info).toPayload());
} }
const translatedProto = this.translateProto(proto, direction);
let sendBuffer = Buffer.allocUnsafe(3 + (buffer ? buffer.length : 0)); let sendBuffer = Buffer.allocUnsafe(3 + (buffer ? buffer.length : 0));
if (buffer) { if (buffer) {
sendBuffer.writeUInt16LE(buffer.length + 1, 0); sendBuffer.writeUInt16LE(buffer.length + 1, 0);
...@@ -232,13 +241,11 @@ class YGOProMessagesHelper { ...@@ -232,13 +241,11 @@ class YGOProMessagesHelper {
} }
const handlerCollection = this.handlers[direction][priority]; const handlerCollection = this.handlers[direction][priority];
if (proto && handlerCollection.has(bufferProto)) { if (proto && handlerCollection.has(bufferProto)) {
let struct = this.structs.get(this.proto_structs[direction][proto]);
for (const handler of handlerCollection.get(bufferProto)) { for (const handler of handlerCollection.get(bufferProto)) {
let info = null; const protoCls = this.getProtoClass(bufferProto, direction);
if (struct) { const info = protoCls
struct._setBuff(buffer); ? (0, ygopro_msg_struct_compat_1.applyYGOProMsgStructCompat)(new protoCls().fromPayload(buffer))
info = underscore_1.default.clone(struct.fields); : null;
}
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (Buffer.isBuffer(cancel)) { if (Buffer.isBuffer(cancel)) {
......
import { Struct } from "./struct";
import _ from "underscore"; import _ from "underscore";
import structs_declaration from "./data/structs.json"; import loadConstants from "./load-constants";
import typedefs from "./data/typedefs.json";
import proto_structs from "./data/proto_structs.json";
import constants from "./data/constants.json";
import net from "net"; import net from "net";
import { YGOProCtos, YGOProCtosBase, YGOProStoc, YGOProStocBase } from "ygopro-msg-encode";
import { applyYGOProMsgStructCompat, fromPartialCompat } from "./ygopro-msg-struct-compat";
import legacyProtoStructs from "./data/proto_structs.json";
class Handler { class Handler {
private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string | Buffer>; constructor(
synchronous: boolean; private handler: (buffer: Buffer, info: YGOProStocBase | YGOProCtosBase, datas: Buffer[], params: any) => Promise<boolean | string | Buffer>,
constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string | Buffer>, synchronous: boolean) { public synchronous: boolean
this.handler = handler; ) {}
this.synchronous = synchronous || false; async handle(buffer: Buffer, info: YGOProStocBase | YGOProCtosBase, datas: Buffer[], params: any): Promise<boolean | string | Buffer> {
}
async handle(buffer: Buffer, info: any, datas: Buffer[], params: any): Promise<boolean | string | Buffer> {
if (this.synchronous) { if (this.synchronous) {
return await this.handler(buffer, info, datas, params); return await this.handler(buffer, info, datas, params);
} else { } else {
...@@ -31,12 +28,21 @@ interface HandlerList { ...@@ -31,12 +28,21 @@ interface HandlerList {
CTOS: Map<number, Handler[]>[]; CTOS: Map<number, Handler[]>[];
} }
interface DirectionBase {
STOC: typeof YGOProStocBase;
CTOS: typeof YGOProCtosBase;
}
type DirectionToBase<T>
= T extends `${infer K extends keyof DirectionBase}_${string}` ? DirectionBase[K] : DirectionBase[keyof DirectionBase];
interface DirectionAndProto { interface DirectionAndProto {
direction: string; direction: keyof HandlerList;
proto: string; proto: string;
} }
export interface Feedback{ export interface Feedback {
type: string; type: string;
message: string; message: string;
} }
...@@ -64,18 +70,48 @@ export interface Constants { ...@@ -64,18 +70,48 @@ export interface Constants {
MSG: Record<string, string>; MSG: Record<string, string>;
} }
export class YGOProMessagesHelper { export class LegacyStructInst {
buffer: Buffer;
constructor(private cls?: typeof YGOProCtosBase | typeof YGOProStocBase) {}
handlers: HandlerList; _setBuff(buff: Buffer) {
structs: Map<string, Struct>; this.buffer = buff;
structs_declaration: Record<string, Struct>; }
typedefs: Record<string, string>;
proto_structs: Record<'CTOS' | 'STOC', Record<string, string>>;
constants: Constants;
singleHandleLimit: number;
constructor(singleHandleLimit?: number) { set(field: string, value: any) {
this.handlers = { if (!this.buffer || !this.cls) return;
const inst = applyYGOProMsgStructCompat(new this.cls().fromPayload(this.buffer));
inst[field] = value;
const parsed = Buffer.from(inst.toPayload());
if (parsed.length >= this.buffer.length) {
// slice it down
parsed.copy(this.buffer, 0, 0, this.buffer.length);
} else {
// copy a small part only
parsed.copy(this.buffer, 0, 0, parsed.length);
}
}
}
export class LegacyStruct {
private protoClasses = new Map<string, typeof YGOProCtosBase | typeof YGOProStocBase>();
constructor(private helper: YGOProMessagesHelper) {
for (const [direction, list] of Object.entries(legacyProtoStructs)) {
for (const [protoStr, structName] of Object.entries(list)) {
if(!structName) continue;
this.protoClasses.set(structName, this.helper.getProtoClass(protoStr, direction as keyof HandlerList));
}
}
}
get(structName: string) {
return new LegacyStructInst(this.protoClasses.get(structName));
}
}
export class YGOProMessagesHelper {
handlers: HandlerList = {
STOC: [new Map(), STOC: [new Map(),
new Map(), new Map(),
new Map(), new Map(),
...@@ -88,56 +124,12 @@ export class YGOProMessagesHelper { ...@@ -88,56 +124,12 @@ export class YGOProMessagesHelper {
new Map(), new Map(),
new Map(), new Map(),
] ]
} };
this.initDatas(); constants = loadConstants();
this.initStructs();
if (singleHandleLimit) {
this.singleHandleLimit = singleHandleLimit;
} else {
this.singleHandleLimit = 1000;
}
}
initDatas() { constructor(public singleHandleLimit = 1000) {}
this.structs_declaration = structs_declaration;
this.typedefs = typedefs;
this.proto_structs = proto_structs;
this.constants = constants;
}
initStructs() { structs = new LegacyStruct(this);
this.structs = new Map();
for (let name in this.structs_declaration) {
const declaration = this.structs_declaration[name];
let result = Struct();
for (let field of declaration) {
if (field.encoding) {
switch (field.encoding) {
case "UTF-16LE":
result.chars(field.name, field.length * 2, field.encoding);
break;
default:
throw `unsupported encoding: ${field.encoding}`;
}
} else {
let type = field.type;
if (this.typedefs[type]) {
type = this.typedefs[type];
}
if (field.length) {
result.array(field.name, field.length, type); //不支持结构体
} else {
if (this.structs.has(type)) {
result.struct(field.name, this.structs.get(type));
} else {
result[type](field.name);
}
}
}
}
this.structs.set(name, result);
}
}
getDirectionAndProto(protoStr: string): DirectionAndProto { getDirectionAndProto(protoStr: string): DirectionAndProto {
const protoStrMatch = protoStr.match(/^(STOC|CTOS)_([_A-Z]+)$/); const protoStrMatch = protoStr.match(/^(STOC|CTOS)_([_A-Z]+)$/);
...@@ -145,13 +137,12 @@ export class YGOProMessagesHelper { ...@@ -145,13 +137,12 @@ export class YGOProMessagesHelper {
throw `Invalid proto string: ${protoStr}` throw `Invalid proto string: ${protoStr}`
} }
return { return {
direction: protoStrMatch[1].toUpperCase(), direction: protoStrMatch[1].toUpperCase() as keyof HandlerList,
proto: protoStrMatch[2].toUpperCase() proto: protoStrMatch[2].toUpperCase()
} }
} }
translateProto(proto: string | number, direction: keyof HandlerList): number {
translateProto(proto: string | number, direction: string): number {
const directionProtoList = this.constants[direction]; const directionProtoList = this.constants[direction];
if (typeof proto !== "string") { if (typeof proto !== "string") {
return proto; return proto;
...@@ -165,25 +156,43 @@ export class YGOProMessagesHelper { ...@@ -165,25 +156,43 @@ export class YGOProMessagesHelper {
return parseInt(translatedProto); return parseInt(translatedProto);
} }
getProtoClass<T extends string | number>(proto: T, direction: keyof HandlerList): DirectionToBase<T> {
const identifier = typeof proto === 'number' ? proto : this.translateProto(proto, direction);
const registry = direction === 'CTOS' ? YGOProCtos : direction === 'STOC' ? YGOProStoc : null;
if (!registry) {
throw `Invalid direction: ${direction}`;
}
return registry.get(identifier) as DirectionToBase<T>;
}
classToProtoStr(cls: typeof YGOProCtosBase | typeof YGOProStocBase): string {
const registry = cls.prototype instanceof YGOProCtosBase ? YGOProCtos : cls.prototype instanceof YGOProStocBase ? YGOProStoc : null;
if (!registry) {
throw `Invalid class: ${cls.name}`;
}
const identifier = cls.identifier;
const direction = cls.prototype instanceof YGOProCtosBase ? 'CTOS' : 'STOC';
return `${direction}_${this.constants[direction][identifier]}`;
}
prepareMessage(protostr: string, info?: string | Buffer | any): Buffer { prepareMessage(protostr: string, info?: string | Buffer | any): Buffer {
const { const {
direction, direction,
proto proto
} = this.getDirectionAndProto(protostr); } = this.getDirectionAndProto(protostr);
const translatedProto = this.translateProto(proto, direction);
let buffer: Buffer; let buffer: Buffer;
//console.log(proto, this.proto_structs[direction][proto]);
//const directionProtoList = this.constants[direction];
if (typeof info === 'undefined') { if (typeof info === 'undefined') {
buffer = null; buffer = null;
} else if (Buffer.isBuffer(info)) { } else if (Buffer.isBuffer(info)) {
buffer = info; buffer = info;
} else { } else {
let struct = this.structs.get(this.proto_structs[direction][proto]); const protoCls = this.getProtoClass(translatedProto, direction);
struct.allocate(); if (!protoCls) {
struct.set(info); throw `No proto class for ${protostr}`;
buffer = struct.buffer(); }
buffer = Buffer.from(fromPartialCompat(protoCls, info).toPayload());
} }
const translatedProto = this.translateProto(proto, direction);
let sendBuffer = Buffer.allocUnsafe(3 + (buffer ? buffer.length : 0)); let sendBuffer = Buffer.allocUnsafe(3 + (buffer ? buffer.length : 0));
if (buffer) { if (buffer) {
sendBuffer.writeUInt16LE(buffer.length + 1, 0); sendBuffer.writeUInt16LE(buffer.length + 1, 0);
...@@ -214,7 +223,7 @@ export class YGOProMessagesHelper { ...@@ -214,7 +223,7 @@ export class YGOProMessagesHelper {
return this.send(socket, sendBuffer); return this.send(socket, sendBuffer);
} }
addHandler(protostr: string, handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean, priority: number) { addHandler<T extends string>(protostr: T, handler: (buffer: Buffer, info: InstanceType<DirectionToBase<T>>, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean, priority: number) {
if (priority < 0 || priority > 4) { if (priority < 0 || priority > 4) {
throw "Invalid priority: " + priority; throw "Invalid priority: " + priority;
} }
...@@ -232,7 +241,7 @@ export class YGOProMessagesHelper { ...@@ -232,7 +241,7 @@ export class YGOProMessagesHelper {
handlerCollection.get(translatedProto).push(handlerObj); handlerCollection.get(translatedProto).push(handlerObj);
} }
async handleBuffer(messageBuffer: Buffer, direction: string, protoFilter?: string[], params?: any, preconnect = false): Promise<HandleResult> { async handleBuffer(messageBuffer: Buffer, direction: keyof HandlerList, protoFilter?: string[], params?: any, preconnect = false): Promise<HandleResult> {
let feedback: Feedback = null; let feedback: Feedback = null;
let messageLength = 0; let messageLength = 0;
let bufferProto = 0; let bufferProto = 0;
...@@ -282,13 +291,11 @@ export class YGOProMessagesHelper { ...@@ -282,13 +291,11 @@ export class YGOProMessagesHelper {
} }
const handlerCollection: Map<number, Handler[]> = this.handlers[direction][priority]; const handlerCollection: Map<number, Handler[]> = this.handlers[direction][priority];
if (proto && handlerCollection.has(bufferProto)) { if (proto && handlerCollection.has(bufferProto)) {
let struct = this.structs.get(this.proto_structs[direction][proto]);
for (const handler of handlerCollection.get(bufferProto)) { for (const handler of handlerCollection.get(bufferProto)) {
let info = null; const protoCls = this.getProtoClass(bufferProto, direction);
if (struct) { const info = protoCls
struct._setBuff(buffer); ? applyYGOProMsgStructCompat(new protoCls().fromPayload(buffer))
info = _.clone(struct.fields); : null;
}
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (Buffer.isBuffer(cancel)) { if (Buffer.isBuffer(cancel)) {
......
...@@ -12,52 +12,6 @@ ...@@ -12,52 +12,6 @@
"5": "TYPE_PLAYER6", "5": "TYPE_PLAYER6",
"7": "TYPE_OBSERVER" "7": "TYPE_OBSERVER"
}, },
"CTOS": {
"1": "RESPONSE",
"2": "UPDATE_DECK",
"3": "HAND_RESULT",
"4": "TP_RESULT",
"16": "PLAYER_INFO",
"17": "CREATE_GAME",
"18": "JOIN_GAME",
"19": "LEAVE_GAME",
"20": "SURRENDER",
"21": "TIME_CONFIRM",
"22": "CHAT",
"23": "EXTERNAL_ADDRESS",
"32": "HS_TODUELIST",
"33": "HS_TOOBSERVER",
"34": "HS_READY",
"35": "HS_NOTREADY",
"36": "HS_KICK",
"37": "HS_START",
"48": "REQUEST_FIELD"
},
"STOC": {
"1": "GAME_MSG",
"2": "ERROR_MSG",
"3": "SELECT_HAND",
"4": "SELECT_TP",
"5": "HAND_RESULT",
"6": "TP_RESULT",
"7": "CHANGE_SIDE",
"8": "WAITING_SIDE",
"9": "DECK_COUNT",
"17": "CREATE_GAME",
"18": "JOIN_GAME",
"19": "TYPE_CHANGE",
"20": "LEAVE_GAME",
"21": "DUEL_START",
"22": "DUEL_END",
"23": "REPLAY",
"24": "TIME_LIMIT",
"25": "CHAT",
"32": "HS_PLAYER_ENTER",
"33": "HS_PLAYER_CHANGE",
"34": "HS_WATCH_CHANGE",
"35": "TEAMMATE_SURRENDER",
"48": "FIELD_FINISH"
},
"PLAYERCHANGE":{ "PLAYERCHANGE":{
"8": "OBSERVE", "8": "OBSERVE",
"9": "READY", "9": "READY",
...@@ -75,203 +29,6 @@ ...@@ -75,203 +29,6 @@
"1": "MATCH", "1": "MATCH",
"2": "TAG" "2": "TAG"
}, },
"MSG": {
"1": "RETRY",
"2": "HINT",
"3": "WAITING",
"4": "START",
"5": "WIN",
"6": "UPDATE_DATA",
"7": "UPDATE_CARD",
"8": "REQUEST_DECK",
"10": "SELECT_BATTLECMD",
"11": "SELECT_IDLECMD",
"12": "SELECT_EFFECTYN",
"13": "SELECT_YESNO",
"14": "SELECT_OPTION",
"15": "SELECT_CARD",
"16": "SELECT_CHAIN",
"18": "SELECT_PLACE",
"19": "SELECT_POSITION",
"20": "SELECT_TRIBUTE",
"21": "SORT_CHAIN",
"22": "SELECT_COUNTER",
"23": "SELECT_SUM",
"24": "SELECT_DISFIELD",
"25": "SORT_CARD",
"26": "SELECT_UNSELECT_CARD",
"30": "CONFIRM_DECKTOP",
"31": "CONFIRM_CARDS",
"32": "SHUFFLE_DECK",
"33": "SHUFFLE_HAND",
"34": "REFRESH_DECK",
"35": "SWAP_GRAVE_DECK",
"36": "SHUFFLE_SET_CARD",
"37": "REVERSE_DECK",
"38": "DECK_TOP",
"39": "MSG_SHUFFLE_EXTRA",
"40": "NEW_TURN",
"41": "NEW_PHASE",
"42": "CONFIRM_EXTRATOP",
"50": "MOVE",
"53": "POS_CHANGE",
"54": "SET",
"55": "SWAP",
"56": "FIELD_DISABLED",
"60": "SUMMONING",
"61": "SUMMONED",
"62": "SPSUMMONING",
"63": "SPSUMMONED",
"64": "FLIPSUMMONING",
"65": "FLIPSUMMONED",
"70": "CHAINING",
"71": "CHAINED",
"72": "CHAIN_SOLVING",
"73": "CHAIN_SOLVED",
"74": "CHAIN_END",
"75": "CHAIN_NEGATED",
"76": "CHAIN_DISABLED",
"80": "CARD_SELECTED",
"81": "RANDOM_SELECTED",
"83": "BECOME_TARGET",
"90": "DRAW",
"91": "DAMAGE",
"92": "RECOVER",
"93": "EQUIP",
"94": "LPUPDATE",
"95": "UNEQUIP",
"96": "CARD_TARGET",
"97": "CANCEL_TARGET",
"100": "PAY_LPCOST",
"101": "ADD_COUNTER",
"102": "REMOVE_COUNTER",
"110": "ATTACK",
"111": "BATTLE",
"112": "ATTACK_DISABLED",
"113": "DAMAGE_STEP_START",
"114": "DAMAGE_STEP_END",
"120": "MISSED_EFFECT",
"121": "BE_CHAIN_TARGET",
"122": "CREATE_RELATION",
"123": "RELEASE_RELATION",
"130": "TOSS_COIN",
"131": "TOSS_DICE",
"132": "ROCK_PAPER_SCISSORS",
"133": "HAND_RES",
"140": "ANNOUNCE_RACE",
"141": "ANNOUNCE_ATTRIB",
"142": "ANNOUNCE_CARD",
"143": "ANNOUNCE_NUMBER",
"160": "CARD_HINT",
"161": "TAG_SWAP",
"162": "RELOAD_FIELD",
"163": "AI_NAME",
"164": "SHOW_HINT",
"170": "MATCH_KILL",
"180": "CUSTOM_MSG"
},
"TIMING":{
"1": "DRAW_PHASE",
"2": "STANDBY_PHASE",
"4": "MAIN_END",
"8": "BATTLE_START",
"16": "BATTLE_END",
"32": "END_PHASE",
"64": "SUMMON",
"128": "SPSUMMON",
"256": "FLIPSUMMON",
"512": "MSET",
"1024": "SSET",
"2048": "POS_CHANGE",
"4096": "ATTACK",
"8192": "DAMAGE_STEP",
"16384": "DAMAGE_CAL",
"32768": "CHAIN_END",
"65536": "DRAW",
"131072": "DAMAGE",
"262144": "RECOVER",
"524288": "DESTROY",
"1048576": "REMOVE",
"2097152": "TOHAND",
"4194304": "TODECK",
"8388608": "TOGRAVE",
"16777216": "BATTLE_PHASE",
"33554432": "EQUIP"
},
"TYPES": {
"TYPE_MONSTER": 1,
"TYPE_SPELL": 2,
"TYPE_TRAP": 4,
"TYPE_NORMAL": 16,
"TYPE_EFFECT": 32,
"TYPE_FUSION": 64,
"TYPE_RITUAL": 128,
"TYPE_TRAPMONSTER": 256,
"TYPE_SPIRIT": 512,
"TYPE_UNION": 1024,
"TYPE_DUAL": 2048,
"TYPE_TUNER": 4096,
"TYPE_SYNCHRO": 8192,
"TYPE_TOKEN": 16384,
"TYPE_QUICKPLAY": 65536,
"TYPE_CONTINUOUS": 131072,
"TYPE_EQUIP": 262144,
"TYPE_FIELD": 524288,
"TYPE_COUNTER": 1048576,
"TYPE_FLIP": 2097152,
"TYPE_TOON": 4194304,
"TYPE_XYZ": 8388608,
"TYPE_PENDULUM": 16777216,
"TYPE_SPSUMMON": 33554432,
"TYPE_LINK": 67108864
},
"RACES": {
"RACE_WARRIOR": 1,
"RACE_SPELLCASTER": 2,
"RACE_FAIRY": 4,
"RACE_FIEND": 8,
"RACE_ZOMBIE": 16,
"RACE_MACHINE": 32,
"RACE_AQUA": 64,
"RACE_PYRO": 128,
"RACE_ROCK": 256,
"RACE_WINDBEAST": 512,
"RACE_PLANT": 1024,
"RACE_INSECT": 2048,
"RACE_THUNDER": 4096,
"RACE_DRAGON": 8192,
"RACE_BEAST": 16384,
"RACE_BEASTWARRIOR": 32768,
"RACE_DINOSAUR": 65536,
"RACE_FISH": 131072,
"RACE_SEASERPENT": 262144,
"RACE_REPTILE": 524288,
"RACE_PSYCHO": 1048576,
"RACE_DEVINE": 2097152,
"RACE_CREATORGOD": 4194304,
"RACE_WYRM": 8388608,
"RACE_CYBERS": 16777216,
"RACE_ILLUSION": 33554432
},
"ATTRIBUTES": {
"ATTRIBUTE_EARTH": 1,
"ATTRIBUTE_WATER": 2,
"ATTRIBUTE_FIRE": 4,
"ATTRIBUTE_WIND": 8,
"ATTRIBUTE_LIGHT": 16,
"ATTRIBUTE_DARK": 32,
"ATTRIBUTE_DEVINE": 64
},
"LINK_MARKERS": {
"LINK_MARKER_BOTTOM_LEFT": 1,
"LINK_MARKER_BOTTOM": 2,
"LINK_MARKER_BOTTOM_RIGHT": 4,
"LINK_MARKER_LEFT": 8,
"LINK_MARKER_RIGHT": 32,
"LINK_MARKER_TOP_LEFT": 64,
"LINK_MARKER_TOP": 128,
"LINK_MARKER_TOP_RIGHT": 256
},
"DUEL_STAGE": { "DUEL_STAGE": {
"BEGIN": 0, "BEGIN": 0,
"FINGER": 1, "FINGER": 1,
......
{
"HostInfo": [
{"name": "lflist", "type": "unsigned int"},
{"name": "rule", "type": "unsigned char"},
{"name": "mode", "type": "unsigned char"},
{"name": "duel_rule", "type": "unsigned char"},
{"name": "no_check_deck", "type": "bool"},
{"name": "no_shuffle_deck", "type": "bool"},
{"name": "start_lp", "type": "unsigned int"},
{"name": "start_hand", "type": "unsigned char"},
{"name": "draw_count", "type": "unsigned char"},
{"name": "time_limit", "type": "unsigned short"}
],
"HostPacket": [
{"name": "identifier", "type": "unsigned short"},
{"name": "version", "type": "unsigned short"},
{"name": "port", "type": "unsigned short"},
{"name": "ipaddr", "type": "unsigned int"},
{"name": "name", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"},
{"name": "host", "type": "HostInfo"}
],
"HostRequest": [
{"name": "identifier", "type": "unsigned short"}
],
"CTOS_HandResult": [
{"name": "res", "type": "unsigned char"}
],
"CTOS_TPResult": [
{"name": "res", "type": "unsigned char"}
],
"CTOS_PlayerInfo": [
{"name": "name", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"}
],
"CTOS_CreateGame": [
{"name": "info", "type": "HostInfo"},
{"name": "name", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"},
{"name": "pass", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"}
],
"CTOS_JoinGame": [
{"name": "version", "type": "unsigned short"},
{"name": "align", "type": "unsigned short"},
{"name": "gameid", "type": "unsigned int"},
{"name": "pass", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"}
],
"CTOS_ExternalAddress": [
{"name": "real_ip", "type": "unsigned int"},
{"name": "hostname", "type": "unsigned short", "length":"256", "encoding": "UTF-16LE"}
],
"CTOS_Kick": [
{"name": "pos", "type": "unsigned char"}
],
"STOC_ErrorMsg": [
{"name": "msg", "type": "unsigned char"},
{"name": "align1", "type": "unsigned char"},
{"name": "align2", "type": "unsigned char"},
{"name": "align3", "type": "unsigned char"},
{"name": "code", "type": "unsigned int"}
],
"STOC_HandResult": [
{"name": "res1", "type": "unsigned char"},
{"name": "res2", "type": "unsigned char"}
],
"STOC_CreateGame": [
{"name": "gameid", "type": "unsigned int"}
],
"STOC_JoinGame": [
{"name": "info", "type": "HostInfo"}
],
"STOC_TypeChange": [
{"name": "type", "type": "unsigned char"}
],
"STOC_ExitGame": [
{"name": "pos", "type": "unsigned char"}
],
"STOC_TimeLimit": [
{"name": "player", "type": "unsigned char"},
{"name": "left_time", "type": "unsigned short"}
],
"STOC_Chat": [
{"name": "player", "type": "unsigned short"},
{"name": "msg", "type": "unsigned short", "length": 255, "encoding": "UTF-16LE"}
],
"STOC_HS_PlayerEnter": [
{"name": "name", "type": "unsigned short", "length": 20, "encoding": "UTF-16LE"},
{"name": "pos", "type": "unsigned char"},
{"name": "padding", "type": "unsigned char"}
],
"STOC_HS_PlayerChange": [
{"name": "status", "type": "unsigned char"}
],
"STOC_HS_WatchChange": [
{"name": "watch_count", "type": "unsigned short"}
],
"GameMsg_Hint_Card_only": [
{"name": "curmsg", "type": "word8Ule"},
{"name": "type", "type": "word8"},
{"name": "player", "type": "word8"},
{"name": "data", "type": "word32Ule"}
],
"deck": [
{"name": "mainc", "type": "unsigned int"},
{"name": "sidec", "type": "unsigned int"},
{"name": "deckbuf", "type": "unsigned int", "length": 90}
],
"chat": [
{"name": "msg", "type": "unsigned short", "length":"255", "encoding": "UTF-16LE"}
],
"STOC_DeckCount": [
{"name": "mainc_s", "type": "unsigned short"},
{"name": "sidec_s", "type": "unsigned short"},
{"name": "extrac_s", "type": "unsigned short"},
{"name": "mainc_o", "type": "unsigned short"},
{"name": "sidec_o", "type": "unsigned short"},
{"name": "extrac_o", "type": "unsigned short"}
]
}
{
"unsigned int": "word32Ule",
"unsigned short": "word16Ule",
"unsigned char": "word8",
"bool": "bool2"
}
\ No newline at end of file
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadConstants = void 0;
const ygopro_msg_encode_1 = require("ygopro-msg-encode");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const loadConstantsJson = () => {
const filePath = path_1.default.join(__dirname, "data", "constants.json");
const raw = fs_1.default.readFileSync(filePath, "utf8");
return JSON.parse(raw);
};
const addMissingNumberEntries = (target, source, prefix) => {
for (const [key, value] of Object.entries(source)) {
if (!key.startsWith(prefix)) {
continue;
}
if (target[key] === undefined) {
target[key] = value;
}
}
};
const addMissingStringEntries = (target, source, prefix) => {
for (const [key, value] of Object.entries(source)) {
if (!key.startsWith(prefix)) {
continue;
}
const codeKey = String(value);
if (target[codeKey] === undefined) {
target[codeKey] = key.slice(prefix.length);
}
}
};
const legacyMsgFallback = {
"3": "WAITING",
"4": "START",
"6": "UPDATE_DATA",
"8": "REQUEST_DECK",
"21": "SORT_CHAIN",
"34": "REFRESH_DECK",
"39": "MSG_SHUFFLE_EXTRA",
"80": "CARD_SELECTED",
"95": "UNEQUIP",
"121": "BE_CHAIN_TARGET",
"122": "CREATE_RELATION",
"123": "RELEASE_RELATION",
};
const toConstantName = (name) => name
.replace(/^_+|_+$/g, "")
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
.toUpperCase();
const normalizeProtoName = (name) => name
.replace("TO_OBSERVER", "TOOBSERVER")
.replace("TO_DUELIST", "TODUELIST")
.replace("HS_NOT_READY", "HS_NOTREADY")
.replace("KICK", "HS_KICK");
const buildProtoMap = (registry, classPrefix) => {
const out = {};
for (const [id, cls] of registry.protos.entries()) {
const rawName = cls.name.startsWith(classPrefix)
? cls.name.slice(classPrefix.length)
: cls.name;
const name = normalizeProtoName(toConstantName(rawName));
out[String(id)] = name;
}
return out;
};
const loadConstants = () => {
const result = loadConstantsJson();
if (!result.TYPES)
result.TYPES = {};
if (!result.RACES)
result.RACES = {};
if (!result.ATTRIBUTES)
result.ATTRIBUTES = {};
if (!result.LINK_MARKERS)
result.LINK_MARKERS = {};
if (!result.MSG)
result.MSG = {};
if (!result.TIMING)
result.TIMING = {};
if (!result.CTOS)
result.CTOS = {};
if (!result.STOC)
result.STOC = {};
if (!result.NETWORK)
result.NETWORK = {};
if (!result.NETPLAYER)
result.NETPLAYER = {};
if (!result.PLAYERCHANGE)
result.PLAYERCHANGE = {};
if (!result.ERRMSG)
result.ERRMSG = {};
if (!result.MODE)
result.MODE = {};
if (!result.DUEL_STAGE)
result.DUEL_STAGE = {};
if (!result.COLORS)
result.COLORS = {};
addMissingNumberEntries(result.TYPES, ygopro_msg_encode_1.OcgcoreCommonConstants, "TYPE_");
addMissingNumberEntries(result.RACES, ygopro_msg_encode_1.OcgcoreCommonConstants, "RACE_");
addMissingNumberEntries(result.ATTRIBUTES, ygopro_msg_encode_1.OcgcoreCommonConstants, "ATTRIBUTE_");
addMissingNumberEntries(result.ATTRIBUTES, ygopro_msg_encode_1.OcgcoreScriptConstants, "ATTRIBUTE_");
addMissingNumberEntries(result.LINK_MARKERS, ygopro_msg_encode_1.OcgcoreCommonConstants, "LINK_MARKER_");
addMissingStringEntries(result.MSG, ygopro_msg_encode_1.OcgcoreCommonConstants, "MSG_");
addMissingStringEntries(result.TIMING, ygopro_msg_encode_1.OcgcoreScriptConstants, "TIMING_");
for (const [code, name] of Object.entries(legacyMsgFallback)) {
result.MSG[code] = name;
}
const ctosMap = buildProtoMap(ygopro_msg_encode_1.YGOProCtos, "YGOProCtos");
const stocMap = buildProtoMap(ygopro_msg_encode_1.YGOProStoc, "YGOProStoc");
const mismatches = [];
for (const [code, name] of Object.entries(ctosMap)) {
if (result.CTOS[code] !== undefined && result.CTOS[code] !== name) {
mismatches.push(`CTOS ${code}: ${result.CTOS[code]} != ${name}`);
}
result.CTOS[code] = name;
}
for (const [code, name] of Object.entries(stocMap)) {
if (result.STOC[code] !== undefined && result.STOC[code] !== name) {
mismatches.push(`STOC ${code}: ${result.STOC[code]} != ${name}`);
}
result.STOC[code] = name;
}
if (mismatches.length) {
throw new Error(`CTOS/STOC name mismatch between constants.json and registry:\\n${mismatches.join("\\n")}`);
}
if (result.RACES.RACE_CYBERS === undefined &&
result.RACES.RACE_CYBERSE !== undefined) {
result.RACES.RACE_CYBERS = result.RACES.RACE_CYBERSE;
}
return result;
};
exports.loadConstants = loadConstants;
exports.default = exports.loadConstants;
if (require.main === module) {
console.log(JSON.stringify((0, exports.loadConstants)(), null, 2));
}
import {
OcgcoreCommonConstants,
OcgcoreScriptConstants,
YGOProCtos,
YGOProStoc,
} from "ygopro-msg-encode";
import fs from "fs";
import path from "path";
export interface ConstantsShape {
TYPES: Record<string, number>;
RACES: Record<string, number>;
ATTRIBUTES: Record<string, number>;
LINK_MARKERS: Record<string, number>;
DUEL_STAGE: Record<string, number>;
COLORS: Record<string, number>;
TIMING: Record<string, string>;
NETWORK: Record<string, string>;
NETPLAYER: Record<string, string>;
CTOS: Record<string, string>;
STOC: Record<string, string>;
PLAYERCHANGE: Record<string, string>;
ERRMSG: Record<string, string>;
MODE: Record<string, string>;
MSG: Record<string, string>;
}
type StringMap = Record<string, string>;
type NumberMap = Record<string, number>;
const loadConstantsJson = (): Partial<ConstantsShape> => {
const filePath = path.join(__dirname, "data", "constants.json");
const raw = fs.readFileSync(filePath, "utf8");
return JSON.parse(raw) as Partial<ConstantsShape>;
};
const addMissingNumberEntries = (
target: NumberMap,
source: Record<string, number>,
prefix: string
) => {
for (const [key, value] of Object.entries(source)) {
if (!key.startsWith(prefix)) {
continue;
}
if (target[key] === undefined) {
target[key] = value;
}
}
};
const addMissingStringEntries = (
target: StringMap,
source: Record<string, number>,
prefix: string
) => {
for (const [key, value] of Object.entries(source)) {
if (!key.startsWith(prefix)) {
continue;
}
const codeKey = String(value);
if (target[codeKey] === undefined) {
target[codeKey] = key.slice(prefix.length);
}
}
};
const legacyMsgFallback: Record<string, string> = {
"3": "WAITING",
"4": "START",
"6": "UPDATE_DATA",
"8": "REQUEST_DECK",
"21": "SORT_CHAIN",
"34": "REFRESH_DECK",
"39": "MSG_SHUFFLE_EXTRA",
"80": "CARD_SELECTED",
"95": "UNEQUIP",
"121": "BE_CHAIN_TARGET",
"122": "CREATE_RELATION",
"123": "RELEASE_RELATION",
};
const toConstantName = (name: string) =>
name
.replace(/^_+|_+$/g, "")
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
.toUpperCase();
const normalizeProtoName = (name: string) =>
name
.replace("TO_OBSERVER", "TOOBSERVER")
.replace("TO_DUELIST", "TODUELIST")
.replace("HS_NOT_READY", "HS_NOTREADY")
.replace("KICK", "HS_KICK");
const buildProtoMap = (
registry: { protos: Map<number, { name: string }> },
classPrefix: string
) => {
const out: Record<string, string> = {};
for (const [id, cls] of registry.protos.entries()) {
const rawName = cls.name.startsWith(classPrefix)
? cls.name.slice(classPrefix.length)
: cls.name;
const name = normalizeProtoName(toConstantName(rawName));
out[String(id)] = name;
}
return out;
};
export const loadConstants = () => {
const result = loadConstantsJson();
if (!result.TYPES) result.TYPES = {};
if (!result.RACES) result.RACES = {};
if (!result.ATTRIBUTES) result.ATTRIBUTES = {};
if (!result.LINK_MARKERS) result.LINK_MARKERS = {};
if (!result.MSG) result.MSG = {};
if (!result.TIMING) result.TIMING = {};
if (!result.CTOS) result.CTOS = {};
if (!result.STOC) result.STOC = {};
if (!result.NETWORK) result.NETWORK = {};
if (!result.NETPLAYER) result.NETPLAYER = {};
if (!result.PLAYERCHANGE) result.PLAYERCHANGE = {};
if (!result.ERRMSG) result.ERRMSG = {};
if (!result.MODE) result.MODE = {};
if (!result.DUEL_STAGE) result.DUEL_STAGE = {};
if (!result.COLORS) result.COLORS = {};
addMissingNumberEntries(result.TYPES, OcgcoreCommonConstants, "TYPE_");
addMissingNumberEntries(result.RACES, OcgcoreCommonConstants, "RACE_");
addMissingNumberEntries(result.ATTRIBUTES, OcgcoreCommonConstants, "ATTRIBUTE_");
addMissingNumberEntries(result.ATTRIBUTES, OcgcoreScriptConstants, "ATTRIBUTE_");
addMissingNumberEntries(result.LINK_MARKERS, OcgcoreCommonConstants, "LINK_MARKER_");
addMissingStringEntries(result.MSG, OcgcoreCommonConstants, "MSG_");
addMissingStringEntries(result.TIMING, OcgcoreScriptConstants, "TIMING_");
for (const [code, name] of Object.entries(legacyMsgFallback)) {
result.MSG[code] = name;
}
const ctosMap = buildProtoMap(YGOProCtos, "YGOProCtos");
const stocMap = buildProtoMap(YGOProStoc, "YGOProStoc");
const mismatches: string[] = [];
for (const [code, name] of Object.entries(ctosMap)) {
if (result.CTOS[code] !== undefined && result.CTOS[code] !== name) {
mismatches.push(`CTOS ${code}: ${result.CTOS[code]} != ${name}`);
}
result.CTOS[code] = name;
}
for (const [code, name] of Object.entries(stocMap)) {
if (result.STOC[code] !== undefined && result.STOC[code] !== name) {
mismatches.push(`STOC ${code}: ${result.STOC[code]} != ${name}`);
}
result.STOC[code] = name;
}
if (mismatches.length) {
throw new Error(
`CTOS/STOC name mismatch between constants.json and registry:\\n${mismatches.join("\\n")}`
);
}
if (
result.RACES.RACE_CYBERS === undefined &&
result.RACES.RACE_CYBERSE !== undefined
) {
result.RACES.RACE_CYBERS = result.RACES.RACE_CYBERSE;
}
return result as ConstantsShape;
};
export default loadConstants;
if (require.main === module) {
console.log(JSON.stringify(loadConstants(), null, 2));
}
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
"underscore.string": "^3.3.6", "underscore.string": "^3.3.6",
"ws": "^8.9.0", "ws": "^8.9.0",
"ygopro-deck-encode": "^1.0.15", "ygopro-deck-encode": "^1.0.15",
"ygopro-msg-encode": "^1.1.5",
"ygopro-yrp-encode": "^1.0.1" "ygopro-yrp-encode": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
...@@ -2630,9 +2631,9 @@ ...@@ -2630,9 +2631,9 @@
} }
}, },
"node_modules/typed-reflector": { "node_modules/typed-reflector": {
"version": "1.0.11", "version": "1.0.14",
"resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.11.tgz", "resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.14.tgz",
"integrity": "sha512-OhryVYaR+tBEW9Yt2PsPqAniNfbVk1idKbnLxBCBPUSHVRm+Ajik/QxifoJUuGoaXAZDLW9JlJTO6ctXGZX9gQ==", "integrity": "sha512-53t+jhADytooqNMpP6+hg/IYhFB3SYxGxrpn045XFEBLzn9mEzQmEVTQtdWg7hToPWvdOCMe5AGH1jlAPK5YFA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
...@@ -3209,6 +3210,17 @@ ...@@ -3209,6 +3210,17 @@
"integrity": "sha512-NMvgWuC3SKant50RDu0bHa3QIRlwBhdTR3bNDrMpNthTTQmCCq8i2HZaWFiCmYIBi9fR3W9CkFIgK6hI4d+PzQ==", "integrity": "sha512-NMvgWuC3SKant50RDu0bHa3QIRlwBhdTR3bNDrMpNthTTQmCCq8i2HZaWFiCmYIBi9fR3W9CkFIgK6hI4d+PzQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/ygopro-msg-encode": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ygopro-msg-encode/-/ygopro-msg-encode-1.1.5.tgz",
"integrity": "sha512-scsIDy7aBksNXCDiIEij23JIpVF1bosGvUJ2OGtfbcmuMEMbrUlX6JQp179AL86sjTkQg8DJ8cYj4UzEYMrrtQ==",
"license": "MIT",
"dependencies": {
"typed-reflector": "^1.0.14",
"ygopro-deck-encode": "^1.0.15",
"ygopro-yrp-encode": "^1.0.1"
}
},
"node_modules/ygopro-yrp-encode": { "node_modules/ygopro-yrp-encode": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ygopro-yrp-encode/-/ygopro-yrp-encode-1.0.1.tgz", "resolved": "https://registry.npmjs.org/ygopro-yrp-encode/-/ygopro-yrp-encode-1.0.1.tgz",
...@@ -5161,9 +5173,9 @@ ...@@ -5161,9 +5173,9 @@
} }
}, },
"typed-reflector": { "typed-reflector": {
"version": "1.0.11", "version": "1.0.14",
"resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.11.tgz", "resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.14.tgz",
"integrity": "sha512-OhryVYaR+tBEW9Yt2PsPqAniNfbVk1idKbnLxBCBPUSHVRm+Ajik/QxifoJUuGoaXAZDLW9JlJTO6ctXGZX9gQ==", "integrity": "sha512-53t+jhADytooqNMpP6+hg/IYhFB3SYxGxrpn045XFEBLzn9mEzQmEVTQtdWg7hToPWvdOCMe5AGH1jlAPK5YFA==",
"requires": { "requires": {
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
} }
...@@ -5578,6 +5590,16 @@ ...@@ -5578,6 +5590,16 @@
"resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.15.tgz", "resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.15.tgz",
"integrity": "sha512-NMvgWuC3SKant50RDu0bHa3QIRlwBhdTR3bNDrMpNthTTQmCCq8i2HZaWFiCmYIBi9fR3W9CkFIgK6hI4d+PzQ==" "integrity": "sha512-NMvgWuC3SKant50RDu0bHa3QIRlwBhdTR3bNDrMpNthTTQmCCq8i2HZaWFiCmYIBi9fR3W9CkFIgK6hI4d+PzQ=="
}, },
"ygopro-msg-encode": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ygopro-msg-encode/-/ygopro-msg-encode-1.1.5.tgz",
"integrity": "sha512-scsIDy7aBksNXCDiIEij23JIpVF1bosGvUJ2OGtfbcmuMEMbrUlX6JQp179AL86sjTkQg8DJ8cYj4UzEYMrrtQ==",
"requires": {
"typed-reflector": "^1.0.14",
"ygopro-deck-encode": "^1.0.15",
"ygopro-yrp-encode": "^1.0.1"
}
},
"ygopro-yrp-encode": { "ygopro-yrp-encode": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ygopro-yrp-encode/-/ygopro-yrp-encode-1.0.1.tgz", "resolved": "https://registry.npmjs.org/ygopro-yrp-encode/-/ygopro-yrp-encode-1.0.1.tgz",
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
"underscore.string": "^3.3.6", "underscore.string": "^3.3.6",
"ws": "^8.9.0", "ws": "^8.9.0",
"ygopro-deck-encode": "^1.0.15", "ygopro-deck-encode": "^1.0.15",
"ygopro-msg-encode": "^1.1.5",
"ygopro-yrp-encode": "^1.0.1" "ygopro-yrp-encode": "^1.0.1"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
......
// a special version of node-struct by xdenser
// https://github.com/xdenser/node-struct/tree/f843487d6768cd0bf20c2ce7803dde2d92df5694
function byteField(p, offset) {
this.length = 1;
this.get = function () {
return p.buf[offset];
}
this.set = function (val) {
p.buf[offset] = val;
}
}
function boolField(p, offset, length) {
this.length = length;
this.get = function () {
return (p.buf[offset] > 0 );
}
this.set = function (val) {
p.buf[offset] = val ? 1 : 0;
}
}
function intField(p, offset, length, le, signed) {
this.length = length;
function bec(cb) {
for (var i = 0; i < length; i++)
cb(i, length - i - 1);
}
function lec(cb) {
for (var i = 0; i < length; i++)
cb(i, i);
}
function getUVal(bor) {
var val = 0;
bor(function (i, o) {
val += Math.pow(256, o) * p.buf[offset + i];
})
return val;
}
function getSVal(bor) {
var val = getUVal(bor);
if ((p.buf[offset + ( le ? (length - 1) : 0)] & 0x80) == 0x80) {
val -= Math.pow(256, length);
}
return val;
}
function setVal(bor, val) {
bor(function (i, o) {
p.buf[offset + i] = Math.floor(val / Math.pow(256, o)) & 0xff;
});
}
this.get = function () {
var bor = le ? lec : bec;
return ( signed ? getSVal(bor) : getUVal(bor));
}
this.set = function (val) {
var bor = le ? lec : bec;
setVal(bor, val);
}
}
function charField(p, offset, length, encoding) {
this.length = length;
this.encoding = encoding;
this.get = function () {
var result = p.buf.toString(this.encoding, offset, offset + length);
var strlen = result.indexOf("\0");
if (strlen == -1) {
return result;
} else {
return result.slice(0, strlen);
}
}
this.set = function (val) {
val += "\0";
if (val.length > length)
val = val.substring(0, length);
p.buf.write(val, offset, this.encoding);
}
}
function structField(p, offset, struct) {
this.length = struct.length();
this.get = function () {
return struct;
}
this.set = function (val) {
struct.set(val);
}
this.allocate = function () {
struct._setBuff(p.buf.slice(offset, offset + struct.length()));
}
}
function arrayField(p, offset, len, type) {
var as = Struct();
var args = [].slice.call(arguments, 4);
args.unshift(0);
for (var i = 0; i < len; i++) {
if (type instanceof Struct) {
as.struct(i, type.clone());
} else if (type in as) {
args[0] = i;
as[type].apply(as, args);
}
}
this.length = as.length();
this.allocate = function () {
as._setBuff(p.buf.slice(offset, offset + as.length()));
}
this.get = function () {
return as;
}
this.set = function (val) {
as.set(val);
}
}
function Struct() {
if (!(this instanceof Struct))
return new Struct;
var priv = {
buf: {},
allocated: false,
len: 0,
fields: {},
closures: []
}, self = this;
function checkAllocated() {
if (priv.allocated)
throw new Error('Cant change struct after allocation');
}
this.word8 = function (key) {
checkAllocated();
priv.closures.push(function (p) {
p.fields[key] = new byteField(p, p.len);
p.len++;
});
return this;
};
// Create handlers for various Bool Field Variants
[1, 2, 3, 4].forEach(function (n) {
self['bool' + (n == 1 ? '' : n)] = function (key) {
checkAllocated();
priv.closures.push(function (p) {
p.fields[key] = new boolField(p, p.len, n);
p.len += n;
});
return this;
}
});
// Create handlers for various Integer Field Variants
[1, 2, 3, 4, 6, 8].forEach(function (n) {
[true, false].forEach(function (le) {
[true, false].forEach(function (signed) {
var name = 'word' + (n * 8) + ( signed ? 'S' : 'U') + ( le ? 'le' : 'be');
self[name] = function (key) {
checkAllocated();
priv.closures.push(function (p) {
p.fields[key] = new intField(p, p.len, n, le, signed);
p.len += n;
});
return this;
};
});
});
});
this.chars = function (key, length, encoding) {
checkAllocated();
priv.closures.push(function (p) {
p.fields[key] = new charField(p, p.len, length, encoding || 'ascii');
p.len += length;
});
return this;
}
this.struct = function (key, struct) {
checkAllocated();
priv.closures.push(function (p) {
p.fields[key] = new structField(p, p.len, struct.clone());
p.len += p.fields[key].length;
});
return this;
}
function construct(constructor, args) {
function F() {
return constructor.apply(this, args);
}
F.prototype = constructor.prototype;
return new F();
}
this.array = function (key, length, type) {
checkAllocated();
var args = [].slice.call(arguments, 1);
args.unshift(null);
args.unshift(null);
priv.closures.push(function (p) {
args[0] = p;
args[1] = p.len;
p.fields[key] = construct(arrayField, args);
p.len += p.fields[key].length;
});
return this;
}
var beenHere = false;
function applyClosures(p) {
if (beenHere)
return;
p.closures.forEach(function (el) {
el(p);
});
beenHere = true;
}
function allocateFields() {
for (var key in priv.fields) {
if ('allocate' in priv.fields[key])
priv.fields[key].allocate();
}
}
this._setBuff = function (buff) {
priv.buf = buff;
applyClosures(priv);
allocateFields();
priv.allocated = true;
}
this.allocate = function () {
applyClosures(priv);
priv.buf = Buffer.alloc(priv.len);
allocateFields();
priv.allocated = true;
return this;
}
this._getPriv = function () {
return priv;
}
this.clone = function () {
var c = new Struct;
var p = c._getPriv();
p.closures = priv.closures;
return c;
}
this.length = function () {
applyClosures(priv);
return priv.len;
}
this.get = function (key) {
if (key in priv.fields) {
return priv.fields[key].get();
} else
throw new Error('Can not find field ' + key);
}
this.set = function (key, val) {
if (arguments.length == 2) {
if (key in priv.fields) {
priv.fields[key].set(val);
} else
throw new Error('Can not find field ' + key);
} else if (Buffer.isBuffer(key)) {
this._setBuff(key);
} else {
for (var k in key) {
this.set(k, key[k]);
}
}
}
this.buffer = function () {
return priv.buf;
}
function getFields() {
var fields = {};
Object.keys(priv.fields).forEach(function (key) {
Object.defineProperty(fields, key, {
get: function () {
var res = self.get(key);
if (res instanceof Struct) return res.fields;
else return res;
},
set: function (newVal) {
self.set(key, newVal);
},
enumerable: true
});
});
return fields;
};
var _fields;
Object.defineProperty(this, 'fields', {
get: function () {
if (_fields) return _fields;
return (_fields = getFields());
},
enumerable: true,
configurable: true
});
}
exports.Struct = Struct;
...@@ -10,7 +10,7 @@ var fs = require('fs'); ...@@ -10,7 +10,7 @@ var fs = require('fs');
var initSqlJs = require('sql.js'); var initSqlJs = require('sql.js');
var loadJSON = require('load-json-file').sync; var loadJSON = require('load-json-file').sync;
var config = loadJSON('./config/deckstats.json'); //{ "deckpath": "../decks", "dbfile": "cards.cdb" } var config = loadJSON('./config/deckstats.json'); //{ "deckpath": "../decks", "dbfile": "cards.cdb" }
var constants = loadJSON('./data/constants.json'); var constants = require('./load-constants').loadConstants();
var ALL_MAIN_CARDS={}; var ALL_MAIN_CARDS={};
var ALL_SIDE_CARDS={}; var ALL_SIDE_CARDS={};
......
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fromPartialCompat = exports.applyYGOProMsgStructCompat = exports.defineYGOProMsgStructCompat = exports.YGOProMsgStructCompat = void 0;
const ygopro_deck_encode_1 = __importDefault(require("ygopro-deck-encode"));
const ygopro_msg_encode_1 = require("ygopro-msg-encode");
exports.YGOProMsgStructCompat = new Map();
const defineYGOProMsgStructCompat = (cls, field, getterAndSetter) => {
if (!exports.YGOProMsgStructCompat.has(cls)) {
exports.YGOProMsgStructCompat.set(cls, []);
}
exports.YGOProMsgStructCompat.get(cls).push((inst) => {
Object.defineProperty(inst, field, {
get() {
return getterAndSetter.get(inst);
},
set(value) {
getterAndSetter.set(inst, value);
}
});
});
};
exports.defineYGOProMsgStructCompat = defineYGOProMsgStructCompat;
const applyYGOProMsgStructCompat = (inst) => {
const compatList = exports.YGOProMsgStructCompat.get(inst.constructor);
if (compatList) {
compatList.forEach(compat => compat(inst));
}
return inst;
};
exports.applyYGOProMsgStructCompat = applyYGOProMsgStructCompat;
const fromPartialCompat = (cls, input) => {
const inst1 = new cls();
(0, exports.applyYGOProMsgStructCompat)(inst1);
Object.assign(inst1, input);
const inst2 = new cls().fromPartial(inst1);
(0, exports.applyYGOProMsgStructCompat)(inst2);
return inst2;
};
exports.fromPartialCompat = fromPartialCompat;
const compatDeckState = new WeakMap();
const getCompatDeckState = (inst) => {
let state = compatDeckState.get(inst);
if (!state) {
state = {};
compatDeckState.set(inst, state);
}
return state;
};
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocChat, "player", {
get(inst) {
return inst.player_type;
},
set(inst, value) {
inst.player_type = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "mainc_s", {
get(inst) {
return inst.player0DeckCount?.main ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.main = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "sidec_s", {
get(inst) {
return inst.player0DeckCount?.side ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.side = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "extrac_s", {
get(inst) {
return inst.player0DeckCount?.extra ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.extra = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "mainc_o", {
get(inst) {
return inst.player1DeckCount?.main ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.main = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "sidec_o", {
get(inst) {
return inst.player1DeckCount?.side ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.side = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProStocDeckCount, "extrac_o", {
get(inst) {
return inst.player1DeckCount?.extra ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new ygopro_msg_encode_1.YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.extra = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProCtosUpdateDeck, "mainc", {
get(inst) {
return inst.deck.main.length + inst.deck.extra.length;
},
set(inst, value) {
const state = getCompatDeckState(inst);
state.mainc = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProCtosUpdateDeck, "sidec", {
get(inst) {
return inst.deck.side.length;
},
set(inst, value) {
const state = getCompatDeckState(inst);
state.sidec = value;
},
});
(0, exports.defineYGOProMsgStructCompat)(ygopro_msg_encode_1.YGOProCtosUpdateDeck, "deckbuf", {
get(inst) {
return [...inst.deck.main, ...inst.deck.extra, ...inst.deck.side];
},
set(inst, value) {
const state = getCompatDeckState(inst);
const deckbuf = Array.isArray(value) ? value.slice() : [];
state.deckbuf = deckbuf;
if (!inst.deck) {
inst.deck = new ygopro_deck_encode_1.default();
}
const hasMainc = state.mainc !== undefined;
const hasSidec = state.sidec !== undefined;
if (!hasMainc && !hasSidec) {
inst.deck.main = deckbuf.slice();
inst.deck.extra = [];
inst.deck.side = [];
return;
}
if (hasMainc && !hasSidec) {
const mainc = Math.max(0, state.mainc | 0);
const mainWithExtra = deckbuf.slice(0, mainc);
const side = deckbuf.slice(mainc);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
return;
}
if (!hasMainc && hasSidec) {
const sidec = Math.max(0, state.sidec | 0);
const split = Math.max(0, deckbuf.length - sidec);
const mainWithExtra = deckbuf.slice(0, split);
const side = deckbuf.slice(split);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
return;
}
const mainc = Math.max(0, state.mainc | 0);
const sidec = Math.max(0, state.sidec | 0);
const mainWithExtra = deckbuf.slice(0, mainc);
const side = deckbuf.slice(mainc, mainc + sidec);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
},
});
import YGOProDeck from "ygopro-deck-encode";
import {
YGOProCtosUpdateDeck,
YGOProCtosBase, YGOProStocBase,
YGOProStocChat,
YGOProStocDeckCount,
YGOProStocDeckCount_DeckInfo,
} from "ygopro-msg-encode";
export const YGOProMsgStructCompat = new Map<new (...args: any[]) => YGOProCtosBase | YGOProStocBase, ((inst: YGOProCtosBase | YGOProStocBase) => void)[]>();
export const defineYGOProMsgStructCompat = <T extends YGOProCtosBase | YGOProStocBase>(cls: new (...args: any[]) => T, field: string, getterAndSetter: {
get: (inst: T) => any,
set: (inst: T, value: any) => void
}) => {
if (!YGOProMsgStructCompat.has(cls)) {
YGOProMsgStructCompat.set(cls, []);
}
YGOProMsgStructCompat.get(cls)!.push((inst: YGOProCtosBase | YGOProStocBase) => {
Object.defineProperty(inst, field, {
get() {
return getterAndSetter.get(inst as T);
},
set(value) {
getterAndSetter.set(inst as T, value);
}
})
})
}
export const applyYGOProMsgStructCompat = (inst: YGOProCtosBase | YGOProStocBase) => {
const compatList = YGOProMsgStructCompat.get(inst.constructor as typeof YGOProCtosBase | typeof YGOProStocBase);
if (compatList) {
compatList.forEach(compat => compat(inst));
}
return inst;
}
export const fromPartialCompat = <T extends YGOProCtosBase | YGOProStocBase>(
cls: new (...args: any[]) => T,
input: Partial<T>
): T => {
const inst1 = new cls();
applyYGOProMsgStructCompat(inst1);
Object.assign(inst1, input);
const inst2 = new cls().fromPartial(inst1 as Partial<T>) as T;
applyYGOProMsgStructCompat(inst2);
return inst2;
};
const compatDeckState = new WeakMap<
YGOProCtosUpdateDeck,
{ mainc?: number; sidec?: number; deckbuf?: number[] }
>();
const getCompatDeckState = (inst: YGOProCtosUpdateDeck) => {
let state = compatDeckState.get(inst);
if (!state) {
state = {};
compatDeckState.set(inst, state);
}
return state;
};
defineYGOProMsgStructCompat(YGOProStocChat, "player", {
get(inst) {
return inst.player_type;
},
set(inst, value) {
inst.player_type = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "mainc_s", {
get(inst) {
return inst.player0DeckCount?.main ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.main = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "sidec_s", {
get(inst) {
return inst.player0DeckCount?.side ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.side = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "extrac_s", {
get(inst) {
return inst.player0DeckCount?.extra ?? 0;
},
set(inst, value) {
if (!inst.player0DeckCount) {
inst.player0DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player0DeckCount.extra = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "mainc_o", {
get(inst) {
return inst.player1DeckCount?.main ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.main = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "sidec_o", {
get(inst) {
return inst.player1DeckCount?.side ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.side = value;
},
});
defineYGOProMsgStructCompat(YGOProStocDeckCount, "extrac_o", {
get(inst) {
return inst.player1DeckCount?.extra ?? 0;
},
set(inst, value) {
if (!inst.player1DeckCount) {
inst.player1DeckCount = new YGOProStocDeckCount_DeckInfo();
}
inst.player1DeckCount.extra = value;
},
});
defineYGOProMsgStructCompat(YGOProCtosUpdateDeck, "mainc", {
get(inst) {
return inst.deck.main.length + inst.deck.extra.length;
},
set(inst, value) {
const state = getCompatDeckState(inst);
state.mainc = value;
},
});
defineYGOProMsgStructCompat(YGOProCtosUpdateDeck, "sidec", {
get(inst) {
return inst.deck.side.length;
},
set(inst, value) {
const state = getCompatDeckState(inst);
state.sidec = value;
},
});
defineYGOProMsgStructCompat(YGOProCtosUpdateDeck, "deckbuf", {
get(inst) {
return [...inst.deck.main, ...inst.deck.extra, ...inst.deck.side];
},
set(inst, value) {
const state = getCompatDeckState(inst);
const deckbuf = Array.isArray(value) ? value.slice() : [];
state.deckbuf = deckbuf;
if (!inst.deck) {
inst.deck = new YGOProDeck();
}
const hasMainc = state.mainc !== undefined;
const hasSidec = state.sidec !== undefined;
if (!hasMainc && !hasSidec) {
inst.deck.main = deckbuf.slice();
inst.deck.extra = [];
inst.deck.side = [];
return;
}
if (hasMainc && !hasSidec) {
const mainc = Math.max(0, state.mainc | 0);
const mainWithExtra = deckbuf.slice(0, mainc);
const side = deckbuf.slice(mainc);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
return;
}
if (!hasMainc && hasSidec) {
const sidec = Math.max(0, state.sidec | 0);
const split = Math.max(0, deckbuf.length - sidec);
const mainWithExtra = deckbuf.slice(0, split);
const side = deckbuf.slice(split);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
return;
}
const mainc = Math.max(0, state.mainc | 0);
const sidec = Math.max(0, state.sidec | 0);
const mainWithExtra = deckbuf.slice(0, mainc);
const side = deckbuf.slice(mainc, mainc + sidec);
inst.deck.main = mainWithExtra.slice();
inst.deck.extra = [];
inst.deck.side = side.slice();
},
});
...@@ -22,7 +22,7 @@ var loadJSON = require('load-json-file').sync; ...@@ -22,7 +22,7 @@ var loadJSON = require('load-json-file').sync;
var auth = require('./ygopro-auth.js'); var auth = require('./ygopro-auth.js');
var constants = loadJSON('./data/constants.json'); var constants = require('./load-constants').loadConstants();
var settings = loadJSON('./config/config.json'); var settings = loadJSON('./config/config.json');
config = settings.modules.pre_util; config = settings.modules.pre_util;
......
...@@ -3739,8 +3739,6 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3739,8 +3739,6 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
else else
CLIENT_send_vip_status(client) CLIENT_send_vip_status(client)
#when '/test'
# ygopro.stoc_send_hint_card_to_room(room, 2333365)
if (msg.length>100) if (msg.length>100)
log.warn "SPAM WORD", client.name, client.ip, msg log.warn "SPAM WORD", client.name, client.ip, msg
client.abuse_count=client.abuse_count+2 if client.abuse_count client.abuse_count=client.abuse_count+2 if client.abuse_count
......
...@@ -4989,8 +4989,6 @@ ...@@ -4989,8 +4989,6 @@
} }
} }
} }
//when '/test'
// ygopro.stoc_send_hint_card_to_room(room, 2333365)
if (msg.length > 100) { if (msg.length > 100) {
log.warn("SPAM WORD", client.name, client.ip, msg); log.warn("SPAM WORD", client.name, client.ip, msg);
if (client.abuse_count) { if (client.abuse_count) {
......
...@@ -21,7 +21,7 @@ var loadJSON = require('load-json-file').sync; ...@@ -21,7 +21,7 @@ var loadJSON = require('load-json-file').sync;
var auth = require('./ygopro-auth.js'); var auth = require('./ygopro-auth.js');
var constants = loadJSON('./data/constants.json'); var constants = require('./load-constants').loadConstants();
var settings = loadJSON('./config/config.json'); var settings = loadJSON('./config/config.json');
config = settings.modules.update_util; config = settings.modules.update_util;
......
...@@ -2,7 +2,6 @@ _ = require 'underscore' ...@@ -2,7 +2,6 @@ _ = require 'underscore'
_.str = require 'underscore.string' _.str = require 'underscore.string'
_.mixin(_.str.exports()) _.mixin(_.str.exports())
Struct = require('./struct.js').Struct
loadJSON = require('load-json-file').sync loadJSON = require('load-json-file').sync
@i18ns = loadJSON './data/i18n.json' @i18ns = loadJSON './data/i18n.json'
...@@ -23,9 +22,6 @@ YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper # 为 ...@@ -23,9 +22,6 @@ YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper # 为
@helper = new YGOProMessagesHelper(9000) @helper = new YGOProMessagesHelper(9000)
@structs = @helper.structs @structs = @helper.structs
@structs_declaration = @helper.structs_declaration
@typedefs = @helper.typedefs
@proto_structs = @helper.proto_structs
@constants = @helper.constants @constants = @helper.constants
translateHandler = (handler) -> translateHandler = (handler) ->
...@@ -91,26 +87,6 @@ translateHandler = (handler) -> ...@@ -91,26 +87,6 @@ translateHandler = (handler) ->
room.recordChatMessage(msg, player) room.recordChatMessage(msg, player)
return return
@stoc_send_hint_card_to_room = (room, card)->
if !room
console.log "err stoc_send_hint_card_to_room"
return
for client in room.players
@stoc_send client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
} if client
for client in room.watchers
@stoc_send client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
} if client
return
@stoc_die = (client, msg)-> @stoc_die = (client, msg)->
await @stoc_send_chat(client, msg, @constants.COLORS.RED) await @stoc_send_chat(client, msg, @constants.COLORS.RED)
await @stoc_send client, 'ERROR_MSG', { await @stoc_send client, 'ERROR_MSG', {
......
// Generated by CoffeeScript 2.7.0 // Generated by CoffeeScript 2.7.0
(function() { (function() {
var Struct, YGOProMessagesHelper, _, loadJSON, translateHandler; var YGOProMessagesHelper, _, loadJSON, translateHandler;
_ = require('underscore'); _ = require('underscore');
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
_.mixin(_.str.exports()); _.mixin(_.str.exports());
Struct = require('./struct.js').Struct;
loadJSON = require('load-json-file').sync; loadJSON = require('load-json-file').sync;
this.i18ns = loadJSON('./data/i18n.json'); this.i18ns = loadJSON('./data/i18n.json');
...@@ -47,12 +45,6 @@ ...@@ -47,12 +45,6 @@
this.structs = this.helper.structs; this.structs = this.helper.structs;
this.structs_declaration = this.helper.structs_declaration;
this.typedefs = this.helper.typedefs;
this.proto_structs = this.helper.proto_structs;
this.constants = this.helper.constants; this.constants = this.helper.constants;
translateHandler = function(handler) { translateHandler = function(handler) {
...@@ -153,38 +145,6 @@ ...@@ -153,38 +145,6 @@
room.recordChatMessage(msg, player); room.recordChatMessage(msg, player);
}; };
this.stoc_send_hint_card_to_room = function(room, card) {
var client, i, j, len, len1, ref, ref1;
if (!room) {
console.log("err stoc_send_hint_card_to_room");
return;
}
ref = room.players;
for (i = 0, len = ref.length; i < len; i++) {
client = ref[i];
if (client) {
this.stoc_send(client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
});
}
}
ref1 = room.watchers;
for (j = 0, len1 = ref1.length; j < len1; j++) {
client = ref1[j];
if (client) {
this.stoc_send(client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
});
}
}
};
this.stoc_die = async function(client, msg) { this.stoc_die = async function(client, msg) {
await this.stoc_send_chat(client, msg, this.constants.COLORS.RED); await this.stoc_send_chat(client, msg, this.constants.COLORS.RED);
if (client) { if (client) {
......
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