Commit 6dff6179 authored by nanahira's avatar nanahira

Merge branch 'mc'

parents 2a7af07f 57adc2f0
Pipeline #6519 failed with stages
in 2 minutes and 53 seconds
...@@ -180,12 +180,13 @@ class YGOProMessagesHelper { ...@@ -180,12 +180,13 @@ class YGOProMessagesHelper {
} }
handlerCollection.get(translatedProto).push(handlerObj); handlerCollection.get(translatedProto).push(handlerObj);
} }
async handleBuffer(messageBuffer, direction, protoFilter, params, disconnectIfInvalid = false) { async handleBuffer(messageBuffer, direction, protoFilter, params, preconnect = false) {
let feedback = null; let feedback = null;
let messageLength = 0; let messageLength = 0;
let bufferProto = 0; let bufferProto = 0;
let datas = []; let datas = [];
for (let l = 0; l < this.singleHandleLimit; ++l) { const limit = preconnect ? 2 : this.singleHandleLimit;
for (let l = 0; l < limit; ++l) {
if (messageLength === 0) { if (messageLength === 0) {
if (messageBuffer.length >= 2) { if (messageBuffer.length >= 2) {
messageLength = messageBuffer.readUInt16LE(0); messageLength = messageBuffer.readUInt16LE(0);
...@@ -216,7 +217,7 @@ class YGOProMessagesHelper { ...@@ -216,7 +217,7 @@ class YGOProMessagesHelper {
if (messageBuffer.length >= 2 + messageLength) { if (messageBuffer.length >= 2 + messageLength) {
const proto = this.constants[direction][bufferProto]; const proto = this.constants[direction][bufferProto];
let cancel = proto && protoFilter && !protoFilter.includes(proto); let cancel = proto && protoFilter && !protoFilter.includes(proto);
if (cancel && disconnectIfInvalid) { if (cancel && preconnect) {
feedback = { feedback = {
type: "INVALID_PACKET", type: "INVALID_PACKET",
message: `${direction} proto not allowed` message: `${direction} proto not allowed`
...@@ -240,6 +241,12 @@ class YGOProMessagesHelper { ...@@ -240,6 +241,12 @@ class YGOProMessagesHelper {
for (let handler of handlerCollection.get(bufferProto)) { for (let handler of handlerCollection.get(bufferProto)) {
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (cancel === '_cancel') {
return {
datas: [],
feedback
};
}
break; break;
} }
} }
...@@ -262,10 +269,10 @@ class YGOProMessagesHelper { ...@@ -262,10 +269,10 @@ class YGOProMessagesHelper {
break; break;
} }
} }
if (l === this.singleHandleLimit - 1) { if (l === limit - 1) {
feedback = { feedback = {
type: "OVERSIZE", type: "OVERSIZE",
message: `Oversized ${direction}` message: `Oversized ${direction} ${limit}`
}; };
} }
} }
......
...@@ -8,13 +8,13 @@ import net from "net"; ...@@ -8,13 +8,13 @@ import net from "net";
class Handler { class Handler {
private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>; private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>;
synchronous: boolean; synchronous: boolean;
constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean) { constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean) {
this.handler = handler; this.handler = handler;
this.synchronous = synchronous || false; this.synchronous = synchronous || false;
} }
async handle(buffer: Buffer, info: any, datas: Buffer[], params: any) { async handle(buffer: Buffer, info: any, datas: Buffer[], params: any): Promise<boolean | string> {
if (this.synchronous) { if (this.synchronous) {
return !!(await this.handler(buffer, info, datas, params)); return !!(await this.handler(buffer, info, datas, params));
} else { } else {
...@@ -208,7 +208,7 @@ export class YGOProMessagesHelper { ...@@ -208,7 +208,7 @@ export class YGOProMessagesHelper {
}); });
} }
addHandler(protostr: string, handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean, priority: number) { addHandler(protostr: string, handler: (buffer: Buffer, info: any, 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;
} }
...@@ -226,12 +226,13 @@ export class YGOProMessagesHelper { ...@@ -226,12 +226,13 @@ export class YGOProMessagesHelper {
handlerCollection.get(translatedProto).push(handlerObj); handlerCollection.get(translatedProto).push(handlerObj);
} }
async handleBuffer(messageBuffer: Buffer, direction: string, protoFilter?: string[], params?: any, disconnectIfInvalid = false): Promise<HandleResult> { async handleBuffer(messageBuffer: Buffer, direction: string, 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;
let datas: Buffer[] = []; let datas: Buffer[] = [];
for (let l = 0; l < this.singleHandleLimit; ++l) { const limit = preconnect ? 2 : this.singleHandleLimit;
for (let l = 0; l < limit; ++l) {
if (messageLength === 0) { if (messageLength === 0) {
if (messageBuffer.length >= 2) { if (messageBuffer.length >= 2) {
messageLength = messageBuffer.readUInt16LE(0); messageLength = messageBuffer.readUInt16LE(0);
...@@ -257,8 +258,8 @@ export class YGOProMessagesHelper { ...@@ -257,8 +258,8 @@ export class YGOProMessagesHelper {
} else { } else {
if (messageBuffer.length >= 2 + messageLength) { if (messageBuffer.length >= 2 + messageLength) {
const proto = this.constants[direction][bufferProto]; const proto = this.constants[direction][bufferProto];
let cancel = proto && protoFilter && !protoFilter.includes(proto); let cancel: string | boolean = proto && protoFilter && !protoFilter.includes(proto);
if (cancel && disconnectIfInvalid) { if (cancel && preconnect) {
feedback = { feedback = {
type: "INVALID_PACKET", type: "INVALID_PACKET",
message: `${direction} proto not allowed` message: `${direction} proto not allowed`
...@@ -282,6 +283,12 @@ export class YGOProMessagesHelper { ...@@ -282,6 +283,12 @@ export class YGOProMessagesHelper {
for (let handler of handlerCollection.get(bufferProto)) { for (let handler of handlerCollection.get(bufferProto)) {
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (cancel === '_cancel') {
return {
datas: [],
feedback
}
}
break; break;
} }
} }
...@@ -303,10 +310,10 @@ export class YGOProMessagesHelper { ...@@ -303,10 +310,10 @@ export class YGOProMessagesHelper {
break; break;
} }
} }
if (l === this.singleHandleLimit - 1) { if (l === limit - 1) {
feedback = { feedback = {
type: "OVERSIZE", type: "OVERSIZE",
message: `Oversized ${direction}` message: `Oversized ${direction} ${limit}`
}; };
} }
} }
......
...@@ -1991,6 +1991,11 @@ netRequestHandler = (client) -> ...@@ -1991,6 +1991,11 @@ netRequestHandler = (client) ->
ROOM_connected_ip[client.ip] = connect_count ROOM_connected_ip[client.ip] = connect_count
#log.info "connect", client.ip, ROOM_connected_ip[client.ip] #log.info "connect", client.ip, ROOM_connected_ip[client.ip]
if ROOM_bad_ip[client.ip] > 5 or ROOM_connected_ip[client.ip] > 10
log.info 'BAD IP', client.ip
client.destroy()
return
# server stand for the connection to ygopro server process # server stand for the connection to ygopro server process
server = new net.Socket() server = new net.Socket()
client.server = server client.server = server
...@@ -2072,11 +2077,6 @@ netRequestHandler = (client) -> ...@@ -2072,11 +2077,6 @@ netRequestHandler = (client) ->
SERVER_clear_disconnect(server) SERVER_clear_disconnect(server)
return return
if ROOM_bad_ip[client.ip] > 5 or ROOM_connected_ip[client.ip] > 10
log.info 'BAD IP', client.ip
CLIENT_kick(client)
return
client.playLines = (lines) -> client.playLines = (lines) ->
for line in _.lines lines for line in _.lines lines
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK) ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
...@@ -2126,16 +2126,16 @@ netRequestHandler = (client) -> ...@@ -2126,16 +2126,16 @@ netRequestHandler = (client) ->
room.watcher.write(buffer) for buffer in handle_data.datas room.watcher.write(buffer) for buffer in handle_data.datas
else else
ctos_filter = null ctos_filter = null
disconnectIfInvalid = false preconnect = false
if settings.modules.reconnect.enabled and client.pre_reconnecting_to_room if settings.modules.reconnect.enabled and client.pre_reconnecting_to_room
ctos_filter = ["UPDATE_DECK"] ctos_filter = ["UPDATE_DECK"]
if !client.name if client.name == null
ctos_filter = ["JOIN_GAME", "PLAYER_INFO"] ctos_filter = ["JOIN_GAME", "PLAYER_INFO"]
disconnectIfInvalid = true preconnect = true
handle_data = await ygopro.helper.handleBuffer(ctos_buffer, "CTOS", ctos_filter, { handle_data = await ygopro.helper.handleBuffer(ctos_buffer, "CTOS", ctos_filter, {
client: client, client: client,
server: client.server server: client.server
}, disconnectIfInvalid) }, preconnect)
if handle_data.feedback if handle_data.feedback
log.warn(handle_data.feedback.message, client.name, client.ip) log.warn(handle_data.feedback.message, client.name, client.ip)
if handle_data.feedback.type == "OVERSIZE" or handle_data.feedback.type == "INVALID_PACKET" or ROOM_bad_ip[client.ip] > 5 if handle_data.feedback.type == "OVERSIZE" or handle_data.feedback.type == "INVALID_PACKET" or ROOM_bad_ip[client.ip] > 5
...@@ -2146,7 +2146,7 @@ netRequestHandler = (client) -> ...@@ -2146,7 +2146,7 @@ netRequestHandler = (client) ->
ROOM_bad_ip[client.ip] = 1 ROOM_bad_ip[client.ip] = 1
CLIENT_kick(client) CLIENT_kick(client)
return return
if !client.server if client.closed || !client.server
return return
if client.established if client.established
client.server.write buffer for buffer in handle_data.datas client.server.write buffer for buffer in handle_data.datas
...@@ -2182,6 +2182,11 @@ deck_name_match = global.deck_name_match = (deck_name, player_name) -> ...@@ -2182,6 +2182,11 @@ deck_name_match = global.deck_name_match = (deck_name, player_name) ->
# return true to cancel a synchronous message # return true to cancel a synchronous message
ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server, datas)-> ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server, datas)->
# second PLAYER_INFO = attack
if client.name
log.info 'DUP PLAYER_INFO', client.ip
CLIENT_kick client
return '_cancel'
# checkmate use username$password, but here don't # checkmate use username$password, but here don't
# so remove the password # so remove the password
name_full =info.name.replace(/\\/g, "").split("$") name_full =info.name.replace(/\\/g, "").split("$")
......
...@@ -2672,7 +2672,11 @@ ...@@ -2672,7 +2672,11 @@
} }
ROOM_connected_ip[client.ip] = connect_count; ROOM_connected_ip[client.ip] = connect_count;
//log.info "connect", client.ip, ROOM_connected_ip[client.ip] //log.info "connect", client.ip, ROOM_connected_ip[client.ip]
if (ROOM_bad_ip[client.ip] > 5 || ROOM_connected_ip[client.ip] > 10) {
log.info('BAD IP', client.ip);
client.destroy();
return;
}
// server stand for the connection to ygopro server process // server stand for the connection to ygopro server process
server = new net.Socket(); server = new net.Socket();
client.server = server; client.server = server;
...@@ -2772,6 +2776,7 @@ ...@@ -2772,6 +2776,7 @@
SERVER_clear_disconnect(server); SERVER_clear_disconnect(server);
} }
}); });
<<<<<<< HEAD
if (ROOM_bad_ip[client.ip] > 5 || ROOM_connected_ip[client.ip] > 10) { if (ROOM_bad_ip[client.ip] > 5 || ROOM_connected_ip[client.ip] > 10) {
log.info('BAD IP', client.ip); log.info('BAD IP', client.ip);
CLIENT_kick(client); CLIENT_kick(client);
...@@ -2787,6 +2792,8 @@ ...@@ -2787,6 +2792,8 @@
} }
return results; return results;
}; };
=======
>>>>>>> mc
if (settings.modules.cloud_replay.enabled) { if (settings.modules.cloud_replay.enabled) {
client.open_cloud_replay = async function(replay) { client.open_cloud_replay = async function(replay) {
var buffer, e, replay_buffer; var buffer, e, replay_buffer;
...@@ -2814,7 +2821,7 @@ ...@@ -2814,7 +2821,7 @@
// 客户端到服务端(ctos)协议分析 // 客户端到服务端(ctos)协议分析
client.pre_establish_buffers = new Array(); client.pre_establish_buffers = new Array();
client.on('data', async function(ctos_buffer) { client.on('data', async function(ctos_buffer) {
var bad_ip_count, buffer, ctos_filter, disconnectIfInvalid, handle_data, j, l, len, len1, len2, m, ref, ref1, ref2, room; var bad_ip_count, buffer, ctos_filter, handle_data, j, l, len, len1, len2, m, preconnect, ref, ref1, ref2, room;
if (client.is_post_watcher) { if (client.is_post_watcher) {
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (room) { if (room) {
...@@ -2843,18 +2850,18 @@ ...@@ -2843,18 +2850,18 @@
} }
} else { } else {
ctos_filter = null; ctos_filter = null;
disconnectIfInvalid = false; preconnect = false;
if (settings.modules.reconnect.enabled && client.pre_reconnecting_to_room) { if (settings.modules.reconnect.enabled && client.pre_reconnecting_to_room) {
ctos_filter = ["UPDATE_DECK"]; ctos_filter = ["UPDATE_DECK"];
} }
if (!client.name) { if (client.name === null) {
ctos_filter = ["JOIN_GAME", "PLAYER_INFO"]; ctos_filter = ["JOIN_GAME", "PLAYER_INFO"];
disconnectIfInvalid = true; preconnect = true;
} }
handle_data = (await ygopro.helper.handleBuffer(ctos_buffer, "CTOS", ctos_filter, { handle_data = (await ygopro.helper.handleBuffer(ctos_buffer, "CTOS", ctos_filter, {
client: client, client: client,
server: client.server server: client.server
}, disconnectIfInvalid)); }, preconnect));
if (handle_data.feedback) { if (handle_data.feedback) {
log.warn(handle_data.feedback.message, client.name, client.ip); log.warn(handle_data.feedback.message, client.name, client.ip);
if (handle_data.feedback.type === "OVERSIZE" || handle_data.feedback.type === "INVALID_PACKET" || ROOM_bad_ip[client.ip] > 5) { if (handle_data.feedback.type === "OVERSIZE" || handle_data.feedback.type === "INVALID_PACKET" || ROOM_bad_ip[client.ip] > 5) {
...@@ -2868,7 +2875,7 @@ ...@@ -2868,7 +2875,7 @@
return; return;
} }
} }
if (!client.server) { if (client.closed || !client.server) {
return; return;
} }
if (client.established) { if (client.established) {
...@@ -2923,6 +2930,12 @@ ...@@ -2923,6 +2930,12 @@
// return true to cancel a synchronous message // return true to cancel a synchronous message
ygopro.ctos_follow('PLAYER_INFO', true, async function(buffer, info, client, server, datas) { ygopro.ctos_follow('PLAYER_INFO', true, async function(buffer, info, client, server, datas) {
var geo, lang, name, name_full, struct, vpass; var geo, lang, name, name_full, struct, vpass;
// second PLAYER_INFO = attack
if (client.name) {
log.info('DUP PLAYER_INFO', client.ip);
CLIENT_kick(client);
return '_cancel';
}
// checkmate use username$password, but here don't // checkmate use username$password, but here don't
// so remove the password // so remove the password
name_full = info.name.replace(/\\/g, "").split("$"); name_full = info.name.replace(/\\/g, "").split("$");
......
...@@ -113,4 +113,4 @@ translateHandler = (handler) -> ...@@ -113,4 +113,4 @@ translateHandler = (handler) ->
if client if client
client.system_kicked = true client.system_kicked = true
client.destroy() client.destroy()
return return '_cancel'
...@@ -185,6 +185,7 @@ ...@@ -185,6 +185,7 @@
client.system_kicked = true; client.system_kicked = true;
client.destroy(); client.destroy();
} }
return '_cancel';
}; };
}).call(this); }).call(this);
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