working buytoken (untested)

This commit is contained in:
peter
2020-02-08 13:54:14 +01:00
parent 6930e2245f
commit 59f518679e
37 changed files with 348 additions and 223 deletions
+3 -2
View File
@@ -4,9 +4,10 @@
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"tsc": "tsc", "tsc": "tsc",
"start": "npm run build; node lib/src/backend/Launcher.js", "launch": "node lib/src/backend/Launcher.js",
"start": "npm run build; npm run launch",
"start-backend": "npm run build-backend; node lib/src/backend/Launcher.js", "start-backend": "npm run build-backend; node lib/src/backend/Launcher.js",
"build": "npm run clean; npm run build-backend; npm run build-frontend", "build": "npm run build-backend; npm run build-frontend",
"test": "npm run clean && npm run build-backend && mocha lib/test/backendTest.js", "test": "npm run clean && npm run build-backend && mocha lib/test/backendTest.js",
"build-backend": "tsc;", "build-backend": "tsc;",
"build-frontend": "mkdir dist; mkdir dist/static; npm run build-dashboard;", "build-frontend": "mkdir dist; mkdir dist/static; npm run build-dashboard;",
+4 -3
View File
@@ -1,14 +1,15 @@
import { Item, Character, SRToken, SRPriority, Spec, Signup } from "../../Types/Types" import { Item, Character, SRToken, SRPriority, Spec, Signup } from "../../Types/Types"
import { Tiers } from "../../Types/Items"
export class IItemManager{ export class IItemManager{
getItems: () => Promise<Item[]> getItems: () => Promise<Item[]>
fetchItem: (name:string) => Promise<Item> fetchItem: (name:string) => Promise<Item>
buyToken: (usertoken: string, charactername:string, itemname:string, signup:Signup) => Promise<(SRToken & Character & Item) | void> buyToken: (usertoken: string, charactername:string, itemname:string, signup:Signup) => Promise<(SRToken & Character & Item) | undefined>
setPriority: (itemname:string, priority: any) => Promise<void> setPriority: (itemname:string, priority: any) => Promise<void>
calculatePriorities: (itemname: string, character:Character) => Promise<number> calculatePriorities: (itemname: string, character:Character) => Promise<number>
deletePriority: (priority:SRPriority) => Promise<void> deletePriority: (priority:SRPriority) => Promise<void>
getTokens: (character:Character, valid?:boolean) => Promise<SRToken[]> getTokens: (character:Character, tiers: Tiers[], valid?:boolean) => Promise<(SRToken & Character & Item)[] | undefined>
getToken: (character:Character, item:Item, valid?:boolean) => Promise<(SRToken & Character & Item) | void> getToken: (character:Character, item:Item, valid?:boolean) => Promise<(SRToken & Character & Item) | undefined>
getAllPriorities: () => Promise<(SRPriority & Spec & Item)[]> getAllPriorities: () => Promise<(SRPriority & Spec & Item)[]>
wipeCurrencyAndItems: () => Promise<void> wipeCurrencyAndItems: () => Promise<void>
} }
+68 -61
View File
@@ -1,4 +1,4 @@
import { T1, T2, allItems, _Tiers } from "../../Types/Items"; import { T1, T2, allItems, _Tiers, Tiers } from "../../Types/Items";
import { Inject, Injectable } from "../../Injector/ServiceDecorator"; import { Inject, Injectable } from "../../Injector/ServiceDecorator";
import { ItemManagerFeatureIfc, ItemManagerIfc } from "./RPCInterface"; import { ItemManagerFeatureIfc, ItemManagerIfc } from "./RPCInterface";
import { FrontworkComponent } from "../../Types/FrontworkComponent"; import { FrontworkComponent } from "../../Types/FrontworkComponent";
@@ -54,7 +54,7 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
wipeCurrencyAndItems = async () => { wipeCurrencyAndItems = async () => {
await Promise.all([ await Promise.all([
this.userManager.wipeCurrency(), this.userManager.wipeCurrency(),
this.admin.knex('tokens').where(true).del() Promise.all(_Tiers.map(tier => this.admin.knex(tier+'tokens').where(true).del()))
]) ])
} }
@@ -84,19 +84,21 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
getTableDefinitions(): TableDefiniton[] { getTableDefinitions(): TableDefiniton[] {
return [ return [
{ ...['null',..._Tiers].map(tier => {
name: 'tokens', return {
tableBuilder: (table) => { name: tier+'tokens',
table.primary(['characterid', 'itemname']) tableBuilder: (table) => {
table.integer("characterid") table.primary(['characterid', 'itemname'])
table.foreign("characterid").references("id").inTable('characters') table.integer("characterid")
table.string("itemname") table.foreign("characterid").references("id").inTable('characters')
table.foreign("itemname").references("itemname").inTable('items') table.string("itemname")
table.string("signupid").nullable() table.foreign("itemname").references("itemname").inTable('items')
table.foreign("signupid").references("id").inTable('signups').onDelete('SET NULL') table.string("signupid").nullable()
table.integer("level").defaultTo(1) table.foreign("signupid").references("id").inTable('signups').onDelete('SET NULL')
table.integer("level").defaultTo(1)
}
} }
},{ }),{
name: 'priorities', name: 'priorities',
tableBuilder: (table) => { tableBuilder: (table) => {
table.increments('id').primary() table.increments('id').primary()
@@ -121,7 +123,7 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
}] }]
} }
buyToken = async (usertoken: string, charactername:string, itemname:string, signup: Signup): Promise<(SRToken & Character & Item) | void> => { buyToken = async (usertoken: string, charactername:string, itemname:string, signup: Signup): Promise<(SRToken & Character & Item) | undefined> => {
const record = this.userManager.getUserRecordByToken(usertoken) const record = this.userManager.getUserRecordByToken(usertoken)
const character = await this.character.getCharacterByName(charactername) const character = await this.character.getCharacterByName(charactername)
@@ -130,52 +132,53 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
const item = await this.getItem(itemname) const item = await this.getItem(itemname)
if(!item) return if(!item) return
const currency = await this.userManager.getCurrency(record.user) const currency = await this.userManager.getCurrency(record.user, item.tier)
if(currency < 1) return if(currency < 1) return
const shadowTokens = await this.getTokens(character, false) const streaks = await this.getTokens(character, [item.tier], false)
const activeTokens = await this.getTokens(character, true) const activeTokens = await this.getTokens(character, [item.tier], true)
await this.userManager.decrementCurrency(record.user, 1) await this.userManager.decrementCurrency(record.user, item.tier, 1)
const modifier = await this.calculatePriorities(itemname, character) const modifier = await this.calculatePriorities(itemname, character)
//tokens with deleted signups if(streaks.length > 0){
if(shadowTokens.length > 0){ const myStreak = streaks.find(token => token.itemname === itemname)
//token for current item if(myStreak){
const matchingtoken = shadowTokens.find(token => token.itemname === itemname)
if(matchingtoken){
//update signupid and increment level
//getLogger('ItemManager').debug('update signupid and increment level')
await this.admin await this.admin
.knex('tokens') .knex(item.tier+'tokens')
.where({ .where({
characterid: character.id, characterid: character.id,
itemname: item.itemname itemname: item.itemname
}) })
.update({ .update({
signupid: signup.id, signupid: signup.id,
level: matchingtoken.level+1 level: myStreak.level+1
}) })
await this.admin
.knex('tokens')
.where({
characterid: character.id,
itemname: item.itemname,
signupid: null
}).del()
return await this.getToken(character, item)
} }
//getLogger('ItemManager').debug('delete streaks')
await Promise.all(streaks.map(async s => await this.admin
.knex(item.tier+'tokens')
.where({
itemname: s.itemname,
characterid: character.id,
signupid: null
})
.del()
))
if(myStreak)
return await this.getToken(character, item)
} }
const matchingtoken = activeTokens.find(token => token.itemname === itemname) const matchingReserve = activeTokens.find(token => token.itemname === itemname)
if(matchingtoken){ if(matchingReserve){
//power up token getLogger('ItemManager').debug('upgrade reserve')
await this.admin await this.admin
.knex('tokens') .knex(item.tier+'tokens')
.increment('level') .increment('level')
.where({ .where({
signupid: signup.id, signupid: signup.id,
@@ -183,8 +186,9 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
itemname: item.itemname itemname: item.itemname
}) })
}else{ }else{
getLogger('ItemManager').debug('new reserve')
await this.admin await this.admin
.knex('tokens') .knex(item.tier+'tokens')
.insert({ .insert({
characterid: character.id, characterid: character.id,
itemname: item.itemname, itemname: item.itemname,
@@ -257,9 +261,9 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
}).reduce((prev, curr) => prev+curr, 0) }).reduce((prev, curr) => prev+curr, 0)
} }
getToken = async (character:Character, item:Item,valid=true): Promise<(SRToken & Character & Item) | void>=> { getToken = async (character:Character, item:Item, valid=true): Promise<(SRToken & Character & Item) | undefined>=> {
return await this.admin return await this.admin
.knex('tokens as t') .knex(item.tier+'tokens as t')
.select('*') .select('*')
.join('characters as c', 'c.id', '=', 't.characterid') .join('characters as c', 'c.id', '=', 't.characterid')
.join('items as i', 'i.itemname', '=', 't.itemname') .join('items as i', 'i.itemname', '=', 't.itemname')
@@ -277,22 +281,25 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
.first() .first()
} }
getTokens = async (character:Character, valid=true) : Promise<(SRToken & Character & Item)[]> => { getTokens = async (character:Character, tiers:Tiers[], valid=true) : Promise<(SRToken & Character & Item)[]> => {
return await this.admin const ret = await Promise.all(tiers.map(async tier => {
.knex('tokens as t') return await this.admin
.select('*') .knex(tier+'tokens as t')
.join('characters as c', 'c.id', '=', 't.characterid') .select('*')
.join('items as i', 'i.itemname', '=', 't.itemname') .join('characters as c', 'c.id', '=', 't.characterid')
.where({ .join('items as i', 'i.itemname', '=', 't.itemname')
characterid: character.id, .where({
}) characterid: character.id,
.andWhere(function(){ })
if(valid){ .andWhere(function(){
this.whereNotNull('t.signupid') if(valid){
}else{ this.whereNotNull('t.signupid')
this.whereNull('t.signupid') }else{
} this.whereNull('t.signupid')
}) }
})
}))
return ret.flat()
} }
countItems = async() :Promise<number> => { countItems = async() :Promise<number> => {
+27 -27
View File
@@ -9,7 +9,6 @@ import { ICharacterManager } from "../Character/Interface";
import { _Tiers } from "../../Types/Items"; import { _Tiers } from "../../Types/Items";
import { IItemManager } from "../Item/Interface"; import { IItemManager } from "../Item/Interface";
import { ItemManager } from "../Item/ItemManager"; import { ItemManager } from "../Item/ItemManager";
import { SpecT } from "../../Types/PlayerSpecs";
@Injectable(IRaidManager) @Injectable(IRaidManager)
export class RaidManager export class RaidManager
@@ -126,11 +125,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
startRaid = async (raid:Raid) : Promise<RaidData> => { startRaid = async (raid:Raid) : Promise<RaidData> => {
const archived = await this.archiveRaid(raid) const archived = await this.archiveRaid(raid)
delete archived.participants.late
const giveCurrency = async (b: Character) => { const giveCurrency = async (b: Character) => {
const usr = await this.characterManager.getUserOfCharacter(b) const usr = await this.characterManager.getUserOfCharacter(b)
await this.userManager.incrementCurrency(usr, 1) await this.userManager.incrementCurrency(usr, raid.tier, 1)
} }
await Promise.all([ await Promise.all([
@@ -144,10 +142,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
archiveRaid = async (raid:Raid) : Promise<RaidData> => { archiveRaid = async (raid:Raid) : Promise<RaidData> => {
const raidData = await this.getRaidData(raid) const raidData = await this.getRaidData(raid)
const tx = await this.admin.knex.transaction() //const tx = await this.admin.knex.transaction()
await this.admin.knex('archive') await this.admin.knex('archive')
.transacting(tx) //.transacting(tx)
.insert({ .insert({
id:raidData.id, id:raidData.id,
raiddata: JSON.stringify(raidData) raiddata: JSON.stringify(raidData)
@@ -155,8 +153,8 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
await Promise.all( await Promise.all(
Object.values(raidData.participants).flat().flatMap((signup) => this.admin Object.values(raidData.participants).flat().flatMap((signup) => this.admin
.knex('tokens') .knex(raid.tier+'tokens')
.transacting(tx) //.transacting(tx)
.where({ .where({
characterid: signup.characterid, characterid: signup.characterid,
signupid: null signupid: null
@@ -165,10 +163,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
)) ))
await this.admin.knex('raids') await this.admin.knex('raids')
.transacting(tx) //.transacting(tx)
.where('id', '=', raid.id) .where('id', '=', raid.id)
.del() .del()
await tx.commit() //await tx.commit()
const row = await this.admin.knex('archive') const row = await this.admin.knex('archive')
@@ -216,7 +214,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
healers:<(Signup&Character&Spec)[]>[], healers:<(Signup&Character&Spec)[]>[],
tanks:<(Signup&Character&Spec)[]>[] tanks:<(Signup&Character&Spec)[]>[]
} }
const tx = await this.admin.knex.transaction() //const tx = await this.admin.knex.transaction()
const subQuery = this.admin const subQuery = this.admin
.knex('signups') .knex('signups')
@@ -231,13 +229,13 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
const raidInDb: Raid = await this.admin.knex('raids') const raidInDb: Raid = await this.admin.knex('raids')
.select('*', subQuery) .select('*', subQuery)
.transacting(tx) //.transacting(tx)
.where('id','=',raid.id) .where('id','=',raid.id)
.first() .first()
const characterData: (Signup & Character & Spec)[] = await this.admin const characterData: (Signup & Character & Spec)[] = await this.admin
.knex('signups as s') .knex('signups as s')
.transacting(tx) //.transacting(tx)
.select('s.id as id', 'charactername', 'class', 'specid', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid', 'specid') .select('s.id as id', 'charactername', 'class', 'specid', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid', 'specid')
.join('raids as r', 's.raidid','=','r.id') .join('raids as r', 's.raidid','=','r.id')
.join('characters as c', 's.characterid','=','c.id') .join('characters as c', 's.characterid','=','c.id')
@@ -259,18 +257,20 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
const tokenData: (Character & SRToken & Item)[] = await this.admin const tokenData: (Character & SRToken & Item)[] = await this.admin
.knex('signups as s') .knex('signups as s')
.transacting(tx) //.transacting(tx)
.select('*', 's.id as id') .select('*', 's.id as id')
.join('raids as r', 's.raidid','=','r.id') .join('raids as r', 's.raidid','=','r.id')
.where('r.id','=',raid.id) .join('characters as c', 's.characterid','=','c.id')
.join(raidInDb.tier+'tokens as t', 't.characterid','=','c.id')
.join('items as i', 'i.itemname','=','t.itemname')
.where({
'r.id': raid.id,
})
.andWhere(function(){ .andWhere(function(){
this.whereNotNull('t.signupid') this.whereNotNull('t.signupid')
}) })
.join('characters as c', 's.characterid','=','c.id')
.join('tokens as t', 't.characterid','=','c.id')
.join('items as i', 'i.itemname','=','t.itemname')
await tx.commit() //await tx.commit()
tokenData.forEach(data => { tokenData.forEach(data => {
if(!raiddata.tokens[data.itemname]) if(!raiddata.tokens[data.itemname])
@@ -313,11 +313,11 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){ if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){
throw new Error("Bad Usertoken") throw new Error("Bad Usertoken")
} }
const tx = await this.admin.knex.transaction() //const tx = await this.admin.knex.transaction()
const exists = await this.admin const exists = await this.admin
.knex('signups') .knex('signups')
.transacting(tx) //.transacting(tx)
.select('*') .select('*')
.where({ .where({
raidid: raid.id!, raidid: raid.id!,
@@ -328,7 +328,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!exists){ if(!exists){
await this.admin await this.admin
.knex('signups') .knex('signups')
.transacting(tx) //.transacting(tx)
.insert({ .insert({
raidid: raid.id!, raidid: raid.id!,
characterid: character.id!, characterid: character.id!,
@@ -338,7 +338,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
}else{ }else{
await this.admin await this.admin
.knex('signups') .knex('signups')
.transacting(tx) //.transacting(tx)
.where({ .where({
id: exists.id id: exists.id
}) })
@@ -349,7 +349,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
benched: false, benched: false,
}) })
} }
await tx.commit() //await tx.commit()
return await this.admin return await this.admin
.knex('signups') .knex('signups')
@@ -380,22 +380,22 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
"si.characterid": character.id!, "si.characterid": character.id!,
}).first() }).first()
const tokens = await this.admin.knex('tokens as t') const tokens = await this.admin.knex(raid.tier+'tokens as t')
.where('t.signupid', signup.id) .where('t.signupid', signup.id)
//check if token has to be deleted //check if token has to be deleted
Promise.all( Promise.all(
tokens.map(async token => { tokens.map(async token => {
await this.userManager.incrementCurrency(user, 1) await this.userManager.incrementCurrency(user, raid.tier, 1)
const prio = await this.itemManager.calculatePriorities(token.itemname, character) const prio = await this.itemManager.calculatePriorities(token.itemname, character)
if(token.level <= prio+1){ if(token.level <= prio+1){
await this.admin.knex('tokens') await this.admin.knex(raid.tier+'tokens')
.where({ .where({
characterid: character.id, characterid: character.id,
itemname: token.itemname itemname: token.itemname
}).del() }).del()
}else{ }else{
await this.admin.knex('tokens') await this.admin.knex(raid.tier+'tokens')
.where({ .where({
characterid: character.id, characterid: character.id,
itemname: token.itemname itemname: token.itemname
+5 -4
View File
@@ -1,4 +1,5 @@
import { Auth, Rank, User, RPCPermission, UserRecord } from "../../Types/Types" import { Auth, Rank, User, RPCPermission, UserRecord } from "../../Types/Types"
import { Tiers } from "../../Types/Items"
export class IUserManager{ export class IUserManager{
login: (username:string, pwHash:string) => Promise<Auth> login: (username:string, pwHash:string) => Promise<Auth>
@@ -11,10 +12,10 @@ export class IUserManager{
getUserRecordByToken: (tokenValue: string) => UserRecord | void getUserRecordByToken: (tokenValue: string) => UserRecord | void
getUser: (username: string) => Promise<User | void> getUser: (username: string) => Promise<User | void>
decrementCurrency: (user: User, value: number) => Promise<void> decrementCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
incrementCurrency: (user: User, value: number) => Promise<void> incrementCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
setCurrency: (user: User, value: number) => Promise<void> setCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
getCurrency: (user:User) => Promise<number> getCurrency: (user:User, tier:Tiers) => Promise<number>
changeRank: (user:User, rank: Rank) => Promise<User> changeRank: (user:User, rank: Rank) => Promise<User>
wipeCurrency: () => Promise<void> wipeCurrency: () => Promise<void>
} }
+24 -16
View File
@@ -12,6 +12,7 @@ import { IAdmin } from "../../Admin/Interface";
import { IUserManager } from "./Interface"; import { IUserManager } from "./Interface";
import { getLogger, Logger } from "log4js"; import { getLogger, Logger } from "log4js";
import { saltedHash } from "../../Util/hash"; import { saltedHash } from "../../Util/hash";
import { _Tiers, Tiers } from "../../Types/Items";
const uuid = require('uuid/v4') const uuid = require('uuid/v4')
@@ -97,8 +98,9 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
table.string("username").notNullable().unique() table.string("username").notNullable().unique()
table.string("pwhash").notNullable() table.string("pwhash").notNullable()
table.string("rank").notNullable() table.string("rank").notNullable()
table.string("email").nullable().unique() _Tiers.forEach(tier => {
table.integer("currency").defaultTo(1) table.integer(tier).defaultTo(1)
})
} }
},{ },{
name: 'rpcpermissions', name: 'rpcpermissions',
@@ -286,8 +288,13 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
} }
wipeCurrency = async () => { wipeCurrency = async () => {
await this.admin.knex('users') await Promise.all(_Tiers.map(tier => {
.update({currency: 0}) const update = {}
update[tier] = 1
return this.admin.knex('users')
.update(update)
}))
} }
login = async(username:string, pwHash:string) : Promise<Auth> => { login = async(username:string, pwHash:string) : Promise<Auth> => {
@@ -405,18 +412,19 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
return token return token
} }
getCurrency = async(user:User) : Promise<number> => { getCurrency = async(user:User, tier?: Tiers) : Promise<number> => {
if(!tier) return 0
const usr : User = await this.admin const usr : User = await this.admin
.knex('users') .knex('users')
.where('username', '=', user.username) .where('username', '=', user.username)
.select('*') .select('*')
.first() .first()
return usr.currency! return usr[tier]!
} }
decrementCurrency = async (user: User, value = 1) => { decrementCurrency = async (user: User, tier?: Tiers, value = 1) => {
if(value < 1) return if(!tier || value < 1) return
const usr : User = await this.admin const usr : User = await this.admin
.knex('users') .knex('users')
@@ -424,28 +432,28 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
.select('*') .select('*')
.first() .first()
if(!usr || usr.currency! <= 0) return if(!usr || usr[tier]! <= 0) return
await this.admin await this.admin
.knex('users') .knex('users')
.where('id', '=', user.id) .where('id', '=', user.id)
.decrement('currency', value) .decrement(tier, value)
} }
incrementCurrency = async (user: User, value = 1) => { incrementCurrency = async (user: User, tier: Tiers, value = 1) => {
if(value < 1) return if(!tier || value < 1) return
await this.admin await this.admin
.knex('users') .knex('users')
.where('id', '=', user.id) .where('id', '=', user.id)
.increment('currency', value) .increment(tier, value)
} }
setCurrency = async (user: User, value: number) => { setCurrency = async (user: User, tier?:Tiers, value = 0) => {
if(value < 0) return if(!tier || value < 0) return
await this.admin await this.admin
.knex('users') .knex('users')
.where('id', '=', user.id) .where('id', '=', user.id)
.update('currency', value) .update(tier, value)
} }
+2 -2
View File
@@ -1,5 +1,5 @@
export type Tiers = "MC" | 'BWL' | 'ZG' | 'AQ20' | 'AQ40' | 'Naxx' export type Tiers = "MC" | 'BWL' | 'ZG' | 'AQ20' | 'AQ40' | 'Naxx'
export const _Tiers = ["MC", 'BWL', 'ZG', 'AQ20', 'AQ40', 'Naxx'] export const _Tiers:Tiers[] = ["MC", 'BWL', 'ZG', 'AQ20', 'AQ40', 'Naxx']
export const T1 = [ export const T1 = [
"Robe of Volatile Power", "Robe of Volatile Power",
+2
View File
@@ -94,6 +94,8 @@ export type User = {
pwhash: string pwhash: string
rank: Rank rank: Rank
currency?: number currency?: number
} & {
[currency in Tiers]? : number
} }
export type Raid = { export type Raid = {
@@ -10,9 +10,12 @@ import { ShoutMessage } from '../../../../../../backend/Components/Shoutbox/Inte
[type]="text" [type]="text"
[message]="msg.message" [message]="msg.message"
[sender]="msg.sender" [sender]="msg.sender"
[date]="msg.date"> [date]="msg.date"
[reply]="msg.reply">
</nb-chat-message> </nb-chat-message>
<nb-chat-form (send)="submit($event)" [dropFiles]="false"> <nb-chat-form
(send)="submit($event)"
[dropFiles]="false">
</nb-chat-form> </nb-chat-form>
</nb-chat> </nb-chat>
`, `,
@@ -25,13 +25,7 @@ status="control">
<br/><br /> <br/><br />
<span *ngFor="let token of tokens"> <span *ngFor="let token of tokens">
[ {{token.level}} ] [ {{token.level}} ]
<a [ngStyle]="{'color':token.quality=='Epic'?'#a335ee':'#ff8000'}" <wowhead [item]="token"></wowhead><br />
target="_blank"
[href]="token.url">
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+token.iconname+'.jpg'" />
{{token.itemname}}
</a><br />
</span> </span>
</nb-card-body> </nb-card-body>
</nb-card> </nb-card>
@@ -3,6 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { ApiService as ApiService } from '../../services/login-api'; import { ApiService as ApiService } from '../../services/login-api';
import { Spec, User, Character } from '../../../../../../backend/Types/Types'; import { Spec, User, Character } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs'; import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers } from '../../../../../../backend/Types/Items';
@Component({ @Component({
selector: 'character', selector: 'character',
@@ -35,7 +36,7 @@ export class FrontcraftCharacterComponent implements OnInit{
if(char){ if(char){
this.color = getClassColor(char.class) this.color = getClassColor(char.class)
this.char = char this.char = char
this.api.get('ItemManager').getTokens(this.char).then(tokens => { this.api.get('ItemManager').getTokens(this.char, _Tiers, true).then(tokens => {
this.tokens = tokens this.tokens = tokens
}) })
} }
@@ -38,6 +38,8 @@ import { FrontcraftItemSelectComponent } from './shop/itemselector.component';
import { NgxEchartsModule } from 'ngx-echarts'; import { NgxEchartsModule } from 'ngx-echarts';
import { FrontcraftCharactersComponent } from './characters/characters.component'; import { FrontcraftCharactersComponent } from './characters/characters.component';
import { FrontcraftBuyTokenComponent } from './shop/buytoken.component'; import { FrontcraftBuyTokenComponent } from './shop/buytoken.component';
import { FrontcraftItemComponent } from './shop/item.component';
import { FrontcraftWowheadComponent } from './shop/wowhead.component';
@NgModule({ @NgModule({
@@ -81,6 +83,8 @@ import { FrontcraftBuyTokenComponent } from './shop/buytoken.component';
FrontcraftRulesComponent, FrontcraftRulesComponent,
FrontcraftCreateRaidsComponent, FrontcraftCreateRaidsComponent,
FrontcraftBuyTokenComponent, FrontcraftBuyTokenComponent,
FrontcraftWowheadComponent,
FrontcraftItemComponent
], ],
entryComponents: [ entryComponents: [
FrontcraftItemSelectComponent, FrontcraftItemSelectComponent,
@@ -13,6 +13,7 @@ export class FrontcraftArchiveComponent implements OnInit{
canSignup = false canSignup = false
isSignedup = false isSignedup = false
canManage = false canManage = false
isTier = false
mySignup mySignup
raid: RaidData = <any>{ raid: RaidData = <any>{
@@ -2,7 +2,10 @@
<nb-card-body> <nb-card-body>
<nb-tabset> <nb-tabset>
<nb-tab tabTitle="Info"> <nb-tab tabTitle="Info">
<h1>{{raid.title}}</h1> <h1>
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'" style="height: 100px" />
{{raid.title}}
</h1>
<p> <p>
{{raid.signupcount}} / {{raid.size}} signups {{raid.signupcount}} / {{raid.size}} signups
</p> </p>
@@ -167,10 +170,10 @@
</ng-container> </ng-container>
</div> </div>
</nb-tab> </nb-tab>
<nb-tab tabTitle="Shop" *ngIf="isSignedup"> <nb-tab tabTitle="Items" *ngIf="isSignedup && isTier">
<shop (onSelect)="itemSelect($event)"></shop> <shop [tier]="raid.tier" (onSelect)="itemSelect($event)"></shop>
</nb-tab> </nb-tab>
<nb-tab tabTitle="Reserves"> <nb-tab tabTitle="Reserves" *ngIf="isTier">
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true"> <input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
<nb-list> <nb-list>
@@ -6,6 +6,7 @@ import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/them
import { FrontcraftCharacerpickerComponent } from './characterpicker.component'; import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
import { getClassColor, SpecT } from '../../../../../../backend/Types/PlayerSpecs'; import { getClassColor, SpecT } from '../../../../../../backend/Types/PlayerSpecs';
import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component'; import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component';
import { allItems } from '../../../../../../backend/Types/Items';
@Component({ @Component({
selector: 'raid', selector: 'raid',
@@ -16,6 +17,7 @@ export class FrontcraftRaidComponent implements OnInit{
canSignup = false canSignup = false
isSignedup = false isSignedup = false
islate = false islate = false
isTier = false
manageRaid manageRaid
mySignup: (Signup & Character & Spec) mySignup: (Signup & Character & Spec)
@@ -33,7 +35,8 @@ export class FrontcraftRaidComponent implements OnInit{
}, },
tanks: [], tanks: [],
healers: [], healers: [],
tokens:{} tokens:{},
tier: 'MC'
} }
tokens = {} tokens = {}
displayedtokens = {} displayedtokens = {}
@@ -50,6 +53,7 @@ export class FrontcraftRaidComponent implements OnInit{
} }
async ngOnInit(){ async ngOnInit(){
this.manageRaid = this.api.get('manageRaid') this.manageRaid = this.api.get('manageRaid')
const signupFeature = this.api.get('signup') const signupFeature = this.api.get('signup')
@@ -63,7 +67,9 @@ export class FrontcraftRaidComponent implements OnInit{
this.dialogService.open(FrontcraftBuyTokenComponent, { this.dialogService.open(FrontcraftBuyTokenComponent, {
context: { context: {
item: item, item: item,
signup: this.mySignup signup: this.mySignup,
tier: this.raid.tier,
characterName: this.mySignup.charactername
} }
}).onClose.subscribe(() => this.refresh()) }).onClose.subscribe(() => this.refresh())
} }
@@ -112,9 +118,6 @@ export class FrontcraftRaidComponent implements OnInit{
const signup = this.api.get('signup') const signup = this.api.get('signup')
if(!signup) return if(!signup) return
console.log("setlate");
await signup.sign(auth.token.value, { await signup.sign(auth.token.value, {
...this.mySignup, ...this.mySignup,
id: this.mySignup.characterid, id: this.mySignup.characterid,
@@ -140,6 +143,7 @@ export class FrontcraftRaidComponent implements OnInit{
const raiddata = await raidManager.getRaidData(<any>{ const raiddata = await raidManager.getRaidData(<any>{
id: param id: param
}) })
this.isTier = allItems[raiddata.tier] != null
this.raid = raiddata this.raid = raiddata
this.tokens = raiddata.tokens; this.tokens = raiddata.tokens;
@@ -8,6 +8,10 @@
<nb-option *ngFor="let template of templates" [value]="template">{{template.title}} {{template.start| date : 'd MMMM'}}</nb-option> <nb-option *ngFor="let template of templates" [value]="template">{{template.title}} {{template.start| date : 'd MMMM'}}</nb-option>
</nb-select> </nb-select>
<nb-select [(selected)]="tier" placeholder="Tier" >
<nb-option *ngFor="let _tier of tiers" [value]="_tier">{{_tier}}</nb-option>
</nb-select>
<input type="text" nbInput [(ngModel)]="title" placeholder="Title" fullWidth="true"> <input type="text" nbInput [(ngModel)]="title" placeholder="Title" fullWidth="true">
<input type="number" nbInput [(ngModel)]="size" placeholder="size" fullWidth="true"> <input type="number" nbInput [(ngModel)]="size" placeholder="size" fullWidth="true">
<textarea nbInput fullWidth [(ngModel)]="description" placeholder="description" fullWidth="true"></textarea> <textarea nbInput fullWidth [(ngModel)]="description" placeholder="description" fullWidth="true"></textarea>
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../services/login-api'; import { ApiService } from '../../services/login-api';
import { Raid, RaidData } from '../../../../../../backend/Types/Types'; import { Raid, RaidData } from '../../../../../../backend/Types/Types';
import { NbWindowRef, NbDialogRef } from '@nebular/theme'; import { NbWindowRef, NbDialogRef } from '@nebular/theme';
import { Tiers, _Tiers } from '../../../../../../backend/Types/Items';
const ONE_MINUTE = 60000 const ONE_MINUTE = 60000
const ONE_HOUR = 60 * ONE_MINUTE const ONE_HOUR = 60 * ONE_MINUTE
@@ -21,6 +22,8 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
minute = 0 minute = 0
size = 40 size = 40
description = "" description = ""
tier: Tiers = null
tiers = _Tiers
constructor( constructor(
protected dialogRef: NbDialogRef<FrontcraftCreateRaidsComponent>, protected dialogRef: NbDialogRef<FrontcraftCreateRaidsComponent>,
@@ -37,6 +40,7 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
this.minute = templateDate.getMinutes() this.minute = templateDate.getMinutes()
this.description = this.template.description this.description = this.template.description
this.startdate = new Date(parseInt(this.template.start) - templateDate.getHours()*ONE_HOUR - templateDate.getMinutes()*ONE_MINUTE) this.startdate = new Date(parseInt(this.template.start) - templateDate.getHours()*ONE_HOUR - templateDate.getMinutes()*ONE_MINUTE)
this.tier = this.template.tier
} }
ngOnInit(){ ngOnInit(){
@@ -49,6 +53,7 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
size: this.size, size: this.size,
start: ""+new Date(this.startdate.getTime() + this.hour*ONE_HOUR + this.minute*ONE_MINUTE).getTime(), start: ""+new Date(this.startdate.getTime() + this.hour*ONE_HOUR + this.minute*ONE_MINUTE).getTime(),
title: this.title, title: this.title,
tier: this.tier
} }
const manage = this.api.get('manageRaid') const manage = this.api.get('manageRaid')
if(!manage) return if(!manage) return
@@ -17,7 +17,7 @@
style="cursor: pointer;"> style="cursor: pointer;">
<div class="row"> <div class="row">
<div class="col-2"> <div class="col-2">
<img src="../../../../assets/images/mage.png" style="height: 75px" /> <img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'" style="height: 75px" />
</div> </div>
<div class="col-2 vcenter"> <div class="col-2 vcenter">
@@ -7,15 +7,7 @@
<nb-tab tabTitle="priorities"> <nb-tab tabTitle="priorities">
<nb-list> <nb-list>
<nb-list-item *ngFor="let item of rules | keyvalue"> <nb-list-item *ngFor="let item of rules | keyvalue">
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}" <wowhead [item]="item.value[0]"></wowhead><br>
target="_blank"
[href]="item.value[0].url">
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.value[0].iconname+'.jpg'" />
&nbsp;
{{item.key}}
</a><br />
<span *ngFor="let rule of item.value" [nbPopover]="templateRef" nbPopoverTrigger="hover"> <span *ngFor="let rule of item.value" [nbPopover]="templateRef" nbPopoverTrigger="hover">
<ng-template #templateRef> <ng-template #templateRef>
<span style="color:white">{{rule.description}}</span> <span style="color:white">{{rule.description}}</span>
@@ -15,49 +15,73 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
</nb-card-header> </nb-card-header>
<nb-card-body> <nb-card-body>
<p> <p>
You currently have {{currency}} softreserve currency {{currency}} softreserves remaining
</p> </p>
<div *ngIf="currency>0"> <div *ngIf="currency>0">
<div *ngFor="let kv of modifier | keyvalue"> <nb-alert accent="danger" *ngIf="invalidatedTokens.length > 0">
Claiming this reserve invalidates the following streaks. <br />
This is not reversible.
<ul *ngFor="let item of invalidatedTokens">
<li>
[ {{item.level}} ]
<img style="min-width: 20px; width: 2.25vw; max-width: 35px" [src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.iconname+'.jpg'" />
<span [ngStyle]="{'color':item.quality=='Epic'?'#a335ee':'#ff8000'}">
{{item.itemname}}
</span>
</li>
</ul>
</nb-alert>
<nb-alert accent="info" *ngIf="noToken">
The following reserve will be created<br />
<ul>
<li>
[ {{1+modifier}} ]
<img style="min-width: 20px; width: 2.25vw; max-width: 35px" [src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.iconname+'.jpg'" />
<span [ngStyle]="{'color':item.quality=='Epic'?'#a335ee':'#ff8000'}">
{{item.itemname}}
</span>
<span *ngIf="modifier>0">(<b>+{{modifier}}</b> from priorities)</span>
</li>
</ul>
</nb-alert>
<nb-alert accent="info" *ngIf="upgradableToken != null">
The following reserve will be created<br />
<ul>
<li>
[ {{upgradableToken.level}} ] => [ {{upgradableToken.level+1}} ] <img style="min-width: 20px; width: 2.25vw; max-width: 35px" [src]="'https://wow.zamimg.com/images/wow/icons/large/'+upgradableToken.iconname+'.jpg'" />
<span [ngStyle]="{'color':upgradableToken.quality=='Epic'?'#a335ee':'#ff8000'}">{{upgradableToken.itemname}}</span>
</li>
</ul>
</nb-alert>
</div>
<button <button
(click)="buyToken(kv.key)" (click)="buyToken()"
[disabled]="currency<=0" [disabled]="currency<=0"
nbButton nbButton
outline outline
status="success" status="success"
size="tiny"> size="small">
buy <nb-icon icon="checkmark-outline"></nb-icon> claim
</button> </button>
{{kv.key}} <span *ngIf="kv.value>0">(<b>+{{kv.value}}</b> from priorities)</span>
</div>
<div *ngFor="let token of ownedtokens">
<button
(click)="buyToken(token.charactername)"
nbButton
outline
status="success"
size="tiny">
buy
</button>
{{token.charactername}} [ {{token.level}} ] => [ {{token.level+1}} ]
</div>
</div>
</nb-card-body> </nb-card-body>
</nb-card> </nb-card>
`, `,
}) })
export class FrontcraftBuyTokenComponent implements OnInit{ export class FrontcraftBuyTokenComponent implements OnInit{
@Input() characterName: string
@Input() item : Item @Input() item : Item
@Input() signup : Signup @Input() signup : Signup
@Input() tier: Tiers @Input() tier: Tiers
characters: Character[] invalidatedTokens: (SRToken & Character & Item)[] | undefined = []
modifier = {} upgradableToken : (SRToken & Character & Item) | undefined
noToken = false
modifier
currency: number = 0 currency: number = 0
ownedtokens: SRToken[] = []
constructor( constructor(
private toastr: NbToastrService, private toastr: NbToastrService,
@@ -65,38 +89,36 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
private api : ApiService private api : ApiService
){} ){}
ngOnInit(): void { async ngOnInit() {
const char = await this.api.get('CharacterManager').getCharacterByName(this.characterName)
if(!char) return
const passiveStreaks = await this.api.get('ItemManager').getTokens(char, [this.item.tier], false)
this.upgradableToken = passiveStreaks.find(p => p.itemname === this.item.itemname)
this.invalidatedTokens = passiveStreaks.filter(token => token.itemname !== this.item.itemname)
if(!this.upgradableToken)
this.upgradableToken = await this.api.get('ItemManager').getToken(char, this.item, true)
this.modifier = await this.api.get('ItemManager').calculatePriorities(this.item.itemname, char)
if(!this.upgradableToken) this.noToken = true
const usr = this.api.getCurrentUser() const usr = this.api.getCurrentUser()
this.api.get('CharacterManager') this.api.get('CharacterManager')
.getCharactersOfUser(usr.username) .getCharactersOfUser(usr.username)
.then(chars => { .then(chars => {
chars.forEach(char => { chars.forEach(async char => {
char['color'] = getClassColor(char.class) char['color'] = getClassColor(char.class)
this.api.get('ItemManager').getToken(char, this.item, false).then(token => {
if(token) this.ownedtokens.push(token)
else{
this.api.get('ItemManager').getToken(char, this.item, true).then(tokken => {
if(tokken) this.ownedtokens.push(tokken)
else{
this.api.get('ItemManager').calculatePriorities(this.item.itemname, char).then(modifier => {
this.modifier[char.charactername] = modifier
})
}
})
}
})
}) })
this.characters = chars
}) })
this.api.get('UserManager').getUser(usr.username).then(u => { this.api.get('UserManager').getUser(usr.username).then(u => {
if(!u) return if(!u) return
this.currency = u.currency this.currency = u[this.tier] || 0
}) })
} }
buyToken = async (charactername:string) => { buyToken = async () => {
const src = this.api.get('ItemManager') const src = this.api.get('ItemManager')
const token = await src.buyToken(this.api.getAuth().token.value, charactername, this.item.itemname, this.signup) const token = await src.buyToken(this.api.getAuth().token.value, this.characterName, this.item.itemname, this.signup)
if(token){ if(token){
this.toastr.show(token.charactername+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'}) this.toastr.show(token.charactername+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'})
@@ -0,0 +1,30 @@
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService as ApiService } from '../../services/login-api';
import { FrontcraftItemSelectComponent } from './itemselector.component';
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
import { Item, Character, SRToken, Signup } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
@Component({
selector: 'item',
template: `
<span [ngStyle]="{'color':item.quality=='Epic'?'#a335ee':'#ff8000'}">
<img style="min-width: 20px; width: 2.25vw; max-width: 35px"
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.iconname+'.jpg'" />
&nbsp;
{{item.itemname}}
</span>
`,
})
export class FrontcraftItemComponent implements OnInit{
@Input() item: Item
constructor(
private toastr: NbToastrService,
private api : ApiService
){}
async ngOnInit() {
}
}
@@ -14,13 +14,7 @@
select select
</button> </button>
&nbsp; &nbsp;
<a target="_blank" [href]="item.url"> <wowhead [item]="item"></wowhead>
<span [ngStyle]="{'color':item.quality=='Epic'?'#a335ee':'#ff8000'}">
<img style="min-width: 20px; width: 2.25vw; max-width: 35px"
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.iconname+'.jpg'" />
&nbsp;
{{item.itemname}}
</span>
</a>
</nb-list-item> </nb-list-item>
</nb-list> </nb-list>
@@ -1,6 +1,6 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService } from '../../services/login-api'; import { ApiService } from '../../services/login-api';
import { Item } from '../../../../../../backend/Types/Types'; import { Item, Character } from '../../../../../../backend/Types/Types';
@Component({ @Component({
selector: 'itemselect', selector: 'itemselect',
@@ -13,6 +13,7 @@ export class FrontcraftItemSelectComponent implements OnInit{
allItems:Item[] = [] allItems:Item[] = []
displayedItems: any[] displayedItems: any[]
@Input() character: string
@Input() items: string[] @Input() items: string[]
@Output() onSelect = new EventEmitter<Item>(); @Output() onSelect = new EventEmitter<Item>();
@@ -21,6 +22,7 @@ export class FrontcraftItemSelectComponent implements OnInit{
){} ){}
async ngOnInit(){ async ngOnInit(){
Promise.all(this.items.map(itemname => Promise.all(this.items.map(itemname =>
this.api.get('ItemManager').getItem(itemname) this.api.get('ItemManager').getItem(itemname)
)).then(items => { )).then(items => {
@@ -1,7 +1,5 @@
<h3>
{{tier}} items
</h3>
<itemselect <itemselect
[character]="character"
[items]="allItems[tier]" [items]="allItems[tier]"
(onSelect)="onSelect.emit($event)"></itemselect> (onSelect)="onSelect.emit($event)"></itemselect
>
@@ -10,7 +10,7 @@ import { _Tiers, allItems } from '../../../../../../backend/Types/Items';
selector: 'shop', selector: 'shop',
templateUrl: './shop.component.html', templateUrl: './shop.component.html',
}) })
export class FrontcraftShopComponent{ export class FrontcraftShopComponent implements OnInit{
@Input() character: Character @Input() character: Character
@Input() signup: Signup @Input() signup: Signup
@@ -22,5 +22,10 @@ export class FrontcraftShopComponent{
constructor( constructor(
private api: ApiService, private api: ApiService,
private dialogService : NbDialogService private dialogService : NbDialogService
){} ){
}
ngOnInit(){
}
} }
@@ -0,0 +1,26 @@
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService as ApiService } from '../../services/login-api';
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
import { Item, Character, SRToken, Signup } from '../../../../../../backend/Types/Types';
import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
@Component({
selector: 'wowhead',
template: `
<a target="_blank" [href]="item.url">
<item [item]="item"></item>
</a>
`,
})
export class FrontcraftWowheadComponent implements OnInit{
@Input() item: Item
constructor(
private toastr: NbToastrService,
private api : ApiService
){}
async ngOnInit() {
}
}
@@ -6,7 +6,12 @@ accent="info">
<h2 style="text-transform: capitalize;">{{user.username}}</h2> <h2 style="text-transform: capitalize;">{{user.username}}</h2>
</nb-card-header> </nb-card-header>
<nb-card-body> <nb-card-body>
{{user.currency}} {{user.MC}} MC
{{user.BWL}} BWL
{{user.ZG}} ZG
{{user.AQ20}} AQ20
{{user.AQ40}} AQ40
{{user.Naxx}} Naxx
<ng-container *ngFor="let char of characters"> <ng-container *ngFor="let char of characters">
<character [name]="char.charactername" [link]="'character'"></character> <character [name]="char.charactername" [link]="'character'"></character>
</ng-container> </ng-container>
@@ -3,6 +3,7 @@ import { ApiService } from '../../services/login-api';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { User, Spec, Character } from '../../../../../../backend/Types/Types'; import { User, Spec, Character } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs'; import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers } from '../../../../../../backend/Types/Items';
@Component({ @Component({
selector: 'user-component', selector: 'user-component',
@@ -28,7 +29,7 @@ export class FrontcraftUserComponent implements OnInit{
const characters = await this.api.get('CharacterManager').getCharactersOfUser(this.user.username) const characters = await this.api.get('CharacterManager').getCharactersOfUser(this.user.username)
characters.forEach(async c => { characters.forEach(async c => {
const tokens = await this.api.get('ItemManager').getTokens(c) const tokens = await this.api.get('ItemManager').getTokens(c, _Tiers, true)
c['tokens'] = tokens c['tokens'] = tokens
c['color'] = getClassColor(c.class) c['color'] = getClassColor(c.class)
}) })
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+21 -10
View File
@@ -60,6 +60,12 @@ const testAccounts : protoAccount[] = [
race: 'Night Elf', race: 'Night Elf',
spec: 'Protection', spec: 'Protection',
rank: 'Officer' rank: 'Officer'
},{
name: 'Silver',
class: 'Druid',
race: 'Night Elf',
spec: 'Restoration',
rank: 'Raider'
},{ },{
name: 'Dagger', name: 'Dagger',
race: 'Dwarf', race: 'Dwarf',
@@ -117,7 +123,7 @@ describe('Frontcraft', () => {
const account = await createAccount({ const account = await createAccount({
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a") pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
rank: acc.rank, rank: acc.rank,
username: acc.name username: acc.name,
}) })
const auth = await client.UserManager.login(acc.name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb') const auth = await client.UserManager.login(acc.name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
const id = await client.CharacterManager.getSpecId(acc.class, acc.spec) const id = await client.CharacterManager.getSpecId(acc.class, acc.spec)
@@ -148,7 +154,7 @@ describe('Frontcraft', () => {
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //hash("a") pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //hash("a")
rank: 'ADMIN', rank: 'ADMIN',
username: 'a', username: 'a',
currency: 2 MC: 2
}).then(adminUser => { }).then(adminUser => {
client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => { client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => {
@@ -187,7 +193,8 @@ describe('Frontcraft', () => {
let insertRaid = <Raid>{ let insertRaid = <Raid>{
description: "Test raid 1", description: "Test raid 1",
title: 'MC', title: 'MC',
start: Date.now().toString() start: Date.now().toString(),
tier: 'MC'
} }
adminClient.manageRaid.createRaid(insertRaid).then(() => { adminClient.manageRaid.createRaid(insertRaid).then(() => {
@@ -391,6 +398,11 @@ describe('Frontcraft', () => {
{class:'Paladin', specname:'Holy'}, {class:'Paladin', specname:'Holy'},
undefined, 2, "crit bias" undefined, 2, "crit bias"
), ),
makePrio(
'Empowered Leggings',
{class:'Druid', specname:'Restoration'},
undefined, 2, "crit bias"
),
makePrio( makePrio(
'Boots of the Shadow Flame', 'Boots of the Shadow Flame',
@@ -516,7 +528,7 @@ describe('Frontcraft', () => {
const user = Object.values(users)[0] const user = Object.values(users)[0]
const itemname = T1[0] const itemname = T1[0]
adminClient.softreserveCurrency.incrementCurrency(user.account, 2).then(async ()=>{ adminClient.softreserveCurrency.incrementCurrency(user.account, raids[0].tier, 2).then(async ()=>{
const item = await client.ItemManager.getItem(itemname) const item = await client.ItemManager.getItem(itemname)
const before = await client.ItemManager.getToken(user.character, item) const before = await client.ItemManager.getToken(user.character, item)
@@ -538,7 +550,7 @@ describe('Frontcraft', () => {
it('should buy more tokens', (done) => { it('should buy more tokens', (done) => {
Promise.all(Object.values(users).map(async (user) => { Promise.all(Object.values(users).map(async (user) => {
await adminClient.softreserveCurrency.incrementCurrency(user.account, 1) await adminClient.softreserveCurrency.incrementCurrency(user.account,raids[0].tier, 1)
return await client.ItemManager return await client.ItemManager
.buyToken( .buyToken(
user.auth.token.value, user.auth.token.value,
@@ -565,7 +577,7 @@ describe('Frontcraft', () => {
const dbRaids = await client.RaidManager.getRaids() const dbRaids = await client.RaidManager.getRaids()
if(dbRaids.length === 0){ if(dbRaids.length === 0){
await client.UserManager.getUser(testAccounts[0].name).then(dbUser => { await client.UserManager.getUser(testAccounts[0].name).then(dbUser => {
if(dbUser && dbUser.currency === 1){ if(dbUser && dbUser.MC === 1){
adminClient.signup.getSignups(raids[0]).then(signups => { adminClient.signup.getSignups(raids[0]).then(signups => {
if(signups.length === 0){ if(signups.length === 0){
done() done()
@@ -586,9 +598,9 @@ describe('Frontcraft', () => {
it('reset system', (done) => { it('reset system', (done) => {
adminClient.reset.wipeCurrencyAndItems().then(() => { adminClient.reset.wipeCurrencyAndItems().then(() => {
client.UserManager.getUser(testAccounts[0].name).then(user => { client.UserManager.getUser(testAccounts[0].name).then(user => {
if(user && user.currency === 0){ if(user && user.MC === 1){
client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character).then(tokens => { client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character, ['MC']).then(tokens => {
if(tokens.length === 0){ if(tokens!.length === 0){
done() done()
}else{ }else{
console.log(tokens); console.log(tokens);
@@ -599,6 +611,5 @@ describe('Frontcraft', () => {
} }
}) })
}) })
}) })
}) })