Logger
This commit is contained in:
parent
0e5c664250
commit
af2c334e66
|
@ -30,3 +30,92 @@ export async function getAPIKeyInformation(key: string): Promise<
|
|||
_response: response
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Skyblock profiles by player
|
||||
* @param key API key
|
||||
* @param player The player's UUID
|
||||
* @returns A response with the player's profiles
|
||||
*/
|
||||
export async function getProfilesByPlayer(
|
||||
key: string,
|
||||
player: string
|
||||
): Promise<
|
||||
HypixelResponse<{
|
||||
profiles?: {
|
||||
profile_id: string;
|
||||
members: any;
|
||||
community_upgrades: any | null;
|
||||
cute_name: string;
|
||||
banking: any | null;
|
||||
game_mode: string | null;
|
||||
}[];
|
||||
}>
|
||||
> {
|
||||
let response = await request(
|
||||
`/skyblock/profiles?uuid=${player}`,
|
||||
authorize(key)
|
||||
);
|
||||
return {
|
||||
...(await response.json()),
|
||||
_response: response
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Skyblock profile by its UUID
|
||||
* @param key API key
|
||||
* @param profile The profile's UUID
|
||||
* @returns A response with the profile data
|
||||
*/
|
||||
export async function getProfileByUUID(
|
||||
key: string,
|
||||
profile: string
|
||||
): Promise<
|
||||
HypixelResponse<{
|
||||
profile?: {
|
||||
profile_id: string;
|
||||
members: any;
|
||||
community_upgrades: any | null;
|
||||
cute_name: string;
|
||||
banking: any | null;
|
||||
game_mode: string | null;
|
||||
};
|
||||
}>
|
||||
> {
|
||||
let response = await request(
|
||||
`/skyblock/profile?profile=${profile}`,
|
||||
authorize(key)
|
||||
);
|
||||
return {
|
||||
...(await response.json()),
|
||||
_response: response
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a player's current online status
|
||||
* @param key API key
|
||||
* @param player Player to get status of
|
||||
* @returns A response with player status data
|
||||
*/
|
||||
export async function getOnlineStatus(
|
||||
key: string,
|
||||
player: string
|
||||
): Promise<
|
||||
HypixelResponse<{
|
||||
uuid?: string;
|
||||
session?: {
|
||||
online: boolean;
|
||||
gameType: string;
|
||||
mode: string;
|
||||
map: string;
|
||||
};
|
||||
}>
|
||||
> {
|
||||
let response = await request(`/status?uuid=${player}`, authorize(key));
|
||||
return {
|
||||
...(await response.json()),
|
||||
_response: response
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export enum Permissions {
|
||||
ALL = "*"
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permissions
|
||||
* @param required The permission required
|
||||
* @param has The permissions to check against
|
||||
* @returns Whether the required permissions are fulfilled
|
||||
*/
|
||||
export function checkPermissions(required: string[], has: string[]): boolean {
|
||||
if (has.includes("*")) return true;
|
||||
|
||||
return !required.some(req => {
|
||||
if (!has.includes(req)) return true;
|
||||
});
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
import { join } from "path";
|
||||
|
||||
/**
|
||||
* Get a fetch function
|
||||
* @returns A fetch function
|
||||
|
@ -11,6 +9,12 @@ export function getFetch(): typeof fetch {
|
|||
return fetch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fetch-like function with defaults
|
||||
* @param baseURL Base URL of all requests
|
||||
* @param defaultInit Default RequestInit options
|
||||
* @returns A fetch-like function
|
||||
*/
|
||||
export function requestWithDefaults(
|
||||
baseURL: string,
|
||||
defaultInit?: RequestInit
|
||||
|
@ -20,7 +24,7 @@ export function requestWithDefaults(
|
|||
overrideInit?: RequestInit
|
||||
): Promise<Response> {
|
||||
let response = await getFetch()(
|
||||
join(baseURL, endpoint),
|
||||
new URL(endpoint, baseURL).href,
|
||||
defaultInit ? deepMerge(defaultInit, overrideInit) : overrideInit
|
||||
);
|
||||
if (response.ok) {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { getOnlineStatus, getProfileByUUID } from "./lib/hypixel";
|
||||
|
||||
export async function log(key: string, profile: string) {
|
||||
let r = await getProfileByUUID(key, profile);
|
||||
if (!r.success || !r.profile) throw new Error("No success from Hypixel");
|
||||
|
||||
let d = r.profile;
|
||||
for (const member in d.members) {
|
||||
let onlineStatus = await getOnlineStatus(key, member);
|
||||
if (onlineStatus.success && onlineStatus.session) {
|
||||
d.members[member].online_status = onlineStatus.session;
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
|
@ -3,8 +3,88 @@ import polka from "polka";
|
|||
import compression from "compression";
|
||||
import * as sapper from "@sapper/server";
|
||||
|
||||
const { PORT, NODE_ENV } = process.env;
|
||||
import arangojs, { Database, aql } from "arangojs";
|
||||
import { hash } from "bcrypt";
|
||||
import { log } from "./logger";
|
||||
|
||||
const { PORT, NODE_ENV, DB_USERNAME, DB_PASSWORD, DB_URL, DB_NAME, API_KEY } =
|
||||
process.env;
|
||||
const dev = NODE_ENV === "development";
|
||||
const db = arangojs({
|
||||
auth: {
|
||||
username: DB_USERNAME || "root",
|
||||
password: DB_PASSWORD
|
||||
},
|
||||
url: DB_URL || "http://127.0.0.1:8529",
|
||||
databaseName: DB_NAME || "sbdatatracker"
|
||||
});
|
||||
const saltRounds = 10;
|
||||
const delay = 3 * 60 * 1000;
|
||||
|
||||
const intervalFunc = async (db: Database) => {
|
||||
const cnf = db.collection("config");
|
||||
const users = db.collection("users");
|
||||
if (!(await cnf.exists())) {
|
||||
await cnf.create();
|
||||
}
|
||||
if (!(await users.exists())) {
|
||||
await users.create();
|
||||
await users.save({
|
||||
username: DB_USERNAME,
|
||||
password: await hash(DB_PASSWORD || "SBDataTracker", saltRounds),
|
||||
forceChangePassword: true,
|
||||
permissions: ["*"]
|
||||
});
|
||||
}
|
||||
|
||||
const cursor = await db.query(
|
||||
aql`
|
||||
FOR doc IN ${cnf}
|
||||
FILTER doc.type == "tracker"
|
||||
RETURN doc
|
||||
`,
|
||||
{
|
||||
count: true
|
||||
}
|
||||
);
|
||||
/*
|
||||
Instead of running a loop on all trackers at once,
|
||||
they are spread out evenly across the delay which
|
||||
lowers the chance of exceeding the Hypixel rate-limit
|
||||
when there are a lot of trackers.
|
||||
|
||||
TODO : Add a hard-stop if the rate-limit is about
|
||||
to be exceeded.
|
||||
*/
|
||||
if (cursor.hasNext) {
|
||||
let counter = 0;
|
||||
let interval: NodeJS.Timeout;
|
||||
const iterate = async () => {
|
||||
if (++counter >= (cursor.count as number)) clearInterval(interval);
|
||||
|
||||
const { _key, profile } = await cursor.next();
|
||||
if (profile) {
|
||||
const col = db.collection(`c${profile}`);
|
||||
if (!(await col.exists())) col.create();
|
||||
|
||||
await col.save(await log(API_KEY || "", profile));
|
||||
} else {
|
||||
console.warn(
|
||||
`Configuration entry '${_key}' with type 'tracker' has no "profile" value`
|
||||
);
|
||||
}
|
||||
};
|
||||
if ((cursor.count as number) > 1)
|
||||
interval = setInterval(
|
||||
iterate,
|
||||
delay / ((cursor.count as number) - 1)
|
||||
);
|
||||
setTimeout(iterate);
|
||||
}
|
||||
};
|
||||
|
||||
setInterval(intervalFunc, delay, db);
|
||||
setTimeout(intervalFunc, 0, db);
|
||||
|
||||
polka({
|
||||
onError: err => {
|
||||
|
|
Loading…
Reference in New Issue