Commit e6e90691 authored by nanahira's avatar nanahira

Merge branch 'cloudrep-chat'

parents 829ee179 a180954a
Pipeline #17871 passed with stages
in 10 minutes and 32 seconds
// Generated by CoffeeScript 2.5.1
// Generated by CoffeeScript 2.6.1
(function() {
var Replay, ReplayReader, fs, lzma, replayHeader;
......
......@@ -156,16 +156,23 @@ class YGOProMessagesHelper {
}
return sendBuffer;
}
sendMessage(socket, protostr, info) {
const sendBuffer = this.prepareMessage(protostr, info);
socket.write(sendBuffer);
}
sendMessageAsync(socket, protostr, info) {
const sendBuffer = this.prepareMessage(protostr, info);
send(socket, buffer) {
return new Promise(done => {
socket.write(sendBuffer, done);
if (socket['isWs']) {
const ws = socket;
// @ts-ignore
ws.send(buffer, {}, done);
}
else {
const sock = socket;
sock.write(buffer, done);
}
});
}
sendMessage(socket, protostr, info) {
const sendBuffer = this.prepareMessage(protostr, info);
return this.send(socket, sendBuffer);
}
addHandler(protostr, handler, synchronous, priority) {
if (priority < 0 || priority > 4) {
throw "Invalid priority: " + priority;
......
......@@ -196,16 +196,22 @@ export class YGOProMessagesHelper {
return sendBuffer;
}
sendMessage(socket: net.Socket, protostr: string, info?: string | Buffer | any) {
const sendBuffer = this.prepareMessage(protostr, info);
socket.write(sendBuffer);
send(socket: net.Socket | WebSocket, buffer: Buffer) {
return new Promise<Error | undefined>(done => {
if (socket['isWs']) {
const ws = socket as WebSocket;
// @ts-ignore
ws.send(buffer, {}, done);
} else {
const sock = socket as net.Socket;
sock.write(buffer, done);
}
})
}
sendMessageAsync(socket: net.Socket, protostr: string, info?: string | Buffer | any): Promise<Error> {
sendMessage(socket: net.Socket | WebSocket, protostr: string, info?: string | Buffer | any): Promise<Error> {
const sendBuffer = this.prepareMessage(protostr, info);
return new Promise(done => {
socket.write(sendBuffer, done);
});
return this.send(socket, sendBuffer);
}
addHandler(protostr: string, handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean, priority: number) {
......
......@@ -196,6 +196,15 @@
"banCount": 0,
"ttl": 600
},
"neos": {
"enabled": false,
"port": 7977,
"trusted_proxies": [
"127.0.0.1/8",
"::1/128"
],
"ip_header": "x-forwarded-for"
},
"test_mode": {
"watch_public_hand": false,
"no_connect_count_limit": false,
......
......@@ -15,6 +15,7 @@
"deepmerge": "^4.2.2",
"formidable": "^1.2.6",
"geoip-country-lite": "^1.0.0",
"ip6addr": "^0.2.5",
"jszip": "^3.5.0",
"load-json-file": "^6.2.0",
"lzma": "^2.3.2",
......@@ -35,6 +36,7 @@
},
"devDependencies": {
"@types/bunyan": "^1.8.8",
"@types/ip6addr": "^0.2.3",
"@types/node": "^17.0.19",
"@types/underscore": "^1.11.4",
"@types/ws": "^8.5.3",
......@@ -79,6 +81,12 @@
"@types/node": "*"
}
},
"node_modules/@types/ip6addr": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@types/ip6addr/-/ip6addr-0.2.3.tgz",
"integrity": "sha512-oe7hzc+P9DU6+gql8+bLKuUf4WL4aakyCSXZMZq2cjhhGK75qYwH1zJ4s94XOlnb4cAhrGKwnbrmMBaqDK8+Ww==",
"dev": true
},
"node_modules/@types/node": {
"version": "17.0.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz",
......@@ -1187,6 +1195,34 @@
"node": "*"
}
},
"node_modules/ip6addr": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.5.tgz",
"integrity": "sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==",
"dependencies": {
"assert-plus": "^1.0.0",
"jsprim": "^2.0.2"
}
},
"node_modules/ip6addr/node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"node_modules/ip6addr/node_modules/jsprim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
"integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
"engines": [
"node >=0.6.0"
],
"dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
......@@ -3112,6 +3148,12 @@
"@types/node": "*"
}
},
"@types/ip6addr": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@types/ip6addr/-/ip6addr-0.2.3.tgz",
"integrity": "sha512-oe7hzc+P9DU6+gql8+bLKuUf4WL4aakyCSXZMZq2cjhhGK75qYwH1zJ4s94XOlnb4cAhrGKwnbrmMBaqDK8+Ww==",
"dev": true
},
"@types/node": {
"version": "17.0.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz",
......@@ -3954,6 +3996,33 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"ip6addr": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.5.tgz",
"integrity": "sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^2.0.2"
},
"dependencies": {
"json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"jsprim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
"integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
}
}
},
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
......
......@@ -17,6 +17,7 @@
"deepmerge": "^4.2.2",
"formidable": "^1.2.6",
"geoip-country-lite": "^1.0.0",
"ip6addr": "^0.2.5",
"jszip": "^3.5.0",
"load-json-file": "^6.2.0",
"lzma": "^2.3.2",
......@@ -46,6 +47,7 @@
},
"devDependencies": {
"@types/bunyan": "^1.8.8",
"@types/ip6addr": "^0.2.3",
"@types/node": "^17.0.19",
"@types/underscore": "^1.11.4",
"@types/ws": "^8.5.3",
......
// Generated by CoffeeScript 2.5.1
// Generated by CoffeeScript 2.6.1
(function() {
/*
Main script of new dashboard account system.
......
......@@ -590,17 +590,31 @@ init = () ->
log.info "NOTE: server not open due to config, ", settings.modules.stop
http_server = http.createServer(httpRequestListener)
http_server.listen settings.modules.http.port
main_http_server = http_server
if settings.modules.http.ssl.enabled
https = require 'https'
options =
httpsOptions =
cert: await fs.promises.readFile(settings.modules.http.ssl.cert)
key: await fs.promises.readFile(settings.modules.http.ssl.key)
https_server = https.createServer(options, httpRequestListener)
if settings.modules.http.websocket_roomlist and roomlist
roomlist.init https_server, ROOM_all
https_server = https.createServer(httpsOptions, httpRequestListener)
https_server.listen settings.modules.http.ssl.port
main_http_server = https_server
if settings.modules.http.websocket_roomlist and roomlist
roomlist.init main_http_server, ROOM_all
http_server.listen settings.modules.http.port
if settings.modules.neos.enabled
ws = require 'ws'
neosHttpServer = null
if settings.modules.http.ssl.enabled
neosHttpServer = https.createServer(httpsOptions)
else
neosHttpServer = http.createServer()
neosWsServer = new ws.WebSocketServer({server: neosHttpServer})
neosWsServer.on 'connection', neosRequestListener
neosHttpServer.listen settings.modules.neos.port
mkdirList = [
"./plugins",
......@@ -838,7 +852,7 @@ CLIENT_kick = global.CLIENT_kick = (client) ->
if !client
return false
client.system_kicked = true
if settings.modules.reconnect.enabled and client.closed
if settings.modules.reconnect.enabled and client.isClosed
if client.server and !client.had_new_reconnection
room = ROOM_all[client.rid]
if room
......@@ -977,7 +991,7 @@ CLIENT_is_able_to_reconnect = global.CLIENT_is_able_to_reconnect = (client, deck
CLIENT_get_kick_reconnect_target = global.CLIENT_get_kick_reconnect_target = (client, deckbuf) ->
for room in ROOM_all when room and room.duel_stage != ygopro.constants.DUEL_STAGE.BEGIN and !room.windbot
for player in room.get_playing_player() when !player.closed and player.name == client.name and (settings.modules.challonge.enabled or player.pass == client.pass) and (settings.modules.mycard.enabled or settings.modules.tournament_mode.enabled or player.ip == client.ip or (client.vpass and client.vpass == player.vpass)) and (!deckbuf or deckbuf.compare(player.start_deckbuf) == 0)
for player in room.get_playing_player() when !player.isClosed and player.name == client.name and (settings.modules.challonge.enabled or player.pass == client.pass) and (settings.modules.mycard.enabled or settings.modules.tournament_mode.enabled or player.ip == client.ip or (client.vpass and client.vpass == player.vpass)) and (!deckbuf or deckbuf.compare(player.start_deckbuf) == 0)
return player
return null
......@@ -1110,7 +1124,7 @@ CLIENT_heartbeat_unregister = global.CLIENT_heartbeat_unregister = (client) ->
return true
CLIENT_heartbeat_register = global.CLIENT_heartbeat_register = (client, send) ->
if !settings.modules.heartbeat_detection.enabled or client.closed or client.is_post_watcher or client.pre_reconnecting or client.reconnecting or client.waiting_for_last or client.pos > 3 or client.heartbeat_protected
if !settings.modules.heartbeat_detection.enabled or client.isClosed or client.is_post_watcher or client.pre_reconnecting or client.reconnecting or client.waiting_for_last or client.pos > 3 or client.heartbeat_protected
return false
if client.heartbeat_timeout
CLIENT_heartbeat_unregister(client)
......@@ -1126,7 +1140,7 @@ CLIENT_heartbeat_register = global.CLIENT_heartbeat_register = (client, send) ->
})
client.heartbeat_timeout = setTimeout(() ->
CLIENT_heartbeat_unregister(client)
client.destroy() unless client.closed or client.heartbeat_responsed
client.destroy() unless client.isClosed or client.heartbeat_responsed
return
, settings.modules.heartbeat_detection.wait_time)
#log.info(1, client.name)
......@@ -1136,7 +1150,7 @@ CLIENT_is_banned_by_mc = global.CLIENT_is_banned_by_mc = (client) ->
return client.ban_mc and client.ban_mc.banned and moment_now.isBefore(client.ban_mc.until)
CLIENT_send_replays = global.CLIENT_send_replays = (client, room) ->
return false unless settings.modules.replay_delay and not (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) and room.replays.length and room.hostinfo.mode == 1 and !client.replays_sent and !client.closed
return false unless settings.modules.replay_delay and not (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) and room.replays.length and room.hostinfo.mode == 1 and !client.replays_sent and !client.isClosed
client.replays_sent = true
i = 0
for buffer in room.replays
......@@ -1147,11 +1161,11 @@ CLIENT_send_replays = global.CLIENT_send_replays = (client, room) ->
return true
SOCKET_flush_data = global.SOCKET_flush_data = (sk, datas) ->
if !sk or sk.closed
if !sk or sk.isClosed
return false
for buffer in datas
sk.write(buffer)
datas.splice(0, datas.length)
while datas.length
buffer = datas.shift()
await ygopro.helper.send(sk, buffer)
return true
getSeedTimet = global.getSeedTimet = (count) ->
......@@ -1304,12 +1318,14 @@ class Room
@recover_buffers = [[], [], [], []]
@welcome = "${recover_hint}"
@hostinfo.replay_mode = 0 # 0x1: Save the replays in file. 0x2: Block the replays to observers.
@hostinfo.replay_mode = 0
if settings.modules.tournament_mode.enabled
if settings.modules.tournament_mode.enabled # 0x1: Save the replays in file
@hostinfo.replay_mode |= 0x1
if (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) or (@hostinfo.mode == 1 and settings.modules.replay_delay)
if (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) or (@hostinfo.mode == 1 and settings.modules.replay_delay) # 0x2: Block the replays to observers
@hostinfo.replay_mode |= 0x2
if settings.modules.tournament_mode.enabled or room.arena # 0x4: Save chat in cloud replay
@hostinfo.replay_mode |= 0x4
if !@recovered
@spawn()
......@@ -1347,7 +1363,7 @@ class Room
@port = parseInt data
_.each @players, (player)=>
player.server.connect @port, '127.0.0.1', ->
player.server.write buffer for buffer in player.pre_establish_buffers
await ygopro.helper.send(player.server, buffer) for buffer in player.pre_establish_buffers
player.established = true
player.pre_establish_buffers = []
return
......@@ -1496,7 +1512,7 @@ class Room
if !settings.modules.reconnect.enabled
return 0
found = 0
for player in @get_playing_player() when player.closed
for player in @get_playing_player() when player.isClosed
found++
return found
......@@ -1577,7 +1593,7 @@ class Room
if @established
roomlist.update(this) if !@windbot and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.http.websocket_roomlist
client.server.connect @port, '127.0.0.1', ->
client.server.write buffer for buffer in client.pre_establish_buffers
await ygopro.helper.send(client.server, buffer) for buffer in client.pre_establish_buffers
client.established = true
client.pre_establish_buffers = []
return
......@@ -1724,7 +1740,7 @@ class Room
@watchers.push client
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE)
for buffer in @watcher_buffers
client.write buffer
await ygopro.helper.send(client, buffer)
return true
else
ygopro.stoc_die(client, "${watch_denied}")
......@@ -1756,9 +1772,26 @@ class Room
else
@last_active_time = moment_now_string
addRecorderBuffer: (buffer) ->
if settings.modules.cloud_replay.enabled
@recorder_buffers.push buffer
return
recordChatMessage: (msg, player) ->
unless settings.modules.cloud_replay.enabled and (@arena or settings.modules.tournament_mode.enabled)
return
for line in ygopro.split_chat_lines(msg, player, settings.modules.i18n.default)
chat_buf = ygopro.helper.prepareMessage("STOC_CHAT", {
player: player
msg: line
})
@addRecorderBuffer(chat_buf)
return
# 网络连接
netRequestHandler = (client) ->
client.ip = client.remoteAddress
if !client.isWs
client.ip = client.remoteAddress
client.is_local = client.ip and (client.ip.includes('127.0.0.1') or client.ip.includes(real_windbot_server_ip))
connect_count = ROOM_connected_ip[client.ip] or 0
......@@ -1780,56 +1813,48 @@ netRequestHandler = (client) ->
client.setTimeout(2000) #连接前超时2秒
# 释放处理
client.on 'close', (had_error) ->
#log.info "client closed", client.name, had_error
room=ROOM_all[client.rid]
connect_count = ROOM_connected_ip[client.ip]
if connect_count > 0
connect_count--
ROOM_connected_ip[client.ip] = connect_count
closeHandler = (error) ->
#log.info "client closed", client.name, error, client.isClosed
#log.info "disconnect", client.ip, ROOM_connected_ip[client.ip]
unless client.closed
client.closed = true
if settings.modules.heartbeat_detection.enabled
CLIENT_heartbeat_unregister(client)
if room
if !CLIENT_reconnect_register(client, client.rid)
room.disconnect(client)
else if !client.had_new_reconnection
SERVER_kick(client.server)
return
client.on 'error', (error)->
#log.info "client error", client.name, error
if client.isClosed
return
room=ROOM_all[client.rid]
connect_count = ROOM_connected_ip[client.ip]
if connect_count > 0
connect_count--
ROOM_connected_ip[client.ip] = connect_count
#log.info "err disconnect", client.ip, ROOM_connected_ip[client.ip]
unless client.closed
client.closed = true
if room
if !CLIENT_reconnect_register(client, client.rid, error)
room.disconnect(client, error)
else if !client.had_new_reconnection
SERVER_kick(client.server)
client.isClosed = true
if settings.modules.heartbeat_detection.enabled
CLIENT_heartbeat_unregister(client)
if room
if !CLIENT_reconnect_register(client, client.rid, error)
room.disconnect(client, error)
else if !client.had_new_reconnection
SERVER_kick(client.server)
return
if client.isWs
client.on 'close', (code, reason) ->
closeHandler()
else
client.on 'close', (had_error) ->
closeHandler(had_error ? 'unknown' : undefined)
client.on 'timeout', ()->
unless settings.modules.reconnect.enabled and (disconnect_list[CLIENT_get_authorize_key(client)] or client.had_new_reconnection)
client.destroy()
return
client.on 'error', closeHandler
client.on 'timeout', ()->
unless settings.modules.reconnect.enabled and (disconnect_list[CLIENT_get_authorize_key(client)] or client.had_new_reconnection)
client.destroy()
return
server.on 'close', (had_error) ->
server.closed = true unless server.closed
server.isClosed = true unless server.isClosed
if !server.client
return
#log.info "server closed", server.client.name, had_error
#log.info "server isClosed", server.client.name, had_error
room=ROOM_all[server.client.rid]
#log.info "server close", server.client.ip, ROOM_connected_ip[server.client.ip]
room.disconnector = 'server' if room and !server.system_kicked and !server.had_new_reconnection
unless server.client.closed
unless server.client.isClosed
ygopro.stoc_send_chat(server.client, "${server_closed}", ygopro.constants.COLORS.RED)
#if room and settings.modules.replay_delay
# room.send_replays()
......@@ -1838,14 +1863,14 @@ netRequestHandler = (client) ->
return
server.on 'error', (error)->
server.closed = error
server.isClosed = error
if !server.client
return
#log.info "server error", client.name, error
room=ROOM_all[server.client.rid]
#log.info "server err close", client.ip, ROOM_connected_ip[client.ip]
room.disconnector = 'server' if room and !server.system_kicked and !server.had_new_reconnection
unless server.client.closed
unless server.client.isClosed
ygopro.stoc_send_chat(server.client, "${server_error}: #{error}", ygopro.constants.COLORS.RED)
#if room and settings.modules.replay_delay
# room.send_replays()
......@@ -1867,9 +1892,8 @@ netRequestHandler = (client) ->
ygopro.stoc_die(client, "${cloud_replay_error}")
return
ygopro.stoc_send_chat(client, "${cloud_replay_playing} #{replay.getDisplayString()}", ygopro.constants.COLORS.BABYBLUE)
client.write replay_buffer, ()->
CLIENT_kick(client)
return
await ygopro.helper.send(client, replay_buffer)
CLIENT_kick(client)
return
# 需要重构
......@@ -1877,7 +1901,7 @@ netRequestHandler = (client) ->
client.pre_establish_buffers = new Array()
client.on 'data', (ctos_buffer) ->
dataHandler = (ctos_buffer) ->
if client.is_post_watcher
room=ROOM_all[client.rid]
if room
......@@ -1895,7 +1919,7 @@ netRequestHandler = (client) ->
ROOM_bad_ip[client.ip] = 1
CLIENT_kick(client)
return
room.watcher.write(buffer) for buffer in handle_data.datas
await ygopro.helper.send(room.watcher, buffer) for buffer in handle_data.datas
else
ctos_filter = null
preconnect = false
......@@ -1918,15 +1942,20 @@ netRequestHandler = (client) ->
ROOM_bad_ip[client.ip] = 1
CLIENT_kick(client)
return
if client.closed || !client.server
if client.isClosed || !client.server
return
if client.established
client.server.write buffer for buffer in handle_data.datas
await ygopro.helper.send(client.server, buffer) for buffer in handle_data.datas
else
client.pre_establish_buffers.push buffer for buffer in handle_data.datas
client.pre_establish_buffers = client.pre_establish_buffers.concat(handle_data.datas)
return
if client.isWs
client.on 'message', dataHandler
else
client.on 'data', dataHandler
# 服务端到客户端(stoc)
server.on 'data', (stoc_buffer)->
handle_data = await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, {
......@@ -1938,8 +1967,8 @@ netRequestHandler = (client) ->
if handle_data.feedback.type == "OVERSIZE"
server.destroy()
return
if server.client and !server.client.closed
server.client.write buffer for buffer in handle_data.datas
if server.client and !server.client.isClosed
await ygopro.helper.send(server.client, buffer) for buffer in handle_data.datas
return
return
......@@ -2104,7 +2133,7 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
(checksum & 0xFF) == 0
create_room_with_action = (buffer, decrypted_buffer)->
if client.closed
if client.isClosed
return
firstByte = buffer.readUInt8(1)
action = firstByte >> 4
......@@ -2183,7 +2212,7 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
match_permit = matchPermitRes.data
catch e
log.warn "match permit fail #{e.toString()}"
if client.closed
if client.isClosed
return
if match_permit and match_permit.permit == false
ygopro.stoc_die(client, '${invalid_password_unauthorized}')
......@@ -2240,10 +2269,10 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
#console.log userData
catch e
log.warn("READ USER FAIL", client.name, e.toString())
if !client.closed
if !client.isClosed
ygopro.stoc_die(client, '${load_user_info_fail}')
return
if client.closed
if client.isClosed
return
users_cache[client.name] = userData.user.id
secret = userData.user.id % 65535 + 1
......@@ -2274,18 +2303,18 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
recover_match = info.pass.match(/^(RC|RECOVER)(\d*)T(\d*)$/)
tournament_data = await challonge.getTournament(!!recover_match)
if !tournament_data
if !client.closed
if !client.isClosed
ygopro.stoc_die(client, '${challonge_match_load_failed}')
return
matching_participant = tournament_data.participants.find((p) => p.participant.name and deck_name_match(p.participant.name, client.name))
unless matching_participant
if !client.closed
if !client.isClosed
ygopro.stoc_die(client, '${challonge_user_not_found}')
return
client.challonge_info = matching_participant.participant
matching_match = tournament_data.matches.find((match) => match.match and !match.match.winner_id and match.match.state != "complete" and match.match.player1_id and match.match.player2_id and (match.match.player1_id == client.challonge_info.id or match.match.player2_id == client.challonge_info.id))
unless matching_match
if !client.closed
if !client.isClosed
ygopro.stoc_die(client, '${challonge_match_not_found}')
return
create_room_name = matching_match.match.id.toString()
......@@ -2392,8 +2421,8 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
recorder.on 'data', (data)->
room=ROOM_all[client.rid]
return unless room and settings.modules.cloud_replay.enabled
room.recorder_buffers.push data
return unless room
room.addRecorderBuffer(data)
return
recorder.on 'error', (error)->
......@@ -2416,7 +2445,7 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
return unless room
room.watcher_buffers.push data
for w in room.watchers
w.write data if w #a WTF fix
ygopro.helper.send(w, data) if w #a WTF fix
return
watcher.on 'error', (error)->
......@@ -2850,7 +2879,7 @@ ygopro.stoc_follow 'FIELD_FINISH', true, (buffer, info, client, server, datas)->
ygopro.stoc_follow 'DUEL_END', false, (buffer, info, client, server, datas)->
room=ROOM_all[client.rid]
return unless room and settings.modules.replay_delay and room.hostinfo.mode == 1
SOCKET_flush_data(client, datas)
await SOCKET_flush_data(client, datas)
CLIENT_send_replays(client, room)
if !room.replays_sent_to_watchers
room.replays_sent_to_watchers = true
......@@ -3340,7 +3369,7 @@ ygopro.stoc_follow 'TIME_LIMIT', true, (buffer, info, client, server, datas)->
ygopro.ctos_send(server, 'TIME_CONFIRM')
return true
if settings.modules.reconnect.enabled
if client.closed
if client.isClosed
ygopro.ctos_send(server, 'TIME_CONFIRM')
return true
else
......@@ -3879,4 +3908,23 @@ if true
response.end()
return
ip6addr = require('ip6addr')
neosRequestListener = (client, req) ->
physicalAddress = req.socket.remoteAddress
if settings.modules.neos.trusted_proxies.some((trusted) ->
cidr = if trusted.includes('/') then ip6addr.createCIDR(trusted) else ip6addr.createAddrRange(trusted, trusted)
return cidr.contains(physicalAddress)
)
ipHeader = req.headers[settings.modules.neos.trusted_proxy_header]
if ipHeader
client.ip = ipHeader.split(',')[0].trim()
if !client.ip
client.ip = physicalAddress
client.setTimeout = () -> true
client.destroy = () -> client.close()
client.isWs = true
netRequestHandler(client)
init()
// Generated by CoffeeScript 2.6.1
(function() {
// 标准库
var CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, _, _async, addCallback, athleticChecker, auth, axios, badwordR, badwords, ban_user, bunyan, challonge, checkFileExists, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, fs, geoip, getDuelLogQueryFromQs, getSeedTimet, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_tips, log, long_resolve_cards, memory_usage, merge, moment, moment_long_ago_string, moment_now, moment_now_string, net, netRequestHandler, os, osu, path, qs, real_windbot_server_ip, release_disconnect, report_to_big_brother, request, roomlist, rooms_count, setting_change, setting_get, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, ygopro, zlib;
var CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, _, _async, addCallback, athleticChecker, auth, axios, badwordR, badwords, ban_user, bunyan, challonge, checkFileExists, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, fs, geoip, getDuelLogQueryFromQs, getSeedTimet, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, ip6addr, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_tips, log, long_resolve_cards, memory_usage, merge, moment, moment_long_ago_string, moment_now, moment_now_string, neosRequestListener, net, netRequestHandler, os, osu, path, qs, real_windbot_server_ip, release_disconnect, report_to_big_brother, request, roomlist, rooms_count, setting_change, setting_get, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, ygopro, zlib;
net = require('net');
......@@ -304,7 +304,7 @@
};
init = async function() {
var AthleticChecker, Challonge, DataManager, chat_color, config, cppversion, defaultConfig, default_data, dirPath, dns, e, get_rooms_count, http_server, https, https_server, imported, j, key, keysFromEnv, l, len, len1, len2, m, mkdirList, options, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, postData, settingKey, val, valFromDefault;
var AthleticChecker, Challonge, DataManager, chat_color, config, cppversion, defaultConfig, default_data, dirPath, dns, e, get_rooms_count, http_server, https, httpsOptions, https_server, imported, j, key, keysFromEnv, l, len, len1, len2, m, main_http_server, mkdirList, neosHttpServer, neosWsServer, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, postData, settingKey, val, valFromDefault, ws;
log.info('Reading config.');
await createDirectoryIfNotExists("./config");
await importOldConfig();
......@@ -764,18 +764,34 @@
log.info("NOTE: server not open due to config, ", settings.modules.stop);
}
http_server = http.createServer(httpRequestListener);
http_server.listen(settings.modules.http.port);
main_http_server = http_server;
if (settings.modules.http.ssl.enabled) {
https = require('https');
options = {
httpsOptions = {
cert: (await fs.promises.readFile(settings.modules.http.ssl.cert)),
key: (await fs.promises.readFile(settings.modules.http.ssl.key))
};
https_server = https.createServer(options, httpRequestListener);
if (settings.modules.http.websocket_roomlist && roomlist) {
roomlist.init(https_server, ROOM_all);
}
https_server = https.createServer(httpsOptions, httpRequestListener);
https_server.listen(settings.modules.http.ssl.port);
main_http_server = https_server;
}
if (settings.modules.http.websocket_roomlist && roomlist) {
roomlist.init(main_http_server, ROOM_all);
}
http_server.listen(settings.modules.http.port);
if (settings.modules.neos.enabled) {
ws = require('ws');
neosHttpServer = null;
if (settings.modules.http.ssl.enabled) {
neosHttpServer = https.createServer(httpsOptions);
} else {
neosHttpServer = http.createServer();
}
neosWsServer = new ws.WebSocketServer({
server: neosHttpServer
});
neosWsServer.on('connection', neosRequestListener);
neosHttpServer.listen(settings.modules.neos.port);
}
mkdirList = ["./plugins", settings.modules.tournament_mode.deck_path, settings.modules.tournament_mode.replay_path, settings.modules.tournament_mode.log_save_path, settings.modules.deck_log.local];
for (l = 0, len1 = mkdirList.length; l < len1; l++) {
......@@ -1103,7 +1119,7 @@
return false;
}
client.system_kicked = true;
if (settings.modules.reconnect.enabled && client.closed) {
if (settings.modules.reconnect.enabled && client.isClosed) {
if (client.server && !client.had_new_reconnection) {
room = ROOM_all[client.rid];
if (room) {
......@@ -1305,7 +1321,7 @@
ref = room.get_playing_player();
for (l = 0, len1 = ref.length; l < len1; l++) {
player = ref[l];
if (!player.closed && player.name === client.name && (settings.modules.challonge.enabled || player.pass === client.pass) && (settings.modules.mycard.enabled || settings.modules.tournament_mode.enabled || player.ip === client.ip || (client.vpass && client.vpass === player.vpass)) && (!deckbuf || deckbuf.compare(player.start_deckbuf) === 0)) {
if (!player.isClosed && player.name === client.name && (settings.modules.challonge.enabled || player.pass === client.pass) && (settings.modules.mycard.enabled || settings.modules.tournament_mode.enabled || player.ip === client.ip || (client.vpass && client.vpass === player.vpass)) && (!deckbuf || deckbuf.compare(player.start_deckbuf) === 0)) {
return player;
}
}
......@@ -1465,7 +1481,7 @@
};
CLIENT_heartbeat_register = global.CLIENT_heartbeat_register = function(client, send) {
if (!settings.modules.heartbeat_detection.enabled || client.closed || client.is_post_watcher || client.pre_reconnecting || client.reconnecting || client.waiting_for_last || client.pos > 3 || client.heartbeat_protected) {
if (!settings.modules.heartbeat_detection.enabled || client.isClosed || client.is_post_watcher || client.pre_reconnecting || client.reconnecting || client.waiting_for_last || client.pos > 3 || client.heartbeat_protected) {
return false;
}
if (client.heartbeat_timeout) {
......@@ -1484,7 +1500,7 @@
}
client.heartbeat_timeout = setTimeout(function() {
CLIENT_heartbeat_unregister(client);
if (!(client.closed || client.heartbeat_responsed)) {
if (!(client.isClosed || client.heartbeat_responsed)) {
client.destroy();
}
}, settings.modules.heartbeat_detection.wait_time);
......@@ -1498,7 +1514,7 @@
CLIENT_send_replays = global.CLIENT_send_replays = function(client, room) {
var buffer, i, j, len, ref;
if (!(settings.modules.replay_delay && !(settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) && room.replays.length && room.hostinfo.mode === 1 && !client.replays_sent && !client.closed)) {
if (!(settings.modules.replay_delay && !(settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) && room.replays.length && room.hostinfo.mode === 1 && !client.replays_sent && !client.isClosed)) {
return false;
}
client.replays_sent = true;
......@@ -1515,16 +1531,15 @@
return true;
};
SOCKET_flush_data = global.SOCKET_flush_data = function(sk, datas) {
var buffer, j, len;
if (!sk || sk.closed) {
SOCKET_flush_data = global.SOCKET_flush_data = async function(sk, datas) {
var buffer;
if (!sk || sk.isClosed) {
return false;
}
for (j = 0, len = datas.length; j < len; j++) {
buffer = datas[j];
sk.write(buffer);
while (datas.length) {
buffer = datas.shift();
await ygopro.helper.send(sk, buffer);
}
datas.splice(0, datas.length);
return true;
};
......@@ -1703,13 +1718,16 @@
this.welcome = "${recover_hint}";
}
}
this.hostinfo.replay_mode = 0; // 0x1: Save the replays in file. 0x2: Block the replays to observers.
if (settings.modules.tournament_mode.enabled) {
this.hostinfo.replay_mode = 0;
if (settings.modules.tournament_mode.enabled) { // 0x1: Save the replays in file
this.hostinfo.replay_mode |= 0x1;
}
if ((settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) || (this.hostinfo.mode === 1 && settings.modules.replay_delay)) {
if ((settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) || (this.hostinfo.mode === 1 && settings.modules.replay_delay)) { // 0x2: Block the replays to observers
this.hostinfo.replay_mode |= 0x2;
}
if (settings.modules.tournament_mode.enabled || room.arena) { // 0x4: Save chat in cloud replay
this.hostinfo.replay_mode |= 0x4;
}
if (!this.recovered) {
this.spawn();
}
......@@ -1756,12 +1774,12 @@
}
this.port = parseInt(data);
_.each(this.players, (player) => {
player.server.connect(this.port, '127.0.0.1', function() {
player.server.connect(this.port, '127.0.0.1', async function() {
var buffer, len, m, ref;
ref = player.pre_establish_buffers;
for (m = 0, len = ref.length; m < len; m++) {
buffer = ref[m];
player.server.write(buffer);
await ygopro.helper.send(player.server, buffer);
}
player.established = true;
player.pre_establish_buffers = [];
......@@ -1984,7 +2002,7 @@
ref = this.get_playing_player();
for (j = 0, len = ref.length; j < len; j++) {
player = ref[j];
if (player.closed) {
if (player.isClosed) {
found++;
}
}
......@@ -2097,12 +2115,12 @@
if (!this.windbot && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.http.websocket_roomlist) {
roomlist.update(this);
}
client.server.connect(this.port, '127.0.0.1', function() {
client.server.connect(this.port, '127.0.0.1', async function() {
var buffer, j, len, ref;
ref = client.pre_establish_buffers;
for (j = 0, len = ref.length; j < len; j++) {
buffer = ref[j];
client.server.write(buffer);
await ygopro.helper.send(client.server, buffer);
}
client.established = true;
client.pre_establish_buffers = [];
......@@ -2316,7 +2334,7 @@
}));
}
join_post_watch(client) {
async join_post_watch(client) {
var buffer, j, len, ref;
if (this.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN) {
if (settings.modules.cloud_replay.enable_halfway_watch && !this.hostinfo.no_watch) {
......@@ -2329,7 +2347,7 @@
ref = this.watcher_buffers;
for (j = 0, len = ref.length; j < len; j++) {
buffer = ref[j];
client.write(buffer);
await ygopro.helper.send(client, buffer);
}
return true;
} else {
......@@ -2379,12 +2397,36 @@
}
}
addRecorderBuffer(buffer) {
if (settings.modules.cloud_replay.enabled) {
this.recorder_buffers.push(buffer);
}
}
recordChatMessage(msg, player) {
var chat_buf, j, len, line, ref;
if (!(settings.modules.cloud_replay.enabled && (this.arena || settings.modules.tournament_mode.enabled))) {
return;
}
ref = ygopro.split_chat_lines(msg, player, settings.modules.i18n.default);
for (j = 0, len = ref.length; j < len; j++) {
line = ref[j];
chat_buf = ygopro.helper.prepareMessage("STOC_CHAT", {
player: player,
msg: line
});
this.addRecorderBuffer(chat_buf);
}
}
};
// 网络连接
netRequestHandler = function(client) {
var connect_count, server;
client.ip = client.remoteAddress;
var closeHandler, connect_count, dataHandler, server;
if (!client.isWs) {
client.ip = client.remoteAddress;
}
client.is_local = client.ip && (client.ip.includes('127.0.0.1') || client.ip.includes(real_windbot_server_ip));
connect_count = ROOM_connected_ip[client.ip] || 0;
if (!settings.modules.test_mode.no_connect_count_limit && !client.is_local) {
......@@ -2404,71 +2446,63 @@
client.setTimeout(2000); //连接前超时2秒
// 释放处理
client.on('close', function(had_error) {
closeHandler = function(error) {
var room;
//log.info "client closed", client.name, had_error
room = ROOM_all[client.rid];
connect_count = ROOM_connected_ip[client.ip];
if (connect_count > 0) {
connect_count--;
}
ROOM_connected_ip[client.ip] = connect_count;
//log.info "client closed", client.name, error, client.isClosed
//log.info "disconnect", client.ip, ROOM_connected_ip[client.ip]
if (!client.closed) {
client.closed = true;
if (settings.modules.heartbeat_detection.enabled) {
CLIENT_heartbeat_unregister(client);
}
if (room) {
if (!CLIENT_reconnect_register(client, client.rid)) {
room.disconnect(client);
}
} else if (!client.had_new_reconnection) {
SERVER_kick(client.server);
}
if (client.isClosed) {
return;
}
});
client.on('error', function(error) {
var room;
//log.info "client error", client.name, error
room = ROOM_all[client.rid];
connect_count = ROOM_connected_ip[client.ip];
if (connect_count > 0) {
connect_count--;
}
ROOM_connected_ip[client.ip] = connect_count;
//log.info "err disconnect", client.ip, ROOM_connected_ip[client.ip]
if (!client.closed) {
client.closed = true;
if (room) {
if (!CLIENT_reconnect_register(client, client.rid, error)) {
room.disconnect(client, error);
}
} else if (!client.had_new_reconnection) {
SERVER_kick(client.server);
}
client.isClosed = true;
if (settings.modules.heartbeat_detection.enabled) {
CLIENT_heartbeat_unregister(client);
}
});
client.on('timeout', function() {
if (!(settings.modules.reconnect.enabled && (disconnect_list[CLIENT_get_authorize_key(client)] || client.had_new_reconnection))) {
client.destroy();
if (room) {
if (!CLIENT_reconnect_register(client, client.rid, error)) {
room.disconnect(client, error);
}
} else if (!client.had_new_reconnection) {
SERVER_kick(client.server);
}
});
};
if (client.isWs) {
client.on('close', function(code, reason) {
return closeHandler();
});
} else {
client.on('close', function(had_error) {
return closeHandler(had_error != null ? had_error : {
'unknown': void 0
});
});
client.on('timeout', function() {
if (!(settings.modules.reconnect.enabled && (disconnect_list[CLIENT_get_authorize_key(client)] || client.had_new_reconnection))) {
client.destroy();
}
});
}
client.on('error', closeHandler);
server.on('close', function(had_error) {
var room;
if (!server.closed) {
server.closed = true;
if (!server.isClosed) {
server.isClosed = true;
}
if (!server.client) {
return;
}
//log.info "server closed", server.client.name, had_error
//log.info "server isClosed", server.client.name, had_error
room = ROOM_all[server.client.rid];
if (room && !server.system_kicked && !server.had_new_reconnection) {
//log.info "server close", server.client.ip, ROOM_connected_ip[server.client.ip]
room.disconnector = 'server';
}
if (!server.client.closed) {
if (!server.client.isClosed) {
ygopro.stoc_send_chat(server.client, "${server_closed}", ygopro.constants.COLORS.RED);
//if room and settings.modules.replay_delay
// room.send_replays()
......@@ -2478,7 +2512,7 @@
});
server.on('error', function(error) {
var room;
server.closed = error;
server.isClosed = error;
if (!server.client) {
return;
}
......@@ -2488,7 +2522,7 @@
//log.info "server err close", client.ip, ROOM_connected_ip[client.ip]
room.disconnector = 'server';
}
if (!server.client.closed) {
if (!server.client.isClosed) {
ygopro.stoc_send_chat(server.client, `\${server_error}: ${error}`, ygopro.constants.COLORS.RED);
//if room and settings.modules.replay_delay
// room.send_replays()
......@@ -2514,16 +2548,15 @@
return;
}
ygopro.stoc_send_chat(client, `\${cloud_replay_playing} ${replay.getDisplayString()}`, ygopro.constants.COLORS.BABYBLUE);
client.write(replay_buffer, function() {
CLIENT_kick(client);
});
await ygopro.helper.send(client, replay_buffer);
CLIENT_kick(client);
};
}
// 需要重构
// 客户端到服务端(ctos)协议分析
client.pre_establish_buffers = new Array();
client.on('data', async function(ctos_buffer) {
var bad_ip_count, buffer, ctos_filter, handle_data, j, l, len, len1, len2, m, preconnect, ref, ref1, ref2, room;
dataHandler = async function(ctos_buffer) {
var bad_ip_count, buffer, ctos_filter, handle_data, j, l, len, len1, preconnect, ref, ref1, room;
if (client.is_post_watcher) {
room = ROOM_all[client.rid];
if (room) {
......@@ -2547,7 +2580,7 @@
ref = handle_data.datas;
for (j = 0, len = ref.length; j < len; j++) {
buffer = ref[j];
room.watcher.write(buffer);
await ygopro.helper.send(room.watcher, buffer);
}
}
} else {
......@@ -2577,24 +2610,25 @@
return;
}
}
if (client.closed || !client.server) {
if (client.isClosed || !client.server) {
return;
}
if (client.established) {
ref1 = handle_data.datas;
for (l = 0, len1 = ref1.length; l < len1; l++) {
buffer = ref1[l];
client.server.write(buffer);
await ygopro.helper.send(client.server, buffer);
}
} else {
ref2 = handle_data.datas;
for (m = 0, len2 = ref2.length; m < len2; m++) {
buffer = ref2[m];
client.pre_establish_buffers.push(buffer);
}
client.pre_establish_buffers = client.pre_establish_buffers.concat(handle_data.datas);
}
}
});
};
if (client.isWs) {
client.on('message', dataHandler);
} else {
client.on('data', dataHandler);
}
// 服务端到客户端(stoc)
server.on('data', async function(stoc_buffer) {
var buffer, handle_data, j, len, ref;
......@@ -2609,11 +2643,11 @@
return;
}
}
if (server.client && !server.client.closed) {
if (server.client && !server.client.isClosed) {
ref = handle_data.datas;
for (j = 0, len = ref.length; j < len; j++) {
buffer = ref[j];
server.client.write(buffer);
await ygopro.helper.send(server.client, buffer);
}
}
});
......@@ -2791,7 +2825,7 @@
};
create_room_with_action = async function(buffer, decrypted_buffer) {
var action, e, firstByte, len2, m, matchPermitRes, match_permit, name, opt0, opt1, opt2, opt3, options, player, ref, ref1, room, room_title, title;
if (client.closed) {
if (client.isClosed) {
return;
}
firstByte = buffer.readUInt8(1);
......@@ -2886,7 +2920,7 @@
e = error1;
log.warn(`match permit fail ${e.toString()}`);
}
if (client.closed) {
if (client.isClosed) {
return;
}
if (match_permit && match_permit.permit === false) {
......@@ -2963,12 +2997,12 @@
//console.log userData
e = error1;
log.warn("READ USER FAIL", client.name, e.toString());
if (!client.closed) {
if (!client.isClosed) {
ygopro.stoc_die(client, '${load_user_info_fail}');
}
return;
}
if (client.closed) {
if (client.isClosed) {
return;
}
users_cache[client.name] = userData.user.id;
......@@ -3005,7 +3039,7 @@
recover_match = info.pass.match(/^(RC|RECOVER)(\d*)T(\d*)$/);
tournament_data = (await challonge.getTournament(!!recover_match));
if (!tournament_data) {
if (!client.closed) {
if (!client.isClosed) {
ygopro.stoc_die(client, '${challonge_match_load_failed}');
}
return;
......@@ -3014,7 +3048,7 @@
return p.participant.name && deck_name_match(p.participant.name, client.name);
});
if (!matching_participant) {
if (!client.closed) {
if (!client.isClosed) {
ygopro.stoc_die(client, '${challonge_user_not_found}');
}
return;
......@@ -3024,7 +3058,7 @@
return match.match && !match.match.winner_id && match.match.state !== "complete" && match.match.player1_id && match.match.player2_id && (match.match.player1_id === client.challonge_info.id || match.match.player2_id === client.challonge_info.id);
});
if (!matching_match) {
if (!client.closed) {
if (!client.isClosed) {
ygopro.stoc_die(client, '${challonge_match_not_found}');
}
return;
......@@ -3148,10 +3182,10 @@
});
recorder.on('data', function(data) {
room = ROOM_all[client.rid];
if (!(room && settings.modules.cloud_replay.enabled)) {
if (!room) {
return;
}
room.recorder_buffers.push(data);
room.addRecorderBuffer(data);
});
recorder.on('error', function(error) {});
}
......@@ -3177,7 +3211,7 @@
for (l = 0, len1 = ref1.length; l < len1; l++) {
w = ref1[l];
if (w) { //a WTF fix
w.write(data);
ygopro.helper.send(w, data);
}
}
});
......@@ -3781,7 +3815,7 @@
if (!(room && settings.modules.replay_delay && room.hostinfo.mode === 1)) {
return;
}
SOCKET_flush_data(client, datas);
await SOCKET_flush_data(client, datas);
CLIENT_send_replays(client, room);
if (!room.replays_sent_to_watchers) {
room.replays_sent_to_watchers = true;
......@@ -4484,7 +4518,7 @@
return true;
}
if (settings.modules.reconnect.enabled) {
if (client.closed) {
if (client.isClosed) {
ygopro.ctos_send(server, 'TIME_CONFIRM');
return true;
} else {
......@@ -5169,6 +5203,34 @@
};
}
ip6addr = require('ip6addr');
neosRequestListener = function(client, req) {
var ipHeader, physicalAddress;
physicalAddress = req.socket.remoteAddress;
if (settings.modules.neos.trusted_proxies.some(function(trusted) {
var cidr;
cidr = trusted.includes('/') ? ip6addr.createCIDR(trusted) : ip6addr.createAddrRange(trusted, trusted);
return cidr.contains(physicalAddress);
})) {
ipHeader = req.headers[settings.modules.neos.trusted_proxy_header];
if (ipHeader) {
client.ip = ipHeader.split(',')[0].trim();
}
}
if (!client.ip) {
client.ip = physicalAddress;
}
client.setTimeout = function() {
return true;
};
client.destroy = function() {
return client.close();
};
client.isWs = true;
return netRequestHandler(client);
};
init();
}).call(this);
......@@ -59,16 +59,22 @@ translateHandler = (handler) ->
return @helper.sendMessage(socket, "CTOS_#{proto}", info)
#util
@stoc_send_chat = (client, msg, player = 8)->
if !client
console.log "err stoc_send_chat"
return
@split_chat_lines = (msg, player, lang) ->
lines = []
for line in _.lines(msg)
if player>=10
line="[Server]: "+line
for o,r of @i18nR[client.lang]
for o,r of @i18nR[lang]
line=line.replace(r.regex, r.text)
@stoc_send client, 'CHAT', {
lines.push(line)
return lines
@stoc_send_chat = (client, msg, player = 8)->
if !client
console.log "err stoc_send_chat"
return
for line in @split_chat_lines(msg, player, client.lang)
await @stoc_send client, 'CHAT', {
player: player
msg: line
}
......@@ -82,6 +88,7 @@ translateHandler = (handler) ->
@stoc_send_chat(client, msg, player) if client
for client in room.watchers
@stoc_send_chat(client, msg, player) if client
room.recordChatMessage(msg, player)
return
@stoc_send_hint_card_to_room = (room, card)->
......@@ -105,8 +112,8 @@ translateHandler = (handler) ->
return
@stoc_die = (client, msg)->
@stoc_send_chat(client, msg, @constants.COLORS.RED)
@stoc_send client, 'ERROR_MSG', {
await @stoc_send_chat(client, msg, @constants.COLORS.RED)
await @stoc_send client, 'ERROR_MSG', {
msg: 1
code: 9
} if client
......
// Generated by CoffeeScript 2.5.1
// Generated by CoffeeScript 2.6.1
(function() {
var Struct, YGOProMessagesHelper, _, loadJSON, translateHandler;
......@@ -95,24 +95,35 @@
};
//util
this.stoc_send_chat = function(client, msg, player = 8) {
var i, len, line, o, r, ref, ref1;
if (!client) {
console.log("err stoc_send_chat");
return;
}
this.split_chat_lines = function(msg, player, lang) {
var i, len, line, lines, o, r, ref, ref1;
lines = [];
ref = _.lines(msg);
for (i = 0, len = ref.length; i < len; i++) {
line = ref[i];
if (player >= 10) {
line = "[Server]: " + line;
}
ref1 = this.i18nR[client.lang];
ref1 = this.i18nR[lang];
for (o in ref1) {
r = ref1[o];
line = line.replace(r.regex, r.text);
}
this.stoc_send(client, 'CHAT', {
lines.push(line);
}
return lines;
};
this.stoc_send_chat = async function(client, msg, player = 8) {
var i, len, line, ref;
if (!client) {
console.log("err stoc_send_chat");
return;
}
ref = this.split_chat_lines(msg, player, client.lang);
for (i = 0, len = ref.length; i < len; i++) {
line = ref[i];
await this.stoc_send(client, 'CHAT', {
player: player,
msg: line
});
......@@ -139,6 +150,7 @@
this.stoc_send_chat(client, msg, player);
}
}
room.recordChatMessage(msg, player);
};
this.stoc_send_hint_card_to_room = function(room, card) {
......@@ -173,10 +185,10 @@
}
};
this.stoc_die = function(client, msg) {
this.stoc_send_chat(client, msg, this.constants.COLORS.RED);
this.stoc_die = async function(client, msg) {
await this.stoc_send_chat(client, msg, this.constants.COLORS.RED);
if (client) {
this.stoc_send(client, 'ERROR_MSG', {
await this.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 9
});
......
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