Commit ed52f897 authored by nanahira's avatar nanahira

add reconnect

parent 5c4550cb
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
"34": "HS_READY", "34": "HS_READY",
"35": "HS_NOTREADY", "35": "HS_NOTREADY",
"36": "HS_KICK", "36": "HS_KICK",
"37": "HS_START" "37": "HS_START",
"48": "REQUEST_FIELD"
}, },
"STOC": { "STOC": {
"1": "GAME_MSG", "1": "GAME_MSG",
...@@ -51,7 +52,8 @@ ...@@ -51,7 +52,8 @@
"25": "CHAT", "25": "CHAT",
"32": "HS_PLAYER_ENTER", "32": "HS_PLAYER_ENTER",
"33": "HS_PLAYER_CHANGE", "33": "HS_PLAYER_CHANGE",
"34": "HS_WATCH_CHANGE" "34": "HS_WATCH_CHANGE",
"48": "FIELD_FINISH"
}, },
"PLAYERCHANGE":{ "PLAYERCHANGE":{
"8": "OBSERVE", "8": "OBSERVE",
......
...@@ -86,6 +86,10 @@ ...@@ -86,6 +86,10 @@
"enabled": true, "enabled": true,
"max_retry_count": false "max_retry_count": false
}, },
"reconnect": {
"enabled": true,
"wait_time": 300000
},
"mycard": { "mycard": {
"enabled": false, "enabled": false,
"auth_base_url": "https://ygobbs.com", "auth_base_url": "https://ygobbs.com",
......
...@@ -131,6 +131,10 @@ ...@@ -131,6 +131,10 @@
"retry_too_much_part2": " times.", "retry_too_much_part2": " times.",
"retry_too_much_room_part1": " was kicked from the room for performing an illegal operation ", "retry_too_much_room_part1": " was kicked from the room for performing an illegal operation ",
"retry_too_much_room_part2": " times.", "retry_too_much_room_part2": " times.",
"pre_reconnecting_to_room": "You will be reconnected to your previous game. Please pick your Previous deck.",
"deck_incorrect_reconnect": "Please pick your Previous deck.",
"reconnect_failed": "Reconnect failed.",
"reconnecting_to_room": "Reconnecting to server...",
"athletic_arena_tip": "During an athletic match, a game quit behavior is regarded as a surrender." "athletic_arena_tip": "During an athletic match, a game quit behavior is regarded as a surrender."
}, },
"es-es": { "es-es": {
...@@ -398,6 +402,10 @@ ...@@ -398,6 +402,10 @@
"retry_too_much_part2": "次,已被请出房间。", "retry_too_much_part2": "次,已被请出房间。",
"retry_too_much_room_part1": " 由于在决斗中违规操作", "retry_too_much_room_part1": " 由于在决斗中违规操作",
"retry_too_much_room_part2": "次,已被请出房间。", "retry_too_much_room_part2": "次,已被请出房间。",
"pre_reconnecting_to_room": "你有未完成的对局,即将重新连接,请选择你在本局决斗中使用的卡组并准备。",
"deck_incorrect_reconnect": "请选择你在本局决斗中使用的卡组。",
"reconnect_failed": "重新连接失败。",
"reconnecting_to_room": "正在重新连接到服务器……",
"athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。" "athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。"
}, },
"ko-kr": { "ko-kr": {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
{"name": "lflist", "type": "unsigned int"}, {"name": "lflist", "type": "unsigned int"},
{"name": "rule", "type": "unsigned char"}, {"name": "rule", "type": "unsigned char"},
{"name": "mode", "type": "unsigned char"}, {"name": "mode", "type": "unsigned char"},
{"name": "enable_priority", "type": "bool"}, {"name": "duel_rule", "type": "unsigned char"},
{"name": "no_check_deck", "type": "bool"}, {"name": "no_check_deck", "type": "bool"},
{"name": "no_shuffle_deck", "type": "bool"}, {"name": "no_shuffle_deck", "type": "bool"},
{"name": "start_lp", "type": "unsigned int"}, {"name": "start_lp", "type": "unsigned int"},
......
...@@ -254,7 +254,7 @@ ROOM_players_oppentlist = {} ...@@ -254,7 +254,7 @@ ROOM_players_oppentlist = {}
ROOM_players_banned = [] ROOM_players_banned = []
ROOM_connected_ip = {} ROOM_connected_ip = {}
ROOM_bad_ip = {} ROOM_bad_ip = {}
# ban a user manually and permanently # ban a user manually and permanently
ban_user = (name) -> ban_user = (name) ->
settings.ban.banned_user.push(name) settings.ban.banned_user.push(name)
...@@ -267,7 +267,7 @@ ban_user = (name) -> ...@@ -267,7 +267,7 @@ ban_user = (name) ->
ROOM_bad_ip[bad_ip]=99 ROOM_bad_ip[bad_ip]=99
settings.ban.banned_ip.push(player.ip) settings.ban.banned_ip.push(player.ip)
ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
player.destroy() CLIENT_kick(player)
continue continue
return return
...@@ -406,6 +406,204 @@ ROOM_unwelcome = (room, bad_player, reason)-> ...@@ -406,6 +406,204 @@ ROOM_unwelcome = (room, bad_player, reason)->
ygopro.stoc_send_chat(player, "${unwelcome_tip_part1}#{reason}${unwelcome_tip_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(player, "${unwelcome_tip_part1}#{reason}${unwelcome_tip_part2}", ygopro.constants.COLORS.BABYBLUE)
return return
CLIENT_kick = (client) ->
client.system_kicked = true
client.destroy()
return
release_disconnect = (dinfo, reconnected) ->
if dinfo.old_client and !reconnected
dinfo.old_client.destroy()
if dinfo.old_server and !reconnected
dinfo.old_server.destroy()
clearTimeout(dinfo.timeout)
return
CLIENT_get_authorize_key = (client) ->
if settings.modules.mycard.enabled or client.is_local
return client.name
else
return client.ip
CLIENT_reconnect_unregister = (client, reconnected) ->
if !settings.modules.reconnect.enabled
return false
if disconnect_list[CLIENT_get_authorize_key(client)]
release_disconnect(disconnect_list[CLIENT_get_authorize_key(client)], reconnected)
delete disconnect_list[CLIENT_get_authorize_key(client)]
return true
return false
CLIENT_reconnect_register = (client, room, error) ->
if client.had_new_reconnection
return false
if !settings.modules.reconnect.enabled or client.system_kicked or client.is_post_watcher or !CLIENT_is_player(client, room) or !room.started or (room.windbot and client.is_local)
return false
old_dinfo = disconnect_list[CLIENT_get_authorize_key(client)]
if old_dinfo
old_dinfo.room.disconnect(old_dinfo.old_client)
dinfo = {
room: room,
old_client: client,
old_server: client.server,
deckbuf: client.start_deckbuf
}
tmot = setTimeout(() ->
room.disconnect(client, error)
dinfo.old_server.destroy()
return
, settings.modules.reconnect.wait_time)
dinfo.timeout = tmot
disconnect_list[CLIENT_get_authorize_key(client)] = dinfo
return true
CLIENT_import_data = (client, old_client, room) ->
for player,index in room.players
if player == old_client
room.players[index] = client
break
room.dueling_players[old_client.pos] = client
if room.waiting_for_player = old_client
room.waiting_for_player = client
if room.waiting_for_player2 = old_client
room.waiting_for_player2 = client
if room.selecting_tp = old_client
room.selecting_tp = client
client.abuse_count = old_client.abuse_count
# client.established = old_client.established
# client.pre_establish_buffers = old_client.pre_establish_buffers
client.rag = old_client.rag
client.rid = old_client.rid
client.is_post_watcher = old_client.is_post_watcher
client.retry_count = old_client.retry_count
client.name = old_client.name
client.is_first = old_client.is_first
client.lp = old_client.lp
client.card_count = old_client.card_count
client.is_host = old_client.is_host
client.pos = old_client.pos
client.surrend_confirm = old_client.surrend_confirm
client.kick_count = old_client.kick_count
client.deck_saved = old_client.deck_saved
client.main = old_client.main
client.side = old_client.side
client.side_interval = old_client.side_interval
client.side_tcount = old_client.side_tcount
client.selected_preduel = old_client.selected_preduel
client.last_game_msg = old_client.last_game_msg
client.last_game_msg_title = old_client.last_game_msg_title
client.start_deckbuf = old_client.start_deckbuf
client.join_game_buffer = old_client.join_game_buffer
old_client.had_new_reconnection = true
return
SERVER_clear_disconnect = (server) ->
return unless settings.modules.reconnect.enabled
for k,v of disconnect_list
if v and server == v.old_server
release_disconnect(v)
delete disconnect_list[k]
return
return
CLIENT_is_player = (client, room) ->
is_player = false
for player in room.players
if client == player
is_player = true
break
return is_player
CLIENT_is_able_to_reconnect = (client) ->
unless settings.modules.reconnect.enabled
return false
if client.system_kicked
return false
disconnect_info = disconnect_list[CLIENT_get_authorize_key(client)]
unless disconnect_info
return false
# if disconnect_info.old_server.closed
# return false
# current_room = disconnect_info.room
# unless current_room and current_room.started
# return false
# if client.is_post_watcher or !CLIENT_is_player(client, current_room) or (room.windbot and client.is_local)
# return false
return true
CLIENT_send_pre_reconnect_info = (client, room, old_client) ->
ygopro.stoc_send_chat(client, "${pre_reconnecting_to_room}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send(client, 'JOIN_GAME', old_client.join_game_buffer)
req_pos = old_client.pos
if old_client.is_host
req_pos += 0x10
ygopro.stoc_send(client, 'TYPE_CHANGE', {
type: req_pos
})
for player in room.players
ygopro.stoc_send(client, 'HS_PLAYER_ENTER', {
name: player.name,
pos: player.pos,
})
CLIENT_send_reconnect_info = (client, server, room) ->
client.reconnecting = true
ygopro.stoc_send_chat(client, "${reconnecting_to_room}", ygopro.constants.COLORS.BABYBLUE)
if room.turn and room.turn > 0
ygopro.ctos_send(server, 'REQUEST_FIELD')
else if room.changing_side
ygopro.stoc_send(client, 'DUEL_START')
if !client.selected_preduel
ygopro.stoc_send(client, 'CHANGE_SIDE')
client.reconnecting = false
else if room.selecting_hand
ygopro.stoc_send(client, 'DUEL_START')
if (room.hostinfo.mode != 2 or client.pos == 0 or client.pos == 2) and !client.selected_preduel
ygopro.stoc_send(client, 'SELECT_HAND')
client.reconnecting = false
else if room.selecting_tp
ygopro.stoc_send(client, 'DUEL_START')
if client == room.selecting_tp and !client.selected_preduel
ygopro.stoc_send(client, 'SELECT_TP')
client.reconnecting = false
else
ygopro.ctos_send(server, 'REQUEST_FIELD')
return
CLIENT_pre_reconnect = (client) ->
if !CLIENT_is_able_to_reconnect(client)
return
dinfo = disconnect_list[CLIENT_get_authorize_key(client)]
client.pre_deckbuf = dinfo.deckbuf
client.pre_reconnecting = true
client.pos = dinfo.old_client.pos
CLIENT_send_pre_reconnect_info(client, dinfo.room, dinfo.old_client)
CLIENT_reconnect = (client) ->
if !CLIENT_is_able_to_reconnect(client)
ygopro.stoc_send_chat(client, "${reconnect_failed}", ygopro.constants.COLORS.RED)
CLIENT_kick(client)
return
client.pre_reconnecting = false
dinfo = disconnect_list[CLIENT_get_authorize_key(client)]
current_old_server = client.server
client.server = dinfo.old_server
client.server.client = client
dinfo.old_client.server = null
current_old_server.client = null
current_old_server.had_new_reconnection = true
current_old_server.destroy()
client.established = true
client.pre_establish_buffers = []
client.setTimeout(300000)
CLIENT_import_data(client, dinfo.old_client, dinfo.room)
CLIENT_send_reconnect_info(client, client.server, dinfo.room)
CLIENT_reconnect_unregister(client, true)
return
if settings.modules.reconnect.enabled
disconnect_list = {} # {old_client, old_server, room, timeout, deckbuf}
class Room class Room
constructor: (name, @hostinfo) -> constructor: (name, @hostinfo) ->
@name = name @name = name
...@@ -424,9 +622,11 @@ class Room ...@@ -424,9 +622,11 @@ class Room
@scores = {} @scores = {}
@duel_count = 0 @duel_count = 0
@death = 0 @death = 0
@turn = 0
ROOM_all.push this ROOM_all.push this
@hostinfo ||= JSON.parse(JSON.stringify(settings.hostinfo)) @hostinfo ||= JSON.parse(JSON.stringify(settings.hostinfo))
delete @hostinfo.comment
if lflists.length if lflists.length
if @hostinfo.rule == 1 and @hostinfo.lflist == 0 if @hostinfo.rule == 1 and @hostinfo.lflist == 0
@hostinfo.lflist = _.findIndex lflists, (list)-> list.tcg @hostinfo.lflist = _.findIndex lflists, (list)-> list.tcg
...@@ -686,11 +886,14 @@ class Room ...@@ -686,11 +886,14 @@ class Room
return return
disconnect: (client, error)-> disconnect: (client, error)->
if client.had_new_reconnection
return
if client.is_post_watcher if client.is_post_watcher
ygopro.stoc_send_chat_to_room this, "#{client.name} ${quit_watch}" + if error then ": #{error}" else '' ygopro.stoc_send_chat_to_room this, "#{client.name} ${quit_watch}" + if error then ": #{error}" else ''
index = _.indexOf(@watchers, client) index = _.indexOf(@watchers, client)
@watchers.splice(index, 1) unless index == -1 @watchers.splice(index, 1) unless index == -1
#client.room = null #client.room = null
client.server.destroy()
else else
#log.info(client.name, @started, @disconnector, @random_type, @players.length) #log.info(client.name, @started, @disconnector, @random_type, @players.length)
if @arena == "athletic" and !@started and @players.length == 2 if @arena == "athletic" and !@started and @players.length == 2
...@@ -712,6 +915,8 @@ class Room ...@@ -712,6 +915,8 @@ class Room
@process.kill() @process.kill()
#client.room = null #client.room = null
this.delete() this.delete()
if !CLIENT_reconnect_unregister(client)
client.server.destroy()
return return
...@@ -729,6 +934,7 @@ net.createServer (client) -> ...@@ -729,6 +934,7 @@ net.createServer (client) ->
# 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
server.client = client
client.setTimeout(2000) #连接前超时2秒 client.setTimeout(2000) #连接前超时2秒
...@@ -743,8 +949,11 @@ net.createServer (client) -> ...@@ -743,8 +949,11 @@ net.createServer (client) ->
#log.info "disconnect", client.ip, ROOM_connected_ip[client.ip] #log.info "disconnect", client.ip, ROOM_connected_ip[client.ip]
unless client.closed unless client.closed
client.closed = true client.closed = true
room.disconnect(client) if room if room
server.destroy() if !CLIENT_reconnect_register(client, room)
room.disconnect(client)
else if !client.had_new_reconnection
client.server.destroy()
return return
client.on 'error', (error)-> client.on 'error', (error)->
...@@ -756,40 +965,52 @@ net.createServer (client) -> ...@@ -756,40 +965,52 @@ net.createServer (client) ->
ROOM_connected_ip[client.ip] = connect_count ROOM_connected_ip[client.ip] = connect_count
#log.info "err disconnect", client.ip, ROOM_connected_ip[client.ip] #log.info "err disconnect", client.ip, ROOM_connected_ip[client.ip]
unless client.closed unless client.closed
client.closed = error client.closed = true
room.disconnect(client, error) if room if room
server.destroy() if !CLIENT_reconnect_register(client, room, error)
room.disconnect(client, error)
else if !client.had_new_reconnection
client.server.destroy()
return return
client.on 'timeout', ()-> client.on 'timeout', ()->
server.destroy() if !client.server
return
unless settings.modules.reconnect.enabled and (disconnect_list[CLIENT_get_authorize_key(client)] or client.had_new_reconnection)
client.server.destroy()
return return
server.on 'close', (had_error) -> server.on 'close', (had_error) ->
#log.info "server closed", client.name, had_error #log.info "server closed", server.client.name, had_error
room=ROOM_all[client.rid] room=ROOM_all[server.client.rid]
#log.info "server close", client.ip, ROOM_connected_ip[client.ip] #log.info "server close", server.client.ip, ROOM_connected_ip[server.client.ip]
room.disconnector = 'server' if room room.disconnector = 'server' if room
server.closed = true unless server.closed server.closed = true unless server.closed
unless client.closed if !server.client
ygopro.stoc_send_chat(client, "${server_closed}", ygopro.constants.COLORS.RED) return
client.destroy() unless server.client.closed
ygopro.stoc_send_chat(server.client, "${server_closed}", ygopro.constants.COLORS.RED)
CLIENT_kick(server.client)
SERVER_clear_disconnect(server)
return return
server.on 'error', (error)-> server.on 'error', (error)->
#log.info "server error", client.name, error #log.info "server error", client.name, error
room=ROOM_all[client.rid] room=ROOM_all[server.client.rid]
#log.info "server err close", client.ip, ROOM_connected_ip[client.ip] #log.info "server err close", client.ip, ROOM_connected_ip[client.ip]
room.disconnector = 'server' if room room.disconnector = 'server' if room
server.closed = error server.closed = error
unless client.closed if !server.client
ygopro.stoc_send_chat(client, "${server_error}: #{error}", ygopro.constants.COLORS.RED) return
client.destroy() unless server.client.closed
ygopro.stoc_send_chat(server.client, "${server_error}: #{error}", ygopro.constants.COLORS.RED)
CLIENT_kick(server.client)
SERVER_clear_disconnect(server)
return return
if ROOM_bad_ip[client.ip] > 5 or ROOM_connected_ip[client.ip] > 10 if ROOM_bad_ip[client.ip] > 5 or ROOM_connected_ip[client.ip] > 10
log.info 'BAD IP', client.ip log.info 'BAD IP', client.ip
client.destroy() CLIENT_kick(client)
return return
if settings.modules.cloud_replay.enabled if settings.modules.cloud_replay.enabled
...@@ -803,11 +1024,11 @@ net.createServer (client) -> ...@@ -803,11 +1024,11 @@ net.createServer (client) ->
if err if err
log.info "cloud replay unzip error: " + err log.info "cloud replay unzip error: " + err
ygopro.stoc_send_chat(client, "${cloud_replay_error}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${cloud_replay_error}", ygopro.constants.COLORS.RED)
client.destroy() CLIENT_kick(client)
return return
ygopro.stoc_send_chat(client, "${cloud_replay_playing} R##{replay.replay_id} #{replay.player_names} #{replay.date_time}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${cloud_replay_playing} R##{replay.replay_id} #{replay.player_names} #{replay.date_time}", ygopro.constants.COLORS.BABYBLUE)
client.write replay_buffer, ()-> client.write replay_buffer, ()->
client.destroy() CLIENT_kick(client)
return return
return return
return return
...@@ -848,16 +1069,18 @@ net.createServer (client) -> ...@@ -848,16 +1069,18 @@ net.createServer (client) ->
if ctos_buffer.length >= 2 + ctos_message_length if ctos_buffer.length >= 2 + ctos_message_length
#console.log "CTOS", ygopro.constants.CTOS[ctos_proto] #console.log "CTOS", ygopro.constants.CTOS[ctos_proto]
cancel = false cancel = false
if ygopro.ctos_follows[ctos_proto] if settings.modules.reconnect.enabled and client.pre_reconnecting and ygopro.constants.CTOS[ctos_proto] != 'UPDATE_DECK'
cancel = true
if ygopro.ctos_follows[ctos_proto] and !cancel
b = ctos_buffer.slice(3, ctos_message_length - 1 + 3) b = ctos_buffer.slice(3, ctos_message_length - 1 + 3)
info = null info = null
if struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]] if struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]
struct._setBuff(b) struct._setBuff(b)
info = _.clone(struct.fields) info = _.clone(struct.fields)
if ygopro.ctos_follows[ctos_proto].synchronous if ygopro.ctos_follows[ctos_proto].synchronous
cancel = ygopro.ctos_follows[ctos_proto].callback b, info, client, server cancel = ygopro.ctos_follows[ctos_proto].callback b, info, client, client.server
else else
ygopro.ctos_follows[ctos_proto].callback b, info, client, server ygopro.ctos_follows[ctos_proto].callback b, info, client, client.server
datas.push ctos_buffer.slice(0, 2 + ctos_message_length) unless cancel datas.push ctos_buffer.slice(0, 2 + ctos_message_length) unless cancel
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length) ctos_buffer = ctos_buffer.slice(2 + ctos_message_length)
ctos_message_length = 0 ctos_message_length = 0
...@@ -875,11 +1098,12 @@ net.createServer (client) -> ...@@ -875,11 +1098,12 @@ net.createServer (client) ->
ROOM_bad_ip[client.ip] = bad_ip_count + 1 ROOM_bad_ip[client.ip] = bad_ip_count + 1
else else
ROOM_bad_ip[client.ip] = 1 ROOM_bad_ip[client.ip] = 1
client.destroy() CLIENT_kick(client)
break break
if !client.server
return
if client.established if client.established
server.write buffer for buffer in datas client.server.write buffer for buffer in datas
else else
client.pre_establish_buffers.push buffer for buffer in datas client.pre_establish_buffers.push buffer for buffer in datas
...@@ -893,7 +1117,7 @@ net.createServer (client) -> ...@@ -893,7 +1117,7 @@ net.createServer (client) ->
#stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学 #stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
#unless ygopro.stoc_follows[stoc_proto] and ygopro.stoc_follows[stoc_proto].synchronous #unless ygopro.stoc_follows[stoc_proto] and ygopro.stoc_follows[stoc_proto].synchronous
#client.write data #server.client.write data
datas = [] datas = []
looplimit = 0 looplimit = 0
...@@ -903,13 +1127,13 @@ net.createServer (client) -> ...@@ -903,13 +1127,13 @@ net.createServer (client) ->
if stoc_buffer.length >= 2 if stoc_buffer.length >= 2
stoc_message_length = stoc_buffer.readUInt16LE(0) stoc_message_length = stoc_buffer.readUInt16LE(0)
else else
log.warn("bad stoc_buffer length", client.ip) unless stoc_buffer.length == 0 log.warn("bad stoc_buffer length", server.client.ip) unless stoc_buffer.length == 0
break break
else if stoc_proto == 0 else if stoc_proto == 0
if stoc_buffer.length >= 3 if stoc_buffer.length >= 3
stoc_proto = stoc_buffer.readUInt8(2) stoc_proto = stoc_buffer.readUInt8(2)
else else
log.warn("bad stoc_proto length", client.ip) log.warn("bad stoc_proto length", server.client.ip)
break break
else else
if stoc_buffer.length >= 2 + stoc_message_length if stoc_buffer.length >= 2 + stoc_message_length
...@@ -923,24 +1147,25 @@ net.createServer (client) -> ...@@ -923,24 +1147,25 @@ net.createServer (client) ->
struct._setBuff(b) struct._setBuff(b)
info = _.clone(struct.fields) info = _.clone(struct.fields)
if ygopro.stoc_follows[stoc_proto].synchronous if ygopro.stoc_follows[stoc_proto].synchronous
cancel = ygopro.stoc_follows[stoc_proto].callback b, info, client, server cancel = ygopro.stoc_follows[stoc_proto].callback b, info, server.client, server
else else
ygopro.stoc_follows[stoc_proto].callback b, info, client, server ygopro.stoc_follows[stoc_proto].callback b, info, server.client, server
datas.push stoc_buffer.slice(0, 2 + stoc_message_length) unless cancel datas.push stoc_buffer.slice(0, 2 + stoc_message_length) unless cancel
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length) stoc_buffer = stoc_buffer.slice(2 + stoc_message_length)
stoc_message_length = 0 stoc_message_length = 0
stoc_proto = 0 stoc_proto = 0
else else
log.warn("bad stoc_message length", client.ip) log.warn("bad stoc_message length", server.client.ip)
break break
looplimit++ looplimit++
#log.info(looplimit) #log.info(looplimit)
if looplimit > 800 if looplimit > 800
log.info("error stoc", client.name) log.info("error stoc", server.client.name)
server.destroy() server.destroy()
break break
client.write buffer for buffer in datas if server.client and !server.client.closed
server.client.write buffer for buffer in datas
return return
return return
...@@ -991,7 +1216,10 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)-> ...@@ -991,7 +1216,10 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)->
ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
#log.info info #log.info info
info.pass=info.pass.trim() info.pass=info.pass.trim()
if settings.modules.stop if CLIENT_is_able_to_reconnect(client)
CLIENT_pre_reconnect(client)
return
else if settings.modules.stop
ygopro.stoc_die(client, settings.modules.stop) ygopro.stoc_die(client, settings.modules.stop)
else if info.pass.toUpperCase()=="R" and settings.modules.cloud_replay.enabled else if info.pass.toUpperCase()=="R" and settings.modules.cloud_replay.enabled
...@@ -1012,7 +1240,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -1012,7 +1240,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
msg: 1 msg: 1
code: 9 code: 9
} }
client.destroy() CLIENT_kick(client)
return), 500 return), 500
else if info.pass[0...2].toUpperCase()=="R#" and settings.modules.cloud_replay.enabled else if info.pass[0...2].toUpperCase()=="R#" and settings.modules.cloud_replay.enabled
...@@ -1040,7 +1268,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -1040,7 +1268,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
msg: 4 msg: 4
code: settings.version code: settings.version
} }
client.destroy() CLIENT_kick(client)
else if !info.pass.length and !settings.modules.random_duel.enabled and !settings.modules.windbot.enabled else if !info.pass.length and !settings.modules.random_duel.enabled and !settings.modules.windbot.enabled
ygopro.stoc_die(client, "${blank_room_name}") ygopro.stoc_die(client, "${blank_room_name}")
...@@ -1265,7 +1493,8 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -1265,7 +1493,8 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)->
#欢迎信息 #欢迎信息
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room return unless room and !client.reconnecting
client.join_game_buffer = buffer
if settings.modules.welcome if settings.modules.welcome
ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN) ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN)
if room.welcome if room.welcome
...@@ -1353,9 +1582,8 @@ if settings.modules.dialogues.get ...@@ -1353,9 +1582,8 @@ if settings.modules.dialogues.get
ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room return unless room and !client.reconnecting
msg = buffer.readInt8(0) msg = buffer.readInt8(0)
if settings.modules.retry_handle.enabled if settings.modules.retry_handle.enabled
if ygopro.constants.MSG[msg] == 'RETRY' if ygopro.constants.MSG[msg] == 'RETRY'
if !client.retry_count? if !client.retry_count?
...@@ -1365,7 +1593,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -1365,7 +1593,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
if settings.modules.retry_handle.max_retry_count and client.retry_count >= settings.modules.retry_handle.max_retry_count if settings.modules.retry_handle.max_retry_count and client.retry_count >= settings.modules.retry_handle.max_retry_count
ygopro.stoc_send_chat_to_room(room, client.name + "${retry_too_much_room_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_room_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, client.name + "${retry_too_much_room_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_room_part2}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${retry_too_much_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_part2}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${retry_too_much_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_part2}", ygopro.constants.COLORS.RED)
client.destroy() CLIENT_kick(client)
return true return true
if client.last_game_msg if client.last_game_msg
if settings.modules.retry_handle.max_retry_count if settings.modules.retry_handle.max_retry_count
...@@ -1376,6 +1604,10 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -1376,6 +1604,10 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
return true return true
else else
client.last_game_msg = buffer client.last_game_msg = buffer
client.last_game_msg_title = ygopro.constants.MSG[msg]
else if ygopro.constants.MSG[msg] != 'RETRY'
client.last_game_msg = buffer
client.last_game_msg_title = ygopro.constants.MSG[msg]
if (msg >= 10 and msg < 30) or msg == 132 or (msg >= 140 and msg < 144) #SELECT和ANNOUNCE开头的消息 if (msg >= 10 and msg < 30) or msg == 132 or (msg >= 140 and msg < 144) #SELECT和ANNOUNCE开头的消息
room.waiting_for_player = client room.waiting_for_player = client
...@@ -1388,6 +1620,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -1388,6 +1620,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
client.is_first = !(playertype & 0xf) client.is_first = !(playertype & 0xf)
client.lp = room.hostinfo.start_lp client.lp = room.hostinfo.start_lp
client.card_count = 0 if room.hostinfo.mode != 2 client.card_count = 0 if room.hostinfo.mode != 2
room.selecting_tp = false
if client.pos == 0 if client.pos == 0
room.turn = 0 room.turn = 0
room.duel_count = room.duel_count + 1 room.duel_count = room.duel_count + 1
...@@ -1415,8 +1648,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -1415,8 +1648,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END')
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1 room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1
room.dueling_players[oppo_pos - win_pos].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
room.dueling_players[oppo_pos - win_pos + 1].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1])
else else
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER') ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
else else
...@@ -1439,8 +1672,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -1439,8 +1672,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END')
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1 room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1
room.dueling_players[oppo_pos - win_pos].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
room.dueling_players[oppo_pos - win_pos + 1].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1])
else else
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER') ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
else else
...@@ -1549,13 +1782,13 @@ ygopro.ctos_follow 'HS_KICK', true, (buffer, info, client, server)-> ...@@ -1549,13 +1782,13 @@ ygopro.ctos_follow 'HS_KICK', true, (buffer, info, client, server)->
if player and player.pos == info.pos and player != client if player and player.pos == info.pos and player != client
if room.arena == "athletic" if room.arena == "athletic"
ygopro.stoc_send_chat_to_room(room, "#{client.name} ${kicked_by_system}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{client.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
client.destroy() CLIENT_kick(client)
return true return true
client.kick_count = if client.kick_count then client.kick_count+1 else 1 client.kick_count = if client.kick_count then client.kick_count+1 else 1
if client.kick_count>=5 and room.random_type if client.kick_count>=5 and room.random_type
ygopro.stoc_send_chat_to_room(room, "#{client.name} ${kicked_by_system}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{client.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}") ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}")
client.destroy() CLIENT_kick(client)
return true return true
ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_player}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_player}", ygopro.constants.COLORS.RED)
return false return false
...@@ -1614,6 +1847,17 @@ ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)-> ...@@ -1614,6 +1847,17 @@ ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
setTimeout (()-> wait_room_start(ROOM_all[client.rid], 20);return), 1000 setTimeout (()-> wait_room_start(ROOM_all[client.rid], 20);return), 1000
return return
ygopro.stoc_follow 'FIELD_FINISH', true, (buffer, info, client, server)->
room=ROOM_all[client.rid]
return unless room
client.reconnecting = false
if client.last_game_msg and client.last_game_msg_title != 'WAITING'
setTimeout( () ->
ygopro.stoc_send(client, 'GAME_MSG', client.last_game_msg)
return
, 1000)
return true
wait_room_start = (room, time)-> wait_room_start = (room, time)->
unless !room or room.started or room.ready_player_count_without_host < room.max_player - 1 unless !room or room.started or room.ready_player_count_without_host < room.max_player - 1
time -= 1 time -= 1
...@@ -1626,7 +1870,7 @@ wait_room_start = (room, time)-> ...@@ -1626,7 +1870,7 @@ wait_room_start = (room, time)->
if player and player.is_host if player and player.is_host
ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}") ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}")
ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
player.destroy() CLIENT_kick(player)
return return
wait_room_start_arena = (room)-> wait_room_start_arena = (room)->
...@@ -1637,7 +1881,7 @@ wait_room_start_arena = (room)-> ...@@ -1637,7 +1881,7 @@ wait_room_start_arena = (room)->
ygopro.stoc_send_chat_to_room(room, "#{if room.waiting_for_player_time <= 9 then ' ' else ''}#{room.waiting_for_player_time}${kick_count_down_arena_part1} #{room.waiting_for_player.name} ${kick_count_down_arena_part2}", if room.waiting_for_player_time <= 9 then ygopro.constants.COLORS.RED else ygopro.constants.COLORS.LIGHTBLUE) ygopro.stoc_send_chat_to_room(room, "#{if room.waiting_for_player_time <= 9 then ' ' else ''}#{room.waiting_for_player_time}${kick_count_down_arena_part1} #{room.waiting_for_player.name} ${kick_count_down_arena_part2}", if room.waiting_for_player_time <= 9 then ygopro.constants.COLORS.RED else ygopro.constants.COLORS.LIGHTBLUE)
else else
ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
room.waiting_for_player.destroy() CLIENT_kick(room.waiting_for_player)
if room.waiting_for_player_interval if room.waiting_for_player_interval
clearInterval room.waiting_for_player_interval clearInterval room.waiting_for_player_interval
room.waiting_for_player_interval = null room.waiting_for_player_interval = null
...@@ -1678,10 +1922,11 @@ if settings.modules.tips.get ...@@ -1678,10 +1922,11 @@ if settings.modules.tips.get
ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)-> ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room return unless room and !client.reconnecting
unless room.started #first start unless room.started #first start
room.started = true room.started = true
room.start_time = moment().format() room.start_time = moment().format()
room.turn = 0
roomlist.start room if !room.windbot and settings.modules.http.websocket_roomlist roomlist.start room if !room.windbot and settings.modules.http.websocket_roomlist
#room.duels = [] #room.duels = []
room.dueling_players = [] room.dueling_players = []
...@@ -1811,7 +2056,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)-> ...@@ -1811,7 +2056,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
when '/color' when '/color'
if settings.modules.chat_color.enabled if settings.modules.chat_color.enabled
cip = if settings.modules.mycard.enabled then client.name else client.ip cip = CLIENT_get_authorize_key(client)
if cmsg = cmd[1] if cmsg = cmd[1]
if cmsg.toLowerCase() == "help" if cmsg.toLowerCase() == "help"
ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE)
...@@ -1860,7 +2105,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)-> ...@@ -1860,7 +2105,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
ygopro.stoc_send_chat(client, "${banned_duel_tip}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${banned_duel_tip}", ygopro.constants.COLORS.RED)
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}") ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}")
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}", 3) ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}", 3)
client.destroy() CLIENT_kick(client)
return true return true
else else
client.abuse_count=client.abuse_count+4 client.abuse_count=client.abuse_count+4
...@@ -1916,6 +2161,19 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)-> ...@@ -1916,6 +2161,19 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
return cancel return cancel
ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)-> ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)->
if settings.modules.reconnect.enabled and client.pre_reconnecting
if _.isEqual(buffer, client.pre_deckbuf)
CLIENT_reconnect(client)
else
ygopro.stoc_send_chat(client, "${deck_incorrect_reconnect}", ygopro.constants.COLORS.RED)
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 2,
code: 0
})
ygopro.stoc_send(client, 'HS_PLAYER_CHANGE', {
status: (client.pos << 4) | 0xa
})
return true
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return false unless room return false unless room
#log.info info #log.info info
...@@ -1923,10 +2181,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)-> ...@@ -1923,10 +2181,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)->
buff_side = (info.deckbuf[i] for i in [info.mainc...info.mainc + info.sidec]) buff_side = (info.deckbuf[i] for i in [info.mainc...info.mainc + info.sidec])
client.main = buff_main client.main = buff_main
client.side = buff_side client.side = buff_side
if client.side_tcount if room.started
clearInterval client.side_interval client.selected_preduel = true
client.side_interval = null if client.side_tcount
client.side_tcount = null clearInterval client.side_interval
client.side_interval = null
client.side_tcount = null
else
client.start_deckbuf = buffer
oppo_pos = if room.hostinfo.mode == 2 then 2 else 1 oppo_pos = if room.hostinfo.mode == 2 then 2 else 1
if settings.modules.http.quick_death_rule >= 2 and room.started and room.death and room.scores[room.dueling_players[0].name] != room.scores[room.dueling_players[oppo_pos].name] if settings.modules.http.quick_death_rule >= 2 and room.started and room.death and room.scores[room.dueling_players[0].name] != room.scores[room.dueling_players[oppo_pos].name]
win_pos = if room.scores[room.dueling_players[0].name] > room.scores[room.dueling_players[oppo_pos].name] then 0 else oppo_pos win_pos = if room.scores[room.dueling_players[0].name] > room.scores[room.dueling_players[oppo_pos].name] then 0 else oppo_pos
...@@ -1934,8 +2196,8 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)-> ...@@ -1934,8 +2196,8 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)->
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') if room.hostinfo.mode == 2 ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') if room.hostinfo.mode == 2
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1 room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1
room.dueling_players[oppo_pos - win_pos].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
room.dueling_players[oppo_pos - win_pos + 1].destroy() if room.hostinfo.mode == 2 CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2
return true return true
if room.random_type or room.arena if room.random_type or room.arena
if client.pos == 0 if client.pos == 0
...@@ -1990,7 +2252,9 @@ ygopro.ctos_follow 'RESPONSE', false, (buffer, info, client, server)-> ...@@ -1990,7 +2252,9 @@ ygopro.ctos_follow 'RESPONSE', false, (buffer, info, client, server)->
ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server)-> ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room and (room.random_type or room.arena) return unless room
client.selected_preduel = true
return unless room.random_type or room.arena
if client.pos == 0 if client.pos == 0
room.waiting_for_player = room.waiting_for_player2 room.waiting_for_player = room.waiting_for_player2
room.last_active_time = moment().subtract(settings.modules.random_duel.hang_timeout - 19, 's') room.last_active_time = moment().subtract(settings.modules.random_duel.hang_timeout - 19, 's')
...@@ -1998,7 +2262,10 @@ ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server)-> ...@@ -1998,7 +2262,10 @@ ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server)->
ygopro.ctos_follow 'TP_RESULT', false, (buffer, info, client, server)-> ygopro.ctos_follow 'TP_RESULT', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room and (room.random_type or room.arena) return unless room
client.selected_preduel = true
room.selecting_tp = false
return unless room.random_type or room.arena
room.last_active_time = moment() room.last_active_time = moment()
return return
...@@ -2030,7 +2297,12 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server)-> ...@@ -2030,7 +2297,12 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server)->
ygopro.stoc_follow 'SELECT_HAND', false, (buffer, info, client, server)-> ygopro.stoc_follow 'SELECT_HAND', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room and (room.random_type or room.arena) return unless room
client.selected_preduel = false
if client.pos == 0
room.selecting_hand = true
room.changing_side = false
return unless room.random_type or room.arena
if client.pos == 0 if client.pos == 0
room.waiting_for_player = client room.waiting_for_player = client
else else
...@@ -2041,7 +2313,10 @@ ygopro.stoc_follow 'SELECT_HAND', false, (buffer, info, client, server)-> ...@@ -2041,7 +2313,10 @@ ygopro.stoc_follow 'SELECT_HAND', false, (buffer, info, client, server)->
ygopro.stoc_follow 'SELECT_TP', false, (buffer, info, client, server)-> ygopro.stoc_follow 'SELECT_TP', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room return unless room
client.selected_preduel = false
room.changing_side = false room.changing_side = false
room.selecting_hand = false
room.selecting_tp = client
if room.random_type or room.arena if room.random_type or room.arena
room.waiting_for_player = client room.waiting_for_player = client
room.last_active_time = moment() room.last_active_time = moment()
...@@ -2051,6 +2326,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)-> ...@@ -2051,6 +2326,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room return unless room
room.changing_side = true room.changing_side = true
client.selected_preduel = false
if settings.modules.side_timeout if settings.modules.side_timeout
client.side_tcount = settings.modules.side_timeout client.side_tcount = settings.modules.side_timeout
ygopro.stoc_send_chat(client, "${side_timeout_part1}#{settings.modules.side_timeout}${side_timeout_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${side_timeout_part1}#{settings.modules.side_timeout}${side_timeout_part2}", ygopro.constants.COLORS.BABYBLUE)
...@@ -2062,7 +2338,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)-> ...@@ -2062,7 +2338,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)->
ygopro.stoc_send_chat_to_room(room, client.name + "${side_overtime_room}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, client.name + "${side_overtime_room}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${side_overtime}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${side_overtime}", ygopro.constants.COLORS.RED)
room.scores[client.name] = -9 room.scores[client.name] = -9
client.destroy() CLIENT_kick(client)
clearInterval sinterval clearInterval sinterval
else else
client.side_tcount = client.side_tcount - 1 client.side_tcount = client.side_tcount - 1
...@@ -2366,8 +2642,8 @@ if settings.modules.http ...@@ -2366,8 +2642,8 @@ if settings.modules.http
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END') ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') if room.hostinfo.mode == 2 ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END') if room.hostinfo.mode == 2
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1 room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1
room.dueling_players[oppo_pos - win_pos].destroy() CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
room.dueling_players[oppo_pos - win_pos + 1].destroy() if room.hostinfo.mode == 2 CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2
when 1 when 1
room.death = -1 room.death = -1
ygopro.stoc_send_chat_to_room(room, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE)
......
// Generated by CoffeeScript 1.12.7 // Generated by CoffeeScript 1.12.7
(function() { (function() {
var Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_connected_ip, ROOM_find_by_name, 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_players_banned, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, Room, _, addCallback, badwords, ban_user, bunyan, chat_color, config, cppversion, crypto, date, default_config, default_data, dialogues, duel_log, e, exec, execFile, fs, geoip, get_memory_usage, http, http_server, https, https_server, j, k, len, len1, lflists, list, loadJSON, load_dialogues, load_tips, log, memory_usage, merge, moment, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, ref, ref1, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, tips, url, users_cache, wait_room_start, wait_room_start_arena, windbot_bin, windbot_parameters, windbot_process, windbots, ygopro, zlib; var CLIENT_get_authorize_key, CLIENT_import_data, CLIENT_is_able_to_reconnect, CLIENT_is_player, CLIENT_kick, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_connected_ip, ROOM_find_by_name, 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_players_banned, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, Room, SERVER_clear_disconnect, _, addCallback, badwords, ban_user, bunyan, chat_color, config, cppversion, crypto, date, default_config, default_data, dialogues, disconnect_list, duel_log, e, exec, execFile, fs, geoip, get_memory_usage, http, http_server, https, https_server, j, l, len, len1, lflists, list, loadJSON, load_dialogues, load_tips, log, memory_usage, merge, moment, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, ref, ref1, release_disconnect, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, tips, url, users_cache, wait_room_start, wait_room_start_arena, windbot_bin, windbot_parameters, windbot_process, windbots, ygopro, zlib;
net = require('net'); net = require('net');
...@@ -235,8 +235,8 @@ ...@@ -235,8 +235,8 @@
try { try {
ref1 = fs.readFileSync('ygopro/lflist.conf', 'utf8').match(/!.*/g); ref1 = fs.readFileSync('ygopro/lflist.conf', 'utf8').match(/!.*/g);
for (k = 0, len1 = ref1.length; k < len1; k++) { for (l = 0, len1 = ref1.length; l < len1; l++) {
list = ref1[k]; list = ref1[l];
date = list.match(/!([\d\.]+)/); date = list.match(/!([\d\.]+)/);
if (!date) { if (!date) {
continue; continue;
...@@ -341,22 +341,22 @@ ...@@ -341,22 +341,22 @@
ROOM_bad_ip = {}; ROOM_bad_ip = {};
ban_user = function(name) { ban_user = function(name) {
var bad_ip, l, len2, len3, m, player, ref2, room; var bad_ip, len2, len3, m, n, player, ref2, room;
settings.ban.banned_user.push(name); settings.ban.banned_user.push(name);
setting_save(settings); setting_save(settings);
bad_ip = 0; bad_ip = 0;
for (l = 0, len2 = ROOM_all.length; l < len2; l++) { for (m = 0, len2 = ROOM_all.length; m < len2; m++) {
room = ROOM_all[l]; room = ROOM_all[m];
if (room && room.established) { if (room && room.established) {
ref2 = room.players; ref2 = room.players;
for (m = 0, len3 = ref2.length; m < len3; m++) { for (n = 0, len3 = ref2.length; n < len3; n++) {
player = ref2[m]; player = ref2[n];
if (player && (player.name === name || player.ip === bad_ip)) { if (player && (player.name === name || player.ip === bad_ip)) {
bad_ip = player.ip; bad_ip = player.ip;
ROOM_bad_ip[bad_ip] = 99; ROOM_bad_ip[bad_ip] = 99;
settings.ban.banned_ip.push(player.ip); settings.ban.banned_ip.push(player.ip);
ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED);
player.destroy(); CLIENT_kick(player);
continue; continue;
} }
} }
...@@ -546,13 +546,13 @@ ...@@ -546,13 +546,13 @@
}; };
ROOM_unwelcome = function(room, bad_player, reason) { ROOM_unwelcome = function(room, bad_player, reason) {
var l, len2, player, ref2; var len2, m, player, ref2;
if (!room) { if (!room) {
return; return;
} }
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player && player === bad_player) { if (player && player === bad_player) {
ygopro.stoc_send_chat(player, "${unwelcome_warn_part1}" + reason + "${unwelcome_warn_part2}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(player, "${unwelcome_warn_part1}" + reason + "${unwelcome_warn_part2}", ygopro.constants.COLORS.RED);
} else if (player && player.pos !== 7 && player !== bad_player) { } else if (player && player.pos !== 7 && player !== bad_player) {
...@@ -562,6 +562,249 @@ ...@@ -562,6 +562,249 @@
} }
}; };
CLIENT_kick = function(client) {
client.system_kicked = true;
client.destroy();
};
release_disconnect = function(dinfo, reconnected) {
if (dinfo.old_client && !reconnected) {
dinfo.old_client.destroy();
}
if (dinfo.old_server && !reconnected) {
dinfo.old_server.destroy();
}
clearTimeout(dinfo.timeout);
};
CLIENT_get_authorize_key = function(client) {
if (settings.modules.mycard.enabled || client.is_local) {
return client.name;
} else {
return client.ip;
}
};
CLIENT_reconnect_unregister = function(client, reconnected) {
if (!settings.modules.reconnect.enabled) {
return false;
}
if (disconnect_list[CLIENT_get_authorize_key(client)]) {
release_disconnect(disconnect_list[CLIENT_get_authorize_key(client)], reconnected);
delete disconnect_list[CLIENT_get_authorize_key(client)];
return true;
}
return false;
};
CLIENT_reconnect_register = function(client, room, error) {
var dinfo, old_dinfo, tmot;
if (client.had_new_reconnection) {
return false;
}
if (!settings.modules.reconnect.enabled || client.system_kicked || client.is_post_watcher || !CLIENT_is_player(client, room) || !room.started || (room.windbot && client.is_local)) {
return false;
}
old_dinfo = disconnect_list[CLIENT_get_authorize_key(client)];
if (old_dinfo) {
old_dinfo.room.disconnect(old_dinfo.old_client);
}
dinfo = {
room: room,
old_client: client,
old_server: client.server,
deckbuf: client.start_deckbuf
};
tmot = setTimeout(function() {
room.disconnect(client, error);
dinfo.old_server.destroy();
}, settings.modules.reconnect.wait_time);
dinfo.timeout = tmot;
disconnect_list[CLIENT_get_authorize_key(client)] = dinfo;
return true;
};
CLIENT_import_data = function(client, old_client, room) {
var index, len2, m, player, ref2;
ref2 = room.players;
for (index = m = 0, len2 = ref2.length; m < len2; index = ++m) {
player = ref2[index];
if (player === old_client) {
room.players[index] = client;
break;
}
}
room.dueling_players[old_client.pos] = client;
if (room.waiting_for_player = old_client) {
room.waiting_for_player = client;
}
if (room.waiting_for_player2 = old_client) {
room.waiting_for_player2 = client;
}
if (room.selecting_tp = old_client) {
room.selecting_tp = client;
}
client.abuse_count = old_client.abuse_count;
client.rag = old_client.rag;
client.rid = old_client.rid;
client.is_post_watcher = old_client.is_post_watcher;
client.retry_count = old_client.retry_count;
client.name = old_client.name;
client.is_first = old_client.is_first;
client.lp = old_client.lp;
client.card_count = old_client.card_count;
client.is_host = old_client.is_host;
client.pos = old_client.pos;
client.surrend_confirm = old_client.surrend_confirm;
client.kick_count = old_client.kick_count;
client.deck_saved = old_client.deck_saved;
client.main = old_client.main;
client.side = old_client.side;
client.side_interval = old_client.side_interval;
client.side_tcount = old_client.side_tcount;
client.selected_preduel = old_client.selected_preduel;
client.last_game_msg = old_client.last_game_msg;
client.last_game_msg_title = old_client.last_game_msg_title;
client.start_deckbuf = old_client.start_deckbuf;
client.join_game_buffer = old_client.join_game_buffer;
old_client.had_new_reconnection = true;
};
SERVER_clear_disconnect = function(server) {
var k, v;
if (!settings.modules.reconnect.enabled) {
return;
}
for (k in disconnect_list) {
v = disconnect_list[k];
if (v && server === v.old_server) {
release_disconnect(v);
delete disconnect_list[k];
return;
}
}
};
CLIENT_is_player = function(client, room) {
var is_player, len2, m, player, ref2;
is_player = false;
ref2 = room.players;
for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[m];
if (client === player) {
is_player = true;
break;
}
}
return is_player;
};
CLIENT_is_able_to_reconnect = function(client) {
var disconnect_info;
if (!settings.modules.reconnect.enabled) {
return false;
}
if (client.system_kicked) {
return false;
}
disconnect_info = disconnect_list[CLIENT_get_authorize_key(client)];
if (!disconnect_info) {
return false;
}
return true;
};
CLIENT_send_pre_reconnect_info = function(client, room, old_client) {
var len2, m, player, ref2, req_pos, results;
ygopro.stoc_send_chat(client, "${pre_reconnecting_to_room}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send(client, 'JOIN_GAME', old_client.join_game_buffer);
req_pos = old_client.pos;
if (old_client.is_host) {
req_pos += 0x10;
}
ygopro.stoc_send(client, 'TYPE_CHANGE', {
type: req_pos
});
ref2 = room.players;
results = [];
for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[m];
results.push(ygopro.stoc_send(client, 'HS_PLAYER_ENTER', {
name: player.name,
pos: player.pos
}));
}
return results;
};
CLIENT_send_reconnect_info = function(client, server, room) {
client.reconnecting = true;
ygopro.stoc_send_chat(client, "${reconnecting_to_room}", ygopro.constants.COLORS.BABYBLUE);
if (room.turn && room.turn > 0) {
ygopro.ctos_send(server, 'REQUEST_FIELD');
} else if (room.changing_side) {
ygopro.stoc_send(client, 'DUEL_START');
if (!client.selected_preduel) {
ygopro.stoc_send(client, 'CHANGE_SIDE');
}
client.reconnecting = false;
} else if (room.selecting_hand) {
ygopro.stoc_send(client, 'DUEL_START');
if ((room.hostinfo.mode !== 2 || client.pos === 0 || client.pos === 2) && !client.selected_preduel) {
ygopro.stoc_send(client, 'SELECT_HAND');
}
client.reconnecting = false;
} else if (room.selecting_tp) {
ygopro.stoc_send(client, 'DUEL_START');
if (client === room.selecting_tp && !client.selected_preduel) {
ygopro.stoc_send(client, 'SELECT_TP');
}
client.reconnecting = false;
} else {
ygopro.ctos_send(server, 'REQUEST_FIELD');
}
};
CLIENT_pre_reconnect = function(client) {
var dinfo;
if (!CLIENT_is_able_to_reconnect(client)) {
return;
}
dinfo = disconnect_list[CLIENT_get_authorize_key(client)];
client.pre_deckbuf = dinfo.deckbuf;
client.pre_reconnecting = true;
client.pos = dinfo.old_client.pos;
return CLIENT_send_pre_reconnect_info(client, dinfo.room, dinfo.old_client);
};
CLIENT_reconnect = function(client) {
var current_old_server, dinfo;
if (!CLIENT_is_able_to_reconnect(client)) {
ygopro.stoc_send_chat(client, "${reconnect_failed}", ygopro.constants.COLORS.RED);
CLIENT_kick(client);
return;
}
client.pre_reconnecting = false;
dinfo = disconnect_list[CLIENT_get_authorize_key(client)];
current_old_server = client.server;
client.server = dinfo.old_server;
client.server.client = client;
dinfo.old_client.server = null;
current_old_server.client = null;
current_old_server.had_new_reconnection = true;
current_old_server.destroy();
client.established = true;
client.pre_establish_buffers = [];
client.setTimeout(300000);
CLIENT_import_data(client, dinfo.old_client, dinfo.room);
CLIENT_send_reconnect_info(client, client.server, dinfo.room);
CLIENT_reconnect_unregister(client, true);
};
if (settings.modules.reconnect.enabled) {
disconnect_list = {};
}
Room = (function() { Room = (function() {
function Room(name, hostinfo) { function Room(name, hostinfo) {
var draw_count, lflist, param, rule, start_hand, start_lp, time_limit; var draw_count, lflist, param, rule, start_hand, start_lp, time_limit;
...@@ -582,8 +825,10 @@ ...@@ -582,8 +825,10 @@
this.scores = {}; this.scores = {};
this.duel_count = 0; this.duel_count = 0;
this.death = 0; this.death = 0;
this.turn = 0;
ROOM_all.push(this); ROOM_all.push(this);
this.hostinfo || (this.hostinfo = JSON.parse(JSON.stringify(settings.hostinfo))); this.hostinfo || (this.hostinfo = JSON.parse(JSON.stringify(settings.hostinfo)));
delete this.hostinfo.comment;
if (lflists.length) { if (lflists.length) {
if (this.hostinfo.rule === 1 && this.hostinfo.lflist === 0) { if (this.hostinfo.rule === 1 && this.hostinfo.lflist === 0) {
this.hostinfo.lflist = _.findIndex(lflists, function(list) { this.hostinfo.lflist = _.findIndex(lflists, function(list) {
...@@ -723,10 +968,10 @@ ...@@ -723,10 +968,10 @@
_this.port = parseInt(data); _this.port = parseInt(data);
_.each(_this.players, function(player) { _.each(_this.players, function(player) {
player.server.connect(_this.port, '127.0.0.1', function() { player.server.connect(_this.port, '127.0.0.1', function() {
var buffer, l, len2, ref2; var buffer, len2, m, ref2;
ref2 = player.pre_establish_buffers; ref2 = player.pre_establish_buffers;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
buffer = ref2[l]; buffer = ref2[m];
player.server.write(buffer); player.server.write(buffer);
} }
player.established = true; player.established = true;
...@@ -908,10 +1153,10 @@ ...@@ -908,10 +1153,10 @@
roomlist.update(this); roomlist.update(this);
} }
client.server.connect(this.port, '127.0.0.1', function() { client.server.connect(this.port, '127.0.0.1', function() {
var buffer, l, len2, ref2; var buffer, len2, m, ref2;
ref2 = client.pre_establish_buffers; ref2 = client.pre_establish_buffers;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
buffer = ref2[l]; buffer = ref2[m];
client.server.write(buffer); client.server.write(buffer);
} }
client.established = true; client.established = true;
...@@ -921,18 +1166,22 @@ ...@@ -921,18 +1166,22 @@
}; };
Room.prototype.disconnect = function(client, error) { Room.prototype.disconnect = function(client, error) {
var index, l, len2, player, ref2; var index, len2, m, player, ref2;
if (client.had_new_reconnection) {
return;
}
if (client.is_post_watcher) { if (client.is_post_watcher) {
ygopro.stoc_send_chat_to_room(this, (client.name + " ${quit_watch}") + (error ? ": " + error : '')); ygopro.stoc_send_chat_to_room(this, (client.name + " ${quit_watch}") + (error ? ": " + error : ''));
index = _.indexOf(this.watchers, client); index = _.indexOf(this.watchers, client);
if (index !== -1) { if (index !== -1) {
this.watchers.splice(index, 1); this.watchers.splice(index, 1);
} }
client.server.destroy();
} else { } else {
if (this.arena === "athletic" && !this.started && this.players.length === 2) { if (this.arena === "athletic" && !this.started && this.players.length === 2) {
ref2 = this.players; ref2 = this.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player.pos !== 7) { if (player.pos !== 7) {
this.scores[player.name] = 0; this.scores[player.name] = 0;
} }
...@@ -959,6 +1208,9 @@ ...@@ -959,6 +1208,9 @@
this.process.kill(); this.process.kill();
this["delete"](); this["delete"]();
} }
if (!CLIENT_reconnect_unregister(client)) {
client.server.destroy();
}
} }
}; };
...@@ -977,6 +1229,7 @@ ...@@ -977,6 +1229,7 @@
ROOM_connected_ip[client.ip] = connect_count; ROOM_connected_ip[client.ip] = connect_count;
server = new net.Socket(); server = new net.Socket();
client.server = server; client.server = server;
server.client = client;
client.setTimeout(2000); client.setTimeout(2000);
client.on('close', function(had_error) { client.on('close', function(had_error) {
var room; var room;
...@@ -989,10 +1242,13 @@ ...@@ -989,10 +1242,13 @@
if (!client.closed) { if (!client.closed) {
client.closed = true; client.closed = true;
if (room) { if (room) {
room.disconnect(client); if (!CLIENT_reconnect_register(client, room)) {
room.disconnect(client);
}
} else if (!client.had_new_reconnection) {
client.server.destroy();
} }
} }
server.destroy();
}); });
client.on('error', function(error) { client.on('error', function(error) {
var room; var room;
...@@ -1003,45 +1259,61 @@ ...@@ -1003,45 +1259,61 @@
} }
ROOM_connected_ip[client.ip] = connect_count; ROOM_connected_ip[client.ip] = connect_count;
if (!client.closed) { if (!client.closed) {
client.closed = error; client.closed = true;
if (room) { if (room) {
room.disconnect(client, error); if (!CLIENT_reconnect_register(client, room, error)) {
room.disconnect(client, error);
}
} else if (!client.had_new_reconnection) {
client.server.destroy();
} }
} }
server.destroy();
}); });
client.on('timeout', function() { client.on('timeout', function() {
server.destroy(); if (!client.server) {
return;
}
if (!(settings.modules.reconnect.enabled && (disconnect_list[CLIENT_get_authorize_key(client)] || client.had_new_reconnection))) {
client.server.destroy();
}
}); });
server.on('close', function(had_error) { server.on('close', function(had_error) {
var room; var room;
room = ROOM_all[client.rid]; room = ROOM_all[server.client.rid];
if (room) { if (room) {
room.disconnector = 'server'; room.disconnector = 'server';
} }
if (!server.closed) { if (!server.closed) {
server.closed = true; server.closed = true;
} }
if (!client.closed) { if (!server.client) {
ygopro.stoc_send_chat(client, "${server_closed}", ygopro.constants.COLORS.RED); return;
client.destroy(); }
if (!server.client.closed) {
ygopro.stoc_send_chat(server.client, "${server_closed}", ygopro.constants.COLORS.RED);
CLIENT_kick(server.client);
SERVER_clear_disconnect(server);
} }
}); });
server.on('error', function(error) { server.on('error', function(error) {
var room; var room;
room = ROOM_all[client.rid]; room = ROOM_all[server.client.rid];
if (room) { if (room) {
room.disconnector = 'server'; room.disconnector = 'server';
} }
server.closed = error; server.closed = error;
if (!client.closed) { if (!server.client) {
ygopro.stoc_send_chat(client, "${server_error}: " + error, ygopro.constants.COLORS.RED); return;
client.destroy(); }
if (!server.client.closed) {
ygopro.stoc_send_chat(server.client, "${server_error}: " + error, ygopro.constants.COLORS.RED);
CLIENT_kick(server.client);
SERVER_clear_disconnect(server);
} }
}); });
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.destroy(); CLIENT_kick(client);
return; return;
} }
if (settings.modules.cloud_replay.enabled) { if (settings.modules.cloud_replay.enabled) {
...@@ -1057,19 +1329,19 @@ ...@@ -1057,19 +1329,19 @@
if (err) { if (err) {
log.info("cloud replay unzip error: " + err); log.info("cloud replay unzip error: " + err);
ygopro.stoc_send_chat(client, "${cloud_replay_error}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${cloud_replay_error}", ygopro.constants.COLORS.RED);
client.destroy(); CLIENT_kick(client);
return; return;
} }
ygopro.stoc_send_chat(client, "${cloud_replay_playing} R#" + replay.replay_id + " " + replay.player_names + " " + replay.date_time, ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${cloud_replay_playing} R#" + replay.replay_id + " " + replay.player_names + " " + replay.date_time, ygopro.constants.COLORS.BABYBLUE);
client.write(replay_buffer, function() { client.write(replay_buffer, function() {
client.destroy(); CLIENT_kick(client);
}); });
}); });
}; };
} }
client.pre_establish_buffers = new Array(); client.pre_establish_buffers = new Array();
client.on('data', function(ctos_buffer) { client.on('data', function(ctos_buffer) {
var b, bad_ip_count, buffer, cancel, ctos_message_length, ctos_proto, datas, info, l, len2, len3, looplimit, m, room, struct; var b, bad_ip_count, buffer, cancel, ctos_message_length, ctos_proto, datas, info, len2, len3, looplimit, m, n, room, struct;
if (client.is_post_watcher) { if (client.is_post_watcher) {
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (room) { if (room) {
...@@ -1100,7 +1372,10 @@ ...@@ -1100,7 +1372,10 @@
} else { } else {
if (ctos_buffer.length >= 2 + ctos_message_length) { if (ctos_buffer.length >= 2 + ctos_message_length) {
cancel = false; cancel = false;
if (ygopro.ctos_follows[ctos_proto]) { if (settings.modules.reconnect.enabled && client.pre_reconnecting && ygopro.constants.CTOS[ctos_proto] !== 'UPDATE_DECK') {
cancel = true;
}
if (ygopro.ctos_follows[ctos_proto] && !cancel) {
b = ctos_buffer.slice(3, ctos_message_length - 1 + 3); b = ctos_buffer.slice(3, ctos_message_length - 1 + 3);
info = null; info = null;
if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]) { if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]) {
...@@ -1108,9 +1383,9 @@ ...@@ -1108,9 +1383,9 @@
info = _.clone(struct.fields); info = _.clone(struct.fields);
} }
if (ygopro.ctos_follows[ctos_proto].synchronous) { if (ygopro.ctos_follows[ctos_proto].synchronous) {
cancel = ygopro.ctos_follows[ctos_proto].callback(b, info, client, server); cancel = ygopro.ctos_follows[ctos_proto].callback(b, info, client, client.server);
} else { } else {
ygopro.ctos_follows[ctos_proto].callback(b, info, client, server); ygopro.ctos_follows[ctos_proto].callback(b, info, client, client.server);
} }
} }
if (!cancel) { if (!cancel) {
...@@ -1135,25 +1410,28 @@ ...@@ -1135,25 +1410,28 @@
} else { } else {
ROOM_bad_ip[client.ip] = 1; ROOM_bad_ip[client.ip] = 1;
} }
client.destroy(); CLIENT_kick(client);
break; break;
} }
} }
if (!client.server) {
return;
}
if (client.established) { if (client.established) {
for (l = 0, len2 = datas.length; l < len2; l++) { for (m = 0, len2 = datas.length; m < len2; m++) {
buffer = datas[l]; buffer = datas[m];
server.write(buffer); client.server.write(buffer);
} }
} else { } else {
for (m = 0, len3 = datas.length; m < len3; m++) { for (n = 0, len3 = datas.length; n < len3; n++) {
buffer = datas[m]; buffer = datas[n];
client.pre_establish_buffers.push(buffer); client.pre_establish_buffers.push(buffer);
} }
} }
} }
}); });
server.on('data', function(stoc_buffer) { server.on('data', function(stoc_buffer) {
var b, buffer, cancel, datas, info, l, len2, looplimit, stanzas, stoc_message_length, stoc_proto, struct; var b, buffer, cancel, datas, info, len2, looplimit, m, stanzas, stoc_message_length, stoc_proto, struct;
stoc_message_length = 0; stoc_message_length = 0;
stoc_proto = 0; stoc_proto = 0;
datas = []; datas = [];
...@@ -1164,7 +1442,7 @@ ...@@ -1164,7 +1442,7 @@
stoc_message_length = stoc_buffer.readUInt16LE(0); stoc_message_length = stoc_buffer.readUInt16LE(0);
} else { } else {
if (stoc_buffer.length !== 0) { if (stoc_buffer.length !== 0) {
log.warn("bad stoc_buffer length", client.ip); log.warn("bad stoc_buffer length", server.client.ip);
} }
break; break;
} }
...@@ -1172,7 +1450,7 @@ ...@@ -1172,7 +1450,7 @@
if (stoc_buffer.length >= 3) { if (stoc_buffer.length >= 3) {
stoc_proto = stoc_buffer.readUInt8(2); stoc_proto = stoc_buffer.readUInt8(2);
} else { } else {
log.warn("bad stoc_proto length", client.ip); log.warn("bad stoc_proto length", server.client.ip);
break; break;
} }
} else { } else {
...@@ -1187,9 +1465,9 @@ ...@@ -1187,9 +1465,9 @@
info = _.clone(struct.fields); info = _.clone(struct.fields);
} }
if (ygopro.stoc_follows[stoc_proto].synchronous) { if (ygopro.stoc_follows[stoc_proto].synchronous) {
cancel = ygopro.stoc_follows[stoc_proto].callback(b, info, client, server); cancel = ygopro.stoc_follows[stoc_proto].callback(b, info, server.client, server);
} else { } else {
ygopro.stoc_follows[stoc_proto].callback(b, info, client, server); ygopro.stoc_follows[stoc_proto].callback(b, info, server.client, server);
} }
} }
if (!cancel) { if (!cancel) {
...@@ -1199,20 +1477,22 @@ ...@@ -1199,20 +1477,22 @@
stoc_message_length = 0; stoc_message_length = 0;
stoc_proto = 0; stoc_proto = 0;
} else { } else {
log.warn("bad stoc_message length", client.ip); log.warn("bad stoc_message length", server.client.ip);
break; break;
} }
} }
looplimit++; looplimit++;
if (looplimit > 800) { if (looplimit > 800) {
log.info("error stoc", client.name); log.info("error stoc", server.client.name);
server.destroy(); server.destroy();
break; break;
} }
} }
for (l = 0, len2 = datas.length; l < len2; l++) { if (server.client && !server.client.closed) {
buffer = datas[l]; for (m = 0, len2 = datas.length; m < len2; m++) {
client.write(buffer); buffer = datas[m];
server.client.write(buffer);
}
} }
}); });
}).listen(settings.port, function() { }).listen(settings.port, function() {
...@@ -1262,9 +1542,12 @@ ...@@ -1262,9 +1542,12 @@
}); });
ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var check, decrypted_buffer, finish, i, id, l, len2, len3, m, name, ref2, ref3, replay_id, room, secret; var check, decrypted_buffer, finish, i, id, len2, len3, m, n, name, ref2, ref3, replay_id, room, secret;
info.pass = info.pass.trim(); info.pass = info.pass.trim();
if (settings.modules.stop) { if (CLIENT_is_able_to_reconnect(client)) {
CLIENT_pre_reconnect(client);
return;
} else if (settings.modules.stop) {
ygopro.stoc_die(client, settings.modules.stop); ygopro.stoc_die(client, settings.modules.stop);
} else if (info.pass.toUpperCase() === "R" && settings.modules.cloud_replay.enabled) { } else if (info.pass.toUpperCase() === "R" && settings.modules.cloud_replay.enabled) {
ygopro.stoc_send_chat(client, "${cloud_replay_hint}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${cloud_replay_hint}", ygopro.constants.COLORS.BABYBLUE);
...@@ -1286,7 +1569,7 @@ ...@@ -1286,7 +1569,7 @@
msg: 1, msg: 1,
code: 9 code: 9
}); });
client.destroy(); CLIENT_kick(client);
}), 500); }), 500);
} else if (info.pass.slice(0, 2).toUpperCase() === "R#" && settings.modules.cloud_replay.enabled) { } else if (info.pass.slice(0, 2).toUpperCase() === "R#" && settings.modules.cloud_replay.enabled) {
replay_id = info.pass.split("#")[1]; replay_id = info.pass.split("#")[1];
...@@ -1315,7 +1598,7 @@ ...@@ -1315,7 +1598,7 @@
msg: 4, msg: 4,
code: settings.version code: settings.version
}); });
client.destroy(); CLIENT_kick(client);
} else if (!info.pass.length && !settings.modules.random_duel.enabled && !settings.modules.windbot.enabled) { } else if (!info.pass.length && !settings.modules.random_duel.enabled && !settings.modules.windbot.enabled) {
ygopro.stoc_die(client, "${blank_room_name}"); ygopro.stoc_die(client, "${blank_room_name}");
} else if (info.pass.length && settings.modules.mycard.enabled && info.pass.slice(0, 3) !== 'AI#') { } else if (info.pass.length && settings.modules.mycard.enabled && info.pass.slice(0, 3) !== 'AI#') {
...@@ -1330,15 +1613,15 @@ ...@@ -1330,15 +1613,15 @@
return; return;
} }
check = function(buf) { check = function(buf) {
var checksum, i, l, ref2; var checksum, i, m, ref2;
checksum = 0; checksum = 0;
for (i = l = 0, ref2 = buf.length; 0 <= ref2 ? l < ref2 : l > ref2; i = 0 <= ref2 ? ++l : --l) { for (i = m = 0, ref2 = buf.length; 0 <= ref2 ? m < ref2 : m > ref2; i = 0 <= ref2 ? ++m : --m) {
checksum += buf.readUInt8(i); checksum += buf.readUInt8(i);
} }
return (checksum & 0xFF) === 0; return (checksum & 0xFF) === 0;
}; };
finish = function(buffer) { finish = function(buffer) {
var action, l, len2, name, opt1, opt2, opt3, options, ref2, room, title; var action, len2, m, name, opt1, opt2, opt3, options, ref2, room, title;
action = buffer.readUInt8(1) >> 4; action = buffer.readUInt8(1) >> 4;
if (buffer !== decrypted_buffer && (action === 1 || action === 2 || action === 4)) { if (buffer !== decrypted_buffer && (action === 1 || action === 2 || action === 4)) {
ygopro.stoc_die(client, '${invalid_password_unauthorized}'); ygopro.stoc_die(client, '${invalid_password_unauthorized}');
...@@ -1416,8 +1699,8 @@ ...@@ -1416,8 +1699,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref2 = room.watcher_buffers; ref2 = room.watcher_buffers;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
buffer = ref2[l]; buffer = ref2[m];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -1433,8 +1716,8 @@ ...@@ -1433,8 +1716,8 @@
secret = id % 65535 + 1; secret = id % 65535 + 1;
decrypted_buffer = new Buffer(6); decrypted_buffer = new Buffer(6);
ref2 = [0, 2, 4]; ref2 = [0, 2, 4];
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
i = ref2[l]; i = ref2[m];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i); decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
} }
if (check(decrypted_buffer)) { if (check(decrypted_buffer)) {
...@@ -1451,14 +1734,14 @@ ...@@ -1451,14 +1734,14 @@
}, },
json: true json: true
}, function(error, response, body) { }, function(error, response, body) {
var len3, m, ref3; var len3, n, ref3;
if (body && body.user) { if (body && body.user) {
users_cache[client.name] = body.user.id; users_cache[client.name] = body.user.id;
secret = body.user.id % 65535 + 1; secret = body.user.id % 65535 + 1;
decrypted_buffer = new Buffer(6); decrypted_buffer = new Buffer(6);
ref3 = [0, 2, 4]; ref3 = [0, 2, 4];
for (m = 0, len3 = ref3.length; m < len3; m++) { for (n = 0, len3 = ref3.length; n < len3; n++) {
i = ref3[m]; i = ref3[n];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i); decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
} }
if (check(decrypted_buffer)) { if (check(decrypted_buffer)) {
...@@ -1522,8 +1805,8 @@ ...@@ -1522,8 +1805,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref3 = room.watcher_buffers; ref3 = room.watcher_buffers;
for (m = 0, len3 = ref3.length; m < len3; m++) { for (n = 0, len3 = ref3.length; n < len3; n++) {
buffer = ref3[m]; buffer = ref3[n];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -1540,9 +1823,10 @@ ...@@ -1540,9 +1823,10 @@
ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var recorder, room, watcher; var recorder, room, watcher;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!(room && !client.reconnecting)) {
return; return;
} }
client.join_game_buffer = buffer;
if (settings.modules.welcome) { if (settings.modules.welcome) {
ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN); ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN);
} }
...@@ -1597,15 +1881,15 @@ ...@@ -1597,15 +1881,15 @@
ygopro.ctos_send(watcher, 'HS_TOOBSERVER'); ygopro.ctos_send(watcher, 'HS_TOOBSERVER');
}); });
watcher.on('data', function(data) { watcher.on('data', function(data) {
var l, len2, ref2, w; var len2, m, ref2, w;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return; return;
} }
room.watcher_buffers.push(data); room.watcher_buffers.push(data);
ref2 = room.watchers; ref2 = room.watchers;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
w = ref2[l]; w = ref2[m];
if (w) { if (w) {
w.write(data); w.write(data);
} }
...@@ -1636,9 +1920,9 @@ ...@@ -1636,9 +1920,9 @@
} }
ygopro.stoc_follow('GAME_MSG', true, function(buffer, info, client, server) { ygopro.stoc_follow('GAME_MSG', true, function(buffer, info, client, server) {
var card, count, l, len2, line, loc, msg, oppo_pos, phase, playertype, pos, reason, ref2, ref3, ref4, room, trigger_location, val, win_pos; var card, count, len2, line, loc, m, msg, oppo_pos, phase, playertype, pos, reason, ref2, ref3, ref4, room, trigger_location, val, win_pos;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!(room && !client.reconnecting)) {
return; return;
} }
msg = buffer.readInt8(0); msg = buffer.readInt8(0);
...@@ -1652,7 +1936,7 @@ ...@@ -1652,7 +1936,7 @@
if (settings.modules.retry_handle.max_retry_count && client.retry_count >= settings.modules.retry_handle.max_retry_count) { if (settings.modules.retry_handle.max_retry_count && client.retry_count >= settings.modules.retry_handle.max_retry_count) {
ygopro.stoc_send_chat_to_room(room, client.name + "${retry_too_much_room_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_room_part2}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(room, client.name + "${retry_too_much_room_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_room_part2}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${retry_too_much_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_part2}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${retry_too_much_part1}" + settings.modules.retry_handle.max_retry_count + "${retry_too_much_part2}", ygopro.constants.COLORS.RED);
client.destroy(); CLIENT_kick(client);
return true; return true;
} }
if (client.last_game_msg) { if (client.last_game_msg) {
...@@ -1666,7 +1950,11 @@ ...@@ -1666,7 +1950,11 @@
} }
} else { } else {
client.last_game_msg = buffer; client.last_game_msg = buffer;
client.last_game_msg_title = ygopro.constants.MSG[msg];
} }
} else if (ygopro.constants.MSG[msg] !== 'RETRY') {
client.last_game_msg = buffer;
client.last_game_msg_title = ygopro.constants.MSG[msg];
} }
if ((msg >= 10 && msg < 30) || msg === 132 || (msg >= 140 && msg < 144)) { if ((msg >= 10 && msg < 30) || msg === 132 || (msg >= 140 && msg < 144)) {
room.waiting_for_player = client; room.waiting_for_player = client;
...@@ -1679,6 +1967,7 @@ ...@@ -1679,6 +1967,7 @@
if (room.hostinfo.mode !== 2) { if (room.hostinfo.mode !== 2) {
client.card_count = 0; client.card_count = 0;
} }
room.selecting_tp = false;
if (client.pos === 0) { if (client.pos === 0) {
room.turn = 0; room.turn = 0;
room.duel_count = room.duel_count + 1; room.duel_count = room.duel_count + 1;
...@@ -1708,8 +1997,8 @@ ...@@ -1708,8 +1997,8 @@
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1; room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1;
room.dueling_players[oppo_pos - win_pos].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
room.dueling_players[oppo_pos - win_pos + 1].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} else { } else {
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER'); ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
} }
...@@ -1738,8 +2027,8 @@ ...@@ -1738,8 +2027,8 @@
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1; room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1;
room.dueling_players[oppo_pos - win_pos].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
room.dueling_players[oppo_pos - win_pos + 1].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} else { } else {
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER'); ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
} }
...@@ -1862,8 +2151,8 @@ ...@@ -1862,8 +2151,8 @@
trigger_location = buffer.readUInt8(6); trigger_location = buffer.readUInt8(6);
if (dialogues.dialogues[card] && (ygopro.constants.MSG[msg] !== 'CHAINING' || (trigger_location & 0x8) && !(trigger_location & 0x200))) { if (dialogues.dialogues[card] && (ygopro.constants.MSG[msg] !== 'CHAINING' || (trigger_location & 0x8) && !(trigger_location & 0x200))) {
ref4 = _.lines(dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]); ref4 = _.lines(dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]);
for (l = 0, len2 = ref4.length; l < len2; l++) { for (m = 0, len2 = ref4.length; m < len2; m++) {
line = ref4[l]; line = ref4[m];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK); ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
} }
} }
...@@ -1873,7 +2162,7 @@ ...@@ -1873,7 +2162,7 @@
}); });
ygopro.ctos_follow('HS_TOOBSERVER', true, function(buffer, info, client, server) { ygopro.ctos_follow('HS_TOOBSERVER', true, function(buffer, info, client, server) {
var l, len2, player, ref2, room; var len2, m, player, ref2, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return; return;
...@@ -1882,8 +2171,8 @@ ...@@ -1882,8 +2171,8 @@
return false; return false;
} }
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player === client) { if (player === client) {
ygopro.stoc_send_chat(client, "${cannot_to_observer}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${cannot_to_observer}", ygopro.constants.COLORS.BABYBLUE);
return true; return true;
...@@ -1893,25 +2182,25 @@ ...@@ -1893,25 +2182,25 @@
}); });
ygopro.ctos_follow('HS_KICK', true, function(buffer, info, client, server) { ygopro.ctos_follow('HS_KICK', true, function(buffer, info, client, server) {
var l, len2, player, ref2, room; var len2, m, player, ref2, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return; return;
} }
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player && player.pos === info.pos && player !== client) { if (player && player.pos === info.pos && player !== client) {
if (room.arena === "athletic") { if (room.arena === "athletic") {
ygopro.stoc_send_chat_to_room(room, client.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, client.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED);
client.destroy(); CLIENT_kick(client);
return true; return true;
} }
client.kick_count = client.kick_count ? client.kick_count + 1 : 1; client.kick_count = client.kick_count ? client.kick_count + 1 : 1;
if (client.kick_count >= 5 && room.random_type) { if (client.kick_count >= 5 && room.random_type) {
ygopro.stoc_send_chat_to_room(room, client.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, client.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED);
ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}"); ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}");
client.destroy(); CLIENT_kick(client);
return true; return true;
} }
ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_player}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_player}", ygopro.constants.COLORS.RED);
...@@ -1929,7 +2218,7 @@ ...@@ -1929,7 +2218,7 @@
}); });
ygopro.stoc_follow('HS_PLAYER_CHANGE', false, function(buffer, info, client, server) { ygopro.stoc_follow('HS_PLAYER_CHANGE', false, function(buffer, info, client, server) {
var is_ready, l, len2, len3, m, p1, p2, player, pos, ref2, ref3, room; var is_ready, len2, len3, m, n, p1, p2, player, pos, ref2, ref3, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && room.max_player && client.is_host)) { if (!(room && room.max_player && client.is_host)) {
return; return;
...@@ -1940,8 +2229,8 @@ ...@@ -1940,8 +2229,8 @@
if (room.arena) { if (room.arena) {
room.ready_player_count = 0; room.ready_player_count = 0;
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player.pos === pos) { if (player.pos === pos) {
player.is_ready = is_ready; player.is_ready = is_ready;
} }
...@@ -1980,8 +2269,8 @@ ...@@ -1980,8 +2269,8 @@
} else { } else {
room.ready_player_count_without_host = 0; room.ready_player_count_without_host = 0;
ref3 = room.players; ref3 = room.players;
for (m = 0, len3 = ref3.length; m < len3; m++) { for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[m]; player = ref3[n];
if (player.pos === pos) { if (player.pos === pos) {
player.is_ready = is_ready; player.is_ready = is_ready;
} }
...@@ -1998,8 +2287,23 @@ ...@@ -1998,8 +2287,23 @@
} }
}); });
ygopro.stoc_follow('FIELD_FINISH', true, function(buffer, info, client, server) {
var room;
room = ROOM_all[client.rid];
if (!room) {
return;
}
client.reconnecting = false;
if (client.last_game_msg && client.last_game_msg_title !== 'WAITING') {
setTimeout(function() {
ygopro.stoc_send(client, 'GAME_MSG', client.last_game_msg);
}, 1000);
}
return true;
});
wait_room_start = function(room, time) { wait_room_start = function(room, time) {
var l, len2, player, ref2; var len2, m, player, ref2;
if (!(!room || room.started || room.ready_player_count_without_host < room.max_player - 1)) { if (!(!room || room.started || room.ready_player_count_without_host < room.max_player - 1)) {
time -= 1; time -= 1;
if (time) { if (time) {
...@@ -2011,12 +2315,12 @@ ...@@ -2011,12 +2315,12 @@
}), 1000); }), 1000);
} else { } else {
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player && player.is_host) { if (player && player.is_host) {
ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}"); ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}");
ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED);
player.destroy(); CLIENT_kick(player);
} }
} }
} }
...@@ -2032,7 +2336,7 @@ ...@@ -2032,7 +2336,7 @@
} }
} else { } else {
ygopro.stoc_send_chat_to_room(room, room.waiting_for_player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, room.waiting_for_player.name + " ${kicked_by_system}", ygopro.constants.COLORS.RED);
room.waiting_for_player.destroy(); CLIENT_kick(room.waiting_for_player);
if (room.waiting_for_player_interval) { if (room.waiting_for_player_interval) {
clearInterval(room.waiting_for_player_interval); clearInterval(room.waiting_for_player_interval);
room.waiting_for_player_interval = null; room.waiting_for_player_interval = null;
...@@ -2072,9 +2376,9 @@ ...@@ -2072,9 +2376,9 @@
if (settings.modules.tips.get) { if (settings.modules.tips.get) {
load_tips(); load_tips();
setInterval(function() { setInterval(function() {
var l, len2, room; var len2, m, room;
for (l = 0, len2 = ROOM_all.length; l < len2; l++) { for (m = 0, len2 = ROOM_all.length; m < len2; m++) {
room = ROOM_all[l]; room = ROOM_all[m];
if (room && room.established) { if (room && room.established) {
if (!room.started || room.changing_side) { if (!room.started || room.changing_side) {
ygopro.stoc_send_random_tip_to_room(room); ygopro.stoc_send_random_tip_to_room(room);
...@@ -2085,21 +2389,22 @@ ...@@ -2085,21 +2389,22 @@
} }
ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) { ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) {
var deck_arena, deck_name, deck_text, l, len2, player, ref2, room; var deck_arena, deck_name, deck_text, len2, m, player, ref2, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!(room && !client.reconnecting)) {
return; return;
} }
if (!room.started) { if (!room.started) {
room.started = true; room.started = true;
room.start_time = moment().format(); room.start_time = moment().format();
room.turn = 0;
if (!room.windbot && settings.modules.http.websocket_roomlist) { if (!room.windbot && settings.modules.http.websocket_roomlist) {
roomlist.start(room); roomlist.start(room);
} }
room.dueling_players = []; room.dueling_players = [];
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (!(player.pos !== 7)) { if (!(player.pos !== 7)) {
continue; continue;
} }
...@@ -2280,7 +2585,7 @@ ...@@ -2280,7 +2585,7 @@
break; break;
case '/color': case '/color':
if (settings.modules.chat_color.enabled) { if (settings.modules.chat_color.enabled) {
cip = settings.modules.mycard.enabled ? client.name : client.ip; cip = CLIENT_get_authorize_key(client);
if (cmsg = cmd[1]) { if (cmsg = cmd[1]) {
if (cmsg.toLowerCase() === "help") { if (cmsg.toLowerCase() === "help") {
ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE);
...@@ -2343,7 +2648,7 @@ ...@@ -2343,7 +2648,7 @@
ygopro.stoc_send_chat(client, "${banned_duel_tip}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${banned_duel_tip}", ygopro.constants.COLORS.RED);
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}"); ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}");
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}", 3); ROOM_ban_player(client.name, client.ip, "${random_ban_reason_abuse}", 3);
client.destroy(); CLIENT_kick(client);
return true; return true;
} else { } else {
client.abuse_count = client.abuse_count + 4; client.abuse_count = client.abuse_count + 4;
...@@ -2405,33 +2710,53 @@ ...@@ -2405,33 +2710,53 @@
}); });
ygopro.ctos_follow('UPDATE_DECK', true, function(buffer, info, client, server) { ygopro.ctos_follow('UPDATE_DECK', true, function(buffer, info, client, server) {
var buff_main, buff_side, card, current_deck, deck, deck_array, deck_main, deck_side, deck_text, deckbuf, decks, found_deck, i, l, len2, len3, line, m, oppo_pos, room, struct, win_pos; var buff_main, buff_side, card, current_deck, deck, deck_array, deck_main, deck_side, deck_text, deckbuf, decks, found_deck, i, len2, len3, line, m, n, oppo_pos, room, struct, win_pos;
if (settings.modules.reconnect.enabled && client.pre_reconnecting) {
if (_.isEqual(buffer, client.pre_deckbuf)) {
CLIENT_reconnect(client);
} else {
ygopro.stoc_send_chat(client, "${deck_incorrect_reconnect}", ygopro.constants.COLORS.RED);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 2,
code: 0
});
ygopro.stoc_send(client, 'HS_PLAYER_CHANGE', {
status: (client.pos << 4) | 0xa
});
}
return true;
}
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return false; return false;
} }
buff_main = (function() { buff_main = (function() {
var l, ref2, results; var m, ref2, results;
results = []; results = [];
for (i = l = 0, ref2 = info.mainc; 0 <= ref2 ? l < ref2 : l > ref2; i = 0 <= ref2 ? ++l : --l) { for (i = m = 0, ref2 = info.mainc; 0 <= ref2 ? m < ref2 : m > ref2; i = 0 <= ref2 ? ++m : --m) {
results.push(info.deckbuf[i]); results.push(info.deckbuf[i]);
} }
return results; return results;
})(); })();
buff_side = (function() { buff_side = (function() {
var l, ref2, ref3, results; var m, ref2, ref3, results;
results = []; results = [];
for (i = l = ref2 = info.mainc, ref3 = info.mainc + info.sidec; ref2 <= ref3 ? l < ref3 : l > ref3; i = ref2 <= ref3 ? ++l : --l) { for (i = m = ref2 = info.mainc, ref3 = info.mainc + info.sidec; ref2 <= ref3 ? m < ref3 : m > ref3; i = ref2 <= ref3 ? ++m : --m) {
results.push(info.deckbuf[i]); results.push(info.deckbuf[i]);
} }
return results; return results;
})(); })();
client.main = buff_main; client.main = buff_main;
client.side = buff_side; client.side = buff_side;
if (client.side_tcount) { if (room.started) {
clearInterval(client.side_interval); client.selected_preduel = true;
client.side_interval = null; if (client.side_tcount) {
client.side_tcount = null; clearInterval(client.side_interval);
client.side_interval = null;
client.side_tcount = null;
}
} else {
client.start_deckbuf = buffer;
} }
oppo_pos = room.hostinfo.mode === 2 ? 2 : 1; oppo_pos = room.hostinfo.mode === 2 ? 2 : 1;
if (settings.modules.http.quick_death_rule >= 2 && room.started && room.death && room.scores[room.dueling_players[0].name] !== room.scores[room.dueling_players[oppo_pos].name]) { if (settings.modules.http.quick_death_rule >= 2 && room.started && room.death && room.scores[room.dueling_players[0].name] !== room.scores[room.dueling_players[oppo_pos].name]) {
...@@ -2442,9 +2767,9 @@ ...@@ -2442,9 +2767,9 @@
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
} }
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1; room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1;
room.dueling_players[oppo_pos - win_pos].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
room.dueling_players[oppo_pos - win_pos + 1].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} }
return true; return true;
} }
...@@ -2462,8 +2787,8 @@ ...@@ -2462,8 +2787,8 @@
buffer = struct.buffer; buffer = struct.buffer;
found_deck = false; found_deck = false;
decks = fs.readdirSync(settings.modules.tournament_mode.deck_path); decks = fs.readdirSync(settings.modules.tournament_mode.deck_path);
for (l = 0, len2 = decks.length; l < len2; l++) { for (m = 0, len2 = decks.length; m < len2; m++) {
deck = decks[l]; deck = decks[m];
if (_.endsWith(deck, client.name + ".ydk")) { if (_.endsWith(deck, client.name + ".ydk")) {
found_deck = deck; found_deck = deck;
} }
...@@ -2479,8 +2804,8 @@ ...@@ -2479,8 +2804,8 @@
deck_main = []; deck_main = [];
deck_side = []; deck_side = [];
current_deck = deck_main; current_deck = deck_main;
for (m = 0, len3 = deck_array.length; m < len3; m++) { for (n = 0, len3 = deck_array.length; n < len3; n++) {
line = deck_array[m]; line = deck_array[n];
if (line.indexOf("!side") >= 0) { if (line.indexOf("!side") >= 0) {
current_deck = deck_side; current_deck = deck_side;
} }
...@@ -2518,7 +2843,11 @@ ...@@ -2518,7 +2843,11 @@
ygopro.ctos_follow('HAND_RESULT', false, function(buffer, info, client, server) { ygopro.ctos_follow('HAND_RESULT', false, function(buffer, info, client, server) {
var room; var room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && (room.random_type || room.arena))) { if (!room) {
return;
}
client.selected_preduel = true;
if (!(room.random_type || room.arena)) {
return; return;
} }
if (client.pos === 0) { if (client.pos === 0) {
...@@ -2530,14 +2859,19 @@ ...@@ -2530,14 +2859,19 @@
ygopro.ctos_follow('TP_RESULT', false, function(buffer, info, client, server) { ygopro.ctos_follow('TP_RESULT', false, function(buffer, info, client, server) {
var room; var room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && (room.random_type || room.arena))) { if (!room) {
return;
}
client.selected_preduel = true;
room.selecting_tp = false;
if (!(room.random_type || room.arena)) {
return; return;
} }
room.last_active_time = moment(); room.last_active_time = moment();
}); });
ygopro.stoc_follow('CHAT', true, function(buffer, info, client, server) { ygopro.stoc_follow('CHAT', true, function(buffer, info, client, server) {
var l, len2, pid, player, ref2, room, tcolor, tplayer; var len2, m, pid, player, ref2, room, tcolor, tplayer;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
pid = info.player; pid = info.player;
if (!(room && pid < 4 && settings.modules.chat_color.enabled)) { if (!(room && pid < 4 && settings.modules.chat_color.enabled)) {
...@@ -2556,8 +2890,8 @@ ...@@ -2556,8 +2890,8 @@
} }
} }
ref2 = room.players; ref2 = room.players;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
player = ref2[l]; player = ref2[m];
if (player && player.pos === pid) { if (player && player.pos === pid) {
tplayer = player; tplayer = player;
} }
...@@ -2578,7 +2912,15 @@ ...@@ -2578,7 +2912,15 @@
ygopro.stoc_follow('SELECT_HAND', false, function(buffer, info, client, server) { ygopro.stoc_follow('SELECT_HAND', false, function(buffer, info, client, server) {
var room; var room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && (room.random_type || room.arena))) { if (!room) {
return;
}
client.selected_preduel = false;
if (client.pos === 0) {
room.selecting_hand = true;
room.changing_side = false;
}
if (!(room.random_type || room.arena)) {
return; return;
} }
if (client.pos === 0) { if (client.pos === 0) {
...@@ -2595,7 +2937,10 @@ ...@@ -2595,7 +2937,10 @@
if (!room) { if (!room) {
return; return;
} }
client.selected_preduel = false;
room.changing_side = false; room.changing_side = false;
room.selecting_hand = false;
room.selecting_tp = client;
if (room.random_type || room.arena) { if (room.random_type || room.arena) {
room.waiting_for_player = client; room.waiting_for_player = client;
room.last_active_time = moment(); room.last_active_time = moment();
...@@ -2609,6 +2954,7 @@ ...@@ -2609,6 +2954,7 @@
return; return;
} }
room.changing_side = true; room.changing_side = true;
client.selected_preduel = false;
if (settings.modules.side_timeout) { if (settings.modules.side_timeout) {
client.side_tcount = settings.modules.side_timeout; client.side_tcount = settings.modules.side_timeout;
ygopro.stoc_send_chat(client, "${side_timeout_part1}" + settings.modules.side_timeout + "${side_timeout_part2}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${side_timeout_part1}" + settings.modules.side_timeout + "${side_timeout_part2}", ygopro.constants.COLORS.BABYBLUE);
...@@ -2621,7 +2967,7 @@ ...@@ -2621,7 +2967,7 @@
ygopro.stoc_send_chat_to_room(room, client.name + "${side_overtime_room}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(room, client.name + "${side_overtime_room}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${side_overtime}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${side_overtime}", ygopro.constants.COLORS.RED);
room.scores[client.name] = -9; room.scores[client.name] = -9;
client.destroy(); CLIENT_kick(client);
return clearInterval(sinterval); return clearInterval(sinterval);
} else { } else {
client.side_tcount = client.side_tcount - 1; client.side_tcount = client.side_tcount - 1;
...@@ -2641,7 +2987,7 @@ ...@@ -2641,7 +2987,7 @@
}); });
ygopro.stoc_follow('REPLAY', true, function(buffer, info, client, server) { ygopro.stoc_follow('REPLAY', true, function(buffer, info, client, server) {
var duellog, dueltime, i, l, len2, len3, m, player, ref2, ref3, replay_filename, room; var duellog, dueltime, i, len2, len3, m, n, player, ref2, ref3, replay_filename, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.replay_safe; return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.replay_safe;
...@@ -2655,13 +3001,13 @@ ...@@ -2655,13 +3001,13 @@
replay_filename = dueltime; replay_filename = dueltime;
if (room.hostinfo.mode !== 2) { if (room.hostinfo.mode !== 2) {
ref2 = room.dueling_players; ref2 = room.dueling_players;
for (i = l = 0, len2 = ref2.length; l < len2; i = ++l) { for (i = m = 0, len2 = ref2.length; m < len2; i = ++m) {
player = ref2[i]; player = ref2[i];
replay_filename = replay_filename + (i > 0 ? " VS " : " ") + player.name; replay_filename = replay_filename + (i > 0 ? " VS " : " ") + player.name;
} }
} else { } else {
ref3 = room.dueling_players; ref3 = room.dueling_players;
for (i = m = 0, len3 = ref3.length; m < len3; i = ++m) { for (i = n = 0, len3 = ref3.length; n < len3; i = ++n) {
player = ref3[i]; player = ref3[i];
replay_filename = replay_filename + (i > 0 ? (i === 2 ? " VS " : " & ") : " ") + player.name; replay_filename = replay_filename + (i > 0 ? (i === 2 ? " VS " : " & ") : " ") + player.name;
} }
...@@ -2675,11 +3021,11 @@ ...@@ -2675,11 +3021,11 @@
replay_filename: replay_filename, replay_filename: replay_filename,
roommode: room.hostinfo.mode, roommode: room.hostinfo.mode,
players: (function() { players: (function() {
var len4, n, ref4, results; var len4, o, ref4, results;
ref4 = room.dueling_players; ref4 = room.dueling_players;
results = []; results = [];
for (n = 0, len4 = ref4.length; n < len4; n++) { for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[n]; player = ref4[o];
results.push({ results.push({
name: player.name + (settings.modules.tournament_mode.show_ip && !player.is_local ? " (IP: " + player.ip.slice(7) + ")" : "") + (settings.modules.tournament_mode.show_info && !(room.hostinfo.mode === 2 && player.pos % 2 > 0) ? " (Score:" + room.scores[player.name] + " LP:" + (player.lp != null ? player.lp : room.hostinfo.start_lp) + (room.hostinfo.mode !== 2 ? " Cards:" + (player.card_count != null ? player.card_count : room.hostinfo.start_hand) : "") + ")" : ""), name: player.name + (settings.modules.tournament_mode.show_ip && !player.is_local ? " (IP: " + player.ip.slice(7) + ")" : "") + (settings.modules.tournament_mode.show_info && !(room.hostinfo.mode === 2 && player.pos % 2 > 0) ? " (Score:" + room.scores[player.name] + " LP:" + (player.lp != null ? player.lp : room.hostinfo.start_lp) + (room.hostinfo.mode !== 2 ? " Cards:" + (player.card_count != null ? player.card_count : room.hostinfo.start_hand) : "") + ")" : ""),
winner: player.pos === room.winner winner: player.pos === room.winner
...@@ -2707,9 +3053,9 @@ ...@@ -2707,9 +3053,9 @@
if (settings.modules.random_duel.enabled) { if (settings.modules.random_duel.enabled) {
setInterval(function() { setInterval(function() {
var l, len2, room, time_passed; var len2, m, room, time_passed;
for (l = 0, len2 = ROOM_all.length; l < len2; l++) { for (m = 0, len2 = ROOM_all.length; m < len2; m++) {
room = ROOM_all[l]; room = ROOM_all[m];
if (!(room && room.started && room.random_type && room.last_active_time && room.waiting_for_player)) { if (!(room && room.started && room.random_type && room.last_active_time && room.waiting_for_player)) {
continue; continue;
} }
...@@ -2729,9 +3075,9 @@ ...@@ -2729,9 +3075,9 @@
if (settings.modules.mycard.enabled) { if (settings.modules.mycard.enabled) {
setInterval(function() { setInterval(function() {
var l, len2, room, time_passed; var len2, m, room, time_passed;
for (l = 0, len2 = ROOM_all.length; l < len2; l++) { for (m = 0, len2 = ROOM_all.length; m < len2; m++) {
room = ROOM_all[l]; room = ROOM_all[m];
if (!(room && room.started && room.arena && room.last_active_time && room.waiting_for_player)) { if (!(room && room.started && room.arena && room.last_active_time && room.waiting_for_player)) {
continue; continue;
} }
...@@ -2785,7 +3131,7 @@ ...@@ -2785,7 +3131,7 @@
return callback + "( " + text + " );"; return callback + "( " + text + " );";
}; };
requestListener = function(request, response) { requestListener = function(request, response) {
var archive_args, archive_name, archive_process, check, death_room_found, duellog, error, filename, getpath, l, len2, len3, len4, len5, m, n, o, oppo_pos, parseQueryString, pass_validated, player, ref2, replay, room, roomsjson, u, win_pos; var archive_args, archive_name, archive_process, check, death_room_found, duellog, error, filename, getpath, len2, len3, len4, len5, m, n, o, oppo_pos, p, parseQueryString, pass_validated, player, ref2, replay, room, roomsjson, u, win_pos;
parseQueryString = true; parseQueryString = true;
u = url.parse(request.url, parseQueryString); u = url.parse(request.url, parseQueryString);
pass_validated = u.query.pass === settings.modules.http.password; pass_validated = u.query.pass === settings.modules.http.password;
...@@ -2797,10 +3143,10 @@ ...@@ -2797,10 +3143,10 @@
response.writeHead(200); response.writeHead(200);
roomsjson = JSON.stringify({ roomsjson = JSON.stringify({
rooms: (function() { rooms: (function() {
var l, len2, results; var len2, m, results;
results = []; results = [];
for (l = 0, len2 = ROOM_all.length; l < len2; l++) { for (m = 0, len2 = ROOM_all.length; m < len2; m++) {
room = ROOM_all[l]; room = ROOM_all[m];
if (room && room.established) { if (room && room.established) {
results.push({ results.push({
pid: room.process.pid.toString(), pid: room.process.pid.toString(),
...@@ -2809,11 +3155,11 @@ ...@@ -2809,11 +3155,11 @@
roommode: room.hostinfo.mode, roommode: room.hostinfo.mode,
needpass: (room.name.indexOf('$') !== -1).toString(), needpass: (room.name.indexOf('$') !== -1).toString(),
users: (function() { users: (function() {
var len3, m, ref2, results1; var len3, n, ref2, results1;
ref2 = room.players; ref2 = room.players;
results1 = []; results1 = [];
for (m = 0, len3 = ref2.length; m < len3; m++) { for (n = 0, len3 = ref2.length; n < len3; n++) {
player = ref2[m]; player = ref2[n];
if (player.pos != null) { if (player.pos != null) {
results1.push({ results1.push({
id: (-1).toString(), id: (-1).toString(),
...@@ -2854,8 +3200,8 @@ ...@@ -2854,8 +3200,8 @@
archive_args = ["a", "-mx0", "-y", archive_name]; archive_args = ["a", "-mx0", "-y", archive_name];
check = false; check = false;
ref2 = duel_log.duel_log; ref2 = duel_log.duel_log;
for (l = 0, len2 = ref2.length; l < len2; l++) { for (m = 0, len2 = ref2.length; m < len2; m++) {
replay = ref2[l]; replay = ref2[m];
check = true; check = true;
archive_args.push(replay.replay_filename); archive_args.push(replay.replay_filename);
} }
...@@ -2953,8 +3299,8 @@ ...@@ -2953,8 +3299,8 @@
return; return;
} }
if (u.query.shout) { if (u.query.shout) {
for (m = 0, len3 = ROOM_all.length; m < len3; m++) { for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
room = ROOM_all[m]; room = ROOM_all[n];
if (room && room.established) { if (room && room.established) {
ygopro.stoc_send_chat_to_room(room, u.query.shout, ygopro.constants.COLORS.YELLOW); ygopro.stoc_send_chat_to_room(room, u.query.shout, ygopro.constants.COLORS.YELLOW);
} }
...@@ -2989,8 +3335,8 @@ ...@@ -2989,8 +3335,8 @@
response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']")); response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']"));
} else if (u.query.death) { } else if (u.query.death) {
death_room_found = false; death_room_found = false;
for (n = 0, len4 = ROOM_all.length; n < len4; n++) { for (o = 0, len4 = ROOM_all.length; o < len4; o++) {
room = ROOM_all[n]; room = ROOM_all[o];
if (!(room && room.established && room.started && !room.death && (u.query.death === "all" || u.query.death === room.port.toString()))) { if (!(room && room.established && room.started && !room.death && (u.query.death === "all" || u.query.death === room.port.toString()))) {
continue; continue;
} }
...@@ -3026,9 +3372,9 @@ ...@@ -3026,9 +3372,9 @@
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
} }
room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1; room.scores[room.dueling_players[oppo_pos - win_pos].name] = -1;
room.dueling_players[oppo_pos - win_pos].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
room.dueling_players[oppo_pos - win_pos + 1].destroy(); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} }
} }
break; break;
...@@ -3050,8 +3396,8 @@ ...@@ -3050,8 +3396,8 @@
} }
} else if (u.query.deathcancel) { } else if (u.query.deathcancel) {
death_room_found = false; death_room_found = false;
for (o = 0, len5 = ROOM_all.length; o < len5; o++) { for (p = 0, len5 = ROOM_all.length; p < len5; p++) {
room = ROOM_all[o]; room = ROOM_all[p];
if (!(room && room.established && room.started && room.death && (u.query.deathcancel === "all" || u.query.deathcancel === room.port.toString()))) { if (!(room && room.established && room.started && room.death && (u.query.deathcancel === "all" || u.query.deathcancel === room.port.toString()))) {
continue; continue;
} }
......
...@@ -60,6 +60,8 @@ for name, declaration of structs_declaration ...@@ -60,6 +60,8 @@ for name, declaration of structs_declaration
#消息发送函数,至少要把俩合起来.... #消息发送函数,至少要把俩合起来....
@stoc_send = (socket, proto, info)-> @stoc_send = (socket, proto, info)->
if socket.closed
return
#console.log proto, proto_structs.STOC[proto], structs[proto_structs.STOC[proto]] #console.log proto, proto_structs.STOC[proto], structs[proto_structs.STOC[proto]]
if typeof info == 'undefined' if typeof info == 'undefined'
buffer = "" buffer = ""
...@@ -86,6 +88,8 @@ for name, declaration of structs_declaration ...@@ -86,6 +88,8 @@ for name, declaration of structs_declaration
return return
@ctos_send = (socket, proto, info)-> @ctos_send = (socket, proto, info)->
if socket.closed
return
#console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]] #console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]]
if typeof info == 'undefined' if typeof info == 'undefined'
buffer = "" buffer = ""
...@@ -164,5 +168,7 @@ for name, declaration of structs_declaration ...@@ -164,5 +168,7 @@ for name, declaration of structs_declaration
msg: 1 msg: 1
code: 9 code: 9
} if client } if client
client.destroy() if client if client
client.system_kicked = true
client.destroy()
return return
\ No newline at end of file
...@@ -104,6 +104,9 @@ ...@@ -104,6 +104,9 @@
this.stoc_send = function(socket, proto, info) { this.stoc_send = function(socket, proto, info) {
var buffer, header, key, ref, struct, value; var buffer, header, key, ref, struct, value;
if (socket.closed) {
return;
}
if (typeof info === 'undefined') { if (typeof info === 'undefined') {
buffer = ""; buffer = "";
} else if (Buffer.isBuffer(info)) { } else if (Buffer.isBuffer(info)) {
...@@ -138,6 +141,9 @@ ...@@ -138,6 +141,9 @@
this.ctos_send = function(socket, proto, info) { this.ctos_send = function(socket, proto, info) {
var buffer, header, key, ref, struct, value; var buffer, header, key, ref, struct, value;
if (socket.closed) {
return;
}
if (typeof info === 'undefined') { if (typeof info === 'undefined') {
buffer = ""; buffer = "";
} else if (Buffer.isBuffer(info)) { } else if (Buffer.isBuffer(info)) {
...@@ -264,6 +270,7 @@ ...@@ -264,6 +270,7 @@
}); });
} }
if (client) { if (client) {
client.system_kicked = true;
client.destroy(); client.destroy();
} }
}; };
......
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