Commit 98cd7f07 authored by nanahira's avatar nanahira

merge

parents e6502813 fa7db253
...@@ -76,6 +76,8 @@ ...@@ -76,6 +76,8 @@
"random_duel": { "random_duel": {
"enabled": false, "enabled": false,
"no_rematch_check": false, "no_rematch_check": false,
"record_match_scores": true,
"blank_pass_match": true,
"ready_time": 20, "ready_time": 20,
"hang_timeout": 90 "hang_timeout": 90
}, },
...@@ -167,7 +169,8 @@ ...@@ -167,7 +169,8 @@
"test_mode": { "test_mode": {
"watch_public_hand": false, "watch_public_hand": false,
"no_connect_count_limit": false, "no_connect_count_limit": false,
"no_ban_player": false "no_ban_player": false,
"surrender_anytime": false
}, },
"pre_util": { "pre_util": {
"enabled": false, "enabled": false,
......
...@@ -59,6 +59,14 @@ ...@@ -59,6 +59,14 @@
"exp_value_part2": " exp", "exp_value_part2": " exp",
"exp_value_part3": ", your score is ", "exp_value_part3": ", your score is ",
"exp_value_part4": ". These points may be reset after the stable release of MyCard.", "exp_value_part4": ". These points may be reset after the stable release of MyCard.",
"random_score_part1": "Today's record of ",
"random_score_part2": ": ",
"random_score_part3": "% WIN, ",
"random_score_part4_combo": "% RAGE QUIT, WIN COMBO ",
"random_score_part5_combo": " !",
"random_score_part4": "%",
"random_score_blank": " didn't have enough duel record today.",
"random_score_not_enough": " didn't have enough duel record today.",
"lp_low_opponent": "もはやお前のライフは風前の灯!", "lp_low_opponent": "もはやお前のライフは風前の灯!",
"lp_low_self": "*Low LP Alert*", "lp_low_self": "*Low LP Alert*",
"kicked_by_player": "was evicted from the game.", "kicked_by_player": "was evicted from the game.",
...@@ -383,6 +391,14 @@ ...@@ -383,6 +391,14 @@
"exp_value_part2": "点经验", "exp_value_part2": "点经验",
"exp_value_part3": ",你的战斗力是", "exp_value_part3": ",你的战斗力是",
"exp_value_part4": "。竞技场部分积分按赛季重置。", "exp_value_part4": "。竞技场部分积分按赛季重置。",
"random_score_part1": "",
"random_score_part2": "的今日战绩:胜率",
"random_score_part3": "%,逃跑率",
"random_score_part4_combo": "%,",
"random_score_part5_combo": "连胜中!",
"random_score_part4": "%",
"random_score_blank": "的今日战绩:正在统计中",
"random_score_not_enough": "的今日战绩:正在统计中",
"lp_low_opponent": "你的生命已经如风中残烛了!", "lp_low_opponent": "你的生命已经如风中残烛了!",
"lp_low_self": "背水一战!", "lp_low_self": "背水一战!",
"kicked_by_player": "被请出了房间", "kicked_by_player": "被请出了房间",
......
...@@ -464,6 +464,7 @@ Cloud_replay_ids = [] ...@@ -464,6 +464,7 @@ Cloud_replay_ids = []
ROOM_all = [] ROOM_all = []
ROOM_players_oppentlist = {} ROOM_players_oppentlist = {}
ROOM_players_banned = [] ROOM_players_banned = []
ROOM_players_scores = {}
ROOM_connected_ip = {} ROOM_connected_ip = {}
ROOM_bad_ip = {} ROOM_bad_ip = {}
...@@ -501,6 +502,42 @@ ROOM_ban_player = (name, ip, reason, countadd = 1)-> ...@@ -501,6 +502,42 @@ ROOM_ban_player = (name, ip, reason, countadd = 1)->
#log.info("banned", name, ip, reason, bannedplayer.count) #log.info("banned", name, ip, reason, bannedplayer.count)
return return
ROOM_player_win = (name)->
if !ROOM_players_scores[name]
ROOM_players_scores[name]={win:0, lose:0, flee:0, combo:0}
ROOM_players_scores[name].win = ROOM_players_scores[name].win + 1
ROOM_players_scores[name].combo = ROOM_players_scores[name].combo + 1
return
ROOM_player_lose = (name)->
if !ROOM_players_scores[name]
ROOM_players_scores[name]={win:0, lose:0, flee:0, combo:0}
ROOM_players_scores[name].lose = ROOM_players_scores[name].lose + 1
ROOM_players_scores[name].combo = 0
return
ROOM_player_flee = (name)->
if !ROOM_players_scores[name]
ROOM_players_scores[name]={win:0, lose:0, flee:0, combo:0}
ROOM_players_scores[name].flee = ROOM_players_scores[name].flee + 1
ROOM_players_scores[name].combo = 0
return
ROOM_player_get_score = (player)->
name = player.name_vpass
score = ROOM_players_scores[name]
if !score
return "#{player.name} ${random_score_blank}"
total = score.win + score.lose + score.flee
if score.win < 2 and total < 3
return "#{player.name} ${random_score_not_enough}"
if score.combo >= 2
return "${random_score_part1}#{player.name} ${random_score_part2} #{Math.ceil(score.win/total*100)}${random_score_part3} #{Math.ceil(score.flee/total*100)}${random_score_part4_combo}#{score.combo}${random_score_part5_combo}"
#return player.name + " 的今日战绩:胜率" + Math.ceil(score.win/total*100) + "%,逃跑率" + Math.ceil(score.flee/total*100) + "%," + score.combo + "连胜中!"
else
return "${random_score_part1}#{player.name} ${random_score_part2} #{Math.ceil(score.win/total*100)}${random_score_part3} #{Math.ceil(score.flee/total*100)}${random_score_part4}"
return
ROOM_find_or_create_by_name = (name, player_ip)-> ROOM_find_or_create_by_name = (name, player_ip)->
uname=name.toUpperCase() uname=name.toUpperCase()
if settings.modules.windbot.enabled and (uname[0...2] == 'AI' or (!settings.modules.random_duel.enabled and uname == '')) if settings.modules.windbot.enabled and (uname[0...2] == 'AI' or (!settings.modules.random_duel.enabled and uname == ''))
...@@ -532,7 +569,7 @@ ROOM_find_or_create_random = (type, player_ip)-> ...@@ -532,7 +569,7 @@ ROOM_find_or_create_random = (type, player_ip)->
playerbanned = (bannedplayer and bannedplayer.count > 3 and moment() < bannedplayer.time) playerbanned = (bannedplayer and bannedplayer.count > 3 and moment() < bannedplayer.time)
result = _.find ROOM_all, (room)-> result = _.find ROOM_all, (room)->
return room and room.random_type != '' and !room.started and return room and room.random_type != '' and !room.started and
((type == '' and room.random_type != 'T') or room.random_type == type) and ((type == '' and (room.random_type == 'S' or (settings.modules.random_duel.blank_pass_match and room.random_type != 'T'))) or room.random_type == type) and
room.get_playing_player().length < max_player and room.get_playing_player().length < max_player and
(settings.modules.random_duel.no_rematch_check or room.get_host() == null or (settings.modules.random_duel.no_rematch_check or room.get_host() == null or
room.get_host().ip != ROOM_players_oppentlist[player_ip]) and room.get_host().ip != ROOM_players_oppentlist[player_ip]) and
...@@ -637,7 +674,7 @@ release_disconnect = (dinfo, reconnected) -> ...@@ -637,7 +674,7 @@ release_disconnect = (dinfo, reconnected) ->
CLIENT_get_authorize_key = (client) -> CLIENT_get_authorize_key = (client) ->
if !settings.modules.mycard.enabled and client.vpass if !settings.modules.mycard.enabled and client.vpass
return client.name + "$" + client.vpass return client.name_vpass
else if settings.modules.mycard.enabled or settings.modules.tournament_mode.enabled or settings.modules.challonge.enabled or client.is_local else if settings.modules.mycard.enabled or settings.modules.tournament_mode.enabled or settings.modules.challonge.enabled or client.is_local
return client.name return client.name
else else
...@@ -938,6 +975,7 @@ class Room ...@@ -938,6 +975,7 @@ class Room
@random_type = '' @random_type = ''
@welcome = '' @welcome = ''
@scores = {} @scores = {}
@decks = {}
@duel_count = 0 @duel_count = 0
@death = 0 @death = 0
@turn = 0 @turn = 0
...@@ -1089,7 +1127,23 @@ class Room ...@@ -1089,7 +1127,23 @@ class Room
#log.info 'room-delete', this.name, ROOM_all.length #log.info 'room-delete', this.name, ROOM_all.length
score_array=[] score_array=[]
for name, score of @scores for name, score of @scores
score_array.push { name: name, score: score } score_form = { name: name.split('$')[0], score: score, deck: null, name_vpass: name }
if @decks[name]
score_form.deck = @decks[name]
score_array.push score_form
if settings.modules.random_duel.record_match_scores and @random_type == 'M'
if score_array.length == 2
if score_array[0].score != score_array[1].score
if score_array[0].score > score_array[1].score
ROOM_player_win(score_array[0].name_vpass)
ROOM_player_lose(score_array[1].name_vpass)
else
ROOM_player_win(score_array[1].name_vpass)
ROOM_player_lose(score_array[0].name_vpass)
if score_array.length == 1 # same name
#log.info score_array[0].name
ROOM_player_win(score_array[0].name_vpass)
ROOM_player_lose(score_array[0].name_vpass)
if settings.modules.arena_mode.enabled and @arena if settings.modules.arena_mode.enabled and @arena
#log.info 'SCORE', score_array, @start_time #log.info 'SCORE', score_array, @start_time
end_time = moment().format() end_time = moment().format()
...@@ -1097,9 +1151,9 @@ class Room ...@@ -1097,9 +1151,9 @@ class Room
@start_time = end_time @start_time = end_time
if score_array.length != 2 if score_array.length != 2
if !score_array[0] if !score_array[0]
score_array[0] = { name: null, score: -5 } score_array[0] = { name: null, score: -5, deck: null }
if !score_array[1] if !score_array[1]
score_array[1] = { name: null, score: -5 } score_array[1] = { name: null, score: -5, deck: null }
score_array[0].score = -5 score_array[0].score = -5
score_array[1].score = -5 score_array[1].score = -5
request.post { url : settings.modules.arena_mode.post_score , form : { request.post { url : settings.modules.arena_mode.post_score , form : {
...@@ -1108,6 +1162,8 @@ class Room ...@@ -1108,6 +1162,8 @@ class Room
usernameB: score_array[1].name, usernameB: score_array[1].name,
userscoreA: score_array[0].score, userscoreA: score_array[0].score,
userscoreB: score_array[1].score, userscoreB: score_array[1].score,
userdeckA: score_array[0].deck,
userdeckB: score_array[1].deck,
start: @start_time, start: @start_time,
end: end_time, end: end_time,
arena: @arena arena: @arena
...@@ -1207,17 +1263,17 @@ class Room ...@@ -1207,17 +1263,17 @@ class Room
if !settings.modules.challonge.enabled or !@started or @hostinfo.mode == 2 if !settings.modules.challonge.enabled or !@started or @hostinfo.mode == 2
return null return null
challonge_duel_log = {} challonge_duel_log = {}
if @scores[@dueling_players[0].name] > @scores[@dueling_players[1].name] if @scores[@dueling_players[0].name_vpass] > @scores[@dueling_players[1].name_vpass]
challonge_duel_log.winnerId = @dueling_players[0].challonge_info.id challonge_duel_log.winnerId = @dueling_players[0].challonge_info.id
else if @scores[@dueling_players[0].name] < @scores[@dueling_players[1].name] else if @scores[@dueling_players[0].name_vpass] < @scores[@dueling_players[1].name_vpass]
challonge_duel_log.winnerId = @dueling_players[1].challonge_info.id challonge_duel_log.winnerId = @dueling_players[1].challonge_info.id
else else
challonge_duel_log.winnerId = "tie" challonge_duel_log.winnerId = "tie"
if settings.modules.challonge.post_detailed_score if settings.modules.challonge.post_detailed_score
if @dueling_players[0].challonge_info.id == @challonge_info.player1Id and @dueling_players[1].challonge_info.id == @challonge_info.player2Id if @dueling_players[0].challonge_info.id == @challonge_info.player1Id and @dueling_players[1].challonge_info.id == @challonge_info.player2Id
challonge_duel_log.scoresCsv = @scores[@dueling_players[0].name] + "-" + @scores[@dueling_players[1].name] challonge_duel_log.scoresCsv = @scores[@dueling_players[0].name_vpass] + "-" + @scores[@dueling_players[1].name_vpass]
else if @dueling_players[1].challonge_info.id == @challonge_info.player1Id and @dueling_players[0].challonge_info.id == @challonge_info.player2Id else if @dueling_players[1].challonge_info.id == @challonge_info.player1Id and @dueling_players[0].challonge_info.id == @challonge_info.player2Id
challonge_duel_log.scoresCsv = @scores[@dueling_players[1].name] + "-" + @scores[@dueling_players[0].name] challonge_duel_log.scoresCsv = @scores[@dueling_players[1].name_vpass] + "-" + @scores[@dueling_players[0].name_vpass]
else else
challonge_duel_log.scoresCsv = "0-0" challonge_duel_log.scoresCsv = "0-0"
log.warn("Score mismatch.", @name) log.warn("Score mismatch.", @name)
...@@ -1278,17 +1334,18 @@ class Room ...@@ -1278,17 +1334,18 @@ class Room
#log.info(client.name, @started, @disconnector, @random_type, @players.length) #log.info(client.name, @started, @disconnector, @random_type, @players.length)
if @arena and !@started if @arena and !@started
for player in @players when player.pos != 7 for player in @players when player.pos != 7
@scores[player.name] = 0 @scores[player.name_vpass] = 0
if @players.length == 2 if @players.length == 2
@scores[client.name] = -9 @scores[client.name_vpass] = -9
index = _.indexOf(@players, client) index = _.indexOf(@players, client)
@players.splice(index, 1) unless index == -1 @players.splice(index, 1) unless index == -1
if @started and @disconnector != 'server' and client.pos < 4 if @started and @disconnector != 'server' and client.pos < 4
@finished = true @finished = true
if !@finished_by_death if !@finished_by_death
@scores[client.name] = -9 @scores[client.name_vpass] = -9
if @random_type and not client.flee_free and (!settings.modules.reconnect.enabled or @get_disconnected_count() == 0) if @random_type and not client.flee_free and (!settings.modules.reconnect.enabled or @get_disconnected_count() == 0)
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_flee}") ROOM_ban_player(client.name, client.ip, "${random_ban_reason_flee}")
ROOM_player_flee(client.name_vpass)
if @players.length and !(@windbot and client.is_host) and !(@arena and !@started and client.pos <= 3) if @players.length and !(@windbot and client.is_host) and !(@arena and !@started and client.pos <= 3)
ygopro.stoc_send_chat_to_room this, "#{client.name} ${left_game}" + if error then ": #{error}" else '' ygopro.stoc_send_chat_to_room this, "#{client.name} ${left_game}" + if error then ": #{error}" else ''
roomlist.update(this) if !@windbot and !@started and settings.modules.http.websocket_roomlist roomlist.update(this) if !@windbot and !@started and settings.modules.http.websocket_roomlist
...@@ -1600,6 +1657,7 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)-> ...@@ -1600,6 +1657,7 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)->
buffer = struct.buffer buffer = struct.buffer
client.name = name client.name = name
client.vpass = vpass client.vpass = vpass
client.name_vpass = if vpass then name + "$" + vpass else name
#console.log client.name, client.vpass #console.log client.name, client.vpass
if settings.modules.vip.enabled and CLIENT_check_vip(client) if settings.modules.vip.enabled and CLIENT_check_vip(client)
client.vip = true client.vip = true
...@@ -1756,6 +1814,9 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -1756,6 +1814,9 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
when 4 when 4
room = ROOM_find_or_create_by_name('M#' + info.pass.slice(8)) room = ROOM_find_or_create_by_name('M#' + info.pass.slice(8))
if room if room
for player in room.get_playing_player() when player and player.name == client.name
ygopro.stoc_die(client, '${invalid_password_unauthorized}')
return
room.private = true room.private = true
room.arena = settings.modules.arena_mode.mode room.arena = settings.modules.arena_mode.mode
if room.arena == "athletic" if room.arena == "athletic"
...@@ -2047,7 +2108,10 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -2047,7 +2108,10 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)->
ygopro.stoc_send_chat(client, "#{client.name}${exp_value_part1}#{body.exp}${exp_value_part2}${exp_value_part3}#{Math.round(body.pt)}#{rank_txt}${exp_value_part4}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "#{client.name}${exp_value_part1}#{body.exp}${exp_value_part2}${exp_value_part3}#{Math.round(body.pt)}#{rank_txt}${exp_value_part4}", ygopro.constants.COLORS.BABYBLUE)
#client.score_shown = true #client.score_shown = true
return return
if settings.modules.random_duel.record_match_scores and room.random_type == 'M'
ygopro.stoc_send_chat_to_room(room, ROOM_player_get_score(client), ygopro.constants.COLORS.GREEN)
for player in room.players when player.pos != 7 and player != client
ygopro.stoc_send_chat(client, ROOM_player_get_score(player), ygopro.constants.COLORS.GREEN)
if !room.recorder if !room.recorder
room.recorder = recorder = net.connect room.port, -> room.recorder = recorder = net.connect room.port, ->
ygopro.ctos_send recorder, 'PLAYER_INFO', { ygopro.ctos_send recorder, 'PLAYER_INFO', {
...@@ -2260,7 +2324,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)-> ...@@ -2260,7 +2324,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server)->
delete room.long_resolve_card delete room.long_resolve_card
delete room.long_resolve_chain delete room.long_resolve_chain
if room and !room.finished and room.dueling_players[pos] if room and !room.finished and room.dueling_players[pos]
room.winner_name = room.dueling_players[pos].name room.winner_name = room.dueling_players[pos].name_vpass
#log.info room.dueling_players, pos #log.info room.dueling_players, pos
room.scores[room.winner_name] = room.scores[room.winner_name] + 1 room.scores[room.winner_name] = room.scores[room.winner_name] + 1
if settings.modules.vip.enabled and room.dueling_players[pos].vip and vip_info.players[room.dueling_players[pos].name].victory if settings.modules.vip.enabled and room.dueling_players[pos].vip and vip_info.players[room.dueling_players[pos].name].victory
...@@ -2619,15 +2683,18 @@ ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)-> ...@@ -2619,15 +2683,18 @@ ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
room.dueling_players = [] room.dueling_players = []
for player in room.players when player.pos != 7 for player in room.players when player.pos != 7
room.dueling_players[player.pos] = player room.dueling_players[player.pos] = player
room.scores[player.name] = 0 room.scores[player.name_vpass] = 0
room.player_datas.push ip: player.ip, name: player.name room.player_datas.push ip: player.ip, name: player.name
if room.random_type == 'T' if room.random_type == 'T'
# 双打房不记录匹配过 # 双打房不记录匹配过
ROOM_players_oppentlist[player.ip] = null ROOM_players_oppentlist[player.ip] = null
if settings.modules.tips.enabled if settings.modules.tips.enabled
ygopro.stoc_send_random_tip(client) ygopro.stoc_send_random_tip(client)
if settings.modules.deck_log.enabled and client.main and client.main.length and not client.deck_saved and not room.windbot deck_text = null
if client.main and client.main.length
deck_text = '#ygopro-server deck log\n#main\n' + client.main.join('\n') + '\n!side\n' + client.side.join('\n') + '\n' deck_text = '#ygopro-server deck log\n#main\n' + client.main.join('\n') + '\n!side\n' + client.side.join('\n') + '\n'
room.decks[client.name] = deck_text
if settings.modules.deck_log.enabled and deck_text and not client.deck_saved and not room.windbot
deck_arena = settings.modules.deck_log.arena + '-' deck_arena = settings.modules.deck_log.arena + '-'
if room.arena if room.arena
deck_arena = deck_arena + room.arena deck_arena = deck_arena + room.arena
...@@ -2668,7 +2735,7 @@ ygopro.ctos_follow 'SURRENDER', true, (buffer, info, client, server)-> ...@@ -2668,7 +2735,7 @@ ygopro.ctos_follow 'SURRENDER', true, (buffer, info, client, server)->
return unless room return unless room
if !room.started if !room.started
return true return true
if room.random_type and room.turn < 3 and not client.flee_free if room.random_type and room.turn < 3 and not client.flee_free and not settings.modules.test_mode.surrender_anytime and not (room.random_type=='M' and settings.modules.random_duel.record_match_scores)
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE)
return true return true
if room.hostinfo.mode == 2 if room.hostinfo.mode == 2
...@@ -2993,13 +3060,13 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)-> ...@@ -2993,13 +3060,13 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server)->
else else
client.start_deckbuf = buffer 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_vpass] != room.scores[room.dueling_players[oppo_pos].name_vpass]
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_vpass] > room.scores[room.dueling_players[oppo_pos].name_vpass] then 0 else oppo_pos
room.finished_by_death = true room.finished_by_death = true
ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE)
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_vpass] = -1
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]) CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2 CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2
return true return true
...@@ -3194,7 +3261,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)-> ...@@ -3194,7 +3261,7 @@ ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)->
if client.side_tcount == 1 if client.side_tcount == 1
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_vpass] = -9
CLIENT_kick(client) CLIENT_kick(client)
clearInterval sinterval clearInterval sinterval
else else
...@@ -3248,7 +3315,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server)-> ...@@ -3248,7 +3315,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server)->
replay_filename: replay_filename, replay_filename: replay_filename,
roommode: room.hostinfo.mode, roommode: room.hostinfo.mode,
players: (for player in room.dueling_players players: (for player in room.dueling_players
name: player.name + (if settings.modules.tournament_mode.show_ip and !player.is_local then (" (IP: " + player.ip.slice(7) + ")") else "") + (if settings.modules.tournament_mode.show_info and not (room.hostinfo.mode == 2 and player.pos % 2 > 0) then (" (Score:" + room.scores[player.name] + " LP:" + (if player.lp? then player.lp else room.hostinfo.start_lp) + (if room.hostinfo.mode != 2 then (" Cards:" + (if player.card_count? then player.card_count else room.hostinfo.start_hand)) else "") + ")") else ""), name: player.name + (if settings.modules.tournament_mode.show_ip and !player.is_local then (" (IP: " + player.ip.slice(7) + ")") else "") + (if settings.modules.tournament_mode.show_info and not (room.hostinfo.mode == 2 and player.pos % 2 > 0) then (" (Score:" + room.scores[player.name_vpass] + " LP:" + (if player.lp? then player.lp else room.hostinfo.start_lp) + (if room.hostinfo.mode != 2 then (" Cards:" + (if player.card_count? then player.card_count else room.hostinfo.start_hand)) else "") + ")") else ""),
winner: player.pos == room.winner winner: player.pos == room.winner
) )
} }
...@@ -3271,8 +3338,8 @@ if settings.modules.random_duel.enabled ...@@ -3271,8 +3338,8 @@ if settings.modules.random_duel.enabled
if time_passed >= settings.modules.random_duel.hang_timeout if time_passed >= settings.modules.random_duel.hang_timeout
room.last_active_time = moment() room.last_active_time = moment()
ROOM_ban_player(room.waiting_for_player.name, room.waiting_for_player.ip, "${random_ban_reason_AFK}") ROOM_ban_player(room.waiting_for_player.name, room.waiting_for_player.ip, "${random_ban_reason_AFK}")
room.scores[room.waiting_for_player.name] = -9 room.scores[room.waiting_for_player.name_vpass] = -9
#log.info room.waiting_for_player.name, room.scores[room.waiting_for_player.name] #log.info room.waiting_for_player.name, room.scores[room.waiting_for_player.name_vpass]
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)
CLIENT_kick(room.waiting_for_player) CLIENT_kick(room.waiting_for_player)
else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10) else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10)
...@@ -3289,8 +3356,8 @@ if settings.modules.mycard.enabled ...@@ -3289,8 +3356,8 @@ if settings.modules.mycard.enabled
if time_passed >= settings.modules.random_duel.hang_timeout if time_passed >= settings.modules.random_duel.hang_timeout
room.last_active_time = moment() room.last_active_time = moment()
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.scores[room.waiting_for_player.name] = -9 room.scores[room.waiting_for_player.name_vpass] = -9
#log.info room.waiting_for_player.name, room.scores[room.waiting_for_player.name] #log.info room.waiting_for_player.name, room.scores[room.waiting_for_player.name_vpass]
CLIENT_kick(room.waiting_for_player) CLIENT_kick(room.waiting_for_player)
else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10) else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10)
ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${afk_warn_part1}#{settings.modules.random_duel.hang_timeout - time_passed}${afk_warn_part2}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${afk_warn_part1}#{settings.modules.random_duel.hang_timeout - time_passed}${afk_warn_part2}", ygopro.constants.COLORS.RED)
...@@ -3369,7 +3436,7 @@ if settings.modules.http ...@@ -3369,7 +3436,7 @@ if settings.modules.http
needpass: (room.name.indexOf('$') != -1).toString(), needpass: (room.name.indexOf('$') != -1).toString(),
users: (for player in room.players when player.pos? users: (for player in room.players when player.pos?
id: (-1).toString(), id: (-1).toString(),
name: player.name + (if settings.modules.http.show_ip and pass_validated and !player.is_local then (" (IP: " + player.ip.slice(7) + ")") else "") + (if settings.modules.http.show_info and room.started and player.pos != 7 and not (room.hostinfo.mode == 2 and player.pos % 2 > 0) then (" (Score:" + room.scores[player.name] + " LP:" + (if player.lp? then player.lp else room.hostinfo.start_lp) + (if room.hostinfo.mode != 2 then (" Cards:" + (if player.card_count? then player.card_count else room.hostinfo.start_hand)) else "") + ")") else ""), name: player.name + (if settings.modules.http.show_ip and pass_validated and !player.is_local then (" (IP: " + player.ip.slice(7) + ")") else "") + (if settings.modules.http.show_info and room.started and player.pos != 7 and not (room.hostinfo.mode == 2 and player.pos % 2 > 0) then (" (Score:" + room.scores[player.name_vpass] + " LP:" + (if player.lp? then player.lp else room.hostinfo.start_lp) + (if room.hostinfo.mode != 2 then (" Cards:" + (if player.card_count? then player.card_count else room.hostinfo.start_hand)) else "") + ")") else ""),
pos: player.pos pos: player.pos
), ),
istart: if room.started then (if settings.modules.http.show_info then ("Duel:" + room.duel_count + " " + (if room.changing_side then "Siding" else "Turn:" + (if room.turn? then room.turn else 0) + (if room.death then "/" + (if room.death > 0 then room.death - 1 else "Death") else ""))) else 'start') else 'wait' istart: if room.started then (if settings.modules.http.show_info then ("Duel:" + room.duel_count + " " + (if room.changing_side then "Siding" else "Turn:" + (if room.turn? then room.turn else 0) + (if room.death then "/" + (if room.death > 0 then room.death - 1 else "Death") else ""))) else 'start') else 'wait'
...@@ -3536,8 +3603,8 @@ if settings.modules.http ...@@ -3536,8 +3603,8 @@ if settings.modules.http
for room in ROOM_all when room and room.established and (u.query.kick == "all" or u.query.kick == room.port.toString() or u.query.kick == room.name) for room in ROOM_all when room and room.established and (u.query.kick == "all" or u.query.kick == room.port.toString() or u.query.kick == room.name)
kick_room_found = true kick_room_found = true
if room.started if room.started
room.scores[room.dueling_players[0].name] = 0 room.scores[room.dueling_players[0].name_vpass] = 0
room.scores[room.dueling_players[1].name] = 0 room.scores[room.dueling_players[1].name_vpass] = 0
room.kicked = true room.kicked = true
room.process.kill() room.process.kill()
room.delete() room.delete()
...@@ -3563,7 +3630,7 @@ if settings.modules.http ...@@ -3563,7 +3630,7 @@ if settings.modules.http
else else
switch settings.modules.http.quick_death_rule switch settings.modules.http.quick_death_rule
when 2,3 when 2,3
if room.scores[room.dueling_players[0].name] == room.scores[room.dueling_players[oppo_pos].name] if room.scores[room.dueling_players[0].name_vpass] == room.scores[room.dueling_players[oppo_pos].name_vpass]
if settings.modules.http.quick_death_rule == 3 if settings.modules.http.quick_death_rule == 3
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)
...@@ -3571,12 +3638,12 @@ if settings.modules.http ...@@ -3571,12 +3638,12 @@ if settings.modules.http
room.death = 5 room.death = 5
ygopro.stoc_send_chat_to_room(room, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE)
else else
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_vpass] > room.scores[room.dueling_players[oppo_pos].name_vpass] then 0 else oppo_pos
room.finished_by_death = true room.finished_by_death = true
ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE)
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_vpass] = -1
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]) CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2 CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]) if room.hostinfo.mode == 2
when 1 when 1
......
// Generated by CoffeeScript 1.12.7 // Generated by CoffeeScript 1.12.7
(function() { (function() {
var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_vip_status, CLIENT_use_cdkey, Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, 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, VIP_generate_cdkeys, _, addCallback, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_queue_callbacks, chat_color, concat_name, config, cppversion, crypto, date, default_config, default_data, dialogues, disconnect_list, duel_log, e, exec, execFile, fs, geoip, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_requesting, j, k, l, len, len1, lflists, list, loadJSON, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, oldwords, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, ref, ref1, ref2, refresh_challonge_cache, release_disconnect, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, v, vip_info, wait_room_start, wait_room_start_arena, windbot_looplimit, windbots, words, ygopro, zlib; var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_vip_status, CLIENT_use_cdkey, Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, 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_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_banned, ROOM_players_oppentlist, ROOM_players_scores, ROOM_unwelcome, ROOM_validate, Room, SERVER_clear_disconnect, VIP_generate_cdkeys, _, addCallback, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_queue_callbacks, chat_color, concat_name, config, cppversion, crypto, date, default_config, default_data, dialogues, disconnect_list, duel_log, e, exec, execFile, fs, geoip, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_requesting, j, k, l, len, len1, lflists, list, loadJSON, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, oldwords, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, ref, ref1, ref2, refresh_challonge_cache, release_disconnect, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, v, vip_info, wait_room_start, wait_room_start_arena, windbot_looplimit, windbots, words, ygopro, zlib;
net = require('net'); net = require('net');
...@@ -566,6 +566,8 @@ ...@@ -566,6 +566,8 @@
ROOM_players_banned = []; ROOM_players_banned = [];
ROOM_players_scores = {};
ROOM_connected_ip = {}; ROOM_connected_ip = {};
ROOM_bad_ip = {}; ROOM_bad_ip = {};
...@@ -627,6 +629,63 @@ ...@@ -627,6 +629,63 @@
} }
}; };
ROOM_player_win = function(name) {
if (!ROOM_players_scores[name]) {
ROOM_players_scores[name] = {
win: 0,
lose: 0,
flee: 0,
combo: 0
};
}
ROOM_players_scores[name].win = ROOM_players_scores[name].win + 1;
ROOM_players_scores[name].combo = ROOM_players_scores[name].combo + 1;
};
ROOM_player_lose = function(name) {
if (!ROOM_players_scores[name]) {
ROOM_players_scores[name] = {
win: 0,
lose: 0,
flee: 0,
combo: 0
};
}
ROOM_players_scores[name].lose = ROOM_players_scores[name].lose + 1;
ROOM_players_scores[name].combo = 0;
};
ROOM_player_flee = function(name) {
if (!ROOM_players_scores[name]) {
ROOM_players_scores[name] = {
win: 0,
lose: 0,
flee: 0,
combo: 0
};
}
ROOM_players_scores[name].flee = ROOM_players_scores[name].flee + 1;
ROOM_players_scores[name].combo = 0;
};
ROOM_player_get_score = function(player) {
var name, score, total;
name = player.name_vpass;
score = ROOM_players_scores[name];
if (!score) {
return player.name + " ${random_score_blank}";
}
total = score.win + score.lose + score.flee;
if (score.win < 2 && total < 3) {
return player.name + " ${random_score_not_enough}";
}
if (score.combo >= 2) {
return "${random_score_part1}" + player.name + " ${random_score_part2} " + (Math.ceil(score.win / total * 100)) + "${random_score_part3} " + (Math.ceil(score.flee / total * 100)) + "${random_score_part4_combo}" + score.combo + "${random_score_part5_combo}";
} else {
return "${random_score_part1}" + player.name + " ${random_score_part2} " + (Math.ceil(score.win / total * 100)) + "${random_score_part3} " + (Math.ceil(score.flee / total * 100)) + "${random_score_part4}";
}
};
ROOM_find_or_create_by_name = function(name, player_ip) { ROOM_find_or_create_by_name = function(name, player_ip) {
var room, uname; var room, uname;
uname = name.toUpperCase(); uname = name.toUpperCase();
...@@ -673,7 +732,7 @@ ...@@ -673,7 +732,7 @@
max_player = type === 'T' ? 4 : 2; max_player = type === 'T' ? 4 : 2;
playerbanned = bannedplayer && bannedplayer.count > 3 && moment() < bannedplayer.time; playerbanned = bannedplayer && bannedplayer.count > 3 && moment() < bannedplayer.time;
result = _.find(ROOM_all, function(room) { result = _.find(ROOM_all, function(room) {
return room && room.random_type !== '' && !room.started && ((type === '' && room.random_type !== 'T') || room.random_type === type) && room.get_playing_player().length < max_player && (settings.modules.random_duel.no_rematch_check || room.get_host() === null || room.get_host().ip !== ROOM_players_oppentlist[player_ip]) && (playerbanned === room.deprecated || type === 'T'); return room && room.random_type !== '' && !room.started && ((type === '' && (room.random_type === 'S' || (settings.modules.random_duel.blank_pass_match && room.random_type !== 'T'))) || room.random_type === type) && room.get_playing_player().length < max_player && (settings.modules.random_duel.no_rematch_check || room.get_host() === null || room.get_host().ip !== ROOM_players_oppentlist[player_ip]) && (playerbanned === room.deprecated || type === 'T');
}); });
if (result) { if (result) {
result.welcome = '${random_duel_enter_room_waiting}'; result.welcome = '${random_duel_enter_room_waiting}';
...@@ -815,7 +874,7 @@ ...@@ -815,7 +874,7 @@
CLIENT_get_authorize_key = function(client) { CLIENT_get_authorize_key = function(client) {
if (!settings.modules.mycard.enabled && client.vpass) { if (!settings.modules.mycard.enabled && client.vpass) {
return client.name + "$" + client.vpass; return client.name_vpass;
} else if (settings.modules.mycard.enabled || settings.modules.tournament_mode.enabled || settings.modules.challonge.enabled || client.is_local) { } else if (settings.modules.mycard.enabled || settings.modules.tournament_mode.enabled || settings.modules.challonge.enabled || client.is_local) {
return client.name; return client.name;
} else { } else {
...@@ -1203,6 +1262,7 @@ ...@@ -1203,6 +1262,7 @@
this.random_type = ''; this.random_type = '';
this.welcome = ''; this.welcome = '';
this.scores = {}; this.scores = {};
this.decks = {};
this.duel_count = 0; this.duel_count = 0;
this.death = 0; this.death = 0;
this.turn = 0; this.turn = 0;
...@@ -1390,7 +1450,7 @@ ...@@ -1390,7 +1450,7 @@
} }
Room.prototype["delete"] = function() { Room.prototype["delete"] = function() {
var end_time, index, log_rep_id, name, player_ips, player_names, recorder_buffer, ref3, replay_id, score, score_array; var end_time, index, log_rep_id, name, player_ips, player_names, recorder_buffer, ref3, replay_id, score, score_array, score_form;
if (this.deleted) { if (this.deleted) {
return; return;
} }
...@@ -1398,10 +1458,33 @@ ...@@ -1398,10 +1458,33 @@
ref3 = this.scores; ref3 = this.scores;
for (name in ref3) { for (name in ref3) {
score = ref3[name]; score = ref3[name];
score_array.push({ score_form = {
name: name, name: name.split('$')[0],
score: score score: score,
}); deck: null,
name_vpass: name
};
if (this.decks[name]) {
score_form.deck = this.decks[name];
}
score_array.push(score_form);
}
if (settings.modules.random_duel.record_match_scores && this.random_type === 'M') {
if (score_array.length === 2) {
if (score_array[0].score !== score_array[1].score) {
if (score_array[0].score > score_array[1].score) {
ROOM_player_win(score_array[0].name_vpass);
ROOM_player_lose(score_array[1].name_vpass);
} else {
ROOM_player_win(score_array[1].name_vpass);
ROOM_player_lose(score_array[0].name_vpass);
}
}
}
if (score_array.length === 1) {
ROOM_player_win(score_array[0].name_vpass);
ROOM_player_lose(score_array[0].name_vpass);
}
} }
if (settings.modules.arena_mode.enabled && this.arena) { if (settings.modules.arena_mode.enabled && this.arena) {
end_time = moment().format(); end_time = moment().format();
...@@ -1412,13 +1495,15 @@ ...@@ -1412,13 +1495,15 @@
if (!score_array[0]) { if (!score_array[0]) {
score_array[0] = { score_array[0] = {
name: null, name: null,
score: -5 score: -5,
deck: null
}; };
} }
if (!score_array[1]) { if (!score_array[1]) {
score_array[1] = { score_array[1] = {
name: null, name: null,
score: -5 score: -5,
deck: null
}; };
} }
score_array[0].score = -5; score_array[0].score = -5;
...@@ -1432,6 +1517,8 @@ ...@@ -1432,6 +1517,8 @@
usernameB: score_array[1].name, usernameB: score_array[1].name,
userscoreA: score_array[0].score, userscoreA: score_array[0].score,
userscoreB: score_array[1].score, userscoreB: score_array[1].score,
userdeckA: score_array[0].deck,
userdeckB: score_array[1].deck,
start: this.start_time, start: this.start_time,
end: end_time, end: end_time,
arena: this.arena arena: this.arena
...@@ -1560,18 +1647,18 @@ ...@@ -1560,18 +1647,18 @@
return null; return null;
} }
challonge_duel_log = {}; challonge_duel_log = {};
if (this.scores[this.dueling_players[0].name] > this.scores[this.dueling_players[1].name]) { if (this.scores[this.dueling_players[0].name_vpass] > this.scores[this.dueling_players[1].name_vpass]) {
challonge_duel_log.winnerId = this.dueling_players[0].challonge_info.id; challonge_duel_log.winnerId = this.dueling_players[0].challonge_info.id;
} else if (this.scores[this.dueling_players[0].name] < this.scores[this.dueling_players[1].name]) { } else if (this.scores[this.dueling_players[0].name_vpass] < this.scores[this.dueling_players[1].name_vpass]) {
challonge_duel_log.winnerId = this.dueling_players[1].challonge_info.id; challonge_duel_log.winnerId = this.dueling_players[1].challonge_info.id;
} else { } else {
challonge_duel_log.winnerId = "tie"; challonge_duel_log.winnerId = "tie";
} }
if (settings.modules.challonge.post_detailed_score) { if (settings.modules.challonge.post_detailed_score) {
if (this.dueling_players[0].challonge_info.id === this.challonge_info.player1Id && this.dueling_players[1].challonge_info.id === this.challonge_info.player2Id) { if (this.dueling_players[0].challonge_info.id === this.challonge_info.player1Id && this.dueling_players[1].challonge_info.id === this.challonge_info.player2Id) {
challonge_duel_log.scoresCsv = this.scores[this.dueling_players[0].name] + "-" + this.scores[this.dueling_players[1].name]; challonge_duel_log.scoresCsv = this.scores[this.dueling_players[0].name_vpass] + "-" + this.scores[this.dueling_players[1].name_vpass];
} else if (this.dueling_players[1].challonge_info.id === this.challonge_info.player1Id && this.dueling_players[0].challonge_info.id === this.challonge_info.player2Id) { } else if (this.dueling_players[1].challonge_info.id === this.challonge_info.player1Id && this.dueling_players[0].challonge_info.id === this.challonge_info.player2Id) {
challonge_duel_log.scoresCsv = this.scores[this.dueling_players[1].name] + "-" + this.scores[this.dueling_players[0].name]; challonge_duel_log.scoresCsv = this.scores[this.dueling_players[1].name_vpass] + "-" + this.scores[this.dueling_players[0].name_vpass];
} else { } else {
challonge_duel_log.scoresCsv = "0-0"; challonge_duel_log.scoresCsv = "0-0";
log.warn("Score mismatch.", this.name); log.warn("Score mismatch.", this.name);
...@@ -1650,11 +1737,11 @@ ...@@ -1650,11 +1737,11 @@
for (m = 0, len2 = ref3.length; m < len2; m++) { for (m = 0, len2 = ref3.length; m < len2; m++) {
player = ref3[m]; player = ref3[m];
if (player.pos !== 7) { if (player.pos !== 7) {
this.scores[player.name] = 0; this.scores[player.name_vpass] = 0;
} }
} }
if (this.players.length === 2) { if (this.players.length === 2) {
this.scores[client.name] = -9; this.scores[client.name_vpass] = -9;
} }
} }
index = _.indexOf(this.players, client); index = _.indexOf(this.players, client);
...@@ -1664,9 +1751,10 @@ ...@@ -1664,9 +1751,10 @@
if (this.started && this.disconnector !== 'server' && client.pos < 4) { if (this.started && this.disconnector !== 'server' && client.pos < 4) {
this.finished = true; this.finished = true;
if (!this.finished_by_death) { if (!this.finished_by_death) {
this.scores[client.name] = -9; this.scores[client.name_vpass] = -9;
if (this.random_type && !client.flee_free && (!settings.modules.reconnect.enabled || this.get_disconnected_count() === 0)) { if (this.random_type && !client.flee_free && (!settings.modules.reconnect.enabled || this.get_disconnected_count() === 0)) {
ROOM_ban_player(client.name, client.ip, "${random_ban_reason_flee}"); ROOM_ban_player(client.name, client.ip, "${random_ban_reason_flee}");
ROOM_player_flee(client.name_vpass);
} }
} }
} }
...@@ -2017,6 +2105,7 @@ ...@@ -2017,6 +2105,7 @@
buffer = struct.buffer; buffer = struct.buffer;
client.name = name; client.name = name;
client.vpass = vpass; client.vpass = vpass;
client.name_vpass = vpass ? name + "$" + vpass : name;
if (settings.modules.vip.enabled && CLIENT_check_vip(client)) { if (settings.modules.vip.enabled && CLIENT_check_vip(client)) {
client.vip = true; client.vip = true;
} }
...@@ -2121,7 +2210,7 @@ ...@@ -2121,7 +2210,7 @@
return (checksum & 0xFF) === 0; return (checksum & 0xFF) === 0;
}; };
finish = function(buffer) { finish = function(buffer) {
var action, len2, len3, len4, line, m, n, name, o, opt1, opt2, opt3, options, ref3, ref4, ref5, room, title; var action, len2, len3, len4, len5, line, m, n, name, o, opt1, opt2, opt3, options, p, player, ref3, ref4, ref5, ref6, room, title;
if (client.closed) { if (client.closed) {
return; return;
} }
...@@ -2173,6 +2262,15 @@ ...@@ -2173,6 +2262,15 @@
case 4: case 4:
room = ROOM_find_or_create_by_name('M#' + info.pass.slice(8)); room = ROOM_find_or_create_by_name('M#' + info.pass.slice(8));
if (room) { if (room) {
ref3 = room.get_playing_player();
for (m = 0, len2 = ref3.length; m < len2; m++) {
player = ref3[m];
if (!(player && player.name === client.name)) {
continue;
}
ygopro.stoc_die(client, '${invalid_password_unauthorized}');
return;
}
room["private"] = true; room["private"] = true;
room.arena = settings.modules.arena_mode.mode; room.arena = settings.modules.arena_mode.mode;
if (room.arena === "athletic") { if (room.arena === "athletic") {
...@@ -2203,24 +2301,24 @@ ...@@ -2203,24 +2301,24 @@
client.rid = _.indexOf(ROOM_all, room); client.rid = _.indexOf(ROOM_all, room);
client.is_post_watcher = true; client.is_post_watcher = true;
if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) { if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) {
ref3 = _.lines(vip_info.players[client.name].words); ref4 = _.lines(vip_info.players[client.name].words);
for (m = 0, len2 = ref3.length; m < len2; m++) { for (n = 0, len3 = ref4.length; n < len3; n++) {
line = ref3[m]; line = ref4[n];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK); ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
} }
} else if (settings.modules.words.enabled && words.words[client.name]) { } else if (settings.modules.words.enabled && words.words[client.name]) {
ref4 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]); ref5 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (n = 0, len3 = ref4.length; n < len3; n++) { for (o = 0, len4 = ref5.length; o < len4; o++) {
line = ref4[n]; line = ref5[o];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK); ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
} }
} }
ygopro.stoc_send_chat_to_room(room, client.name + " ${watch_join}"); ygopro.stoc_send_chat_to_room(room, client.name + " ${watch_join}");
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);
ref5 = room.watcher_buffers; ref6 = room.watcher_buffers;
for (o = 0, len4 = ref5.length; o < len4; o++) { for (p = 0, len5 = ref6.length; p < len5; p++) {
buffer = ref5[o]; buffer = ref6[p];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -2486,7 +2584,7 @@ ...@@ -2486,7 +2584,7 @@
}); });
ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var len2, len3, line, m, n, recorder, ref3, ref4, room, watcher; var len2, len3, len4, line, m, n, o, player, recorder, ref3, ref4, ref5, room, watcher;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && !client.reconnecting)) { if (!(room && !client.reconnecting)) {
return; return;
...@@ -2529,6 +2627,16 @@ ...@@ -2529,6 +2627,16 @@
} }
}); });
} }
if (settings.modules.random_duel.record_match_scores && room.random_type === 'M') {
ygopro.stoc_send_chat_to_room(room, ROOM_player_get_score(client), ygopro.constants.COLORS.GREEN);
ref5 = room.players;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player.pos !== 7 && player !== client) {
ygopro.stoc_send_chat(client, ROOM_player_get_score(player), ygopro.constants.COLORS.GREEN);
}
}
}
if (!room.recorder) { if (!room.recorder) {
room.recorder = recorder = net.connect(room.port, function() { room.recorder = recorder = net.connect(room.port, function() {
ygopro.ctos_send(recorder, 'PLAYER_INFO', { ygopro.ctos_send(recorder, 'PLAYER_INFO', {
...@@ -2561,15 +2669,15 @@ ...@@ -2561,15 +2669,15 @@
ygopro.ctos_send(watcher, 'HS_TOOBSERVER'); ygopro.ctos_send(watcher, 'HS_TOOBSERVER');
}); });
watcher.on('data', function(data) { watcher.on('data', function(data) {
var len4, o, ref5, w; var len5, p, ref6, 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);
ref5 = room.watchers; ref6 = room.watchers;
for (o = 0, len4 = ref5.length; o < len4; o++) { for (p = 0, len5 = ref6.length; p < len5; p++) {
w = ref5[o]; w = ref6[p];
if (w) { if (w) {
w.write(data); w.write(data);
} }
...@@ -2773,7 +2881,7 @@ ...@@ -2773,7 +2881,7 @@
delete room.long_resolve_chain; delete room.long_resolve_chain;
} }
if (room && !room.finished && room.dueling_players[pos]) { if (room && !room.finished && room.dueling_players[pos]) {
room.winner_name = room.dueling_players[pos].name; room.winner_name = room.dueling_players[pos].name_vpass;
room.scores[room.winner_name] = room.scores[room.winner_name] + 1; room.scores[room.winner_name] = room.scores[room.winner_name] + 1;
if (settings.modules.vip.enabled && room.dueling_players[pos].vip && vip_info.players[room.dueling_players[pos].name].victory) { if (settings.modules.vip.enabled && room.dueling_players[pos].vip && vip_info.players[room.dueling_players[pos].name].victory) {
ref4 = _.lines(vip_info.players[room.dueling_players[pos].name].victory); ref4 = _.lines(vip_info.players[room.dueling_players[pos].name].victory);
...@@ -3297,7 +3405,7 @@ ...@@ -3297,7 +3405,7 @@
continue; continue;
} }
room.dueling_players[player.pos] = player; room.dueling_players[player.pos] = player;
room.scores[player.name] = 0; room.scores[player.name_vpass] = 0;
room.player_datas.push({ room.player_datas.push({
ip: player.ip, ip: player.ip,
name: player.name name: player.name
...@@ -3310,8 +3418,12 @@ ...@@ -3310,8 +3418,12 @@
if (settings.modules.tips.enabled) { if (settings.modules.tips.enabled) {
ygopro.stoc_send_random_tip(client); ygopro.stoc_send_random_tip(client);
} }
if (settings.modules.deck_log.enabled && client.main && client.main.length && !client.deck_saved && !room.windbot) { deck_text = null;
if (client.main && client.main.length) {
deck_text = '#ygopro-server deck log\n#main\n' + client.main.join('\n') + '\n!side\n' + client.side.join('\n') + '\n'; deck_text = '#ygopro-server deck log\n#main\n' + client.main.join('\n') + '\n!side\n' + client.side.join('\n') + '\n';
room.decks[client.name] = deck_text;
}
if (settings.modules.deck_log.enabled && deck_text && !client.deck_saved && !room.windbot) {
deck_arena = settings.modules.deck_log.arena + '-'; deck_arena = settings.modules.deck_log.arena + '-';
if (room.arena) { if (room.arena) {
deck_arena = deck_arena + room.arena; deck_arena = deck_arena + room.arena;
...@@ -3364,7 +3476,7 @@ ...@@ -3364,7 +3476,7 @@
if (!room.started) { if (!room.started) {
return true; return true;
} }
if (room.random_type && room.turn < 3 && !client.flee_free) { if (room.random_type && room.turn < 3 && !client.flee_free && !settings.modules.test_mode.surrender_anytime && !(room.random_type === 'M' && settings.modules.random_duel.record_match_scores)) {
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE);
return true; return true;
} }
...@@ -3793,15 +3905,15 @@ ...@@ -3793,15 +3905,15 @@
client.start_deckbuf = buffer; 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_vpass] !== room.scores[room.dueling_players[oppo_pos].name_vpass]) {
win_pos = room.scores[room.dueling_players[0].name] > room.scores[room.dueling_players[oppo_pos].name] ? 0 : oppo_pos; win_pos = room.scores[room.dueling_players[0].name_vpass] > room.scores[room.dueling_players[oppo_pos].name_vpass] ? 0 : oppo_pos;
room.finished_by_death = true; room.finished_by_death = true;
ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
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_vpass] = -1;
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
...@@ -4153,7 +4265,7 @@ ...@@ -4153,7 +4265,7 @@
for (o = 0, len4 = ref5.length; o < len4; o++) { for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o]; player = ref5[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_vpass] + " 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
}); });
} }
...@@ -4189,7 +4301,7 @@ ...@@ -4189,7 +4301,7 @@
if (time_passed >= settings.modules.random_duel.hang_timeout) { if (time_passed >= settings.modules.random_duel.hang_timeout) {
room.last_active_time = moment(); room.last_active_time = moment();
ROOM_ban_player(room.waiting_for_player.name, room.waiting_for_player.ip, "${random_ban_reason_AFK}"); ROOM_ban_player(room.waiting_for_player.name, room.waiting_for_player.ip, "${random_ban_reason_AFK}");
room.scores[room.waiting_for_player.name] = -9; room.scores[room.waiting_for_player.name_vpass] = -9;
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);
CLIENT_kick(room.waiting_for_player); CLIENT_kick(room.waiting_for_player);
} else if (time_passed >= (settings.modules.random_duel.hang_timeout - 20) && !(time_passed % 10)) { } else if (time_passed >= (settings.modules.random_duel.hang_timeout - 20) && !(time_passed % 10)) {
...@@ -4212,7 +4324,7 @@ ...@@ -4212,7 +4324,7 @@
if (time_passed >= settings.modules.random_duel.hang_timeout) { if (time_passed >= settings.modules.random_duel.hang_timeout) {
room.last_active_time = moment(); room.last_active_time = moment();
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.scores[room.waiting_for_player.name] = -9; room.scores[room.waiting_for_player.name_vpass] = -9;
CLIENT_kick(room.waiting_for_player); CLIENT_kick(room.waiting_for_player);
} else if (time_passed >= (settings.modules.random_duel.hang_timeout - 20) && !(time_passed % 10)) { } else if (time_passed >= (settings.modules.random_duel.hang_timeout - 20) && !(time_passed % 10)) {
ygopro.stoc_send_chat_to_room(room, room.waiting_for_player.name + " ${afk_warn_part1}" + (settings.modules.random_duel.hang_timeout - time_passed) + "${afk_warn_part2}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(room, room.waiting_for_player.name + " ${afk_warn_part1}" + (settings.modules.random_duel.hang_timeout - time_passed) + "${afk_warn_part2}", ygopro.constants.COLORS.RED);
...@@ -4323,7 +4435,7 @@ ...@@ -4323,7 +4435,7 @@
if (player.pos != null) { if (player.pos != null) {
results1.push({ results1.push({
id: (-1).toString(), id: (-1).toString(),
name: player.name + (settings.modules.http.show_ip && pass_validated && !player.is_local ? " (IP: " + player.ip.slice(7) + ")" : "") + (settings.modules.http.show_info && room.started && player.pos !== 7 && !(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.http.show_ip && pass_validated && !player.is_local ? " (IP: " + player.ip.slice(7) + ")" : "") + (settings.modules.http.show_info && room.started && player.pos !== 7 && !(room.hostinfo.mode === 2 && player.pos % 2 > 0) ? " (Score:" + room.scores[player.name_vpass] + " 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) : "") + ")" : ""),
pos: player.pos pos: player.pos
}); });
} }
...@@ -4531,8 +4643,8 @@ ...@@ -4531,8 +4643,8 @@
} }
kick_room_found = true; kick_room_found = true;
if (room.started) { if (room.started) {
room.scores[room.dueling_players[0].name] = 0; room.scores[room.dueling_players[0].name_vpass] = 0;
room.scores[room.dueling_players[1].name] = 0; room.scores[room.dueling_players[1].name_vpass] = 0;
} }
room.kicked = true; room.kicked = true;
room.process.kill(); room.process.kill();
...@@ -4567,7 +4679,7 @@ ...@@ -4567,7 +4679,7 @@
switch (settings.modules.http.quick_death_rule) { switch (settings.modules.http.quick_death_rule) {
case 2: case 2:
case 3: case 3:
if (room.scores[room.dueling_players[0].name] === room.scores[room.dueling_players[oppo_pos].name]) { if (room.scores[room.dueling_players[0].name_vpass] === room.scores[room.dueling_players[oppo_pos].name_vpass]) {
if (settings.modules.http.quick_death_rule === 3) { if (settings.modules.http.quick_death_rule === 3) {
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);
...@@ -4576,14 +4688,14 @@ ...@@ -4576,14 +4688,14 @@
ygopro.stoc_send_chat_to_room(room, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(room, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE);
} }
} else { } else {
win_pos = room.scores[room.dueling_players[0].name] > room.scores[room.dueling_players[oppo_pos].name] ? 0 : oppo_pos; win_pos = room.scores[room.dueling_players[0].name_vpass] > room.scores[room.dueling_players[oppo_pos].name_vpass] ? 0 : oppo_pos;
room.finished_by_death = true; room.finished_by_death = true;
ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(room, "${death2_finish_part1}" + room.dueling_players[win_pos].name + "${death2_finish_part2}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END'); ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
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_vpass] = -1;
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]); CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]); CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
......
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