checkpoint
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"frontcraft": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src/backend",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"server": {
|
||||||
|
"builder": "@angular-devkit/build-angular:server",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/server",
|
||||||
|
"main": "src/backend/Launcher.ts",
|
||||||
|
"tsConfig": "tsconfig.server.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "frontcraft"
|
||||||
|
}
|
||||||
Generated
+5581
-388
File diff suppressed because it is too large
Load Diff
+13
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "frontblock-admin",
|
"name": "frontcraft",
|
||||||
"description": "Dynamic configurator for frontblock",
|
"description": "Guild website framework",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tsc": "tsc",
|
"tsc": "tsc",
|
||||||
@@ -9,13 +9,14 @@
|
|||||||
"start-backend": "npm run build-backend && npm run launch",
|
"start-backend": "npm run build-backend && npm run launch",
|
||||||
"test": "rm -rf data && npm run build-backend && mocha lib/test/backendTest.js",
|
"test": "rm -rf data && npm run build-backend && mocha lib/test/backendTest.js",
|
||||||
"build": "npm run build-backend && npm run build-frontend",
|
"build": "npm run build-backend && npm run build-frontend",
|
||||||
"build-backend": "npm run clean-backend && tsc",
|
"build-backend": "npm run clean-backend && ng v && ng run frontcraft:server",
|
||||||
"build-frontend": "npm run clean-frontend && (mkdir static || rm -rf static/*) && npm run build-dashboard",
|
"build-frontend": "npm run clean-frontend && (mkdir static || rm -rf static/*) && npm run build-dashboard",
|
||||||
"build-dashboard": "cd src/frontend && npm i && npm run build && cp -r dist/* ../../static",
|
"build-dashboard": "cd src/frontend && npm i && npm run build && cp -r dist/* ../../static",
|
||||||
"clean": "rm -rf data && npm run clean-backend && npm run clean-frontend",
|
"clean": "rm -rf data && npm run clean-backend && npm run clean-frontend",
|
||||||
"clean-backend": "rm -rf lib plugins config widget .rpt2_cache *.js *.ts",
|
"clean-backend": "rm -rf lib plugins config widget .rpt2_cache *.js *.ts",
|
||||||
"clean-frontend": "rm -rf src/frontend/dist static",
|
"clean-frontend": "rm -rf src/frontend/dist static",
|
||||||
"webpack": "webpack --config src/backend/webpack.prod.js --progress --colors"
|
"webpack": "webpack --config src/backend/webpack.prod.js --progress --colors",
|
||||||
|
"setangular": "ng update @angular/cli@8.2.2 @angular/core@8.2.2 @angular/compiler-cli@8.2.2"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -24,7 +25,14 @@
|
|||||||
"author": "frontblock.me",
|
"author": "frontblock.me",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular-devkit/build-angular": "^0.900.5",
|
||||||
|
"@angular/compiler": "^9.0.5",
|
||||||
|
"@angular/compiler-cli": "^9.0.5",
|
||||||
|
"@angular/platform-server": "^9.0.5",
|
||||||
|
"@nguniversal/express-engine": "^9.0.1",
|
||||||
|
"@nguniversal/module-map-ngfactory-loader": "^8.2.6",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
|
"angular": "^1.7.9",
|
||||||
"bsert": "0.0.10",
|
"bsert": "0.0.10",
|
||||||
"bsock": "^0.1.9",
|
"bsock": "^0.1.9",
|
||||||
"child-process-promise": "^2.2.1",
|
"child-process-promise": "^2.2.1",
|
||||||
@@ -56,6 +64,7 @@
|
|||||||
"xml2js": "^0.4.22"
|
"xml2js": "^0.4.22"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@angular/cli": "^9.0.5",
|
||||||
"@types/express": "^4.17.0",
|
"@types/express": "^4.17.0",
|
||||||
"@types/node": "^11.13.19",
|
"@types/node": "^11.13.19",
|
||||||
"@types/semver": "^6.0.1",
|
"@types/semver": "^6.0.1",
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ import { Injector } from '../Injector/Injector';
|
|||||||
import { Shoutbox } from '../Components/Shoutbox/Shoutbox';
|
import { Shoutbox } from '../Components/Shoutbox/Shoutbox';
|
||||||
import { PubSub } from '../Components/PubSub/PubSub';
|
import { PubSub } from '../Components/PubSub/PubSub';
|
||||||
|
|
||||||
|
import { ngExpressEngine } from '@nguniversal/express-engine';
|
||||||
|
import { APP_BASE_HREF } from '@angular/common';
|
||||||
|
import { AppServerModule } from './app.server.module';
|
||||||
|
|
||||||
|
|
||||||
const logger = getLogger("admin", 'debug')
|
const logger = getLogger("admin", 'debug')
|
||||||
|
|
||||||
@@ -132,6 +136,24 @@ implements TableDefinitionExporter, IAdmin {
|
|||||||
this.express = express()
|
this.express = express()
|
||||||
this.express.use('/', express.static('static'))
|
this.express.use('/', express.static('static'))
|
||||||
|
|
||||||
|
|
||||||
|
this.express.engine('html', ngExpressEngine({
|
||||||
|
bootstrap: AppServerModule,
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.express.set('view engine', 'html');
|
||||||
|
this.express.set('views', 'static');
|
||||||
|
|
||||||
|
// Serve static files from /browser
|
||||||
|
this.express.get('*.*', express.static('static', {
|
||||||
|
maxAge: '1y'
|
||||||
|
}));
|
||||||
|
|
||||||
|
// All regular routes use the Universal engine
|
||||||
|
this.express.get('*', (req, res) => {
|
||||||
|
res.render('index', { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the compiled FrontendPlugins.js
|
* get the compiled FrontendPlugins.js
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { ServerModule } from '@angular/platform-server';
|
||||||
|
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
|
||||||
|
|
||||||
|
import { AppModule } from '../../frontend/src/app/app.module';
|
||||||
|
import { AppComponent } from '../../frontend/src/app/app.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
AppModule,
|
||||||
|
ServerModule,
|
||||||
|
ModuleMapLoaderModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
// Add universal-only providers here
|
||||||
|
],
|
||||||
|
bootstrap: [ AppComponent ],
|
||||||
|
})
|
||||||
|
export class AppServerModule {}
|
||||||
@@ -2,15 +2,11 @@ import { ConfigLoader } from "loadson";
|
|||||||
import { Inject, Injectable } from "../../Injector/ServiceDecorator";
|
import { Inject, Injectable } from "../../Injector/ServiceDecorator";
|
||||||
import { GuildManagerFeatureIfc, GuildManagerIfc } from "./RPCInterface";
|
import { GuildManagerFeatureIfc, GuildManagerIfc } from "./RPCInterface";
|
||||||
import { FrontworkComponent } from "../../Types/FrontworkComponent";
|
import { FrontworkComponent } from "../../Types/FrontworkComponent";
|
||||||
import { _Rank, Rank } from "../../Types/Types";
|
import { _Rank, Rank, Guild } from "../../Types/Types";
|
||||||
import { IAdmin } from "../../Admin/Interface";
|
import { IAdmin } from "../../Admin/Interface";
|
||||||
import { IGuildManager } from "./Interface";
|
import { IGuildManager } from "./Interface";
|
||||||
|
|
||||||
export type Guild = {
|
|
||||||
name: string
|
|
||||||
realm: string
|
|
||||||
description: string
|
|
||||||
};
|
|
||||||
|
|
||||||
@Injectable(IGuildManager)
|
@Injectable(IGuildManager)
|
||||||
export class GuildManager
|
export class GuildManager
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Rank } from "../../Types/Types"
|
import { Rank, Guild } from "../../Types/Types"
|
||||||
import { Guild } from "./GuildManager"
|
|
||||||
|
|
||||||
export class IGuildManager{
|
export class IGuildManager{
|
||||||
getHeadCount: () => Promise<{rank:Rank, count: number}[]>
|
getHeadCount: () => Promise<{rank:Rank, count: number}[]>
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { Tiers } from "../../Types/Items"
|
|||||||
|
|
||||||
export class IItemManager{
|
export class IItemManager{
|
||||||
getItems: () => Promise<Item[]>
|
getItems: () => Promise<Item[]>
|
||||||
fetchItem: (name:string) => Promise<Item>
|
getItem: (name:string, tier?:Tiers) => Promise<Item | undefined>
|
||||||
|
fetchItem: (name:string, tier?:Tiers) => Promise<Item | undefined>
|
||||||
buyToken: (usertoken: string, charactername:string, itemname:string, signup:Signup) => Promise<(SRToken & Character & Item) | undefined>
|
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>
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ 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";
|
||||||
import { TableDefinitionExporter } from "../../Types/Interfaces";
|
import { TableDefinitionExporter } from "../../Types/Interfaces";
|
||||||
import { TableDefiniton, Item, User, Character, SRToken, SRPriority, Spec, Signup, Raid } from "../../Types/Types";
|
import { TableDefiniton, Item, User, Character, SRToken, SRPriority, Spec, Signup, Raid, Stats } from "../../Types/Types";
|
||||||
import { IAdmin } from "../../Admin/Interface";
|
import { IAdmin } from "../../Admin/Interface";
|
||||||
import { IItemManager } from "./Interface";
|
import { IItemManager } from "./Interface";
|
||||||
import { getLogger } from "log4js";
|
|
||||||
import { IUserManager } from "../User/Interface";
|
import { IUserManager } from "../User/Interface";
|
||||||
import { ICharacterManager } from "../Character/Interface";
|
import { ICharacterManager } from "../Character/Interface";
|
||||||
import { IPubSub } from "../PubSub/Interface";
|
import { IPubSub } from "../PubSub/Interface";
|
||||||
import { IRaidManager } from "../Raid/Interface";
|
import { IRaidManager } from "../Raid/Interface";
|
||||||
|
import { getLogger } from "frontblock-generic/Types";
|
||||||
|
|
||||||
const fetch = require('node-fetch')
|
const fetch = require('node-fetch')
|
||||||
const xml2js = require('xml2js');
|
const xml2js = require('xml2js');
|
||||||
@@ -60,13 +60,13 @@ export class ItemManager
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
notifyRaid = async (raid: Raid | { id: number }) => {
|
notifyRaid = async (raid: Raid | { id: number }) => {
|
||||||
const data = await this.raidManager.getRaidData(<Raid>raid)
|
|
||||||
this.pubsub.publish("" + raid.id, data)
|
|
||||||
await this.notifyRaids()
|
await this.notifyRaids()
|
||||||
|
const data = await this.raidManager.getRaidData(<Raid>raid)
|
||||||
|
await this.pubsub.publish("" + raid.id, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyRaids = async () => {
|
notifyRaids = async () => {
|
||||||
this.pubsub.publish('raids', undefined)
|
await this.pubsub.publish('raids', undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
wipeCurrencyAndItems = async () => {
|
wipeCurrencyAndItems = async () => {
|
||||||
@@ -78,26 +78,58 @@ export class ItemManager
|
|||||||
|
|
||||||
getItems = async (): Promise<Item[]> => await this.admin.knex.select('*').from('items')
|
getItems = async (): Promise<Item[]> => await this.admin.knex.select('*').from('items')
|
||||||
|
|
||||||
getItem = async (name: string): Promise<Item> => {
|
getItem = async (name: string, tier?:Tiers): Promise<Item | undefined> => {
|
||||||
return await this.admin.knex('items').select('*').where('itemname', '=', name).first()
|
let item = await this.admin.knex('items').select('*').where('itemname', '=', name).first()
|
||||||
|
if(!item){
|
||||||
|
item = await this.fetchItem(name, tier)
|
||||||
|
if (!item)
|
||||||
|
return
|
||||||
|
|
||||||
|
await this.admin
|
||||||
|
.knex('items')
|
||||||
|
.insert({
|
||||||
|
...item,
|
||||||
|
stats: JSON.stringify(item.stats)
|
||||||
|
})
|
||||||
|
|
||||||
|
return this.getItem(name, tier)
|
||||||
|
}
|
||||||
|
|
||||||
|
item.stats = JSON.parse(item.stats)
|
||||||
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchItem = async (name: string): Promise<Item> => {
|
fetchItem = async (name: string, tier?:Tiers): Promise<Item | undefined> => {
|
||||||
const res = await fetch('https://classic.wowhead.com/item=' + name + '&xml');
|
const res = await fetch('https://classic.wowhead.com/item=' + name + '&xml');
|
||||||
const txt = await res.text();
|
const txt = await res.text();
|
||||||
const r = await parser.parseStringPromise(txt);
|
const r = await parser.parseStringPromise(txt);
|
||||||
|
try{
|
||||||
|
if(!r.wowhead.item || !r.wowhead.item[0])
|
||||||
|
return
|
||||||
|
|
||||||
try {
|
const j = JSON.parse('{'+r.wowhead.item[0].json[0]+"}")
|
||||||
return <Item>{
|
if(!tier){
|
||||||
|
if(j.sourcemore && Number.isInteger(j.sourcemore[0].t) && j.sourcemore[0].t > 0){
|
||||||
|
tier = _Tiers[j.sourcemore[0].t-1]
|
||||||
|
}else{
|
||||||
|
tier = "MC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const stats = JSON.parse('{'+r.wowhead.item[0].jsonEquip[0]+"}")
|
||||||
|
|
||||||
|
const item = <Item>{
|
||||||
itemname: r.wowhead.item[0].name[0],
|
itemname: r.wowhead.item[0].name[0],
|
||||||
iconname: r.wowhead.item[0].icon[0]._,
|
iconname: r.wowhead.item[0].icon[0]._,
|
||||||
url: r.wowhead.item[0].link[0],
|
url: r.wowhead.item[0].link[0],
|
||||||
quality: r.wowhead.item[0].quality[0]._,
|
quality: r.wowhead.item[0].quality[0]._,
|
||||||
tooltip: r.wowhead.item[0].htmlTooltip[0]
|
tooltip: r.wowhead.item[0].htmlTooltip[0],
|
||||||
|
stats: toStats(stats),
|
||||||
|
tier: tier
|
||||||
}
|
}
|
||||||
} catch (e) {
|
return item
|
||||||
console.log(name)
|
|
||||||
throw e
|
}catch(e){
|
||||||
|
getLogger('ItemManager', 'error').error(name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +171,7 @@ export class ItemManager
|
|||||||
table.boolean('hidden').defaultTo(false).notNullable()
|
table.boolean('hidden').defaultTo(false).notNullable()
|
||||||
table.string('tooltip').notNullable()
|
table.string('tooltip').notNullable()
|
||||||
table.enu('tier', _Tiers).notNullable()
|
table.enu('tier', _Tiers).notNullable()
|
||||||
|
table.json('stats').notNullable()
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
@@ -249,7 +282,7 @@ export class ItemManager
|
|||||||
await this.admin
|
await this.admin
|
||||||
.knex('priorities')
|
.knex('priorities')
|
||||||
.insert(<SRPriority>{
|
.insert(<SRPriority>{
|
||||||
itemname: item.itemname,
|
itemname: item!.itemname,
|
||||||
...priority
|
...priority
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -354,19 +387,55 @@ export class ItemManager
|
|||||||
if (countCache != Object.values(itemTiers).flat().length) {
|
if (countCache != Object.values(itemTiers).flat().length) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.entries(itemTiers)
|
Object.entries(itemTiers)
|
||||||
.map((kv) => Promise.all(
|
.map((kv: [string, string[]]) => Promise.all(
|
||||||
kv[1].map(i => this.fetchItem(i)
|
kv[1].map(i => this.getItem(i, kv[0] as Tiers) )
|
||||||
.then(item =>
|
|
||||||
this.admin
|
|
||||||
.knex('items')
|
|
||||||
.insert({
|
|
||||||
tier: kv[0],
|
|
||||||
...item
|
|
||||||
}).catch(() => { })
|
|
||||||
)
|
|
||||||
)
|
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toStats(obj:any){
|
||||||
|
if(!obj) obj = {}
|
||||||
|
return {
|
||||||
|
stamina: obj.sta || 0,
|
||||||
|
agility: obj.agi || 0,
|
||||||
|
strength: obj.str || 0,
|
||||||
|
intellect: obj.int || 0,
|
||||||
|
spirit: obj.spi || 0,
|
||||||
|
|
||||||
|
attackpower: obj.atkpwr || 0,
|
||||||
|
|
||||||
|
meleehit: obj.mlehitpct || 0,
|
||||||
|
meleecrit: obj.mlecritstrkpct || 0,
|
||||||
|
|
||||||
|
rangeattackpower: obj.rgdatkpwr || 0,
|
||||||
|
rangehit: obj.rgdhitpct || 0,
|
||||||
|
rangecrit: obj.rgdcritstrkpct || 0,
|
||||||
|
|
||||||
|
spellpower: obj.splpwr || 0,
|
||||||
|
spellhit: obj.splhitpct || 0,
|
||||||
|
spellcrit: obj.splcritstrkpct || 0,
|
||||||
|
heal: obj.splheal || 0,
|
||||||
|
|
||||||
|
frostspellpower: obj.frosplpwr || 0,
|
||||||
|
firespellpower: obj.firsplpwr || 0,
|
||||||
|
naturespellpower: obj.natsplpwr || 0,
|
||||||
|
shadowspellpower: obj.shasplpwr || 0,
|
||||||
|
arcanespellpower: obj.arcsplpwr || 0,
|
||||||
|
|
||||||
|
fireresist: obj.firres || 0,
|
||||||
|
arcaneresist: obj.arcres || 0,
|
||||||
|
frostresist: obj.frores || 0,
|
||||||
|
natureresist: obj.natres || 0,
|
||||||
|
shadowresist: obj.shares || 0,
|
||||||
|
|
||||||
|
armor: obj.armor || 0,
|
||||||
|
defense: obj.def || 0,
|
||||||
|
block: obj.blockpct || 0,
|
||||||
|
blockvalue: obj.blockamount || 0,
|
||||||
|
dodge: obj.dodgepct || 0,
|
||||||
|
parry: obj.parrypct || 0,
|
||||||
|
} as Stats
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import { IItemManager } from "./Interface"
|
|||||||
|
|
||||||
export type ItemManagerIfc = {
|
export type ItemManagerIfc = {
|
||||||
ItemManager: {
|
ItemManager: {
|
||||||
getItem: IItemManager['fetchItem']
|
getItem: IItemManager['getItem']
|
||||||
getItems: IItemManager['getItems']
|
getItems: IItemManager['getItems']
|
||||||
buyToken: IItemManager['buyToken']
|
buyToken: IItemManager['buyToken']
|
||||||
calculatePriorities: IItemManager['calculatePriorities']
|
calculatePriorities: IItemManager['calculatePriorities']
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ export const T1 = [
|
|||||||
"Cenarion Bracers",
|
"Cenarion Bracers",
|
||||||
"Cenarion Vestments",
|
"Cenarion Vestments",
|
||||||
"Cenarion Helm",
|
"Cenarion Helm",
|
||||||
"Cenarion Helm",
|
|
||||||
"Cenarion Leggings",
|
"Cenarion Leggings",
|
||||||
"Cenarion Spaulders",
|
"Cenarion Spaulders",
|
||||||
"Giantstalker's Belt",
|
"Giantstalker's Belt",
|
||||||
@@ -106,7 +105,6 @@ export const T1 = [
|
|||||||
"Robes of Prophecy",
|
"Robes of Prophecy",
|
||||||
"Vambraces of Prophecy",
|
"Vambraces of Prophecy",
|
||||||
"Nightslayer Belt",
|
"Nightslayer Belt",
|
||||||
"Nightslayer Belt",
|
|
||||||
"Nightslayer Bracelets",
|
"Nightslayer Bracelets",
|
||||||
"Nightslayer Chestpiece",
|
"Nightslayer Chestpiece",
|
||||||
"Nightslayer Cover",
|
"Nightslayer Cover",
|
||||||
@@ -120,7 +118,6 @@ export const T1 = [
|
|||||||
"Felheart Robes",
|
"Felheart Robes",
|
||||||
"Felheart Shoulder Pads",
|
"Felheart Shoulder Pads",
|
||||||
"Felheart Horns",
|
"Felheart Horns",
|
||||||
"Felheart Horns",
|
|
||||||
"Belt of Might",
|
"Belt of Might",
|
||||||
"Bracers of Might",
|
"Bracers of Might",
|
||||||
"Breastplate of Might",
|
"Breastplate of Might",
|
||||||
@@ -150,7 +147,6 @@ export const T1 = [
|
|||||||
"Bloodfang Hood",
|
"Bloodfang Hood",
|
||||||
"Bloodfang Pants",
|
"Bloodfang Pants",
|
||||||
"Helmet of Ten Storms",
|
"Helmet of Ten Storms",
|
||||||
"Helmet of Ten Storms",
|
|
||||||
"Nemesis Skullcap",
|
"Nemesis Skullcap",
|
||||||
"Nemesis Leggings",
|
"Nemesis Leggings",
|
||||||
"Helm of Wrath",
|
"Helm of Wrath",
|
||||||
|
|||||||
@@ -81,6 +81,53 @@ export type SRPriority = {
|
|||||||
modifier:number
|
modifier:number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Stats = {
|
||||||
|
stamina: number,
|
||||||
|
agility: number,
|
||||||
|
strength: number,
|
||||||
|
intellect: number,
|
||||||
|
spirit: number,
|
||||||
|
|
||||||
|
fireresist: number,
|
||||||
|
frostresist: number,
|
||||||
|
arcaneresist: number,
|
||||||
|
shadowresist: number,
|
||||||
|
natureresist: number,
|
||||||
|
|
||||||
|
spellpower: number,
|
||||||
|
spellhit: number,
|
||||||
|
spellcrit: number,
|
||||||
|
heal: number,
|
||||||
|
|
||||||
|
frostspellpower: number,
|
||||||
|
firespellpower: number,
|
||||||
|
naturespellpower: number,
|
||||||
|
shadowspellpower: number,
|
||||||
|
arcanespellpower: number,
|
||||||
|
|
||||||
|
attackpower: number,
|
||||||
|
|
||||||
|
meleehit: number,
|
||||||
|
meleecrit: number,
|
||||||
|
|
||||||
|
rangeattackpower: number,
|
||||||
|
rangehit: number,
|
||||||
|
rangecrit: number,
|
||||||
|
|
||||||
|
armor:number,
|
||||||
|
defense: number,
|
||||||
|
block: number,
|
||||||
|
blockvalue: number,
|
||||||
|
parry: number,
|
||||||
|
dodge:number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Guild = {
|
||||||
|
name: string
|
||||||
|
realm: string
|
||||||
|
description: string
|
||||||
|
};
|
||||||
|
|
||||||
export type Item = {
|
export type Item = {
|
||||||
itemname:string
|
itemname:string
|
||||||
iconname:string
|
iconname:string
|
||||||
@@ -89,6 +136,7 @@ export type Item = {
|
|||||||
hidden:boolean
|
hidden:boolean
|
||||||
tooltip: string
|
tooltip: string
|
||||||
tier: Tiers
|
tier: Tiers
|
||||||
|
stats: Stats
|
||||||
}
|
}
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"conventional-changelog": "conventional-changelog",
|
"conventional-changelog": "conventional-changelog",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build --aot",
|
||||||
"build:prod": "npm run build -- --prod --aot",
|
"build:prod": "npm run build -- --prod --aot",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"test:coverage": "rimraf coverage && npm run test -- --code-coverage",
|
"test:coverage": "rimraf coverage && npm run test -- --code-coverage",
|
||||||
|
|||||||
@@ -31,8 +31,7 @@
|
|||||||
<nb-action class="user-action">
|
<nb-action class="user-action">
|
||||||
<nb-user [nbContextMenu]="userMenu"
|
<nb-user [nbContextMenu]="userMenu"
|
||||||
[onlyPicture]="false"
|
[onlyPicture]="false"
|
||||||
[name]="user?.username"
|
[name]="user?.username">
|
||||||
[picture]="user?.picture">
|
|
||||||
</nb-user>
|
</nb-user>
|
||||||
</nb-action>
|
</nb-action>
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export class RegisterComponent implements OnInit{
|
|||||||
selectedSpec = specs[this.selectedClass][0]
|
selectedSpec = specs[this.selectedClass][0]
|
||||||
specs = specs[this.selectedClass]
|
specs = specs[this.selectedClass]
|
||||||
showApplication = false
|
showApplication = false
|
||||||
|
submitted = false
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router : Router,
|
private router : Router,
|
||||||
|
|||||||
@@ -1,90 +1,106 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Item } from '../../../../../../backend/Types/Types';
|
import { Item, Stats } from '../../../../../../backend/Types/Types';
|
||||||
|
|
||||||
import { NbToastrService } from '@nebular/theme';
|
import { NbToastrService } from '@nebular/theme';
|
||||||
|
import { ApiService } from '../../services/login-api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'armory',
|
selector: 'armory',
|
||||||
templateUrl: './armory.component.html',
|
templateUrl: './armory.component.html',
|
||||||
})
|
})
|
||||||
export class FrontcraftArmoryComponent implements OnInit{
|
export class FrontcraftArmoryComponent implements OnInit {
|
||||||
|
|
||||||
servers = servers
|
servers = servers
|
||||||
|
submitted = false
|
||||||
charactername = ""
|
charactername = ""
|
||||||
server = "Gandling"
|
server = "Gandling"
|
||||||
region = "EU"
|
region = "EU"
|
||||||
gear:string[] = []
|
gear: Item[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private api: ApiService,
|
||||||
private toastr: NbToastrService
|
private toastr: NbToastrService
|
||||||
){}
|
) { }
|
||||||
|
|
||||||
async submit(){
|
async submit() {
|
||||||
const dataLink = "https://classic.warcraftlogs.com:443/v1/parses/character/"+this.charactername.toLowerCase().replace(/^\w/, c => c.toUpperCase())+"/"+this.server+"/"+this.region+"?api_key=c698515ab4f592cdb848d80b3abe616c&metric=dps"
|
const dataLink = "https://classic.warcraftlogs.com:443/v1/parses/character/" + this.charactername.toLowerCase().replace(/^\w/, c => c.toUpperCase()) + "/" + this.server + "/" + this.region + "?api_key=c698515ab4f592cdb848d80b3abe616c&metric=dps"
|
||||||
|
|
||||||
fetch(dataLink).then(raw => raw.json().then((json:any[]) => {
|
fetch(dataLink).then(raw => raw.json().then(async (json: any[]) => {
|
||||||
if(json.length < 1) return
|
if (json.length < 1) return
|
||||||
let min = -1
|
let min = -1
|
||||||
let data
|
let data
|
||||||
|
|
||||||
for(let i = json.length-1; i > 0; i--){
|
for (let i = json.length - 1; i > 0; i--) {
|
||||||
if(json[i].startTime > min && json[i].gear[0].name != "Unknown Item"){
|
if (json[i].startTime > min && json[i].gear[0].name != "Unknown Item") {
|
||||||
data = json[i]
|
data = json[i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!data){
|
if (!data) {
|
||||||
this.toastr.danger('Unknown character, or no warcraftlogs', "Error", {
|
this.toastr.danger('Unknown character, or no warcraftlogs', "Error", {
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gear = data.gear.map(item => {return <Item>{
|
const maybeItems: (Item | undefined)[] = await Promise.all(data.gear
|
||||||
itemname: item.name,
|
.filter(item => item.name != "Unknown Item")
|
||||||
iconname: item.icon.replace('.jpg', ''),
|
.map(async item => await this.api.get('ItemManager').getItem(item.name)))
|
||||||
quality: item.quality.replace(/^\w/, c => c.toUpperCase()),
|
|
||||||
url: "https://classic.wowhead.com/item="+item.id,
|
const geardata = maybeItems.filter(maybeItem => maybeItem != null)
|
||||||
}}).filter(item => item.itemname != "Unknown Item")
|
|
||||||
|
this.gear = geardata
|
||||||
|
console.log(this.gear.map(g => g.stats).reduce(sumStats))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(){
|
async ngOnInit() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sumStats(stat1: Stats, stat2: Stats):Stats{
|
||||||
|
const ret = {} as any
|
||||||
|
Object.keys(stat1).forEach(key => {
|
||||||
|
ret[key] = stat1[key] + stat2[key]
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const servers = [
|
const servers = [
|
||||||
"Ashbringer"
|
"Ashbringer"
|
||||||
,"Bloodfang"
|
, "Bloodfang"
|
||||||
,"Dreadmist"
|
, "Dreadmist"
|
||||||
,"Firemaw"
|
, "Firemaw"
|
||||||
,"Flamelash"
|
, "Flamelash"
|
||||||
,"Gandling"
|
, "Gandling"
|
||||||
,"Gehennas"
|
, "Gehennas"
|
||||||
,"Golemagg"
|
, "Golemagg"
|
||||||
,"Hydraxian Waterlords"
|
, "Hydraxian Waterlords"
|
||||||
,"Judgement"
|
, "Judgement"
|
||||||
,"Mirage Rach"
|
, "Mirage Rach"
|
||||||
,"Mograine"
|
, "Mograine"
|
||||||
,"Nethergarde"
|
, "Nethergarde"
|
||||||
,"Noggenfogg"
|
, "Noggenfogg"
|
||||||
,"Pyrewood Village"
|
, "Pyrewood Village"
|
||||||
,"Razorgore"
|
, "Razorgore"
|
||||||
,"Shazzrah"
|
, "Shazzrah"
|
||||||
,"Skullflame"
|
, "Skullflame"
|
||||||
,"Stonespine"
|
, "Stonespine"
|
||||||
,"Ten Storms"
|
, "Ten Storms"
|
||||||
,"Zandalar Tribe"
|
, "Zandalar Tribe"
|
||||||
,"Amnennar"
|
, "Amnennar"
|
||||||
,"Auberdine"
|
, "Auberdine"
|
||||||
,"Finkle"
|
, "Finkle"
|
||||||
,"Sulfuron"
|
, "Sulfuron"
|
||||||
,"Everlook"
|
, "Everlook"
|
||||||
,"Lucifron"
|
, "Lucifron"
|
||||||
,"Razorfen"
|
, "Razorfen"
|
||||||
,"Patchwerk"
|
, "Patchwerk"
|
||||||
,"Venoxis"
|
, "Venoxis"
|
||||||
,"Dragon’s Call"
|
, "Dragon’s Call"
|
||||||
,"Lakeshire"
|
, "Lakeshire"
|
||||||
,"Transcendence"
|
, "Transcendence"
|
||||||
]
|
]
|
||||||
@@ -24,7 +24,7 @@ export class FrontcraftCharacterComponent implements OnInit{
|
|||||||
boss1 = {}
|
boss1 = {}
|
||||||
gear1:string[] = []
|
gear1:string[] = []
|
||||||
|
|
||||||
boss2= {}
|
boss2= {name: undefined, date:undefined}
|
||||||
gear2:string[] = []
|
gear2:string[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
|||||||
})
|
})
|
||||||
export class FrontcraftArchiveComponent implements OnInit{
|
export class FrontcraftArchiveComponent implements OnInit{
|
||||||
|
|
||||||
|
manageRaid = false
|
||||||
canSignup = false
|
canSignup = false
|
||||||
isSignedup = false
|
isSignedup = false
|
||||||
canManage = false
|
canManage = false
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-xl-6">
|
<div class="col-12 col-xl-6">
|
||||||
<nb-card [size]="giant">
|
<nb-card [size]="'giant'">
|
||||||
<nb-card-body>
|
<nb-card-body>
|
||||||
<nb-tabset>
|
<nb-tabset>
|
||||||
<nb-tab tabTitle="Info">
|
<nb-tab tabTitle="Info">
|
||||||
|
|||||||
+4
-16
@@ -3,7 +3,7 @@ import { FrontworkAdmin } from "../src/backend/Admin/Admin";
|
|||||||
import { T1, T2, Tiers } from "../src/backend/Types/Items";
|
import { T1, T2, Tiers } from "../src/backend/Types/Items";
|
||||||
|
|
||||||
import { RPCSocket } from "rpclibrary";
|
import { RPCSocket } from "rpclibrary";
|
||||||
import { FrontcraftIfc, Auth, User, FrontcraftFeatureIfc, Raid, Character, Rank, Class, Race, SRPriority, Spec, Signup } from "../src/backend/Types/Types";
|
import { FrontcraftIfc, Auth, User, FrontcraftFeatureIfc, Raid, Character, Rank, Class, Race, Spec, Signup } from "../src/backend/Types/Types";
|
||||||
import { SpecT } from "../src/backend/Types/PlayerSpecs";
|
import { SpecT } from "../src/backend/Types/PlayerSpecs";
|
||||||
|
|
||||||
|
|
||||||
@@ -129,18 +129,6 @@ describe('Frontcraft', () => {
|
|||||||
return client.UserManager.createUser(user)
|
return client.UserManager.createUser(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
const login = async (name: string) : Promise<Auth> => {
|
|
||||||
const auth = await client.UserManager.login(name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
|
|
||||||
|
|
||||||
if(users[name]) users[name] = {
|
|
||||||
...users[name],
|
|
||||||
auth: auth
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return auth
|
|
||||||
}
|
|
||||||
|
|
||||||
const createAccountAndUser = async (acc: protoAccount) => {
|
const createAccountAndUser = async (acc: protoAccount) => {
|
||||||
const account = await createAccount({
|
const account = await createAccount({
|
||||||
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
|
pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
|
||||||
@@ -573,8 +561,8 @@ describe('Frontcraft', () => {
|
|||||||
const user = Object.values(users)[0]
|
const user = Object.values(users)[0]
|
||||||
const itemname = "Maladath, Runed Blade of the Black Flight"
|
const itemname = "Maladath, Runed Blade of the Black Flight"
|
||||||
client.ItemManager.getItem(itemname).then(async item => {
|
client.ItemManager.getItem(itemname).then(async item => {
|
||||||
await adminClient.softreserveCurrency.incrementCurrency(user.account, item.tier, 2)
|
await adminClient.softreserveCurrency.incrementCurrency(user.account, item!.tier, 2)
|
||||||
const before = await client.ItemManager.getToken(user.character, item)
|
const before = await client.ItemManager.getToken(user.character, item!)
|
||||||
|
|
||||||
if (!before || before.level !== 4) {
|
if (!before || before.level !== 4) {
|
||||||
console.log("expected level to be 4", before ? before.level : '?');
|
console.log("expected level to be 4", before ? before.level : '?');
|
||||||
@@ -690,7 +678,7 @@ describe('Frontcraft', () => {
|
|||||||
let streaks = await client.ItemManager.getTokens(user.character, [BWL0.tier], false)
|
let streaks = await client.ItemManager.getTokens(user.character, [BWL0.tier], false)
|
||||||
if (reserves!.length != 1
|
if (reserves!.length != 1
|
||||||
|| streaks!.length != 0
|
|| streaks!.length != 0
|
||||||
|| reserves![0].itemname !== T2_0.itemname
|
|| reserves![0].itemname !== T2_0!.itemname
|
||||||
|| reserves![0].level !== 1) {
|
|| reserves![0].level !== 1) {
|
||||||
console.log("Bad Token status 1", reserves, streaks);
|
console.log("Bad Token status 1", reserves, streaks);
|
||||||
done(new Error("Bad Token status"))
|
done(new Error("Bad Token status"))
|
||||||
|
|||||||
+3
-4
@@ -3,13 +3,12 @@
|
|||||||
"strictPropertyInitialization": false,
|
"strictPropertyInitialization": false,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"target": "ESnext",
|
"target": "ESnext",
|
||||||
"module": "commonjs",
|
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "./lib",
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true
|
"emitDecoratorMetadata": true
|
||||||
},
|
},
|
||||||
"include": ["src/backend/**/*", "test/**/*"],
|
"angularCompilerOptions": {
|
||||||
"exclude": ["node_modules", "**/__tests__/*"]
|
"entryModule": "./src/backend/Admin/app.server.module#AppServerModule"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./lib",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"include": ["src/backend/**/*", "test/**/*"],
|
||||||
|
"exclude": ["node_modules", "**/__tests__/*"],
|
||||||
|
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"entryModule": "./src/app/app.server.module#AppServerModule"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user