import { RPCInterface } from "rpclibrary"; import { Inject, Injectable } from "../../Injector/ServiceDecorator"; import { TableDefiniton, Character, Spec, User, Class, _Rank, Rank } from "../../Types/Types"; import { CharacterManagerIfc } from "./RPCInterface"; import { FrontworkComponent } from "../../Types/FrontworkComponent"; import { getSpecTableData, SpecT } from "../../Types/PlayerSpecs"; import { IAdmin } from "../../Admin/Interface"; import { IUserManager } from "../User/Interface"; import { ICharacterManager } from "./Interface"; import { getLogger } from "log4js"; @Injectable(ICharacterManager) export class CharacterManager implements FrontworkComponent, ICharacterManager{ name = "CharacterManager" as "CharacterManager"; @Inject(IAdmin) private admin: IAdmin @Inject(IUserManager) private loginManager : IUserManager RPCs = () => [ this.getSpecId, this.getCharacterByName, this.getCharacters, this.getCharactersOfUser, this.createCharacter, this.getUserOfCharacter, this.getHeadCount ] RPCFeatures = () => [{ name: 'manageCharacter' as 'manageCharacter', RPCs: [ this.updateCharacter ] }] getTableDefinitions = (): TableDefiniton[] => [ { name: 'characters', tableBuilder: (table) => { table.increments("id").primary() table.string("charactername").notNullable().unique() table.integer("specid").notNullable() table.foreign("specid").references("specs.id") table.integer("userid").notNullable() table.foreign("userid").references("users.id") table.string("race").notNullable() table.boolean('alt').defaultTo(false) } },{ name: 'specs', tableBuilder: (table) => { table.increments("id") table.string('class') table.string('specname') table.unique(['class', 'specname']) } } ] private initialized = false initialize = async () => { if(this.initialized) return this.initialized = true await this.admin.knex('specs').insert(getSpecTableData()).catch(e => { getLogger('CharacterManager#createCharacter').debug("skipping spec insertion") }) } updateCharacter = async (character: Character) : Promise => { await this.admin .knex('characters') .update({ race: character.race, specid: character.specid, charactername: character.charactername.toLowerCase(), userid: character.userid }) .where({ id: character.id }) return await this.getCharacterByName(character.charactername) as Character } createCharacter = async (userToken: string, character : Character) : Promise => { try{ character.charactername = character.charactername.toLowerCase() const user = this.loginManager.getUserRecordByToken(userToken) await this.admin.knex('characters').insert(character) const char : Character = await this.admin.knex.select('*').from('characters').where(character).first() return char }catch(e){ getLogger('CharacterManager#createCharacter').error(e); } throw new Error('Unable to create character') } getCharacters = async() : Promise<(Character & Spec & User)[]> => { return this.admin.knex .select('*') .from('characters as c') .join('specs as sp', 'c.specid', 'sp.id') .join('users as u', 'c.userid', 'u.id') } getCharacterByName = async(charactername: string) : Promise<(Character & User & Spec) | void> => { charactername = charactername.toLowerCase() return await this.admin.knex('characters as c') .join('specs as s', 's.id', '=', 'c.specid') .join('users as u', 'u.id', '=', 'c.userid') .select('c.id as id', 'charactername', 'race', 'specid', 'class', 'specname', 'username', 'rank') .where('charactername', '=', charactername) .first() } getCharactersOfUser = async(username: string) : Promise<(Character & Spec)[]> => { username = username.toLowerCase() return await this.admin.knex('characters as c') .join('users as u', 'u.id', '=', 'c.userid') .join('specs as s', 's.id', '=', 'c.specid') .select('class', 'charactername', 'class', 'race', 'specname', 'userid', 'c.id as id', 'specid') .where('u.username', '=', username) } getUserOfCharacter = async(character: Character) : Promise => { return await this.admin.knex('users').where({ id: character.userid }).first() } getSpecId = async (clazz: c, name: SpecT[c]) => await this.admin.knex .from('specs') .select('id') .where({ class: clazz, specname: name }) .first() .then(spec => spec.id) getHeadCount = async(c:Class):Promise => { const cnt = await this.admin .knex('characters as c') .join('users as u', 'c.userid', '=', 'u.id') .join('specs as s', 'c.specid', '=', 's.id') .where({ class: c }).andWhere(function(){ this.whereNotIn('u.rank', [ 'Guest' ]) this.whereNot('c.alt', '1') }) .count('*') return cnt[0]['count(*)'] as number } }