Commit e345b2ae authored by nanahira's avatar nanahira

Merge branch 'koishi' into ai-play

parents 1d3b70aa 9e33544d
Pipeline #27454 failed with stages
in 4 minutes and 17 seconds
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k); Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) { }) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
o[k2] = m[k]; o[k2] = m[k];
......
...@@ -26,7 +26,7 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B ...@@ -26,7 +26,7 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B
currentDeckBuffer; currentDeckBuffer;
winner; winner;
setStartDeck(deck) { setStartDeck(deck) {
if (deck === null) { if (!deck) {
this.startDeckBuffer = null; this.startDeckBuffer = null;
return; return;
} }
...@@ -36,7 +36,7 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B ...@@ -36,7 +36,7 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B
return (0, DeckEncoder_1.decodeDeck)(Buffer.from(this.startDeckBuffer, "base64")); return (0, DeckEncoder_1.decodeDeck)(Buffer.from(this.startDeckBuffer, "base64"));
} }
setCurrentDeck(deck) { setCurrentDeck(deck) {
if (deck === null) { if (!deck) {
this.currentDeckBuffer = null; this.currentDeckBuffer = null;
return; return;
} }
......
...@@ -36,7 +36,7 @@ export class DuelLogPlayer extends BasePlayer { ...@@ -36,7 +36,7 @@ export class DuelLogPlayer extends BasePlayer {
winner: number; winner: number;
setStartDeck(deck: Deck) { setStartDeck(deck: Deck) {
if(deck === null) { if(!deck) {
this.startDeckBuffer = null; this.startDeckBuffer = null;
return; return;
} }
...@@ -48,7 +48,7 @@ export class DuelLogPlayer extends BasePlayer { ...@@ -48,7 +48,7 @@ export class DuelLogPlayer extends BasePlayer {
} }
setCurrentDeck(deck: Deck) { setCurrentDeck(deck: Deck) {
if(deck === null) { if(!deck) {
this.currentDeckBuffer = null; this.currentDeckBuffer = null;
return; return;
} }
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
"32": "HS_PLAYER_ENTER", "32": "HS_PLAYER_ENTER",
"33": "HS_PLAYER_CHANGE", "33": "HS_PLAYER_CHANGE",
"34": "HS_WATCH_CHANGE", "34": "HS_WATCH_CHANGE",
"35": "TEAMMATE_SURRENDER",
"48": "FIELD_FINISH" "48": "FIELD_FINISH"
}, },
"PLAYERCHANGE":{ "PLAYERCHANGE":{
...@@ -248,7 +249,8 @@ ...@@ -248,7 +249,8 @@
"RACE_DEVINE": 2097152, "RACE_DEVINE": 2097152,
"RACE_CREATORGOD": 4194304, "RACE_CREATORGOD": 4194304,
"RACE_WYRM": 8388608, "RACE_WYRM": 8388608,
"RACE_CYBERS": 16777216 "RACE_CYBERS": 16777216,
"RACE_ILLUSION": 33554432
}, },
"ATTRIBUTES": { "ATTRIBUTES": {
"ATTRIBUTE_EARTH": 1, "ATTRIBUTE_EARTH": 1,
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
"full": "服务器已爆满", "full": "服务器已爆满",
"max_rooms_count": 0, "max_rooms_count": 0,
"side_timeout": false, "side_timeout": false,
"tag_duel_surrender": true,
"replay_delay": true, "replay_delay": true,
"hide_name": false, "hide_name": false,
"display_watchers": false, "display_watchers": false,
...@@ -228,6 +227,12 @@ ...@@ -228,6 +227,12 @@
], ],
"ip_header": "x-forwarded-for" "ip_header": "x-forwarded-for"
}, },
"chatgpt": {
"enabled": false,
"endpoint": "https://chatgpt.hanatan.net",
"token": "hanatan",
"session": "srvpro"
},
"test_mode": { "test_mode": {
"watch_public_hand": false, "watch_public_hand": false,
"no_connect_count_limit": false, "no_connect_count_limit": false,
......
...@@ -203,6 +203,7 @@ ...@@ -203,6 +203,7 @@
"auto_death_part1": "This room is an auto-extra-duel room. The Extra Duel will begin after ", "auto_death_part1": "This room is an auto-extra-duel room. The Extra Duel will begin after ",
"auto_death_part2": " minutes.", "auto_death_part2": " minutes.",
"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.",
"entertain_arena_tip": "Welcome! This mode bans the top 20 most frequent deck used in athletic mode for past 7 days.",
"windbot_disable_random_room": "By adding the AI, this random game won't get any new player unless they enter the room name:", "windbot_disable_random_room": "By adding the AI, this random game won't get any new player unless they enter the room name:",
"stand_bot_added": "Deck confirmed. Adding bot.", "stand_bot_added": "Deck confirmed. Adding bot.",
"stand_bot_removed": "Deck resetted.", "stand_bot_removed": "Deck resetted.",
...@@ -562,6 +563,7 @@ ...@@ -562,6 +563,7 @@
"auto_death_part1": "本房间为自动加时赛房间。比赛开始", "auto_death_part1": "本房间为自动加时赛房间。比赛开始",
"auto_death_part2": "分钟后,将自动进入加时赛。", "auto_death_part2": "分钟后,将自动进入加时赛。",
"athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。", "athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。",
"entertain_arena_tip": "欢迎来到娱乐匹配。系统会禁止锁定竞技匹配过去一周使用数 TOP 20 的卡组。",
"windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:", "windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:",
"stand_bot_added": "已确认卡组。将添加AI参与决斗。", "stand_bot_added": "已确认卡组。将添加AI参与决斗。",
"stand_bot_removed": "已重置卡组。", "stand_bot_removed": "已重置卡组。",
......
...@@ -124,6 +124,7 @@ var loadDb = function(db_file, callback) { ...@@ -124,6 +124,7 @@ var loadDb = function(db_file, callback) {
if (result.race & constants.RACES.RACE_CREATORGOD) {cardRace="创造神";} if (result.race & constants.RACES.RACE_CREATORGOD) {cardRace="创造神";}
if (result.race & constants.RACES.RACE_WYRM) {cardRace="幻龙";} if (result.race & constants.RACES.RACE_WYRM) {cardRace="幻龙";}
if (result.race & constants.RACES.RACE_CYBERS) {cardRace="电子界";} if (result.race & constants.RACES.RACE_CYBERS) {cardRace="电子界";}
if (result.race & constants.RACES.RACE_ILLUSION) {cardRace = "幻想魔";}
cardText+=" "+ cardRace; cardText+=" "+ cardRace;
var cardAttr=""; var cardAttr="";
......
...@@ -251,6 +251,7 @@ geoip = null ...@@ -251,6 +251,7 @@ geoip = null
dataManager = null dataManager = null
windbots = [] windbots = []
disconnect_list = {} # {old_client, old_server, room_id, timeout, deckbuf} disconnect_list = {} # {old_client, old_server, room_id, timeout, deckbuf}
extra_mode_list = global.extra_mode_list = [] # (rule) => void, with 'this' is ROOM
moment_now = global.moment_now = null moment_now = global.moment_now = null
moment_now_string = global.moment_now_string = null moment_now_string = global.moment_now_string = null
...@@ -733,6 +734,7 @@ init = () -> ...@@ -733,6 +734,7 @@ init = () ->
plugin_list = await fs.promises.readdir("./plugins") plugin_list = await fs.promises.readdir("./plugins")
for plugin_filename in plugin_list for plugin_filename in plugin_list
if plugin_filename.endsWith '.js'
plugin_path = process.cwd() + "/plugins/" + plugin_filename plugin_path = process.cwd() + "/plugins/" + plugin_filename
require(plugin_path) require(plugin_path)
log.info("Plugin loaded:", plugin_filename) log.info("Plugin loaded:", plugin_filename)
...@@ -858,7 +860,7 @@ ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_i ...@@ -858,7 +860,7 @@ ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_i
(room.random_type == settings.modules.random_duel.default_type or (room.random_type == settings.modules.random_duel.default_type or
settings.modules.random_duel.blank_pass_modes[room.random_type])) or settings.modules.random_duel.blank_pass_modes[room.random_type])) or
room.random_type == type) and room.random_type == type) and
room.get_playing_player().length < max_player and 0 < 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
(playerbanned == room.deprecated or type == 'T') (playerbanned == room.deprecated or type == 'T')
...@@ -1339,7 +1341,7 @@ class Room ...@@ -1339,7 +1341,7 @@ class Room
@hostinfo.rule = 5 @hostinfo.rule = 5
@hostinfo.lflist = -1 @hostinfo.lflist = -1
@hostinfo.time_limit = 0 @hostinfo.time_limit = 0
@hostinfo.no_check_deck = true #@hostinfo.no_check_deck = true
else if (param = name.match /^(\d)(\d)([12345TF])(T|F)(T|F)(\d+),(\d+),(\d+)/i) else if (param = name.match /^(\d)(\d)([12345TF])(T|F)(T|F)(\d+),(\d+),(\d+)/i)
@hostinfo.rule = parseInt(param[1]) @hostinfo.rule = parseInt(param[1])
...@@ -1449,6 +1451,9 @@ class Room ...@@ -1449,6 +1451,9 @@ class Room
lflist = parseInt(param[3]) - 1 lflist = parseInt(param[3]) - 1
@hostinfo.lflist = lflist @hostinfo.lflist = lflist
for extra_mode_func from extra_mode_list
extra_mode_func.call this, rule
if (rule.match /(^|,|,)(NOLFLIST|NF)(,|,|$)/) if (rule.match /(^|,|,)(NOLFLIST|NF)(,|,|$)/)
@hostinfo.lflist = -1 @hostinfo.lflist = -1
...@@ -1826,7 +1831,7 @@ class Room ...@@ -1826,7 +1831,7 @@ class Room
ROOM_player_flee(client.name_vpass) ROOM_player_flee(client.name_vpass)
if @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and !client.is_local and client.bot_bound if @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and !client.is_local and client.bot_bound
@kill_bots_with_name(client.name_vpass) @kill_bots_with_name(client.name_vpass)
if @players.length and !(@windbot and client.is_host) and !(@arena and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and client.pos <= 3) if @players.length and !(@windbot and client.is_host and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN) and !(@arena and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and client.pos <= 3)
left_name = (if settings.modules.hide_name and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN then "********" else client.name) left_name = (if settings.modules.hide_name and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN then "********" else client.name)
ygopro.stoc_send_chat_to_room this, "#{left_name} ${left_game}" + if error then ": #{error}" else '' ygopro.stoc_send_chat_to_room this, "#{left_name} ${left_game}" + if error then ": #{error}" else ''
roomlist.update(this) if !@windbot and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.http.websocket_roomlist roomlist.update(this) if !@windbot and @duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.http.websocket_roomlist
...@@ -1846,6 +1851,14 @@ class Room ...@@ -1846,6 +1851,14 @@ class Room
oppo_pos = if @hostinfo.mode == 2 then 2 else 1 oppo_pos = if @hostinfo.mode == 2 then 2 else 1
if @duel_stage == ygopro.constants.DUEL_STAGE.DUELING if @duel_stage == ygopro.constants.DUEL_STAGE.DUELING
switch settings.modules.http.quick_death_rule switch settings.modules.http.quick_death_rule
when 4 # instant death
win_pos = 0
if @dueling_players[0].lp == @dueling_players[oppo_pos].lp
win_pos = if @dueling_players[oppo_pos].is_first then 0 else oppo_pos
else
win_pos = if @dueling_players[0].lp > @dueling_players[oppo_pos].lp then 0 else oppo_pos
ygopro.stoc_send_chat_to_room(this, "${death_finish_part1}" + @dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE)
ygopro.ctos_send(@dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
when 3 when 3
@death = -2 @death = -2
ygopro.stoc_send_chat_to_room(this, "${death_start_phase}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(this, "${death_start_phase}", ygopro.constants.COLORS.BABYBLUE)
...@@ -1875,7 +1888,7 @@ class Room ...@@ -1875,7 +1888,7 @@ class Room
when 1 when 1
@death = -1 @death = -1
ygopro.stoc_send_chat_to_room(this, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(this, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE)
else when 0
@death = 5 @death = 5
ygopro.stoc_send_chat_to_room(this, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(this, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE)
return true return true
...@@ -2260,6 +2273,14 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2260,6 +2273,14 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
} }
CLIENT_kick(client) CLIENT_kick(client)
else if info.pass.toUpperCase()=="IP"
ygopro.stoc_send_chat(client, "IP: " + client.ip, ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send client, 'ERROR_MSG', {
msg: 1
code: 9
}
CLIENT_kick(client)
else if info.pass.toUpperCase()=="RC" and settings.modules.tournament_mode.enable_recover else if info.pass.toUpperCase()=="RC" and settings.modules.tournament_mode.enable_recover
ygopro.stoc_send_chat(client,"${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client,"${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE)
available_logs = await dataManager.getDuelLogFromRecoverSearch(client.name_vpass) available_logs = await dataManager.getDuelLogFromRecoverSearch(client.name_vpass)
...@@ -2437,6 +2458,8 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2437,6 +2458,8 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
room.max_player = 2 room.max_player = 2
if room.arena == "athletic" if room.arena == "athletic"
room.welcome = "${athletic_arena_tip}" room.welcome = "${athletic_arena_tip}"
else
room.welcome = "${entertain_arena_tip}"
when 5 when 5
title = info.pass.slice(8).replace(String.fromCharCode(0xFEFF), ' ') title = info.pass.slice(8).replace(String.fromCharCode(0xFEFF), ' ')
room = ROOM_find_by_title(title) room = ROOM_find_by_title(title)
...@@ -3282,13 +3305,13 @@ ygopro.ctos_follow 'SURRENDER', true, (buffer, info, client, server, datas)-> ...@@ -3282,13 +3305,13 @@ ygopro.ctos_follow 'SURRENDER', true, (buffer, info, client, server, datas)->
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
if !settings.modules.tag_duel_surrender if !client.surrend_confirm and !CLIENT_get_partner(client).closed and !CLIENT_get_partner(client).is_local
return true
else if !client.surrend_confirm and !CLIENT_get_partner(client).closed and !CLIENT_get_partner(client).is_local
sur_player = CLIENT_get_partner(client) sur_player = CLIENT_get_partner(client)
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE)
sur_player.surrend_confirm = true sur_player.surrend_confirm = true
for player in [client, sur_player]
ygopro.stoc_send(client, 'TEAMMATE_SURRENDER')
return true return true
await return false await return false
...@@ -3323,7 +3346,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3323,7 +3346,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
isVip = await CLIENT_check_vip(client) isVip = await CLIENT_check_vip(client)
switch cmd[0] switch cmd[0]
when '/投降', '/surrender' when '/投降', '/surrender'
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN or (room.hostinfo.mode==2 and !settings.modules.tag_duel_surrender) if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN
return cancel return cancel
if room.random_type and room.turn < 3 and !client.flee_free if room.random_type and room.turn < 3 and !client.flee_free
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE)
...@@ -3337,6 +3360,8 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3337,6 +3360,8 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
if room.hostinfo.mode==2 and sur_player != client if room.hostinfo.mode==2 and sur_player != client
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE)
for player in [client, sur_player]
ygopro.stoc_send(client, 'TEAMMATE_SURRENDER')
else else
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE)
sur_player.surrend_confirm = true sur_player.surrend_confirm = true
...@@ -3496,6 +3521,30 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3496,6 +3521,30 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
client.abuse_count=client.abuse_count+2 if client.abuse_count client.abuse_count=client.abuse_count+2 if client.abuse_count
ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED)
cancel = true cancel = true
if not cancel and settings.modules.chatgpt.enabled and room.windbot and not client.is_post_watcher and client.pos < 2 and not client.is_local
session_key = "#{settings.modules.chatgpt.session}:#{settings.port}:#{CLIENT_get_authorize_key(client)}"
axios.post("#{settings.modules.chatgpt.endpoint}/api/chat", {
session: session_key,
text: msg
}, {
timeout: 300000,
headers: {
Authorization: "Bearer #{settings.modules.chatgpt.token}"
}
}).then((res) ->
text = res.data.data.text
lines = text.split("\n")
for line in lines
if line
chunks = _.chunk(line, 100)
for chunk in chunks
ygopro.stoc_send_chat_to_room(room, chunk.join(''), 1 - client.pos)
else
ygopro.stoc_send_chat_to_room(room, ' ', 1 - client.pos)
).catch((err) ->
log.error "CHATGPT ERROR", session_key, err
)
return false
if !(room and (room.random_type or room.arena)) and not settings.modules.mycard.enabled if !(room and (room.random_type or room.arena)) and not settings.modules.mycard.enabled
if !cancel and settings.modules.display_watchers and (client.is_post_watcher or client.pos > 3) if !cancel and settings.modules.display_watchers and (client.is_post_watcher or client.pos > 3)
ygopro.stoc_send_chat_to_room(room, "#{client.name}: #{msg}", 9) ygopro.stoc_send_chat_to_room(room, "#{client.name}: #{msg}", 9)
...@@ -3922,7 +3971,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)-> ...@@ -3922,7 +3971,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
dataManager.saveDuelLog(room.name, room.process_pid, room.cloud_replay_id, replay_filename, room.hostinfo.mode, room.duel_count, playerInfos) # no synchronize here because too slow dataManager.saveDuelLog(room.name, room.process_pid, room.cloud_replay_id, replay_filename, room.hostinfo.mode, room.duel_count, playerInfos) # no synchronize here because too slow
if settings.modules.mysql.enabled && settings.modules.cloud_replay.enabled and settings.modules.tournament_mode.enabled if settings.modules.mysql.enabled && settings.modules.cloud_replay.enabled and settings.modules.tournament_mode.enabled
ygopro.stoc_send_chat(client, "${cloud_replay_delay_part1}R##{room.cloud_replay_id}${cloud_replay_delay_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${cloud_replay_delay_part1}R##{room.cloud_replay_id}${cloud_replay_delay_part2}", ygopro.constants.COLORS.BABYBLUE)
await return settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player or settings.modules.replay_delay and room.hostinfo.mode == 1 await return settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player or settings.modules.replay_delay and room and room.hostinfo.mode == 1
# spawn windbot # spawn windbot
windbot_looplimit = 0 windbot_looplimit = 0
......
// Generated by CoffeeScript 2.6.1 // Generated by CoffeeScript 2.6.1
(function() { (function() {
// 标准库 // 标准库
var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_get_save_data, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, CLIENT_send_replays_and_kick, CLIENT_send_vip_status, CLIENT_use_cdkey, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwordR, badwords, ban_user, bunyan, challonge, checkFileExists, concat_name, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, fs, geoip, getDuelLogQueryFromQs, getSeedTimet, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, ip6addr, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, moment_long_ago_string, moment_now, moment_now_string, neosRequestListener, net, netRequestHandler, os, osu, path, qs, real_windbot_server_ip, release_disconnect, report_to_big_brother, request, roomlist, rooms_count, setting_change, setting_get, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib; var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_get_save_data, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, CLIENT_send_replays_and_kick, CLIENT_send_vip_status, CLIENT_use_cdkey, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwordR, badwords, ban_user, bunyan, challonge, checkFileExists, concat_name, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, extra_mode_list, fs, geoip, getDuelLogQueryFromQs, getSeedTimet, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, ip6addr, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, moment_long_ago_string, moment_now, moment_now_string, neosRequestListener, net, netRequestHandler, os, osu, path, qs, real_windbot_server_ip, release_disconnect, report_to_big_brother, request, roomlist, rooms_count, setting_change, setting_get, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib;
net = require('net'); net = require('net');
...@@ -314,6 +314,8 @@ ...@@ -314,6 +314,8 @@
disconnect_list = {}; // {old_client, old_server, room_id, timeout, deckbuf} disconnect_list = {}; // {old_client, old_server, room_id, timeout, deckbuf}
extra_mode_list = global.extra_mode_list = []; // (rule) => void, with 'this' is ROOM
moment_now = global.moment_now = null; moment_now = global.moment_now = null;
moment_now_string = global.moment_now_string = null; moment_now_string = global.moment_now_string = null;
...@@ -927,10 +929,12 @@ ...@@ -927,10 +929,12 @@
plugin_list = (await fs.promises.readdir("./plugins")); plugin_list = (await fs.promises.readdir("./plugins"));
for (m = 0, len2 = plugin_list.length; m < len2; m++) { for (m = 0, len2 = plugin_list.length; m < len2; m++) {
plugin_filename = plugin_list[m]; plugin_filename = plugin_list[m];
if (plugin_filename.endsWith('.js')) {
plugin_path = process.cwd() + "/plugins/" + plugin_filename; plugin_path = process.cwd() + "/plugins/" + plugin_filename;
require(plugin_path); require(plugin_path);
log.info("Plugin loaded:", plugin_filename); log.info("Plugin loaded:", plugin_filename);
} }
}
}; };
// 获取可用内存 // 获取可用内存
...@@ -1101,7 +1105,8 @@ ...@@ -1101,7 +1105,8 @@
max_player = type === 'T' ? 4 : 2; max_player = type === 'T' ? 4 : 2;
playerbanned = randomDuelBanRecord && randomDuelBanRecord.count > 3 && moment_now < randomDuelBanRecord.time; playerbanned = randomDuelBanRecord && randomDuelBanRecord.count > 3 && moment_now < randomDuelBanRecord.time;
result = _.find(ROOM_all, function(room) { result = _.find(ROOM_all, function(room) {
return room && room.random_type !== '' && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && !room.windbot && ((type === '' && (room.random_type === settings.modules.random_duel.default_type || settings.modules.random_duel.blank_pass_modes[room.random_type])) || 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'); var ref;
return room && room.random_type !== '' && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && !room.windbot && ((type === '' && (room.random_type === settings.modules.random_duel.default_type || settings.modules.random_duel.blank_pass_modes[room.random_type])) || room.random_type === type) && (0 < (ref = room.get_playing_player().length) && ref < 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}';
...@@ -1706,7 +1711,7 @@ ...@@ -1706,7 +1711,7 @@
Room = class Room { Room = class Room {
constructor(name, hostinfo) { constructor(name, hostinfo) {
var death_time, draw_count, duel_rule, lflist, param, rule, start_hand, start_lp, time_limit; var death_time, draw_count, duel_rule, extra_mode_func, lflist, param, rule, start_hand, start_lp, time_limit;
this.hostinfo = hostinfo; this.hostinfo = hostinfo;
this.name = name; this.name = name;
//@alive = true //@alive = true
...@@ -1750,7 +1755,7 @@ ...@@ -1750,7 +1755,7 @@
this.hostinfo.rule = 5; this.hostinfo.rule = 5;
this.hostinfo.lflist = -1; this.hostinfo.lflist = -1;
this.hostinfo.time_limit = 0; this.hostinfo.time_limit = 0;
this.hostinfo.no_check_deck = true; //@hostinfo.no_check_deck = true
} else if ((param = name.match(/^(\d)(\d)([12345TF])(T|F)(T|F)(\d+),(\d+),(\d+)/i))) { } else if ((param = name.match(/^(\d)(\d)([12345TF])(T|F)(T|F)(\d+),(\d+),(\d+)/i))) {
this.hostinfo.rule = parseInt(param[1]); this.hostinfo.rule = parseInt(param[1]);
this.hostinfo.mode = parseInt(param[2]); this.hostinfo.mode = parseInt(param[2]);
...@@ -1883,6 +1888,9 @@ ...@@ -1883,6 +1888,9 @@
lflist = parseInt(param[3]) - 1; lflist = parseInt(param[3]) - 1;
this.hostinfo.lflist = lflist; this.hostinfo.lflist = lflist;
} }
for (extra_mode_func of extra_mode_list) {
extra_mode_func.call(this, rule);
}
if (rule.match(/(^|,|,)(NOLFLIST|NF)(,|,|$)/)) { if (rule.match(/(^|,|,)(NOLFLIST|NF)(,|,|$)/)) {
this.hostinfo.lflist = -1; this.hostinfo.lflist = -1;
} }
...@@ -2423,7 +2431,7 @@ ...@@ -2423,7 +2431,7 @@
if (this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && !client.is_local && client.bot_bound) { if (this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && !client.is_local && client.bot_bound) {
this.kill_bots_with_name(client.name_vpass); this.kill_bots_with_name(client.name_vpass);
} }
if (this.players.length && !(this.windbot && client.is_host) && !(this.arena && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && client.pos <= 3)) { if (this.players.length && !(this.windbot && client.is_host && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN) && !(this.arena && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && client.pos <= 3)) {
left_name = (settings.modules.hide_name && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN ? "********" : client.name); left_name = (settings.modules.hide_name && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN ? "********" : client.name);
ygopro.stoc_send_chat_to_room(this, `${left_name} \${left_game}` + (error ? `: ${error}` : '')); ygopro.stoc_send_chat_to_room(this, `${left_name} \${left_game}` + (error ? `: ${error}` : ''));
if (!this.windbot && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.http.websocket_roomlist) { if (!this.windbot && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.http.websocket_roomlist) {
...@@ -2450,6 +2458,16 @@ ...@@ -2450,6 +2458,16 @@
oppo_pos = this.hostinfo.mode === 2 ? 2 : 1; oppo_pos = this.hostinfo.mode === 2 ? 2 : 1;
if (this.duel_stage === ygopro.constants.DUEL_STAGE.DUELING) { if (this.duel_stage === ygopro.constants.DUEL_STAGE.DUELING) {
switch (settings.modules.http.quick_death_rule) { switch (settings.modules.http.quick_death_rule) {
case 4: // instant death
win_pos = 0;
if (this.dueling_players[0].lp === this.dueling_players[oppo_pos].lp) {
win_pos = this.dueling_players[oppo_pos].is_first ? 0 : oppo_pos;
} else {
win_pos = this.dueling_players[0].lp > this.dueling_players[oppo_pos].lp ? 0 : oppo_pos;
}
ygopro.stoc_send_chat_to_room(this, "${death_finish_part1}" + this.dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE);
ygopro.ctos_send(this.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
break;
case 3: case 3:
this.death = -2; this.death = -2;
ygopro.stoc_send_chat_to_room(this, "${death_start_phase}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(this, "${death_start_phase}", ygopro.constants.COLORS.BABYBLUE);
...@@ -2492,7 +2510,7 @@ ...@@ -2492,7 +2510,7 @@
this.death = -1; this.death = -1;
ygopro.stoc_send_chat_to_room(this, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(this, "${death_start_quick}", ygopro.constants.COLORS.BABYBLUE);
break; break;
default: case 0:
this.death = 5; this.death = 5;
ygopro.stoc_send_chat_to_room(this, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(this, "${death_start_siding}", ygopro.constants.COLORS.BABYBLUE);
} }
...@@ -3012,6 +3030,13 @@ ...@@ -3012,6 +3030,13 @@
code: 9 code: 9
}); });
CLIENT_kick(client); CLIENT_kick(client);
} else if (info.pass.toUpperCase() === "IP") {
ygopro.stoc_send_chat(client, "IP: " + client.ip, ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 9
});
CLIENT_kick(client);
} else if (info.pass.toUpperCase() === "RC" && settings.modules.tournament_mode.enable_recover) { } else if (info.pass.toUpperCase() === "RC" && settings.modules.tournament_mode.enable_recover) {
ygopro.stoc_send_chat(client, "${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE);
available_logs = (await dataManager.getDuelLogFromRecoverSearch(client.name_vpass)); available_logs = (await dataManager.getDuelLogFromRecoverSearch(client.name_vpass));
...@@ -3214,6 +3239,8 @@ ...@@ -3214,6 +3239,8 @@
room.max_player = 2; room.max_player = 2;
if (room.arena === "athletic") { if (room.arena === "athletic") {
room.welcome = "${athletic_arena_tip}"; room.welcome = "${athletic_arena_tip}";
} else {
room.welcome = "${entertain_arena_tip}";
} }
} }
break; break;
...@@ -4381,7 +4408,7 @@ ...@@ -4381,7 +4408,7 @@
}); });
ygopro.ctos_follow('SURRENDER', true, async function(buffer, info, client, server, datas) { ygopro.ctos_follow('SURRENDER', true, async function(buffer, info, client, server, datas) {
var room, sur_player; var j, len, player, ref, room, sur_player;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return; return;
...@@ -4394,13 +4421,16 @@ ...@@ -4394,13 +4421,16 @@
return true; return true;
} }
if (room.hostinfo.mode === 2) { if (room.hostinfo.mode === 2) {
if (!settings.modules.tag_duel_surrender) { if (!client.surrend_confirm && !CLIENT_get_partner(client).closed && !CLIENT_get_partner(client).is_local) {
return true;
} else if (!client.surrend_confirm && !CLIENT_get_partner(client).closed && !CLIENT_get_partner(client).is_local) {
sur_player = CLIENT_get_partner(client); sur_player = CLIENT_get_partner(client);
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE);
sur_player.surrend_confirm = true; sur_player.surrend_confirm = true;
ref = [client, sur_player];
for (j = 0, len = ref.length; j < len; j++) {
player = ref[j];
ygopro.stoc_send(client, 'TEAMMATE_SURRENDER');
}
return true; return true;
} }
} }
...@@ -4436,7 +4466,7 @@ ...@@ -4436,7 +4466,7 @@
//else //else
//log.info 'BIG BROTHER OK', response.statusCode, roomname, body //log.info 'BIG BROTHER OK', response.statusCode, roomname, body
ygopro.ctos_follow('CHAT', true, async function(buffer, info, client, server, datas) { ygopro.ctos_follow('CHAT', true, async function(buffer, info, client, server, datas) {
var buy_result, cancel, ccolor, cip, cmd, cmsg, cname, code, color, cvalue, isVip, key, msg, name, oldmsg, ref, room, struct, sur_player, uname, windbot, word; var buy_result, cancel, ccolor, cip, cmd, cmsg, cname, code, color, cvalue, isVip, j, key, len, msg, name, oldmsg, player, ref, ref1, room, session_key, struct, sur_player, uname, windbot, word;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return; return;
...@@ -4451,7 +4481,7 @@ ...@@ -4451,7 +4481,7 @@
switch (cmd[0]) { switch (cmd[0]) {
case '/投降': case '/投降':
case '/surrender': case '/surrender':
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN || (room.hostinfo.mode === 2 && !settings.modules.tag_duel_surrender)) { if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN) {
return cancel; return cancel;
} }
if (room.random_type && room.turn < 3 && !client.flee_free) { if (room.random_type && room.turn < 3 && !client.flee_free) {
...@@ -4468,6 +4498,11 @@ ...@@ -4468,6 +4498,11 @@
if (room.hostinfo.mode === 2 && sur_player !== client) { if (room.hostinfo.mode === 2 && sur_player !== client) {
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE);
ref = [client, sur_player];
for (j = 0, len = ref.length; j < len; j++) {
player = ref[j];
ygopro.stoc_send(client, 'TEAMMATE_SURRENDER');
}
} else { } else {
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE);
} }
...@@ -4548,9 +4583,9 @@ ...@@ -4548,9 +4583,9 @@
} else if (cmsg = cmd[1]) { } else 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);
ref = ygopro.constants.COLORS; ref1 = ygopro.constants.COLORS;
for (cname in ref) { for (cname in ref1) {
cvalue = ref[cname]; cvalue = ref1[cname];
if (cvalue > 10) { if (cvalue > 10) {
ygopro.stoc_send_chat(client, cname, cvalue); ygopro.stoc_send_chat(client, cname, cvalue);
} }
...@@ -4685,6 +4720,44 @@ ...@@ -4685,6 +4720,44 @@
ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED);
cancel = true; cancel = true;
} }
if (!cancel && settings.modules.chatgpt.enabled && room.windbot && !client.is_post_watcher && client.pos < 2 && !client.is_local) {
session_key = `${settings.modules.chatgpt.session}:${settings.port}:${CLIENT_get_authorize_key(client)}`;
axios.post(`${settings.modules.chatgpt.endpoint}/api/chat`, {
session: session_key,
text: msg
}, {
timeout: 300000,
headers: {
Authorization: `Bearer ${settings.modules.chatgpt.token}`
}
}).then(function(res) {
var chunk, chunks, l, len1, line, lines, results, text;
text = res.data.data.text;
lines = text.split("\n");
results = [];
for (l = 0, len1 = lines.length; l < len1; l++) {
line = lines[l];
if (line) {
chunks = _.chunk(line, 100);
results.push((function() {
var len2, m, results1;
results1 = [];
for (m = 0, len2 = chunks.length; m < len2; m++) {
chunk = chunks[m];
results1.push(ygopro.stoc_send_chat_to_room(room, chunk.join(''), 1 - client.pos));
}
return results1;
})());
} else {
results.push(ygopro.stoc_send_chat_to_room(room, ' ', 1 - client.pos));
}
}
return results;
}).catch(function(err) {
return log.error("CHATGPT ERROR", session_key, err);
});
return false;
}
if (!(room && (room.random_type || room.arena)) && !settings.modules.mycard.enabled) { if (!(room && (room.random_type || room.arena)) && !settings.modules.mycard.enabled) {
if (!cancel && settings.modules.display_watchers && (client.is_post_watcher || client.pos > 3)) { if (!cancel && settings.modules.display_watchers && (client.is_post_watcher || client.pos > 3)) {
ygopro.stoc_send_chat_to_room(room, `${client.name}: ${msg}`, 9); ygopro.stoc_send_chat_to_room(room, `${client.name}: ${msg}`, 9);
...@@ -5272,7 +5345,7 @@ ...@@ -5272,7 +5345,7 @@
ygopro.stoc_send_chat(client, `\${cloud_replay_delay_part1}R#${room.cloud_replay_id}\${cloud_replay_delay_part2}`, ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, `\${cloud_replay_delay_part1}R#${room.cloud_replay_id}\${cloud_replay_delay_part2}`, ygopro.constants.COLORS.BABYBLUE);
} }
} }
return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player || settings.modules.replay_delay && room.hostinfo.mode === 1; return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player || settings.modules.replay_delay && room && room.hostinfo.mode === 1;
}); });
// spawn windbot // spawn windbot
......
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