mirror of
https://github.com/smogon/pokemon-showdown-loginserver.git
synced 2026-04-27 01:57:26 -05:00
Add an action to manually check if a user is verified for a suspect
For fallbacks, mostly. Shouldn't truly be needed.
This commit is contained in:
parent
735b408ed0
commit
72661ecf4a
101
src/actions.ts
101
src/actions.ts
|
|
@ -9,7 +9,7 @@ import * as pathModule from 'path';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import {Config} from './config-loader';
|
import {Config} from './config-loader';
|
||||||
import {Ladder} from './ladder';
|
import {Ladder, LadderEntry} from './ladder';
|
||||||
import {Replays} from './replays';
|
import {Replays} from './replays';
|
||||||
import {ActionError, QueryHandler, Server} from './server';
|
import {ActionError, QueryHandler, Server} from './server';
|
||||||
import {Session} from './user';
|
import {Session} from './user';
|
||||||
|
|
@ -80,6 +80,51 @@ const smogonFetch = async (targetUrl: string, method: string, data: {[k: string]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function checkSuspectVerified(
|
||||||
|
rating: LadderEntry,
|
||||||
|
suspect: {formatid: string, start_date: number},
|
||||||
|
reqs: Record<string, number | null>
|
||||||
|
) {
|
||||||
|
let reqsMet = 0;
|
||||||
|
let reqCount = 0;
|
||||||
|
const userData: Partial<{elo: number, gxe: number, coil: number}> = {};
|
||||||
|
for (const k in reqs) {
|
||||||
|
if (!reqs[k as 'elo' | 'coil' | 'gxe']) continue;
|
||||||
|
reqCount++;
|
||||||
|
switch (k) {
|
||||||
|
case 'coil':
|
||||||
|
const N = rating.w + rating.l + rating.t;
|
||||||
|
const coilNum = Math.round(40.0 * rating.gxe * Math.pow(2.0, -coil[suspect.formatid] / N));
|
||||||
|
if (coilNum >= reqs.coil!) {
|
||||||
|
reqsMet++;
|
||||||
|
}
|
||||||
|
userData.coil = coilNum;
|
||||||
|
break;
|
||||||
|
case 'elo': case 'gxe':
|
||||||
|
if (reqs[k] && rating[k] >= reqs[k]!) {
|
||||||
|
reqsMet++;
|
||||||
|
}
|
||||||
|
userData[k] = rating[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
// sanity check for reqs existing just to be totally safe
|
||||||
|
(reqsMet >= 1 && reqsMet === reqCount) &&
|
||||||
|
// did not play games before the test began
|
||||||
|
(rating?.first_played && rating.first_played > suspect.start_date)
|
||||||
|
) {
|
||||||
|
void smogonFetch("tools/api/suspect-verify", "POST", {
|
||||||
|
userid: rating.userid,
|
||||||
|
format: suspect.formatid,
|
||||||
|
reqs: {required: reqs, actual: userData},
|
||||||
|
suspectStartDate: suspect.start_date,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export const actions: {[k: string]: QueryHandler} = {
|
export const actions: {[k: string]: QueryHandler} = {
|
||||||
async register(params) {
|
async register(params) {
|
||||||
this.verifyCrossDomainRequest();
|
this.verifyCrossDomainRequest();
|
||||||
|
|
@ -372,43 +417,7 @@ export const actions: {[k: string]: QueryHandler} = {
|
||||||
if (suspect) {
|
if (suspect) {
|
||||||
const reqs = {elo: suspect.elo, gxe: suspect.gxe, coil: suspect.gxe};
|
const reqs = {elo: suspect.elo, gxe: suspect.gxe, coil: suspect.gxe};
|
||||||
for (const rating of [p1rating, p2rating]) {
|
for (const rating of [p1rating, p2rating]) {
|
||||||
let reqsMet = 0;
|
checkSuspectVerified(rating, suspect, reqs);
|
||||||
let reqCount = 0;
|
|
||||||
const userData: Partial<{elo: number, gxe: number, coil: number}> = {};
|
|
||||||
for (const k in reqs) {
|
|
||||||
if (!reqs[k as 'elo' | 'coil' | 'gxe']) continue;
|
|
||||||
reqCount++;
|
|
||||||
switch (k) {
|
|
||||||
case 'coil':
|
|
||||||
const N = rating.w + rating.l + rating.t;
|
|
||||||
const coilNum = Math.round(40.0 * rating.gxe * Math.pow(2.0, -coil[formatid] / N));
|
|
||||||
if (coilNum >= reqs.coil!) {
|
|
||||||
reqsMet++;
|
|
||||||
}
|
|
||||||
userData.coil = coilNum;
|
|
||||||
break;
|
|
||||||
case 'elo': case 'gxe':
|
|
||||||
if (reqs[k] && rating[k] >= reqs[k]!) {
|
|
||||||
reqsMet++;
|
|
||||||
}
|
|
||||||
userData[k] = rating[k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const ratingData = await ladder.getRating(rating.userid);
|
|
||||||
if (
|
|
||||||
// sanity check for reqs existing just to be totally safe
|
|
||||||
(reqsMet >= 1 && reqsMet === reqCount) &&
|
|
||||||
// did not play games before the test began
|
|
||||||
(ratingData?.first_played && ratingData.first_played > suspect.start_date)
|
|
||||||
) {
|
|
||||||
void smogonFetch("tools/api/suspect-verify", "POST", {
|
|
||||||
userid: rating.userid,
|
|
||||||
format: formatid,
|
|
||||||
reqs: {required: reqs, actual: userData},
|
|
||||||
suspectStartDate: suspect.start_date,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.actionsuccess = true;
|
out.actionsuccess = true;
|
||||||
|
|
@ -1076,6 +1085,22 @@ export const actions: {[k: string]: QueryHandler} = {
|
||||||
await tables.suspects.delete(id);
|
await tables.suspects.delete(id);
|
||||||
return {success: true};
|
return {success: true};
|
||||||
},
|
},
|
||||||
|
async 'suspects/verify'(params) {
|
||||||
|
if (this.getIp() !== Config.restartip) {
|
||||||
|
throw new ActionError("Access denied.");
|
||||||
|
}
|
||||||
|
const id = toID(params.format);
|
||||||
|
if (!id) throw new ActionError("No format ID specified.");
|
||||||
|
const suspect = await tables.suspects.get(id);
|
||||||
|
if (!suspect) throw new ActionError("There is no ongoing suspect for " + id);
|
||||||
|
const userid = toID(params.userid);
|
||||||
|
if (!userid || userid.length > 18) throw new ActionError("Invalid userid Pprovided.");
|
||||||
|
const rating = await tables.ladder.get(userid);
|
||||||
|
if (!rating) throw new ActionError("That user has no ratings in the given ladder.");
|
||||||
|
return {
|
||||||
|
result: checkSuspectVerified(rating, suspect, {elo: suspect.elo, coil: suspect.coil, gxe: suspect.gxe}),
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Config.actions) {
|
if (Config.actions) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
-- Unfortunately necessary to be a table in order to properly synchronize
|
-- Unfortunately necessary to be a table in order to properly synchronize
|
||||||
-- cross-processes
|
-- cross-processes
|
||||||
|
|
||||||
CREATE TABLE ntbb_suspects (
|
CREATE TABLE `ntbb_suspects` (
|
||||||
formatid varchar(100) NOT NULL PRIMARY KEY,
|
formatid varchar(100) NOT NULL PRIMARY KEY,
|
||||||
start_date bigint(20) NOT NULL,
|
start_date bigint(20) NOT NULL,
|
||||||
elo int,
|
elo int,
|
||||||
|
|
|
||||||
|
|
@ -149,4 +149,4 @@ export const suspects = psdb.getTable<{
|
||||||
coil: number | null;
|
coil: number | null;
|
||||||
gxe: number | null;
|
gxe: number | null;
|
||||||
elo: number | null;
|
elo: number | null;
|
||||||
}>("ntbb_suspects", 'formatid');
|
}>("suspects", 'formatid');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user