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",
"scripts": {
"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",
"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",
"build-backend": "tsc;",
"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 { Tiers } from "../../Types/Items"
export class IItemManager{
getItems: () => 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>
calculatePriorities: (itemname: string, character:Character) => Promise<number>
deletePriority: (priority:SRPriority) => Promise<void>
getTokens: (character:Character, valid?:boolean) => Promise<SRToken[]>
getToken: (character:Character, item:Item, valid?:boolean) => Promise<(SRToken & Character & Item) | void>
getTokens: (character:Character, tiers: Tiers[], valid?:boolean) => Promise<(SRToken & Character & Item)[] | undefined>
getToken: (character:Character, item:Item, valid?:boolean) => Promise<(SRToken & Character & Item) | undefined>
getAllPriorities: () => Promise<(SRPriority & Spec & Item)[]>
wipeCurrencyAndItems: () => Promise<void>
}
+44 -37
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 { ItemManagerFeatureIfc, ItemManagerIfc } from "./RPCInterface";
import { FrontworkComponent } from "../../Types/FrontworkComponent";
@@ -54,7 +54,7 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
wipeCurrencyAndItems = async () => {
await Promise.all([
this.userManager.wipeCurrency(),
this.admin.knex('tokens').where(true).del()
Promise.all(_Tiers.map(tier => this.admin.knex(tier+'tokens').where(true).del()))
])
}
@@ -84,8 +84,9 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
getTableDefinitions(): TableDefiniton[] {
return [
{
name: 'tokens',
...['null',..._Tiers].map(tier => {
return {
name: tier+'tokens',
tableBuilder: (table) => {
table.primary(['characterid', 'itemname'])
table.integer("characterid")
@@ -96,7 +97,8 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
table.foreign("signupid").references("id").inTable('signups').onDelete('SET NULL')
table.integer("level").defaultTo(1)
}
},{
}
}),{
name: 'priorities',
tableBuilder: (table) => {
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 character = await this.character.getCharacterByName(charactername)
@@ -130,52 +132,53 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
const item = await this.getItem(itemname)
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
const shadowTokens = await this.getTokens(character, false)
const activeTokens = await this.getTokens(character, true)
const streaks = await this.getTokens(character, [item.tier], false)
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)
//tokens with deleted signups
if(shadowTokens.length > 0){
//token for current item
const matchingtoken = shadowTokens.find(token => token.itemname === itemname)
if(matchingtoken){
//update signupid and increment level
if(streaks.length > 0){
const myStreak = streaks.find(token => token.itemname === itemname)
if(myStreak){
//getLogger('ItemManager').debug('update signupid and increment level')
await this.admin
.knex('tokens')
.knex(item.tier+'tokens')
.where({
characterid: character.id,
itemname: item.itemname
})
.update({
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()
}
//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)
if(matchingtoken){
//power up token
const matchingReserve = activeTokens.find(token => token.itemname === itemname)
if(matchingReserve){
getLogger('ItemManager').debug('upgrade reserve')
await this.admin
.knex('tokens')
.knex(item.tier+'tokens')
.increment('level')
.where({
signupid: signup.id,
@@ -183,8 +186,9 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
itemname: item.itemname
})
}else{
getLogger('ItemManager').debug('new reserve')
await this.admin
.knex('tokens')
.knex(item.tier+'tokens')
.insert({
characterid: character.id,
itemname: item.itemname,
@@ -257,9 +261,9 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
}).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
.knex('tokens as t')
.knex(item.tier+'tokens as t')
.select('*')
.join('characters as c', 'c.id', '=', 't.characterid')
.join('items as i', 'i.itemname', '=', 't.itemname')
@@ -277,9 +281,10 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
.first()
}
getTokens = async (character:Character, valid=true) : Promise<(SRToken & Character & Item)[]> => {
getTokens = async (character:Character, tiers:Tiers[], valid=true) : Promise<(SRToken & Character & Item)[]> => {
const ret = await Promise.all(tiers.map(async tier => {
return await this.admin
.knex('tokens as t')
.knex(tier+'tokens as t')
.select('*')
.join('characters as c', 'c.id', '=', 't.characterid')
.join('items as i', 'i.itemname', '=', 't.itemname')
@@ -293,6 +298,8 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
this.whereNull('t.signupid')
}
})
}))
return ret.flat()
}
countItems = async() :Promise<number> => {
+27 -27
View File
@@ -9,7 +9,6 @@ import { ICharacterManager } from "../Character/Interface";
import { _Tiers } from "../../Types/Items";
import { IItemManager } from "../Item/Interface";
import { ItemManager } from "../Item/ItemManager";
import { SpecT } from "../../Types/PlayerSpecs";
@Injectable(IRaidManager)
export class RaidManager
@@ -126,11 +125,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
startRaid = async (raid:Raid) : Promise<RaidData> => {
const archived = await this.archiveRaid(raid)
delete archived.participants.late
const giveCurrency = async (b: Character) => {
const usr = await this.characterManager.getUserOfCharacter(b)
await this.userManager.incrementCurrency(usr, 1)
await this.userManager.incrementCurrency(usr, raid.tier, 1)
}
await Promise.all([
@@ -144,10 +142,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
archiveRaid = async (raid:Raid) : Promise<RaidData> => {
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')
.transacting(tx)
//.transacting(tx)
.insert({
id:raidData.id,
raiddata: JSON.stringify(raidData)
@@ -155,8 +153,8 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
await Promise.all(
Object.values(raidData.participants).flat().flatMap((signup) => this.admin
.knex('tokens')
.transacting(tx)
.knex(raid.tier+'tokens')
//.transacting(tx)
.where({
characterid: signup.characterid,
signupid: null
@@ -165,10 +163,10 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
))
await this.admin.knex('raids')
.transacting(tx)
//.transacting(tx)
.where('id', '=', raid.id)
.del()
await tx.commit()
//await tx.commit()
const row = await this.admin.knex('archive')
@@ -216,7 +214,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
healers:<(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
.knex('signups')
@@ -231,13 +229,13 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
const raidInDb: Raid = await this.admin.knex('raids')
.select('*', subQuery)
.transacting(tx)
//.transacting(tx)
.where('id','=',raid.id)
.first()
const characterData: (Signup & Character & Spec)[] = await this.admin
.knex('signups as s')
.transacting(tx)
//.transacting(tx)
.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('characters as c', 's.characterid','=','c.id')
@@ -259,18 +257,20 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
const tokenData: (Character & SRToken & Item)[] = await this.admin
.knex('signups as s')
.transacting(tx)
//.transacting(tx)
.select('*', 's.id as 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(){
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 => {
if(!raiddata.tokens[data.itemname])
@@ -313,11 +313,11 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){
throw new Error("Bad Usertoken")
}
const tx = await this.admin.knex.transaction()
//const tx = await this.admin.knex.transaction()
const exists = await this.admin
.knex('signups')
.transacting(tx)
//.transacting(tx)
.select('*')
.where({
raidid: raid.id!,
@@ -328,7 +328,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!exists){
await this.admin
.knex('signups')
.transacting(tx)
//.transacting(tx)
.insert({
raidid: raid.id!,
characterid: character.id!,
@@ -338,7 +338,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
}else{
await this.admin
.knex('signups')
.transacting(tx)
//.transacting(tx)
.where({
id: exists.id
})
@@ -349,7 +349,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
benched: false,
})
}
await tx.commit()
//await tx.commit()
return await this.admin
.knex('signups')
@@ -380,22 +380,22 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
"si.characterid": character.id!,
}).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)
//check if token has to be deleted
Promise.all(
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)
if(token.level <= prio+1){
await this.admin.knex('tokens')
await this.admin.knex(raid.tier+'tokens')
.where({
characterid: character.id,
itemname: token.itemname
}).del()
}else{
await this.admin.knex('tokens')
await this.admin.knex(raid.tier+'tokens')
.where({
characterid: character.id,
itemname: token.itemname
+5 -4
View File
@@ -1,4 +1,5 @@
import { Auth, Rank, User, RPCPermission, UserRecord } from "../../Types/Types"
import { Tiers } from "../../Types/Items"
export class IUserManager{
login: (username:string, pwHash:string) => Promise<Auth>
@@ -11,10 +12,10 @@ export class IUserManager{
getUserRecordByToken: (tokenValue: string) => UserRecord | void
getUser: (username: string) => Promise<User | void>
decrementCurrency: (user: User, value: number) => Promise<void>
incrementCurrency: (user: User, value: number) => Promise<void>
setCurrency: (user: User, value: number) => Promise<void>
getCurrency: (user:User) => Promise<number>
decrementCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
incrementCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
setCurrency: (user: User, tier:Tiers, value: number) => Promise<void>
getCurrency: (user:User, tier:Tiers) => Promise<number>
changeRank: (user:User, rank: Rank) => Promise<User>
wipeCurrency: () => Promise<void>
}
+24 -16
View File
@@ -12,6 +12,7 @@ import { IAdmin } from "../../Admin/Interface";
import { IUserManager } from "./Interface";
import { getLogger, Logger } from "log4js";
import { saltedHash } from "../../Util/hash";
import { _Tiers, Tiers } from "../../Types/Items";
const uuid = require('uuid/v4')
@@ -97,8 +98,9 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
table.string("username").notNullable().unique()
table.string("pwhash").notNullable()
table.string("rank").notNullable()
table.string("email").nullable().unique()
table.integer("currency").defaultTo(1)
_Tiers.forEach(tier => {
table.integer(tier).defaultTo(1)
})
}
},{
name: 'rpcpermissions',
@@ -286,8 +288,13 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
}
wipeCurrency = async () => {
await this.admin.knex('users')
.update({currency: 0})
await Promise.all(_Tiers.map(tier => {
const update = {}
update[tier] = 1
return this.admin.knex('users')
.update(update)
}))
}
login = async(username:string, pwHash:string) : Promise<Auth> => {
@@ -405,18 +412,19 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
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
.knex('users')
.where('username', '=', user.username)
.select('*')
.first()
return usr.currency!
return usr[tier]!
}
decrementCurrency = async (user: User, value = 1) => {
if(value < 1) return
decrementCurrency = async (user: User, tier?: Tiers, value = 1) => {
if(!tier || value < 1) return
const usr : User = await this.admin
.knex('users')
@@ -424,28 +432,28 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
.select('*')
.first()
if(!usr || usr.currency! <= 0) return
if(!usr || usr[tier]! <= 0) return
await this.admin
.knex('users')
.where('id', '=', user.id)
.decrement('currency', value)
.decrement(tier, value)
}
incrementCurrency = async (user: User, value = 1) => {
if(value < 1) return
incrementCurrency = async (user: User, tier: Tiers, value = 1) => {
if(!tier || value < 1) return
await this.admin
.knex('users')
.where('id', '=', user.id)
.increment('currency', value)
.increment(tier, value)
}
setCurrency = async (user: User, value: number) => {
if(value < 0) return
setCurrency = async (user: User, tier?:Tiers, value = 0) => {
if(!tier || value < 0) return
await this.admin
.knex('users')
.where('id', '=', user.id)
.update('currency', value)
.update(tier, value)
}
+1 -1
View File
@@ -1,5 +1,5 @@
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 = [
"Robe of Volatile Power",
+2
View File
@@ -94,6 +94,8 @@ export type User = {
pwhash: string
rank: Rank
currency?: number
} & {
[currency in Tiers]? : number
}
export type Raid = {
@@ -10,9 +10,12 @@ import { ShoutMessage } from '../../../../../../backend/Components/Shoutbox/Inte
[type]="text"
[message]="msg.message"
[sender]="msg.sender"
[date]="msg.date">
[date]="msg.date"
[reply]="msg.reply">
</nb-chat-message>
<nb-chat-form (send)="submit($event)" [dropFiles]="false">
<nb-chat-form
(send)="submit($event)"
[dropFiles]="false">
</nb-chat-form>
</nb-chat>
`,
@@ -25,13 +25,7 @@ status="control">
<br/><br />
<span *ngFor="let token of tokens">
[ {{token.level}} ]
<a [ngStyle]="{'color':token.quality=='Epic'?'#a335ee':'#ff8000'}"
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 />
<wowhead [item]="token"></wowhead><br />
</span>
</nb-card-body>
</nb-card>
@@ -3,6 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { ApiService as ApiService } from '../../services/login-api';
import { Spec, User, Character } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers } from '../../../../../../backend/Types/Items';
@Component({
selector: 'character',
@@ -35,7 +36,7 @@ export class FrontcraftCharacterComponent implements OnInit{
if(char){
this.color = getClassColor(char.class)
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
})
}
@@ -38,6 +38,8 @@ import { FrontcraftItemSelectComponent } from './shop/itemselector.component';
import { NgxEchartsModule } from 'ngx-echarts';
import { FrontcraftCharactersComponent } from './characters/characters.component';
import { FrontcraftBuyTokenComponent } from './shop/buytoken.component';
import { FrontcraftItemComponent } from './shop/item.component';
import { FrontcraftWowheadComponent } from './shop/wowhead.component';
@NgModule({
@@ -81,6 +83,8 @@ import { FrontcraftBuyTokenComponent } from './shop/buytoken.component';
FrontcraftRulesComponent,
FrontcraftCreateRaidsComponent,
FrontcraftBuyTokenComponent,
FrontcraftWowheadComponent,
FrontcraftItemComponent
],
entryComponents: [
FrontcraftItemSelectComponent,
@@ -13,6 +13,7 @@ export class FrontcraftArchiveComponent implements OnInit{
canSignup = false
isSignedup = false
canManage = false
isTier = false
mySignup
raid: RaidData = <any>{
@@ -2,7 +2,10 @@
<nb-card-body>
<nb-tabset>
<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>
{{raid.signupcount}} / {{raid.size}} signups
</p>
@@ -167,10 +170,10 @@
</ng-container>
</div>
</nb-tab>
<nb-tab tabTitle="Shop" *ngIf="isSignedup">
<shop (onSelect)="itemSelect($event)"></shop>
<nb-tab tabTitle="Items" *ngIf="isSignedup && isTier">
<shop [tier]="raid.tier" (onSelect)="itemSelect($event)"></shop>
</nb-tab>
<nb-tab tabTitle="Reserves">
<nb-tab tabTitle="Reserves" *ngIf="isTier">
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
<nb-list>
@@ -6,6 +6,7 @@ import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/them
import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
import { getClassColor, SpecT } from '../../../../../../backend/Types/PlayerSpecs';
import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component';
import { allItems } from '../../../../../../backend/Types/Items';
@Component({
selector: 'raid',
@@ -16,6 +17,7 @@ export class FrontcraftRaidComponent implements OnInit{
canSignup = false
isSignedup = false
islate = false
isTier = false
manageRaid
mySignup: (Signup & Character & Spec)
@@ -33,7 +35,8 @@ export class FrontcraftRaidComponent implements OnInit{
},
tanks: [],
healers: [],
tokens:{}
tokens:{},
tier: 'MC'
}
tokens = {}
displayedtokens = {}
@@ -50,6 +53,7 @@ export class FrontcraftRaidComponent implements OnInit{
}
async ngOnInit(){
this.manageRaid = this.api.get('manageRaid')
const signupFeature = this.api.get('signup')
@@ -63,7 +67,9 @@ export class FrontcraftRaidComponent implements OnInit{
this.dialogService.open(FrontcraftBuyTokenComponent, {
context: {
item: item,
signup: this.mySignup
signup: this.mySignup,
tier: this.raid.tier,
characterName: this.mySignup.charactername
}
}).onClose.subscribe(() => this.refresh())
}
@@ -112,9 +118,6 @@ export class FrontcraftRaidComponent implements OnInit{
const signup = this.api.get('signup')
if(!signup) return
console.log("setlate");
await signup.sign(auth.token.value, {
...this.mySignup,
id: this.mySignup.characterid,
@@ -140,6 +143,7 @@ export class FrontcraftRaidComponent implements OnInit{
const raiddata = await raidManager.getRaidData(<any>{
id: param
})
this.isTier = allItems[raiddata.tier] != null
this.raid = raiddata
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-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="number" nbInput [(ngModel)]="size" placeholder="size" fullWidth="true">
<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 { Raid, RaidData } from '../../../../../../backend/Types/Types';
import { NbWindowRef, NbDialogRef } from '@nebular/theme';
import { Tiers, _Tiers } from '../../../../../../backend/Types/Items';
const ONE_MINUTE = 60000
const ONE_HOUR = 60 * ONE_MINUTE
@@ -21,6 +22,8 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
minute = 0
size = 40
description = ""
tier: Tiers = null
tiers = _Tiers
constructor(
protected dialogRef: NbDialogRef<FrontcraftCreateRaidsComponent>,
@@ -37,6 +40,7 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
this.minute = templateDate.getMinutes()
this.description = this.template.description
this.startdate = new Date(parseInt(this.template.start) - templateDate.getHours()*ONE_HOUR - templateDate.getMinutes()*ONE_MINUTE)
this.tier = this.template.tier
}
ngOnInit(){
@@ -49,6 +53,7 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
size: this.size,
start: ""+new Date(this.startdate.getTime() + this.hour*ONE_HOUR + this.minute*ONE_MINUTE).getTime(),
title: this.title,
tier: this.tier
}
const manage = this.api.get('manageRaid')
if(!manage) return
@@ -17,7 +17,7 @@
style="cursor: pointer;">
<div class="row">
<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 class="col-2 vcenter">
@@ -7,15 +7,7 @@
<nb-tab tabTitle="priorities">
<nb-list>
<nb-list-item *ngFor="let item of rules | keyvalue">
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
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 />
<wowhead [item]="item.value[0]"></wowhead><br>
<span *ngFor="let rule of item.value" [nbPopover]="templateRef" nbPopoverTrigger="hover">
<ng-template #templateRef>
<span style="color:white">{{rule.description}}</span>
@@ -15,49 +15,73 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
</nb-card-header>
<nb-card-body>
<p>
You currently have {{currency}} softreserve currency
{{currency}} softreserves remaining
</p>
<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
(click)="buyToken(kv.key)"
(click)="buyToken()"
[disabled]="currency<=0"
nbButton
outline
status="success"
size="tiny">
buy
size="small">
<nb-icon icon="checkmark-outline"></nb-icon> claim
</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>
`,
})
export class FrontcraftBuyTokenComponent implements OnInit{
@Input() characterName: string
@Input() item : Item
@Input() signup : Signup
@Input() tier: Tiers
characters: Character[]
modifier = {}
invalidatedTokens: (SRToken & Character & Item)[] | undefined = []
upgradableToken : (SRToken & Character & Item) | undefined
noToken = false
modifier
currency: number = 0
ownedtokens: SRToken[] = []
constructor(
private toastr: NbToastrService,
@@ -65,38 +89,36 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
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()
this.api.get('CharacterManager')
.getCharactersOfUser(usr.username)
.then(chars => {
chars.forEach(char => {
chars.forEach(async char => {
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 => {
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 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){
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
</button>
&nbsp;
<a target="_blank" [href]="item.url">
<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>
<wowhead [item]="item"></wowhead>
</nb-list-item>
</nb-list>
@@ -1,6 +1,6 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService } from '../../services/login-api';
import { Item } from '../../../../../../backend/Types/Types';
import { Item, Character } from '../../../../../../backend/Types/Types';
@Component({
selector: 'itemselect',
@@ -13,6 +13,7 @@ export class FrontcraftItemSelectComponent implements OnInit{
allItems:Item[] = []
displayedItems: any[]
@Input() character: string
@Input() items: string[]
@Output() onSelect = new EventEmitter<Item>();
@@ -21,6 +22,7 @@ export class FrontcraftItemSelectComponent implements OnInit{
){}
async ngOnInit(){
Promise.all(this.items.map(itemname =>
this.api.get('ItemManager').getItem(itemname)
)).then(items => {
@@ -1,7 +1,5 @@
<h3>
{{tier}} items
</h3>
<itemselect
[character]="character"
[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',
templateUrl: './shop.component.html',
})
export class FrontcraftShopComponent{
export class FrontcraftShopComponent implements OnInit{
@Input() character: Character
@Input() signup: Signup
@@ -22,5 +22,10 @@ export class FrontcraftShopComponent{
constructor(
private api: ApiService,
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>
</nb-card-header>
<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">
<character [name]="char.charactername" [link]="'character'"></character>
</ng-container>
@@ -3,6 +3,7 @@ import { ApiService } from '../../services/login-api';
import { Router, ActivatedRoute } from '@angular/router';
import { User, Spec, Character } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers } from '../../../../../../backend/Types/Items';
@Component({
selector: 'user-component',
@@ -28,7 +29,7 @@ export class FrontcraftUserComponent implements OnInit{
const characters = await this.api.get('CharacterManager').getCharactersOfUser(this.user.username)
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['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',
spec: 'Protection',
rank: 'Officer'
},{
name: 'Silver',
class: 'Druid',
race: 'Night Elf',
spec: 'Restoration',
rank: 'Raider'
},{
name: 'Dagger',
race: 'Dwarf',
@@ -117,7 +123,7 @@ describe('Frontcraft', () => {
const account = await createAccount({
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
rank: acc.rank,
username: acc.name
username: acc.name,
})
const auth = await client.UserManager.login(acc.name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
const id = await client.CharacterManager.getSpecId(acc.class, acc.spec)
@@ -148,7 +154,7 @@ describe('Frontcraft', () => {
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //hash("a")
rank: 'ADMIN',
username: 'a',
currency: 2
MC: 2
}).then(adminUser => {
client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => {
@@ -187,7 +193,8 @@ describe('Frontcraft', () => {
let insertRaid = <Raid>{
description: "Test raid 1",
title: 'MC',
start: Date.now().toString()
start: Date.now().toString(),
tier: 'MC'
}
adminClient.manageRaid.createRaid(insertRaid).then(() => {
@@ -391,6 +398,11 @@ describe('Frontcraft', () => {
{class:'Paladin', specname:'Holy'},
undefined, 2, "crit bias"
),
makePrio(
'Empowered Leggings',
{class:'Druid', specname:'Restoration'},
undefined, 2, "crit bias"
),
makePrio(
'Boots of the Shadow Flame',
@@ -516,7 +528,7 @@ describe('Frontcraft', () => {
const user = Object.values(users)[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 before = await client.ItemManager.getToken(user.character, item)
@@ -538,7 +550,7 @@ describe('Frontcraft', () => {
it('should buy more tokens', (done) => {
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
.buyToken(
user.auth.token.value,
@@ -565,7 +577,7 @@ describe('Frontcraft', () => {
const dbRaids = await client.RaidManager.getRaids()
if(dbRaids.length === 0){
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 => {
if(signups.length === 0){
done()
@@ -586,9 +598,9 @@ describe('Frontcraft', () => {
it('reset system', (done) => {
adminClient.reset.wipeCurrencyAndItems().then(() => {
client.UserManager.getUser(testAccounts[0].name).then(user => {
if(user && user.currency === 0){
client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character).then(tokens => {
if(tokens.length === 0){
if(user && user.MC === 1){
client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character, ['MC']).then(tokens => {
if(tokens!.length === 0){
done()
}else{
console.log(tokens);
@@ -599,6 +611,5 @@ describe('Frontcraft', () => {
}
})
})
})
})