feat: hide game masters
This commit is contained in:
parent
04ea344bb2
commit
1fd6b326dc
8 changed files with 201 additions and 4213 deletions
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"aowowUrl": "https://wotlkdb.com",
|
||||
"loadDbcs": true,
|
||||
"hideGameMasters": true,
|
||||
"realms": [
|
||||
{
|
||||
"name": "AzerothCore",
|
||||
"database": {
|
||||
"realmId": 1,
|
||||
"authDatabase": "acore_auth",
|
||||
"charactersDatabase": {
|
||||
"host": "localhost",
|
||||
"port": 3306,
|
||||
"user": "root",
|
||||
|
|
|
|||
4308
package-lock.json
generated
4308
package-lock.json
generated
File diff suppressed because it is too large
Load diff
19
package.json
19
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "azerothcore-armory",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
|
|
@ -18,26 +18,25 @@
|
|||
"@types/express": "^4.17.13",
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/mkdirp": "^1.0.2",
|
||||
"@types/node": "^17.0.5",
|
||||
"@types/node-fetch": "^2.5.12",
|
||||
"@types/node": "^17.0.21",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@types/pako": "^1.0.3",
|
||||
"concurrently": "^6.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"nodemon": "^2.0.15",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.5.4"
|
||||
"typescript": "^4.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@supercharge/promise-pool": "^2.1.0",
|
||||
"camelcase": "^6.2.1",
|
||||
"cli-progress": "^3.9.1",
|
||||
"express": "^4.17.2",
|
||||
"camelcase": "^6.3.0",
|
||||
"cli-progress": "^3.10.0",
|
||||
"express": "^4.17.3",
|
||||
"express-handlebars": "^6.0.2",
|
||||
"glob": "^7.2.0",
|
||||
"glob-promise": "^4.2.2",
|
||||
"handlebars-helpers": "^0.10.0",
|
||||
"mkdirp": "^1.0.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"node-fetch": "^2.6.6",
|
||||
"node-fetch": "^2.6.7",
|
||||
"pako": "^2.0.4",
|
||||
"pretty-ms": "^7.0.1",
|
||||
"source-map-support": "^0.5.21"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export class Armory {
|
|||
console.log("Connecting to databases...");
|
||||
this.worldDb = await createConnection(this.config.worldDatabase);
|
||||
for (const realm of this.config.realms) {
|
||||
this.charsDbs[realm.name.toLowerCase()] = await createConnection(realm.database);
|
||||
this.charsDbs[realm.name.toLowerCase()] = await createConnection(realm.charactersDatabase);
|
||||
}
|
||||
|
||||
console.log("Starting server...");
|
||||
|
|
@ -49,7 +49,6 @@ export class Armory {
|
|||
partialsDir: path.join(process.cwd(), "static", "partials"),
|
||||
layoutsDir: path.join(process.cwd(), "static"),
|
||||
defaultLayout: "layout.html",
|
||||
helpers: require("handlebars-helpers")(),
|
||||
}));
|
||||
app.set("view engine", "handlebars");
|
||||
app.set("views", path.join(process.cwd(), "static"));
|
||||
|
|
|
|||
|
|
@ -11,12 +11,15 @@ export interface IDatabaseConfig {
|
|||
|
||||
export interface IRealmConfig {
|
||||
name: string;
|
||||
database: IDatabaseConfig;
|
||||
realmId: number;
|
||||
authDatabase: string;
|
||||
charactersDatabase: IDatabaseConfig;
|
||||
}
|
||||
|
||||
export class Config {
|
||||
public aowowUrl: string;
|
||||
public loadDbcs: boolean;
|
||||
public hideGameMasters: boolean;
|
||||
public realms: IRealmConfig[];
|
||||
public worldDatabase: IDatabaseConfig;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export interface IColumnSettings {
|
|||
collation?: string;
|
||||
formatter?: (data: string | number | null, row: any) => string;
|
||||
table?: string;
|
||||
database?: string;
|
||||
}
|
||||
|
||||
export interface IColumnJoin {
|
||||
|
|
@ -20,6 +21,7 @@ export interface IColumnJoin {
|
|||
column1: string;
|
||||
table2: string;
|
||||
column2: string;
|
||||
database2?: string;
|
||||
kind: "INNER" | "FULL OUTER" | "LEFT" | "RIGHT";
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +92,11 @@ export class DataTablesSsp {
|
|||
this.columnSettings = columnSettings;
|
||||
}
|
||||
|
||||
private colSettingsToStr(colSettings: IColumnSettings) {
|
||||
const db = colSettings.database ? ("`" + colSettings.database + "`.") : "";
|
||||
return `${db}\`${colSettings.table || this.table}\`.\`${colSettings.name}\``;
|
||||
}
|
||||
|
||||
private limit() {
|
||||
if (this.start !== undefined && this.length !== -1) {
|
||||
this.limitSql = `LIMIT ${this.length} OFFSET ${this.start}`;
|
||||
|
|
@ -110,7 +117,7 @@ export class DataTablesSsp {
|
|||
}
|
||||
|
||||
const colSettings = this.columnSettings[requestColumn.data];
|
||||
orderBy.push(`\`${colSettings.table || this.table}\`.\`${colSettings.name}\` ${order.dir}`);
|
||||
orderBy.push(`${this.colSettingsToStr(colSettings)} ${order.dir}`);
|
||||
}
|
||||
orderBy.push(`\`${this.table}\`.\`${this.primaryKey}\``);
|
||||
|
||||
|
|
@ -123,7 +130,8 @@ export class DataTablesSsp {
|
|||
|
||||
private join() {
|
||||
for (const join of this.joins) {
|
||||
this.joinSql += `${join.kind} JOIN \`${join.table2}\` ON \`${join.table2}\`.\`${join.column2}\` = \`${join.table1}\`.\`${join.column1}\`\n`;
|
||||
const db2 = join.database2 ? "`" + join.database2 + "`." : "";
|
||||
this.joinSql += `${join.kind} JOIN ${db2}\`${join.table2}\` ON ${db2}\`${join.table2}\`.\`${join.column2}\` = \`${join.table1}\`.\`${join.column1}\`\n`;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
@ -141,7 +149,7 @@ export class DataTablesSsp {
|
|||
|
||||
const colSettings = this.columnSettings[col.data];
|
||||
const collate = colSettings.collation !== undefined ? `COLLATE ${colSettings.collation} ` : "";
|
||||
filterWheres.push(`\`${colSettings.table || this.table}\`.\`${colSettings.name}\` ${collate}LIKE ?`);
|
||||
filterWheres.push(`${this.colSettingsToStr(colSettings)} ${collate}LIKE ?`);
|
||||
this.filterBindings.push(`%${this.search.value}%`);
|
||||
}
|
||||
if (filterWheres.length > 0) {
|
||||
|
|
@ -153,9 +161,9 @@ export class DataTablesSsp {
|
|||
return this;
|
||||
}
|
||||
|
||||
private buildSql(): string {
|
||||
public sql(): string {
|
||||
const columns = [
|
||||
...this.columnSettings.map(c => `\`${c.table || this.table}\`.\`${c.name}\``),
|
||||
...this.columnSettings.map(c => this.colSettingsToStr(c)),
|
||||
...this.extraDataColumns,
|
||||
];
|
||||
return `
|
||||
|
|
@ -205,7 +213,7 @@ export class DataTablesSsp {
|
|||
const recordsFiltered = rows[0].count;
|
||||
|
||||
[rows, fields] = await this.db.query({
|
||||
sql: this.buildSql(),
|
||||
sql: this.sql(),
|
||||
rowsAsArray: true,
|
||||
values: bindings,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export class CharacterController {
|
|||
return;
|
||||
}
|
||||
|
||||
const charData = await this.getCharacterData(realmName, charName);
|
||||
const charData = await this.getCharacterData(realm, charName);
|
||||
if (charData === null) {
|
||||
// Could not find character
|
||||
res.sendStatus(404);
|
||||
|
|
@ -203,7 +203,7 @@ export class CharacterController {
|
|||
return;
|
||||
}
|
||||
|
||||
const charData = await this.getCharacterData(realm.name, charName);
|
||||
const charData = await this.getCharacterData(realm, charName);
|
||||
if (charData === null) {
|
||||
// Could not find character
|
||||
res.sendStatus(404);
|
||||
|
|
@ -232,7 +232,7 @@ export class CharacterController {
|
|||
return;
|
||||
}
|
||||
|
||||
const charData = await this.getCharacterData(realm.name, charName);
|
||||
const charData = await this.getCharacterData(realm, charName);
|
||||
if (charData === null) {
|
||||
// Could not find character
|
||||
res.sendStatus(404);
|
||||
|
|
@ -256,7 +256,7 @@ export class CharacterController {
|
|||
return;
|
||||
}
|
||||
|
||||
const charData = await this.getCharacterData(realm.name, character);
|
||||
const charData = await this.getCharacterData(realm, character);
|
||||
if (charData === null) {
|
||||
// Could not find character
|
||||
res.sendStatus(404);
|
||||
|
|
@ -285,13 +285,16 @@ export class CharacterController {
|
|||
return this.armory.config.realms.find(r => r.name.toLowerCase() === realm.toLowerCase());
|
||||
}
|
||||
|
||||
private async getCharacterData(realm: string, character: string | number): Promise<ICharacterData> {
|
||||
private async getCharacterData(realm: IRealmConfig, character: string | number): Promise<ICharacterData> {
|
||||
const where = typeof character === "string" ? "LOWER(name) = LOWER(?)" : "guid = ?";
|
||||
const [rows, fields] = await this.armory.getCharactersDb(realm).query(`
|
||||
SELECT guid, name, race, class, gender, level, skin, face, hairStyle, hairColor, facialStyle, playerFlags, online
|
||||
FROM characters
|
||||
WHERE ${where}
|
||||
`, [character]);
|
||||
const [rows, fields] = await this.armory.getCharactersDb(realm.name).query(`
|
||||
SELECT \`guid\`, \`name\`, \`race\`, \`class\`, \`gender\`, \`level\`, \`skin\`, \`face\`, \`hairStyle\`, \`hairColor\`, \`facialStyle\`, \`playerFlags\`, \`online\`
|
||||
FROM \`characters\`
|
||||
LEFT JOIN \`${realm.authDatabase}\`.\`account_access\` ON \`account_access\`.\`id\` = \`characters\`.\`account\`
|
||||
WHERE
|
||||
${where}
|
||||
AND (\`account_access\`.\`id\` IS NULL OR \`account_access\`.\`RealmID\` NOT IN (-1, ${realm.realmId}) OR \`account_access\`.\`gmlevel\` = 0 OR ? = 0)
|
||||
`, [character, this.armory.config.hideGameMasters ? 1 : 0]);
|
||||
|
||||
if ((rows as RowDataPacket[]).length === 0) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ const classFiles = {
|
|||
|
||||
export class IndexController {
|
||||
private armory: Armory;
|
||||
private charsetCache: { [key: string]: string };
|
||||
|
||||
public constructor(armory: Armory) {
|
||||
this.armory = armory;
|
||||
this.charsetCache = {};
|
||||
}
|
||||
|
||||
public async index(req: express.Request, res: express.Response): Promise<void> {
|
||||
|
|
@ -53,6 +55,8 @@ export class IndexController {
|
|||
}
|
||||
|
||||
const db = this.armory.getCharactersDb(realm.name);
|
||||
|
||||
if (!(realm.name in this.charsetCache)) {
|
||||
let [rows, fields] = await db.query(`
|
||||
SELECT CCSA.character_set_name FROM information_schema.\`TABLES\` T,
|
||||
information_schema.\`COLLATION_CHARACTER_SET_APPLICABILITY\` CCSA
|
||||
|
|
@ -60,11 +64,13 @@ export class IndexController {
|
|||
AND T.table_schema = "${db.config.database}"
|
||||
AND T.table_name = "characters"
|
||||
`);
|
||||
const charSet = rows[0].character_set_name;
|
||||
this.charsetCache[realm.name] = rows[0].character_set_name;
|
||||
}
|
||||
const charSet = this.charsetCache[realm.name];
|
||||
|
||||
const ssp = new DataTablesSsp(req.query, db, "characters", "guid", [
|
||||
let ssp = new DataTablesSsp(req.query, db, "characters", "guid", [
|
||||
{ name: "name", collation: `${charSet}_general_ci` },
|
||||
{ name: "name", table: "guild" },
|
||||
{ table: "guild", name: "name" },
|
||||
{ name: "level" },
|
||||
{ name: "race", formatter: (race, row) => `${raceFiles[race]}_${row[6] === 0 ? "male" : "female"}` },
|
||||
{ name: "class", formatter: cls => classFiles[cls] },
|
||||
|
|
@ -76,6 +82,11 @@ export class IndexController {
|
|||
];
|
||||
ssp.extraDataColumns = ["`characters`.`gender`"];
|
||||
|
||||
if (this.armory.config.hideGameMasters) {
|
||||
ssp.joins.push({ table1: "characters", column1: "account", table2: "account_access", column2: "id", database2: realm.authDatabase, kind: "LEFT" });
|
||||
ssp = ssp.where(`\`account_access\`.\`id\` IS NULL OR \`account_access\`.\`RealmID\` NOT IN (-1, ${realm.realmId}) OR \`account_access\`.\`gmlevel\` = 0`);
|
||||
}
|
||||
|
||||
const result = await ssp
|
||||
.where("`deleteInfos_Account` IS NULL")
|
||||
.run();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue