tslint changes

This commit is contained in:
Jeremy Simpson
2019-08-30 01:52:40 -07:00
parent 7603879d35
commit 7f7efbb94b
446 changed files with 70650 additions and 70661 deletions
+184 -184
View File
@@ -1,13 +1,13 @@
import * as fs from 'fs';
import * as moment from 'moment';
import {
AdminState, eventFields, BaseValues, UpdateOrigin, UserCountStats, AccountDetails, SupporterInvite,
InternalGameServerState, InternalLoginServerState, OtherStats, Settings, GameServerSettings
AdminState, eventFields, BaseValues, UpdateOrigin, UserCountStats, AccountDetails, SupporterInvite,
InternalGameServerState, InternalLoginServerState, OtherStats, Settings, GameServerSettings
} from '../../common/adminInterfaces';
import { execAsync } from '../serverUtils';
import {
IAccount, Account, Origin, Event, iterate, ISession, Session, SupporterInvite as DBSupporterInvite,
findAccount, ISupporterInvite, ID
IAccount, Account, Origin, Event, iterate, ISession, Session, SupporterInvite as DBSupporterInvite,
findAccount, ISupporterInvite, ID
} from '../db';
import { servers, serverStatus, loginServers } from '../internal';
import { encodeEvent, BaseTimes, getBaseDate, getBaseTimes } from '../adminEncoders';
@@ -19,280 +19,280 @@ import { loadSettings, saveSettings } from '../settings';
import { flatten } from '../../common/utils';
function encodeItems<T>(items: T[], base: BaseValues, encode: (items: T, base: BaseTimes) => any[]): any[][] {
const baseValues = getBaseTimes(base);
return items.map(i => encode(i, baseValues));
const baseValues = getBaseTimes(base);
return items.map(i => encode(i, baseValues));
}
const events = createLiveEndPoint({
model: Event,
fields: eventFields,
encode(items, base) {
base.createdAt = getBaseDate(items, i => i.createdAt!);
base.updatedAt = getBaseDate(items, i => i.updatedAt);
return encodeItems(items, base, encodeEvent);
},
model: Event,
fields: eventFields,
encode(items, base) {
base.createdAt = getBaseDate(items, i => i.createdAt!);
base.updatedAt = getBaseDate(items, i => i.updatedAt);
return encodeItems(items, base, encodeEvent);
},
});
export interface EndPoints {
events: LiveEndPoint;
events: LiveEndPoint;
}
export function createEndPoints(): EndPoints {
return { events };
return { events };
}
export function getAdminState(): AdminState {
return {
status: serverStatus,
loginServers: loginServers.map(s => s.state),
gameServers: servers.map(s => s.state),
};
return {
status: serverStatus,
loginServers: loginServers.map(s => s.state),
gameServers: servers.map(s => s.state),
};
}
async function forAllLoginServers(
action: (server: InternalLoginServerState) => any, filter = (_: InternalLoginServerState) => true
action: (server: InternalLoginServerState) => any, filter = (_: InternalLoginServerState) => true
) {
await Promise.all(loginServers.filter(filter).map(action));
await Promise.all(loginServers.filter(filter).map(action));
}
export async function forAllGameServers(
action: (server: InternalGameServerState) => any, filter = (_: InternalGameServerState) => true
action: (server: InternalGameServerState) => any, filter = (_: InternalGameServerState) => true
) {
const liveServers = servers.filter(s => !s.state.dead);
await Promise.all(liveServers.filter(filter).map(action));
const liveServers = servers.filter(s => !s.state.dead);
await Promise.all(liveServers.filter(filter).map(action));
}
export function actionForAllServers(action: string, accountId: string) {
return forAllGameServers(s => s.api.action(action, accountId));
return forAllGameServers(s => s.api.action(action, accountId));
}
export function kickFromAllServers(accountId: string) {
return forAllGameServers(s => s.api.kick(accountId, undefined));
return forAllGameServers(s => s.api.kick(accountId, undefined));
}
export function kickFromAllServersByCharacter(characterId: string) {
return forAllGameServers(s => s.api.kick(undefined, characterId));
return forAllGameServers(s => s.api.kick(undefined, characterId));
}
function createFilter(id: string) {
return (server: { id: string; }) => id === '*' || server.id === id;
return (server: { id: string; }) => id === '*' || server.id === id;
}
export async function notifyUpdate(server: string) {
await Promise.all([
forAllLoginServers(s => s.api.updateLiveSettings({ updating: true }), createFilter(server)),
forAllGameServers(s => s.api.notifyUpdate(), createFilter(server)),
]);
await Promise.all([
forAllLoginServers(s => s.api.updateLiveSettings({ updating: true }), createFilter(server)),
forAllGameServers(s => s.api.notifyUpdate(), createFilter(server)),
]);
}
export function shutdownServers(server: string, value: boolean) {
return forAllGameServers(s => s.api.shutdownServer(value), createFilter(server));
return forAllGameServers(s => s.api.shutdownServer(value), createFilter(server));
}
export async function resetUpdating(server: string) {
await Promise.all([
forAllLoginServers(s => s.api.updateLiveSettings({ updating: false }), createFilter(server)),
forAllGameServers(s => s.api.cancelUpdate(), createFilter(server)),
shutdownServers(server, false),
]);
await Promise.all([
forAllLoginServers(s => s.api.updateLiveSettings({ updating: false }), createFilter(server)),
forAllGameServers(s => s.api.cancelUpdate(), createFilter(server)),
shutdownServers(server, false),
]);
}
export async function reloadSettingsOnAllServers() {
await Promise.all([
forAllLoginServers(s => s.api.reloadSettings()),
forAllGameServers(s => s.api.reloadSettings()),
]);
await Promise.all([
forAllLoginServers(s => s.api.reloadSettings()),
forAllGameServers(s => s.api.reloadSettings()),
]);
}
export async function getChat(search: string, date: string, caseInsensitive: boolean) {
const query = search
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\./g, '\\.')
.replace(/\*/g, '\\*')
.replace(/\$/g, '\\*')
.replace(/\^/g, '\\*');
const flags = caseInsensitive ? '-i -E ' : '-E ';
const options = { maxBuffer: 1 * 1024 * 1024 }; // 1MB
const query = search
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\./g, '\\.')
.replace(/\*/g, '\\*')
.replace(/\$/g, '\\*')
.replace(/\^/g, '\\*');
const flags = caseInsensitive ? '-i -E ' : '-E ';
const options = { maxBuffer: 1 * 1024 * 1024 }; // 1MB
async function fetchChatlog(lines: number) {
const logFile = paths.pathTo('logs', `info.${moment(date).format('YYYYMMDD')}.log`);
const { stdout } = await execAsync(`grep ${flags}"${query}" "${logFile}" | tail -n ${lines}`, options);
return stdout;
}
async function fetchChatlog(lines: number) {
const logFile = paths.pathTo('logs', `info.${moment(date).format('YYYYMMDD')}.log`);
const { stdout } = await execAsync(`grep ${flags}"${query}" "${logFile}" | tail -n ${lines}`, options);
return stdout;
}
try {
if (!search) {
return '';
} else if (date === 'all') {
const { stdout } = await execAsync(`for f in ${paths.pathTo('logs')}/*.log; do `
+ `echo "$f" | grep -o '[0-9]*';`
+ `cat "$f" | grep ${flags}"${query}";`
+ `done`, options);
return stdout;
} else {
let lines = 8192;
let more = '';
try {
if (!search) {
return '';
} else if (date === 'all') {
const { stdout } = await execAsync(`for f in ${paths.pathTo('logs')}/*.log; do `
+ `echo "$f" | grep -o '[0-9]*';`
+ `cat "$f" | grep ${flags}"${query}";`
+ `done`, options);
return stdout;
} else {
let lines = 8192;
let more = '';
do {
try {
const log = await fetchChatlog(lines);
return more + log;
} catch (e) {
if (e.message !== 'stdout maxBuffer exceeded') {
throw e;
}
}
do {
try {
const log = await fetchChatlog(lines);
return more + log;
} catch (e) {
if (e.message !== 'stdout maxBuffer exceeded') {
throw e;
}
}
lines /= 2;
more = '... more lines ...\n';
} while (lines > 1);
lines /= 2;
more = '... more lines ...\n';
} while (lines > 1);
return '<error size exceeded>';
}
} catch (e) {
console.error('Failed to fetch chatlog: ', e);
return '<error>';
}
return '<error size exceeded>';
}
} catch (e) {
console.error('Failed to fetch chatlog: ', e);
return '<error>';
}
}
export async function getChatForAccounts(accountIds: string[], date: string) {
const accounts: Partial<IAccount>[] = await Account.find({ _id: { $in: accountIds } }, '_id merges').lean().exec();
const map = new Map<string, string>();
const ids = flatten(accounts.map(a => [a._id.toString(), ...(a.merges || []).map(a => a.id)]));
const accounts: Partial<IAccount>[] = await Account.find({ _id: { $in: accountIds } }, '_id merges').lean().exec();
const map = new Map<string, string>();
const ids = flatten(accounts.map(a => [a._id.toString(), ...(a.merges || []).map(a => a.id)]));
for (const a of accounts) {
const index = accountIds.indexOf(a._id.toString());
map.set(a._id.toString(), index ? `[${index}]` : ``);
for (const a of accounts) {
const index = accountIds.indexOf(a._id.toString());
map.set(a._id.toString(), index ? `[${index}]` : ``);
(a.merges || []).forEach(({ id }) => {
map.set(id, index ? `[${index}:merged]` : `[merged]`);
});
}
(a.merges || []).forEach(({ id }) => {
map.set(id, index ? `[${index}:merged]` : `[merged]`);
});
}
const chat = await getChat(ids.join('|'), date, false);
const fixed = chat.replace(/^([0-9:]+) \[([a-f0-9]{24})\]/gmu, (_, date, id) =>
`${date} ${map.has(id) ? map.get(id) : `[${id}]`}`);
const chat = await getChat(ids.join('|'), date, false);
const fixed = chat.replace(/^([0-9:]+) \[([a-f0-9]{24})\]/gmu, (_, date, id) =>
`${date} ${map.has(id) ? map.get(id) : `[${id}]`}`);
return fixed;
return fixed;
}
export async function clearSessions(accountId: string) {
const clearIds: string[] = [];
const clearIds: string[] = [];
await iterate<ISession>(Session.find({ session: { $exists: true } }).lean() as any, session => {
try {
if (session.session) {
const data = JSON.parse(session.session);
const user = data && data.passport && data.passport.user;
await iterate<ISession>(Session.find({ session: { $exists: true } }).lean() as any, session => {
try {
if (session.session) {
const data = JSON.parse(session.session);
const user = data && data.passport && data.passport.user;
if (user === accountId) {
clearIds.push(session._id);
}
}
} catch (e) {
logger.error('Error when claring session', e, session._id, session.session);
}
});
if (user === accountId) {
clearIds.push(session._id);
}
}
} catch (e) {
logger.error('Error when claring session', e, session._id, session.session);
}
});
await Session.deleteOne({ _id: { $in: clearIds } }).exec();
await Session.deleteOne({ _id: { $in: clearIds } }).exec();
}
export async function updateOrigin(update: UpdateOrigin) {
await Origin.updateOne({ ip: update.ip }, update, { upsert: true }).exec();
await Origin.updateOne({ ip: update.ip }, update, { upsert: true }).exec();
}
export async function getUserCounts(): Promise<UserCountStats[]> {
const statsFile = paths.pathTo('settings', `user-counts.log`);
const statsFile = paths.pathTo('settings', `user-counts.log`);
try {
const content = await fs.readFileAsync(statsFile, 'utf8');
const lines = content.trim().split(/\n/);
return lines.map(line => JSON.parse(line));
} catch {
return [];
}
try {
const content = await fs.readFileAsync(statsFile, 'utf8');
const lines = content.trim().split(/\n/);
return lines.map(line => JSON.parse(line));
} catch {
return [];
}
}
function convertInvite(invite: ISupporterInvite): SupporterInvite {
return {
_id: invite._id.toString(),
name: invite.name,
info: invite.info,
source: invite.source.toHexString(),
target: invite.target.toHexString(),
active: invite.active,
updatedAt: invite.updatedAt,
createdAt: invite.createdAt,
};
return {
_id: invite._id.toString(),
name: invite.name,
info: invite.info,
source: invite.source.toHexString(),
target: invite.target.toHexString(),
active: invite.active,
updatedAt: invite.updatedAt,
createdAt: invite.createdAt,
};
}
export async function getAccountDetails(accountId: ID): Promise<AccountDetails> {
const [account, invitesReceived, invitesSent] = await Promise.all([
findAccount(accountId, 'merges supporterLog banLog state'),
DBSupporterInvite.find({ target: accountId }).exec(),
DBSupporterInvite.find({ source: accountId }).exec(),
]);
const [account, invitesReceived, invitesSent] = await Promise.all([
findAccount(accountId, 'merges supporterLog banLog state'),
DBSupporterInvite.find({ target: accountId }).exec(),
DBSupporterInvite.find({ source: accountId }).exec(),
]);
return account ? {
merges: account.merges || [],
banLog: account.banLog || [],
supporterLog: account.supporterLog || [],
invitesReceived: invitesReceived.map(convertInvite),
invitesSent: invitesSent.map(convertInvite),
state: account.state || {},
} : {
merges: [],
banLog: [],
supporterLog: [],
invitesReceived: [],
invitesSent: [],
state: {},
};
return account ? {
merges: account.merges || [],
banLog: account.banLog || [],
supporterLog: account.supporterLog || [],
invitesReceived: invitesReceived.map(convertInvite),
invitesSent: invitesSent.map(convertInvite),
state: account.state || {},
} : {
merges: [],
banLog: [],
supporterLog: [],
invitesReceived: [],
invitesSent: [],
state: {},
};
}
export async function getOtherStats(service: AdminService): Promise<OtherStats> {
let totalIgnores = 0;
let authsWithEmptyAccount = 0;
let authsWithMissingAccount = 0;
let totalIgnores = 0;
let authsWithEmptyAccount = 0;
let authsWithMissingAccount = 0;
for (const account of service.accounts.items) {
totalIgnores += account.ignoresCount!;
}
for (const account of service.accounts.items) {
totalIgnores += account.ignoresCount!;
}
for (const auth of service.auths.items) {
if (!auth.account) {
authsWithEmptyAccount++;
} else if (!service.accounts.get(auth.account)) {
authsWithMissingAccount++;
}
}
for (const auth of service.auths.items) {
if (!auth.account) {
authsWithEmptyAccount++;
} else if (!service.accounts.get(auth.account)) {
authsWithMissingAccount++;
}
}
return {
totalIgnores,
authsWithEmptyAccount,
authsWithMissingAccount,
};
return {
totalIgnores,
authsWithEmptyAccount,
authsWithMissingAccount,
};
}
export async function updateServerSettings(currentSettings: Settings, update: Partial<Settings>) {
const settings = await Promise.resolve(loadSettings());
Object.assign(currentSettings, settings, update);
const settings = await Promise.resolve(loadSettings());
Object.assign(currentSettings, settings, update);
await saveSettings(currentSettings);
await reloadSettingsOnAllServers();
await saveSettings(currentSettings);
await reloadSettingsOnAllServers();
}
export async function updateGameServerSettings(
currentSettings: Settings, serverId: string, update: Partial<GameServerSettings>
currentSettings: Settings, serverId: string, update: Partial<GameServerSettings>
) {
const settings = await Promise.resolve(loadSettings());
Object.assign(currentSettings, settings);
const settings = await Promise.resolve(loadSettings());
Object.assign(currentSettings, settings);
const serverSettings = currentSettings.servers[serverId] = currentSettings.servers[serverId] || {};
Object.assign(serverSettings, update);
const serverSettings = currentSettings.servers[serverId] = currentSettings.servers[serverId] || {};
Object.assign(serverSettings, update);
await saveSettings(currentSettings);
await reloadSettingsOnAllServers();
await saveSettings(currentSettings);
await reloadSettingsOnAllServers();
}