Commit 246cf5da authored by nanahira's avatar nanahira

Merge branch 'master' into tcg_random

parents 80a8e171 b5310819
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AthleticChecker = void 0;
const axios_1 = __importDefault(require("axios"));
const querystring_1 = __importDefault(require("querystring"));
const moment_1 = __importDefault(require("moment"));
class AthleticChecker {
constructor(config) {
this.config = config;
}
deckToString(deck) {
const deckText = '#ygopro-server deck log\n#main\n' + deck.main.join('\n') + '\n!side\n' + deck.side.join('\n') + '\n';
return deckText;
}
async getAthleticDecks() {
if (this.athleticDeckCache && moment_1.default().diff(this.lastAthleticDeckFetchTime, "seconds") < this.config.ttl) {
return this.athleticDeckCache;
}
const { data } = await axios_1.default.get(this.config.rankURL, {
timeout: 10000,
responseType: "json",
paramsSerializer: querystring_1.default.stringify,
params: this.config.athleticFetchParams
});
const athleticDecks = data.slice(0, this.config.rankCount).map(m => m.name);
this.athleticDeckCache = athleticDecks;
this.lastAthleticDeckFetchTime = moment_1.default();
return athleticDecks;
}
async getDeckType(deck) {
const deckString = this.deckToString(deck);
const { data } = await axios_1.default.post(this.config.identifierURL, querystring_1.default.stringify({ deck: deckString }), {
timeout: 10000,
responseType: "json"
});
return data.deck;
}
async checkAthletic(deck) {
try {
const athleticDecks = await this.getAthleticDecks();
const deckType = await this.getDeckType(deck);
const athletic = athleticDecks.includes(deckType);
return { success: true, athletic, message: null };
}
catch (e) {
return { success: false, message: e.toString() };
}
}
}
exports.AthleticChecker = AthleticChecker;
//# sourceMappingURL=athletic-check.js.map
\ No newline at end of file
import axios from "axios";
import qs from "querystring";
import moment, {Moment} from "moment";
interface Deck {
main: number[];
side: number[];
}
interface Config {
rankURL: string;
identifierURL: string;
athleticFetchParams: any;
rankCount: number;
ttl: number;
}
interface AthleticDecksReturnData {
name: string
}
interface ReturnMessage {
success: boolean;
athletic?: boolean;
message: string;
}
export class AthleticChecker {
config: Config;
athleticDeckCache: string[];
lastAthleticDeckFetchTime: Moment;
constructor(config: Config) {
this.config = config;
}
deckToString(deck: Deck) {
const deckText = '#ygopro-server deck log\n#main\n' + deck.main.join('\n') + '\n!side\n' + deck.side.join('\n') + '\n';
return deckText;
}
async getAthleticDecks(): Promise<string[]> {
if (this.athleticDeckCache && moment().diff(this.lastAthleticDeckFetchTime, "seconds") < this.config.ttl) {
return this.athleticDeckCache;
}
const { data } = await axios.get(this.config.rankURL, {
timeout: 10000,
responseType: "json",
paramsSerializer: qs.stringify,
params: this.config.athleticFetchParams
});
const athleticDecks = (data as AthleticDecksReturnData[]).slice(0, this.config.rankCount).map(m => m.name);
this.athleticDeckCache = athleticDecks;
this.lastAthleticDeckFetchTime = moment();
return athleticDecks;
}
async getDeckType(deck: Deck): Promise<string> {
const deckString = this.deckToString(deck);
const { data } = await axios.post(this.config.identifierURL, qs.stringify({ deck: deckString }), {
timeout: 10000,
responseType: "json"
});
return data.deck;
}
async checkAthletic(deck: Deck): Promise<ReturnMessage> {
try {
const athleticDecks = await this.getAthleticDecks();
const deckType = await this.getDeckType(deck);
const athletic = athleticDecks.includes(deckType);
return { success: true, athletic, message: null }
} catch (e) {
return { success: false, message: e.toString() };
}
}
}
{ {
"file": "./config/config.json", "file": "./config/config.json",
"port": 7911, "port": 7911,
"version": 4930, "version": 4945,
"alternative_versions": [],
"hostinfo": { "hostinfo": {
"lflist": 0, "lflist": 0,
"rule": 0, "rule": 0,
...@@ -197,6 +198,17 @@ ...@@ -197,6 +198,17 @@
"log_save_path": "./config/", "log_save_path": "./config/",
"port": 7933 "port": 7933
}, },
"athletic_check": {
"enabled": false,
"rankURL": "https://api.mycard.moe/ygopro/analytics/deck/type",
"identifierURL": "https://api.mycard.moe/ygopro/identifier/production",
"athleticFetchParams": {
"type": "week",
"source": "mycard-athletic"
},
"rankCount": 10,
"ttl": 600
},
"test_mode": { "test_mode": {
"watch_public_hand": false, "watch_public_hand": false,
"no_connect_count_limit": false, "no_connect_count_limit": false,
......
...@@ -200,7 +200,8 @@ ...@@ -200,7 +200,8 @@
"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.",
"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:",
"using_athletic_deck": " is using an athletic deck."
}, },
"es-es": { "es-es": {
"random_duel_enter_room_waiting": "Tu oponente esta listo, Iniciar!", "random_duel_enter_room_waiting": "Tu oponente esta listo, Iniciar!",
...@@ -549,7 +550,8 @@ ...@@ -549,7 +550,8 @@
"auto_death_part1": "本房间为自动加时赛房间。比赛开始", "auto_death_part1": "本房间为自动加时赛房间。比赛开始",
"auto_death_part2": "分钟后,将自动进入加时赛。", "auto_death_part2": "分钟后,将自动进入加时赛。",
"athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。", "athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。",
"windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:" "windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:",
"using_athletic_deck": " 正在使用竞技卡组。"
}, },
"ko-kr": { "ko-kr": {
"random_duel_enter_room_waiting": "땅콩: 게임을 진행하게 준비 또는 시작을 하십시오.", "random_duel_enter_room_waiting": "땅콩: 게임을 진행하게 준비 또는 시작을 하십시오.",
......
...@@ -452,6 +452,10 @@ if settings.modules.heartbeat_detection.enabled ...@@ -452,6 +452,10 @@ if settings.modules.heartbeat_detection.enabled
if settings.modules.tournament_mode.enable_recover if settings.modules.tournament_mode.enable_recover
ReplayParser = global.ReplayParser = require "./Replay.js" ReplayParser = global.ReplayParser = require "./Replay.js"
if settings.modules.athletic_check.enabled
AthleticChecker = require("./athletic-check.js").AthleticChecker
athleticChecker = global.athleticChecker = new AthleticChecker(settings.modules.athletic_check)
# 组件 # 组件
ygopro = global.ygopro = require './ygopro.js' ygopro = global.ygopro = require './ygopro.js'
roomlist = global.roomlist = require './roomlist.js' if settings.modules.http.websocket_roomlist roomlist = global.roomlist = require './roomlist.js' if settings.modules.http.websocket_roomlist
...@@ -1702,7 +1706,7 @@ class Room ...@@ -1702,7 +1706,7 @@ class Room
else else
for player in @players when player.pos != 7 for player in @players when player.pos != 7
@scores[player.name_vpass] = -5 @scores[player.name_vpass] = -5
if @players.length == 2 if @players.length == 2 and !client.arena_quit_free
@scores[client.name_vpass] = -9 @scores[client.name_vpass] = -9
@arena_score_handled = true @arena_score_handled = true
index = _.indexOf(@players, client) index = _.indexOf(@players, client)
...@@ -1796,6 +1800,20 @@ class Room ...@@ -1796,6 +1800,20 @@ class Room
for buffer in @recover_buffers[player.pos] for buffer in @recover_buffers[player.pos]
ygopro.stoc_send(player, "GAME_MSG", buffer) ygopro.stoc_send(player, "GAME_MSG", buffer)
check_athletic: ->
players = @get_playing_player()
room = this
await Promise.all(players.map((player) ->
main = _.clone(player.main)
side = _.clone(player.side)
using_athletic = await athleticChecker.checkAthletic({main: main, side: side})
if !using_athletic.success
log.warn("GET ATHLETIC FAIL", player.name, using_athletic.message)
else if using_athletic.athletic
ygopro.stoc_send_chat_to_room(room, "#{player.name}${using_athletic_deck}", ygopro.constants.COLORS.BABYBLUE)
))
await return
# 网络连接 # 网络连接
net.createServer (client) -> net.createServer (client) ->
client.ip = client.remoteAddress client.ip = client.remoteAddress
...@@ -2124,7 +2142,7 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2124,7 +2142,7 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
replay_id=Cloud_replay_ids[Math.floor(Math.random()*Cloud_replay_ids.length)] replay_id=Cloud_replay_ids[Math.floor(Math.random()*Cloud_replay_ids.length)]
redisdb.hgetall "replay:"+replay_id, client.open_cloud_replay redisdb.hgetall "replay:"+replay_id, client.open_cloud_replay
else if info.version != settings.version # and (info.version < 9020 or settings.version != 4927) #强行兼容23333版 else if info.version != settings.version and !settings.alternative_versions.includes(info.version)
ygopro.stoc_send_chat(client, settings.modules.update, ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, settings.modules.update, ygopro.constants.COLORS.RED)
ygopro.stoc_send client, 'ERROR_MSG', { ygopro.stoc_send client, 'ERROR_MSG', {
msg: 4 msg: 4
...@@ -2141,12 +2159,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2141,12 +2159,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
ygopro.stoc_die(client, '${invalid_password_length}') ygopro.stoc_die(client, '${invalid_password_length}')
return return
#if info.version >= 9020 and settings.version == 4927 #强行兼容23333版 if info.version != settings.version and settings.alternative_versions.includes(info.version)
# info.version = settings.version info.version = settings.version
# struct = ygopro.structs.get("CTOS_JoinGame") struct = ygopro.structs.get("CTOS_JoinGame")
# struct._setBuff(buffer) struct._setBuff(buffer)
# struct.set("version", info.version) struct.set("version", info.version)
# buffer = struct.buffer buffer = struct.buffer
buffer = Buffer.from(info.pass[0...8], 'base64') buffer = Buffer.from(info.pass[0...8], 'base64')
...@@ -2372,6 +2390,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2372,6 +2390,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
else if settings.modules.challonge.enabled else if settings.modules.challonge.enabled
if info.version != settings.version and settings.alternative_versions.includes(info.version)
info.version = settings.version
struct = ygopro.structs.get("CTOS_JoinGame")
struct._setBuff(buffer)
struct.set("version", info.version)
buffer = struct.buffer
pre_room = ROOM_find_by_name(info.pass) pre_room = ROOM_find_by_name(info.pass)
if pre_room and pre_room.duel_stage != ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.cloud_replay.enable_halfway_watch and !pre_room.hostinfo.no_watch if pre_room and pre_room.duel_stage != ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.cloud_replay.enable_halfway_watch and !pre_room.hostinfo.no_watch
room = pre_room room = pre_room
...@@ -2514,13 +2538,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2514,13 +2538,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
ygopro.stoc_die(client, "${invalid_password_room}") ygopro.stoc_die(client, "${invalid_password_room}")
else else
#if info.version >= 9020 and settings.version == 4927 #强行兼容23333版 if info.version != settings.version and settings.alternative_versions.includes(info.version)
# info.version = settings.version info.version = settings.version
# struct = ygopro.structs.get("CTOS_JoinGame") struct = ygopro.structs.get("CTOS_JoinGame")
# struct._setBuff(buffer) struct._setBuff(buffer)
# struct.set("version", info.version) struct.set("version", info.version)
# buffer = struct.buffer buffer = struct.buffer
# #ygopro.stoc_send_chat(client, "看起来你是YGOMobile的用户,请记得更新先行卡补丁,否则会看到白卡", ygopro.constants.COLORS.GREEN)
#log.info 'join_game',info.pass, client.name #log.info 'join_game',info.pass, client.name
room = ROOM_find_or_create_by_name(info.pass, client.ip) room = ROOM_find_or_create_by_name(info.pass, client.ip)
...@@ -3055,15 +3078,24 @@ ygopro.stoc_follow 'HS_PLAYER_ENTER', true, (buffer, info, client, server, datas ...@@ -3055,15 +3078,24 @@ ygopro.stoc_follow 'HS_PLAYER_ENTER', true, (buffer, info, client, server, datas
ygopro.stoc_follow 'HS_PLAYER_CHANGE', true, (buffer, info, client, server, datas)-> ygopro.stoc_follow 'HS_PLAYER_CHANGE', true, (buffer, info, client, server, datas)->
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
return unless room and room.max_player and client.pos == 0 return unless room and client.pos == 0
pos = info.status >> 4 pos = info.status >> 4
is_ready = (info.status & 0xf) == 9 is_ready = (info.status & 0xf) == 9
if pos < room.max_player room.ready_player_count = 0
if room.arena room.ready_player_count_without_host = 0
room.ready_player_count = 0 for player in room.players
for player in room.players if player.pos == pos
if player.pos == pos player.is_ready = is_ready
player.is_ready = is_ready if player.is_ready
++room.ready_player_count
unless player.is_host
++room.ready_player_count_without_host
if settings.modules.athletic_check.enabled
possibly_max_player = if room.hostinfo.mode == 2 then 4 else 2
if room.ready_player_count >= possibly_max_player
room.check_athletic()
if room.max_player and pos < room.max_player
if room.arena # mycard
p1 = room.players[0] p1 = room.players[0]
p2 = room.players[1] p2 = room.players[1]
if !p1 or !p2 if !p1 or !p2
...@@ -3087,13 +3119,7 @@ ygopro.stoc_follow 'HS_PLAYER_CHANGE', true, (buffer, info, client, server, data ...@@ -3087,13 +3119,7 @@ ygopro.stoc_follow 'HS_PLAYER_CHANGE', true, (buffer, info, client, server, data
clearInterval room.waiting_for_player_interval clearInterval room.waiting_for_player_interval
room.waiting_for_player_interval = null room.waiting_for_player_interval = null
room.waiting_for_player_time = settings.modules.arena_mode.ready_time room.waiting_for_player_time = settings.modules.arena_mode.ready_time
else else # random duel
room.ready_player_count_without_host = 0
for player in room.players
if player.pos == pos
player.is_ready = is_ready
unless player.is_host
room.ready_player_count_without_host += player.is_ready
if room.ready_player_count_without_host >= room.max_player - 1 if room.ready_player_count_without_host >= room.max_player - 1
#log.info "all ready" #log.info "all ready"
setTimeout (()-> wait_room_start(ROOM_all[client.rid], settings.modules.random_duel.ready_time);return), 1000 setTimeout (()-> wait_room_start(ROOM_all[client.rid], settings.modules.random_duel.ready_time);return), 1000
...@@ -4001,7 +4027,7 @@ if settings.modules.mycard.enabled ...@@ -4001,7 +4027,7 @@ if settings.modules.mycard.enabled
return return
) )
if settings.modules.arena_mode.punish_quit_before_match if true # settings.modules.arena_mode.punish_quit_before_match
_async.each(ROOM_all, (room, done) -> _async.each(ROOM_all, (room, done) ->
if not (room and room.arena and room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.get_playing_player().length < 2) if not (room and room.arena and room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.get_playing_player().length < 2)
done() done()
......
// Generated by CoffeeScript 2.5.1 // Generated by CoffeeScript 2.5.1
(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_replays, 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_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_banned, ROOM_players_oppentlist, ROOM_players_scores, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_module_name, challonge_queue_callbacks, challonge_type, chat_color, concat_name, config, cppversion, crypto, date, deck_name_match, default_config, default_data, dialogues, disconnect_list, dns, duel_log, e, exec, execFile, fs, geoip, getSeedTimet, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_challonge_requesting, j, k, l, len, len1, len2, len3, lflists, list, loadJSON, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, m, memory_usage, merge, moment, n, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, oldwords, options, os, path, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, qs, real_windbot_server_ip, redis, redisdb, ref, ref1, ref2, ref3, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, v, vip_info, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib; var AthleticChecker, 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_replays, 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_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_banned, ROOM_players_oppentlist, ROOM_players_scores, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_module_name, challonge_queue_callbacks, challonge_type, chat_color, concat_name, config, cppversion, crypto, date, deck_name_match, default_config, default_data, dialogues, disconnect_list, dns, duel_log, e, exec, execFile, fs, geoip, getSeedTimet, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_challonge_requesting, j, k, l, len, len1, len2, len3, lflists, list, loadJSON, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, m, memory_usage, merge, moment, n, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, oldwords, options, os, path, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, qs, real_windbot_server_ip, redis, redisdb, ref, ref1, ref2, ref3, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, v, vip_info, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib;
net = require('net'); net = require('net');
...@@ -582,6 +582,11 @@ ...@@ -582,6 +582,11 @@
ReplayParser = global.ReplayParser = require("./Replay.js"); ReplayParser = global.ReplayParser = require("./Replay.js");
} }
if (settings.modules.athletic_check.enabled) {
AthleticChecker = require("./athletic-check.js").AthleticChecker;
athleticChecker = global.athleticChecker = new AthleticChecker(settings.modules.athletic_check);
}
// 组件 // 组件
ygopro = global.ygopro = require('./ygopro.js'); ygopro = global.ygopro = require('./ygopro.js');
...@@ -2282,7 +2287,7 @@ ...@@ -2282,7 +2287,7 @@
this.scores[player.name_vpass] = -5; this.scores[player.name_vpass] = -5;
} }
} }
if (this.players.length === 2) { if (this.players.length === 2 && !client.arena_quit_free) {
this.scores[client.name_vpass] = -9; this.scores[client.name_vpass] = -9;
} }
} }
...@@ -2428,6 +2433,26 @@ ...@@ -2428,6 +2433,26 @@
} }
} }
async check_athletic() {
var players, room;
players = this.get_playing_player();
room = this;
await Promise.all(players.map(async function(player) {
var main, side, using_athletic;
main = _.clone(player.main);
side = _.clone(player.side);
using_athletic = (await athleticChecker.checkAthletic({
main: main,
side: side
}));
if (!using_athletic.success) {
return log.warn("GET ATHLETIC FAIL", player.name, using_athletic.message);
} else if (using_athletic.athletic) {
return ygopro.stoc_send_chat_to_room(room, `${player.name}\${using_athletic_deck}`, ygopro.constants.COLORS.BABYBLUE);
}
}));
}
}; };
// 网络连接 // 网络连接
...@@ -2749,7 +2774,7 @@ ...@@ -2749,7 +2774,7 @@
}); });
ygopro.ctos_follow('JOIN_GAME', true, async function(buffer, info, client, server, datas) { ygopro.ctos_follow('JOIN_GAME', true, async function(buffer, info, client, server, datas) {
var available_logs, check_buffer_indentity, create_room_with_action, len3, len4, len5, len6, line, n, name, o, p, pre_room, q, recover_match, ref4, ref5, ref6, ref7, replay_id, room; var available_logs, check_buffer_indentity, create_room_with_action, len3, len4, len5, len6, line, n, name, o, p, pre_room, q, recover_match, ref4, ref5, ref6, ref7, replay_id, room, struct;
//log.info info //log.info info
info.pass = info.pass.trim(); info.pass = info.pass.trim();
client.pass = info.pass; client.pass = info.pass;
...@@ -2824,7 +2849,7 @@ ...@@ -2824,7 +2849,7 @@
} else if (info.pass.toUpperCase() === "W" && settings.modules.cloud_replay.enabled) { } else if (info.pass.toUpperCase() === "W" && settings.modules.cloud_replay.enabled) {
replay_id = Cloud_replay_ids[Math.floor(Math.random() * Cloud_replay_ids.length)]; replay_id = Cloud_replay_ids[Math.floor(Math.random() * Cloud_replay_ids.length)];
redisdb.hgetall("replay:" + replay_id, client.open_cloud_replay); redisdb.hgetall("replay:" + replay_id, client.open_cloud_replay);
} else if (info.version !== settings.version) { // and (info.version < 9020 or settings.version != 4927) #强行兼容23333版 } else if (info.version !== settings.version && !settings.alternative_versions.includes(info.version)) {
ygopro.stoc_send_chat(client, settings.modules.update, ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, settings.modules.update, ygopro.constants.COLORS.RED);
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 4, msg: 4,
...@@ -2839,12 +2864,13 @@ ...@@ -2839,12 +2864,13 @@
ygopro.stoc_die(client, '${invalid_password_length}'); ygopro.stoc_die(client, '${invalid_password_length}');
return; return;
} }
//if info.version >= 9020 and settings.version == 4927 #强行兼容23333版 if (info.version !== settings.version && settings.alternative_versions.includes(info.version)) {
// info.version = settings.version info.version = settings.version;
// struct = ygopro.structs.get("CTOS_JoinGame") struct = ygopro.structs.get("CTOS_JoinGame");
// struct._setBuff(buffer) struct._setBuff(buffer);
// struct.set("version", info.version) struct.set("version", info.version);
// buffer = struct.buffer buffer = struct.buffer;
}
buffer = Buffer.from(info.pass.slice(0, 8), 'base64'); buffer = Buffer.from(info.pass.slice(0, 8), 'base64');
if (buffer.length !== 6) { if (buffer.length !== 6) {
ygopro.stoc_die(client, '${invalid_password_payload}'); ygopro.stoc_die(client, '${invalid_password_payload}');
...@@ -3122,6 +3148,13 @@ ...@@ -3122,6 +3148,13 @@
return create_room_with_action(data.get_user.original, data.get_user.decrypted, data.match_permit); return create_room_with_action(data.get_user.original, data.get_user.decrypted, data.match_permit);
}); });
} else if (settings.modules.challonge.enabled) { } else if (settings.modules.challonge.enabled) {
if (info.version !== settings.version && settings.alternative_versions.includes(info.version)) {
info.version = settings.version;
struct = ygopro.structs.get("CTOS_JoinGame");
struct._setBuff(buffer);
struct.set("version", info.version);
buffer = struct.buffer;
}
pre_room = ROOM_find_by_name(info.pass); pre_room = ROOM_find_by_name(info.pass);
if (pre_room && pre_room.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.cloud_replay.enable_halfway_watch && !pre_room.hostinfo.no_watch) { if (pre_room && pre_room.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.cloud_replay.enable_halfway_watch && !pre_room.hostinfo.no_watch) {
room = pre_room; room = pre_room;
...@@ -3293,14 +3326,13 @@ ...@@ -3293,14 +3326,13 @@
} else if (info.pass.length && !ROOM_validate(info.pass)) { } else if (info.pass.length && !ROOM_validate(info.pass)) {
ygopro.stoc_die(client, "${invalid_password_room}"); ygopro.stoc_die(client, "${invalid_password_room}");
} else { } else {
//if info.version >= 9020 and settings.version == 4927 #强行兼容23333版 if (info.version !== settings.version && settings.alternative_versions.includes(info.version)) {
// info.version = settings.version info.version = settings.version;
// struct = ygopro.structs.get("CTOS_JoinGame") struct = ygopro.structs.get("CTOS_JoinGame");
// struct._setBuff(buffer) struct._setBuff(buffer);
// struct.set("version", info.version) struct.set("version", info.version);
// buffer = struct.buffer buffer = struct.buffer;
// #ygopro.stoc_send_chat(client, "看起来你是YGOMobile的用户,请记得更新先行卡补丁,否则会看到白卡", ygopro.constants.COLORS.GREEN) }
//log.info 'join_game',info.pass, client.name //log.info 'join_game',info.pass, client.name
room = ROOM_find_or_create_by_name(info.pass, client.ip); room = ROOM_find_or_create_by_name(info.pass, client.ip);
if (!room) { if (!room) {
...@@ -4029,23 +4061,36 @@ ...@@ -4029,23 +4061,36 @@
}); });
ygopro.stoc_follow('HS_PLAYER_CHANGE', true, async function(buffer, info, client, server, datas) { ygopro.stoc_follow('HS_PLAYER_CHANGE', true, async function(buffer, info, client, server, datas) {
var is_ready, len3, len4, n, o, p1, p2, player, pos, ref4, ref5, room; var is_ready, len3, n, p1, p2, player, pos, possibly_max_player, ref4, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!(room && room.max_player && client.pos === 0)) { if (!(room && client.pos === 0)) {
return; return;
} }
pos = info.status >> 4; pos = info.status >> 4;
is_ready = (info.status & 0xf) === 9; is_ready = (info.status & 0xf) === 9;
if (pos < room.max_player) { room.ready_player_count = 0;
if (room.arena) { room.ready_player_count_without_host = 0;
room.ready_player_count = 0; ref4 = room.players;
ref4 = room.players; for (n = 0, len3 = ref4.length; n < len3; n++) {
for (n = 0, len3 = ref4.length; n < len3; n++) { player = ref4[n];
player = ref4[n]; if (player.pos === pos) {
if (player.pos === pos) { player.is_ready = is_ready;
player.is_ready = is_ready; }
} if (player.is_ready) {
++room.ready_player_count;
if (!player.is_host) {
++room.ready_player_count_without_host;
} }
}
}
if (settings.modules.athletic_check.enabled) {
possibly_max_player = room.hostinfo.mode === 2 ? 4 : 2;
if (room.ready_player_count >= possibly_max_player) {
room.check_athletic();
}
}
if (room.max_player && pos < room.max_player) {
if (room.arena) { // mycard
p1 = room.players[0]; p1 = room.players[0];
p2 = room.players[1]; p2 = room.players[1];
if (!p1 || !p2) { if (!p1 || !p2) {
...@@ -4075,20 +4120,9 @@ ...@@ -4075,20 +4120,9 @@
} else if (!room.waiting_for_player && room.waiting_for_player_interval) { } else if (!room.waiting_for_player && room.waiting_for_player_interval) {
clearInterval(room.waiting_for_player_interval); clearInterval(room.waiting_for_player_interval);
room.waiting_for_player_interval = null; room.waiting_for_player_interval = null;
room.waiting_for_player_time = settings.modules.arena_mode.ready_time; room.waiting_for_player_time = settings.modules.arena_mode.ready_time; // random duel
} }
} else { } else {
room.ready_player_count_without_host = 0;
ref5 = room.players;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player.pos === pos) {
player.is_ready = is_ready;
}
if (!player.is_host) {
room.ready_player_count_without_host += player.is_ready;
}
}
if (room.ready_player_count_without_host >= room.max_player - 1) { if (room.ready_player_count_without_host >= room.max_player - 1) {
//log.info "all ready" //log.info "all ready"
setTimeout((function() { setTimeout((function() {
...@@ -5368,7 +5402,7 @@ ...@@ -5368,7 +5402,7 @@
} }
done(); done();
}); });
if (settings.modules.arena_mode.punish_quit_before_match) { if (true) { // settings.modules.arena_mode.punish_quit_before_match
_async.each(ROOM_all, function(room, done) { _async.each(ROOM_all, function(room, done) {
var player, waited_time; var player, waited_time;
if (!(room && room.arena && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.get_playing_player().length < 2)) { if (!(room && room.arena && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.get_playing_player().length < 2)) {
......
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