Commit aa4e8dd9 authored by nanahira's avatar nanahira

Merge branch 'master' into ai-play

parents 1dc9ca38 92fd82f4
Pipeline #38689 passed with stages
in 16 minutes and 50 seconds
...@@ -6,9 +6,8 @@ RUN apt update && \ ...@@ -6,9 +6,8 @@ RUN apt update && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/*
WORKDIR /usr/src WORKDIR /usr/src
RUN wget -O premake.zip https://github.com/premake/premake-core/releases/download/v5.0.0-beta5/premake-5.0.0-beta5-src.zip && \ RUN wget -O premake.zip https://github.com/premake/premake-core/releases/download/v5.0.0-beta7/premake-5.0.0-beta7-src.zip && \
7z x -y premake.zip && \ 7z x -y -opremake premake.zip && \
mv premake-5.0.0-beta5-src premake && \
cd premake/build/gmake.unix && \ cd premake/build/gmake.unix && \
make -j$(nproc) make -j$(nproc)
......
...@@ -15,15 +15,25 @@ const getPolyfillers = (version) => { ...@@ -15,15 +15,25 @@ const getPolyfillers = (version) => {
}; };
async function polyfillGameMsg(version, msgTitle, buffer) { async function polyfillGameMsg(version, msgTitle, buffer) {
const polyfillers = getPolyfillers(version); const polyfillers = getPolyfillers(version);
let mutated = false; let pbuf = buffer;
for (const polyfiller of polyfillers) { for (const polyfiller of polyfillers) {
const newBuf = await polyfiller.polyfillGameMsg(msgTitle, buffer); const newBuf = await polyfiller.polyfillGameMsg(msgTitle, pbuf);
if (newBuf) { if (newBuf) {
mutated = true; pbuf = newBuf;
buffer = newBuf;
} }
} }
return mutated ? buffer : undefined; if (pbuf === buffer) {
return undefined;
}
else if (pbuf.length <= buffer.length) {
pbuf.copy(buffer, 0, 0, pbuf.length);
return pbuf.length === buffer.length
? undefined
: buffer.slice(0, pbuf.length);
}
else {
return pbuf;
}
} }
async function polyfillResponse(version, msgTitle, buffer) { async function polyfillResponse(version, msgTitle, buffer) {
const polyfillers = getPolyfillers(version); const polyfillers = getPolyfillers(version);
......
...@@ -15,15 +15,23 @@ const getPolyfillers = (version: number) => { ...@@ -15,15 +15,23 @@ const getPolyfillers = (version: number) => {
export async function polyfillGameMsg(version: number, msgTitle: string, buffer: Buffer) { export async function polyfillGameMsg(version: number, msgTitle: string, buffer: Buffer) {
const polyfillers = getPolyfillers(version); const polyfillers = getPolyfillers(version);
let mutated = false; let pbuf = buffer;
for (const polyfiller of polyfillers) { for (const polyfiller of polyfillers) {
const newBuf = await polyfiller.polyfillGameMsg(msgTitle, buffer); const newBuf = await polyfiller.polyfillGameMsg(msgTitle, pbuf);
if (newBuf) { if (newBuf) {
mutated = true; pbuf = newBuf;
buffer = newBuf;
} }
} }
return mutated ? buffer : undefined; if (pbuf === buffer) {
return undefined;
} else if (pbuf.length <= buffer.length) {
pbuf.copy(buffer, 0, 0, pbuf.length);
return pbuf.length === buffer.length
? undefined
: buffer.slice(0, pbuf.length);
} else {
return pbuf;
}
} }
export async function polyfillResponse(version: number, msgTitle: string, buffer: Buffer) { export async function polyfillResponse(version: number, msgTitle: string, buffer: Buffer) {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
"moment": "^2.29.1", "moment": "^2.29.1",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-os-utils": "^1.3.2", "node-os-utils": "^1.3.2",
"p-queue": "6.6.2", "p-queue": "^6.6.2",
"pg": "^6.4.2", "pg": "^6.4.2",
"q": "^1.5.1", "q": "^1.5.1",
"querystring": "^0.2.0", "querystring": "^0.2.0",
...@@ -2318,6 +2318,7 @@ ...@@ -2318,6 +2318,7 @@
"version": "6.6.2", "version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
"integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"eventemitter3": "^4.0.4", "eventemitter3": "^4.0.4",
"p-timeout": "^3.2.0" "p-timeout": "^3.2.0"
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"moment": "^2.29.1", "moment": "^2.29.1",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-os-utils": "^1.3.2", "node-os-utils": "^1.3.2",
"p-queue": "6.6.2", "p-queue": "^6.6.2",
"pg": "^6.4.2", "pg": "^6.4.2",
"q": "^1.5.1", "q": "^1.5.1",
"querystring": "^0.2.0", "querystring": "^0.2.0",
......
...@@ -103,6 +103,8 @@ Aragami = require('aragami').Aragami ...@@ -103,6 +103,8 @@ Aragami = require('aragami').Aragami
aragami = global.aragami = new Aragami() # we use memory mode only aragami = global.aragami = new Aragami() # we use memory mode only
PQueue = require('p-queue').default
aragami_classes = global.aragami_classes = require('./aragami-classes.js') aragami_classes = global.aragami_classes = require('./aragami-classes.js')
msg_polyfill = global.msg_polyfill = require('./msg-polyfill/index.js') msg_polyfill = global.msg_polyfill = require('./msg-polyfill/index.js')
...@@ -1016,7 +1018,7 @@ CLIENT_get_authorize_key = global.CLIENT_get_authorize_key = (client) -> ...@@ -1016,7 +1018,7 @@ CLIENT_get_authorize_key = global.CLIENT_get_authorize_key = (client) ->
if !settings.modules.mycard.enabled and client.vpass if !settings.modules.mycard.enabled and client.vpass
return client.name_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 or client.ip or 'undefined'
else else
return client.ip + ":" + client.name return client.ip + ":" + client.name
...@@ -1330,8 +1332,11 @@ toIpv6 = global.toIpv6 = (ip) -> ...@@ -1330,8 +1332,11 @@ toIpv6 = global.toIpv6 = (ip) ->
isTrustedProxy = global.isTrustedProxy = (ip) -> isTrustedProxy = global.isTrustedProxy = (ip) ->
return settings.modules.trusted_proxies.some((trusted) -> return settings.modules.trusted_proxies.some((trusted) ->
cidr = if trusted.includes('/') then ip6addr.createCIDR(trusted) else ip6addr.createAddrRange(trusted, trusted) try
return cidr.contains(ip) cidr = if trusted.includes('/') then ip6addr.createCIDR(trusted) else ip6addr.createAddrRange(trusted, trusted)
return cidr.contains(ip)
catch e
return false
) )
getRealIp = global.getRealIp = (physical_ip, xff_ip) -> getRealIp = global.getRealIp = (physical_ip, xff_ip) ->
...@@ -2242,6 +2247,12 @@ netRequestHandler = (client) -> ...@@ -2242,6 +2247,12 @@ netRequestHandler = (client) ->
client.pre_establish_buffers = new Array() client.pre_establish_buffers = new Array()
client_data_queue = new PQueue
concurrency: 1
server_data_queue = new PQueue
concurrency: 1
dataHandler = (ctos_buffer) -> dataHandler = (ctos_buffer) ->
if client.is_post_watcher if client.is_post_watcher
room=ROOM_all[client.rid] room=ROOM_all[client.rid]
...@@ -2292,13 +2303,18 @@ netRequestHandler = (client) -> ...@@ -2292,13 +2303,18 @@ netRequestHandler = (client) ->
return return
queuedDataHandler = (ctos_buffer) ->
if client.isClosed or client.system_kicked
return
return await client_data_queue.add(() -> dataHandler(ctos_buffer))
if client.isWs if client.isWs
client.on 'message', dataHandler client.on 'message', queuedDataHandler
else else
client.on 'data', dataHandler client.on 'data', queuedDataHandler
# 服务端到客户端(stoc) # 服务端到客户端(stoc)
server.on 'data', (stoc_buffer)-> serverDataHandler = (stoc_buffer)->
handle_data = await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, { handle_data = await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, {
client: server.client, client: server.client,
server: server server: server
...@@ -2312,6 +2328,13 @@ netRequestHandler = (client) -> ...@@ -2312,6 +2328,13 @@ netRequestHandler = (client) ->
await ygopro.helper.send(server.client, buffer) for buffer in handle_data.datas await ygopro.helper.send(server.client, buffer) for buffer in handle_data.datas
return return
queuedServerDataHandler = (stoc_buffer) ->
if server.isClosed
return
return await server_data_queue.add(() -> serverDataHandler(stoc_buffer))
server.on 'data', queuedServerDataHandler
return return
deck_name_match = global.deck_name_match = (deck_name, player_name) -> deck_name_match = global.deck_name_match = (deck_name, player_name) ->
...@@ -2392,17 +2415,20 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2392,17 +2415,20 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
} }
CLIENT_kick(client) CLIENT_kick(client)
return false return false
client_key = CLIENT_get_authorize_key(client)
clean_blocker = () ->
aragami.del(aragami_classes.ClientVersionBlocker, client_key)
if info.version == settings.version if info.version == settings.version
await clean_blocker()
return true return true
if settings.alternative_versions.includes(info.version) if settings.alternative_versions.includes(info.version)
client_key = CLIENT_get_authorize_key(client)
if !await aragami.has(aragami_classes.ClientVersionBlocker, client_key) if !await aragami.has(aragami_classes.ClientVersionBlocker, client_key)
blocker_obj = new aragami_classes.ClientVersionBlocker() blocker_obj = new aragami_classes.ClientVersionBlocker()
blocker_obj.clientKey = client_key blocker_obj.clientKey = client_key
await aragami.set(blocker_obj) await aragami.set(blocker_obj)
return bad_version("${version_to_polyfill}") return bad_version("${version_to_polyfill}")
else else
await aragami.del(aragami_classes.ClientVersionBlocker, client_key) await clean_blocker()
return true return true
return bad_version(if info.version < settings.version then settings.modules.update else settings.modules.wait_update) return bad_version(if info.version < settings.version then settings.modules.update else settings.modules.wait_update)
polyfill_version = () -> polyfill_version = () ->
......
// Generated by CoffeeScript 2.7.0 // Generated by CoffeeScript 2.7.0
(function() { (function() {
// 标准库 // 标准库
var Aragami, 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_set_ip, 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, YGOProDeck, _, _async, addCallback, aragami, aragami_classes, 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, getRealIp, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, ip6addr, isTrustedProxy, 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, msg_polyfill, 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, toIpv4, toIpv6, url, users_cache, util, utility, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib; var Aragami, 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_set_ip, CLIENT_use_cdkey, PQueue, 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, YGOProDeck, _, _async, addCallback, aragami, aragami_classes, 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, getRealIp, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, ip6addr, isTrustedProxy, 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, msg_polyfill, 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, toIpv4, toIpv6, url, users_cache, util, utility, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib;
net = require('net'); net = require('net');
...@@ -91,6 +91,8 @@ ...@@ -91,6 +91,8 @@
aragami = global.aragami = new Aragami(); // we use memory mode only aragami = global.aragami = new Aragami(); // we use memory mode only
PQueue = require('p-queue').default;
aragami_classes = global.aragami_classes = require('./aragami-classes.js'); aragami_classes = global.aragami_classes = require('./aragami-classes.js');
msg_polyfill = global.msg_polyfill = require('./msg-polyfill/index.js'); msg_polyfill = global.msg_polyfill = require('./msg-polyfill/index.js');
...@@ -1323,7 +1325,7 @@ ...@@ -1323,7 +1325,7 @@
if (!settings.modules.mycard.enabled && client.vpass) { if (!settings.modules.mycard.enabled && client.vpass) {
return client.name_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 || client.ip || 'undefined';
} else { } else {
return client.ip + ":" + client.name; return client.ip + ":" + client.name;
} }
...@@ -1744,9 +1746,14 @@ ...@@ -1744,9 +1746,14 @@
isTrustedProxy = global.isTrustedProxy = function(ip) { isTrustedProxy = global.isTrustedProxy = function(ip) {
return settings.modules.trusted_proxies.some(function(trusted) { return settings.modules.trusted_proxies.some(function(trusted) {
var cidr; var cidr, e;
cidr = trusted.includes('/') ? ip6addr.createCIDR(trusted) : ip6addr.createAddrRange(trusted, trusted); try {
return cidr.contains(ip); cidr = trusted.includes('/') ? ip6addr.createCIDR(trusted) : ip6addr.createAddrRange(trusted, trusted);
return cidr.contains(ip);
} catch (error1) {
e = error1;
return false;
}
}); });
}; };
...@@ -2835,7 +2842,7 @@ ...@@ -2835,7 +2842,7 @@
// 网络连接 // 网络连接
netRequestHandler = function(client) { netRequestHandler = function(client) {
var closeHandler, dataHandler, server; var client_data_queue, closeHandler, dataHandler, queuedDataHandler, queuedServerDataHandler, server, serverDataHandler, server_data_queue;
if (!client.isWs) { if (!client.isWs) {
client.physical_ip = client.remoteAddress || ""; client.physical_ip = client.remoteAddress || "";
if (CLIENT_set_ip(client)) { if (CLIENT_set_ip(client)) {
...@@ -2972,6 +2979,12 @@ ...@@ -2972,6 +2979,12 @@
// 需要重构 // 需要重构
// 客户端到服务端(ctos)协议分析 // 客户端到服务端(ctos)协议分析
client.pre_establish_buffers = new Array(); client.pre_establish_buffers = new Array();
client_data_queue = new PQueue({
concurrency: 1
});
server_data_queue = new PQueue({
concurrency: 1
});
dataHandler = async function(ctos_buffer) { dataHandler = async function(ctos_buffer) {
var bad_ip_count, buffer, ctos_filter, handle_data, j, l, len, len1, preconnect, ref, ref1, room; var bad_ip_count, buffer, ctos_filter, handle_data, j, l, len, len1, preconnect, ref, ref1, room;
if (client.is_post_watcher) { if (client.is_post_watcher) {
...@@ -3040,13 +3053,21 @@ ...@@ -3040,13 +3053,21 @@
} }
} }
}; };
queuedDataHandler = async function(ctos_buffer) {
if (client.isClosed || client.system_kicked) {
return;
}
return (await client_data_queue.add(function() {
return dataHandler(ctos_buffer);
}));
};
if (client.isWs) { if (client.isWs) {
client.on('message', dataHandler); client.on('message', queuedDataHandler);
} else { } else {
client.on('data', dataHandler); client.on('data', queuedDataHandler);
} }
// 服务端到客户端(stoc) // 服务端到客户端(stoc)
server.on('data', async function(stoc_buffer) { serverDataHandler = async function(stoc_buffer) {
var buffer, handle_data, j, len, ref; var buffer, handle_data, j, len, ref;
handle_data = (await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, { handle_data = (await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, {
client: server.client, client: server.client,
...@@ -3066,7 +3087,16 @@ ...@@ -3066,7 +3087,16 @@
await ygopro.helper.send(server.client, buffer); await ygopro.helper.send(server.client, buffer);
} }
} }
}); };
queuedServerDataHandler = async function(stoc_buffer) {
if (server.isClosed) {
return;
}
return (await server_data_queue.add(function() {
return serverDataHandler(stoc_buffer);
}));
};
server.on('data', queuedServerDataHandler);
}; };
deck_name_match = global.deck_name_match = function(deck_name, player_name) { deck_name_match = global.deck_name_match = function(deck_name, player_name) {
...@@ -3149,7 +3179,7 @@ ...@@ -3149,7 +3179,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, check_version, create_room_name, create_room_with_action, decrypted_buffer, duelLog, e, exactBan, i, id, index, j, l, len, len1, len2, len3, m, matching_match, matching_participant, n, polyfill_version, pre_room, recover_match, ref, ref1, replay, replay_id, replays, room, secret, struct, tournament_data, userData, userDataRes, userUrl; var available_logs, check_buffer_indentity, check_version, create_room_name, create_room_with_action, decrypted_buffer, duelLog, e, exactBan, i, id, index, j, l, len, len1, len2, len3, m, matching_match, matching_participant, n, polyfill_version, pre_room, recover_match, ref, ref1, replay, replay_id, replays, room, secret, struct, tournament_data, userData, userDataRes, userUrl;
check_version = async function() { check_version = async function() {
var bad_version, blocker_obj, client_key; var bad_version, blocker_obj, clean_blocker, client_key;
bad_version = function(msg) { bad_version = function(msg) {
ygopro.stoc_send_chat(client, msg, ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, msg, ygopro.constants.COLORS.RED);
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
...@@ -3159,18 +3189,22 @@ ...@@ -3159,18 +3189,22 @@
CLIENT_kick(client); CLIENT_kick(client);
return false; return false;
}; };
client_key = CLIENT_get_authorize_key(client);
clean_blocker = function() {
return aragami.del(aragami_classes.ClientVersionBlocker, client_key);
};
if (info.version === settings.version) { if (info.version === settings.version) {
await clean_blocker();
return true; return true;
} }
if (settings.alternative_versions.includes(info.version)) { if (settings.alternative_versions.includes(info.version)) {
client_key = CLIENT_get_authorize_key(client);
if (!(await aragami.has(aragami_classes.ClientVersionBlocker, client_key))) { if (!(await aragami.has(aragami_classes.ClientVersionBlocker, client_key))) {
blocker_obj = new aragami_classes.ClientVersionBlocker(); blocker_obj = new aragami_classes.ClientVersionBlocker();
blocker_obj.clientKey = client_key; blocker_obj.clientKey = client_key;
await aragami.set(blocker_obj); await aragami.set(blocker_obj);
return bad_version("${version_to_polyfill}"); return bad_version("${version_to_polyfill}");
} else { } else {
await aragami.del(aragami_classes.ClientVersionBlocker, client_key); await clean_blocker();
return true; return true;
} }
} }
......
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