Skip to content

Commit

Permalink
Feature/193 WG API to Proxy + Refactor Room State + Implement basic A…
Browse files Browse the repository at this point in the history
…uthentication + Implement premature code for Socket.io (#196)

* WIP

* #193 - Migrate from WG API to Proxy + update Room state

* Remove console logs for authentication
  • Loading branch information
bryansamuel1 authored May 1, 2020
1 parent c939f88 commit 66ac79f
Show file tree
Hide file tree
Showing 27 changed files with 779 additions and 346 deletions.
10 changes: 6 additions & 4 deletions .env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
NODE_ENV=development
VUE_APP_MS_SOCK=localhost:4000
VUE_APP_MS_AUTH=https://auth.eu.gametactic.eu
VUE_APP_MS_MAPS=https://maps.eu.gametactic.eu
VUE_APP_MS_USER=https://user.eu.gametactic.eu
VUE_APP_MS_SOCK=https://socket.gametactic.eu
# VUE_APP_MS_SOCK=http://localhost:3000
VUE_APP_MS_AUTH=https://authentication.gametactic.eu
VUE_APP_MS_MAPS=https://maps.gametactic.eu
VUE_APP_MS_USER=https://user.gametactic.eu
VUE_APP_MS_WG_API=https://wg-api.gametactic.eu
VUE_APP_ROOM_PRIMARY_COLOUR=#004e8c
VUE_APP_DEFAULT_LOCALE=en
VUE_APP_LOCALE=en
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-this-alias": "off",
semi: ["error", "never"]
},
parser: "vue-eslint-parser",
Expand Down
59 changes: 35 additions & 24 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,51 @@
<script lang="ts">
import Component from 'vue-class-component'
import Vue from 'vue'
import { Action } from 'vuex-class'
import { RoomAction, Game, Locale, GameName, Ship } from '@/store/modules/room'
import { WowsShipsApiResponse, WowsShipInfoApiResponse } from '@/types/Games/Wows'
import axios from 'axios'
import { Action, namespace, Getter } from 'vuex-class'
import { RoomAction, Locale, GameName, RoomGetters } from '@/store/modules/room'
import { Namespaces } from '@/store'
import { AuthenticationActions, AuthenticationGetters, ExtendedJWT, JWT_KEY } from '@/store/modules/authentication'
import { Api } from './store/modules/types'
import { getWowsApiData } from '@/games/wows/api'
const authNamespace = namespace(Namespaces.AUTH)
@Component({
name: 'TheApp'
})
export default class TheApp extends Vue {
@Action(`room/${RoomAction.SET_GAME}`) setGame!: (game: Game) => void
@Action(`room/${RoomAction.SET_GAME_NAME}`) setGameName!: (name: string) => void
@Action(`room/${RoomAction.SET_GAME_API}`) setGameApi!: (api: Api) => void
@Action(`room/${RoomAction.SET_LOCALE}`) setLocale!: (locale: Locale) => void
@Getter(`room/${RoomGetters.GAME_NAME}`) game!: GameName
@authNamespace.Action(AuthenticationActions.AUTHENTICATE) authenticate!: (token: string) => Promise<ExtendedJWT>
@authNamespace.Action(AuthenticationActions.CHECK_TOKEN_EXPIRY) checkTokenExpiry!: () => Promise<boolean>
@authNamespace.Action(AuthenticationActions.STORE_TOKEN) storeToken!: (token: string) => void
@authNamespace.Getter(AuthenticationGetters.JWT) jwt!: ExtendedJWT
async created () {
this.setGame({ name: GameName['WOWS'], ships: [], gameInfo: undefined })
this.setLocale(Locale['ENUK'])
this.setGame(await this.getWowsApiData())
this.setGameName(GameName['WOWS'])
this.setLocale(Locale['EN'])
this.initAuthentication()
}
async getWowsApiData (): Promise<Game> {
const response: WowsShipsApiResponse = await axios.get('https://api.worldofwarships.eu/wows/encyclopedia/ships/?application_id=d84a218b4fec37003e799f13777bf880')
const pageTotal = response.data.meta.page_total
let ships: Ship[] = []
ships = ships.concat(Object.values(response.data.data))
if (pageTotal > 1) {
for (let i = 2; i <= pageTotal; i++) {
const response: WowsShipsApiResponse = await axios.get(`https://api.worldofwarships.eu/wows/encyclopedia/ships/?page_no=${i}&application_id=d84a218b4fec37003e799f13777bf880`)
ships = ships.concat(Object.values(response.data.data))
}
}
const gameInfo: WowsShipInfoApiResponse = await axios.get('https://api.worldofwarships.eu/wows/encyclopedia/info/?application_id=d84a218b4fec37003e799f13777bf880')
async initAuthentication () {
const localToken = localStorage.getItem(JWT_KEY)
return {
name: GameName['WOWS'],
ships: ships,
gameInfo: gameInfo.data.data
if (this.checkTokenExpiry()) {
if (this.$route?.query?.code) {
this.authenticate(this.$route.query.code as string).then(jwt => this.storeToken(jwt.encoded))
} else if (localToken !== null) {
this.authenticate(localToken)
}
if (localToken) {
switch (this.game) {
case 'wows':
await getWowsApiData(localToken, this.setGameApi)
break
default: break
}
}
}
}
}
Expand Down
62 changes: 31 additions & 31 deletions src/components/TheCanvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Action, Getter, namespace } from 'vuex-class'
import { ToolGetters, ToolsAction } from '@/store/modules/tools'
import { CanvasAction, CanvasGetters, HideCanvasElementInterface } from '@/store/modules/canvas'
import Konva from 'konva'
import { SocketActions, SocketGetters } from '@/store/modules/socket'
import { SocketActions } from '@/store/modules/socket'
import { EventBus } from '@/event-bus'
import PointerEventMapper, { CustomStageConfig, CustomStageEvent } from '@/util/PointerEventMapper'
import { KonvaPointerEvent } from 'konva/types/PointerEvents'
Expand All @@ -53,8 +53,8 @@ export default class TheCanvas extends Vue {
@Getter(`tools/${ToolGetters.ENABLED_TOOL}`) enabledTool!: Tool
@Getter(`tools/${ToolGetters.ENABLED}`) enabled!: boolean
@Getter(`tools/${ToolGetters.TOOLS}`) tools!: Tool[]
@Sockets.Getter(SocketGetters.SOCKET) socket!: WebSocket
@Sockets.Action(SocketActions.SEND_IF_OPEN) send!: (message: string) => void
// @Sockets.Getter(SocketGetters.SOCKET) socket!: WebSocket
// @Sockets.Action(SocketActions.SEND_IF_OPEN) send!: (message: string) => void
@Action(`canvas/${CanvasAction.ADD_CANVAS_ELEMENT}`) addCanvasElement!: (canvasElement: CanvasElement) => void
@Action(`canvas/${CanvasAction.ADD_CANVAS_ELEMENT_HISTORY}`) addCanvasElementHistory!: (canvasElement: CanvasElement) => void
@Action(`canvas/${CanvasAction.HIDE_CANVAS_ELEMENT}`) hideCanvasElement!: (payload: HideCanvasElementInterface) => void
Expand Down Expand Up @@ -135,7 +135,7 @@ export default class TheCanvas extends Vue {
const response = handleUndoRedo.handleUndoRedo(undoRedo)
if (response) {
this.addCanvasElementHistory(response.addToHistory)
this.socket.send(JSON.stringify(response.returnElement))
// this.socket.send(JSON.stringify(response.returnElement))
this.renderShapes()
}
})
Expand All @@ -144,7 +144,7 @@ export default class TheCanvas extends Vue {
if (this.canvasElement.tool.textString && this.canvasElement.tool.textString?.length > 0) {
this.addCanvasElement({ ...canvasElement })
this.addCanvasElementHistory(canvasElement)
this.socket.send(JSON.stringify(this.canvasElement))
// this.socket.send(JSON.stringify(this.canvasElement))
this.renderShapes()
}
})
Expand Down Expand Up @@ -174,32 +174,32 @@ export default class TheCanvas extends Vue {
this.onTouchUpHandler(e)
})
this.socket.onmessage = (data: MessageEvent) => {
const stageEvent: CustomStageEvent = {
stage: this.stageNode,
stageConfig: this.stageConfig,
zoom: this.stageZoom
}
const socketMessageHandler = new HandleSocketMessage(
JSON.parse(data.data).payload,
this.$data.canvasElement,
this.tools,
this.layerNode,
this.canvasElements,
stageEvent
)
const response = socketMessageHandler.handle()
if (response) {
if (response.change === SocketHandlerChange.ADD && response.payload.canvasElement) {
this.addCanvasElement(response.payload.canvasElement)
} else if (response.change === SocketHandlerChange.HIDE && response.payload.groupIds) {
response.payload.groupIds.forEach((groupId: string) => {
this.hideCanvasElement({ fromSocket: true, id: groupId })
})
}
}
this.renderShapes()
}
// this.socket.onmessage = (data: MessageEvent) => {
// const stageEvent: CustomStageEvent = {
// stage: this.stageNode,
// stageConfig: this.stageConfig,
// zoom: this.stageZoom
// }
// const socketMessageHandler = new HandleSocketMessage(
// JSON.parse(data.data).payload,
// this.$data.canvasElement,
// this.tools,
// this.layerNode,
// this.canvasElements,
// stageEvent
// )
// const response = socketMessageHandler.handle()
// if (response) {
// if (response.change === SocketHandlerChange.ADD && response.payload.canvasElement) {
// this.addCanvasElement(response.payload.canvasElement)
// } else if (response.change === SocketHandlerChange.HIDE && response.payload.groupIds) {
// response.payload.groupIds.forEach((groupId: string) => {
// this.hideCanvasElement({ fromSocket: true, id: groupId })
// })
// }
// }
// this.renderShapes()
// }
}
beforeDestroy () {
Expand Down
10 changes: 5 additions & 5 deletions src/components/TheEntityPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
tile
class="custom-entity-panel"
>
<wows-panel v-if="roomState.game.name === 'wows'" :clickedItemKey="clickedItemKey" :teams="teams" />
<wot-panel v-if="roomState.game.name === 'wot'" :clickedItemKey="clickedItemKey" :teams="teams" />
<wows-panel v-if="gameName === 'wows'" :clickedItemKey="clickedItemKey" :teams="teams" />
<wot-panel v-if="gameName === 'wot'" :clickedItemKey="clickedItemKey" :teams="teams" />
</v-card>
</v-col>
<v-col class="pt-1">
Expand All @@ -23,7 +23,7 @@
<div>
<v-list-item class="px-2">
<v-list-item-avatar>
<v-img :src="images[roomState.game.name]"></v-img>
<v-img :src="images[gameName]"></v-img>
</v-list-item-avatar>
</v-list-item>
<v-divider></v-divider>
Expand Down Expand Up @@ -82,7 +82,7 @@

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { RoomGetters, RoomState } from '@/store/modules/room'
import { RoomGetters, GameName } from '@/store/modules/room'
import { Getter } from 'vuex-class'
import { WowsPanel, WotPanel } from './entity-panel'
Expand All @@ -103,7 +103,7 @@ export interface MenuItem {
})
export default class MapButtons extends Vue {
@Prop() private id!: string;
@Getter(`room/${RoomGetters.ROOM_STATE}`) private readonly roomState!: RoomState;
@Getter(`room/${RoomGetters.GAME_NAME}`) private readonly gameName!: GameName;
show = true
Expand Down
106 changes: 57 additions & 49 deletions src/components/entity-panel/games/Wows.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@
<script lang="ts">
import axios from 'axios'
import { Component, Prop, Vue } from 'vue-property-decorator'
import { RoomGetters, RoomState, Ship } from '@/store/modules/room'
import { RoomGetters, GameName } from '@/store/modules/room'
import { Getter } from 'vuex-class'
import { MenuItem } from '@/components/TheEntityPanel.vue'
import { Field } from '@/types/Games/Index.ts'
import { Field, ApiHeader } from '@/types/Games/Index.ts'
import { Item } from '@/types/Games/Index'
import TheCreateEntity from '@/components/entity-panel/sections/TheCreateEntity.vue'
import { Api, Entity } from '../../../store/modules/types'
import { Ship } from '../../../types/Games/Wows'
import { AuthenticationGetters, ExtendedJWT } from '../../../store/modules/authentication'
@Component({
name: 'WOWS',
Expand All @@ -36,9 +39,10 @@ import TheCreateEntity from '@/components/entity-panel/sections/TheCreateEntity.
export default class Wows extends Vue {
@Prop() private clickedItemKey!: number;
@Prop() private teams!: MenuItem[];
@Getter(`room/${RoomGetters.ROOM_STATE}`) roomState!: RoomState;
@Getter(`room/${RoomGetters.GAME_API}`) gameApi!: Api[];
@Getter(`authentication/${AuthenticationGetters.JWT}`) jwt!: ExtendedJWT;
entities: Item[] = []
entities: Entity[] = []
fields: Field[] = [{
id: 'shipMainBatteryRange',
Expand Down Expand Up @@ -90,57 +94,61 @@ export default class Wows extends Vue {
suffix: 'entity.wows.hydroRange.suffix'
}]
get shipsData (): Item[] {
const roomStateGameInfo = this.roomState.game.gameInfo
if (roomStateGameInfo) {
if (this.roomState.game?.ships) {
return [{
text: 'Aircraft Carrier (CV)',
shortText: 'CV',
value: 1,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/AirCarrier/standard_84f55678325d4b492215390a7f0b43008f3947ab201502cd979dcf4c37633cf3.png',
tier: 0,
data: {}
}, {
text: 'Battleship (BB)',
shortText: 'BB',
value: 2,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Battleship/standard_01624cacb82f39f77a4e677a7b9fdf4df20dafd61f971f4b2d3e54c3065e2892.png',
tier: 0,
data: {}
}, {
text: 'Cruiser (CA)',
shortText: 'CA',
value: 3,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Cruiser/standard_874a3bdc3134b8da4fd6f52186f1b2b682f13ef78688732d3016785c0649a424.png',
tier: 0,
data: {}
}, {
text: 'Destroyer (DD)',
shortText: 'DD',
value: 4,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Destroyer/standard_357acc9fc0e2f7d98f047c99edffad359a8c45f2093024400fef2b9abbaf3a59.png',
tier: 0,
data: {}
}, ...this.roomState.game?.ships.map((ship: Ship) => ({
text: `${ship.name} (${ship.tier})`,
shortText: ship.name,
value: ship.ship_id,
image: roomStateGameInfo.ship_type_images[ship.type][ship.is_special ? 'image_elite' : ship.is_premium ? 'image_premium' : 'image'],
tier: ship.tier,
data: {}
})).sort((x: Item, y: Item) => x.text > y.text ? 1 : -1)]
}
get shipsData (): Entity[] {
const gameInfo = this.gameApi.find((api: Api) => api.name === 'wows.encyclopedia.info')
const gameShips = this.gameApi.find((api: Api) => api.name === 'wows.encyclopedia.ships')
if (gameInfo?.data && gameShips?.data) {
return [{
text: 'Aircraft Carrier (CV)',
shortText: 'CV',
value: 1,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/AirCarrier/standard_84f55678325d4b492215390a7f0b43008f3947ab201502cd979dcf4c37633cf3.png',
tier: 0,
data: {}
}, {
text: 'Battleship (BB)',
shortText: 'BB',
value: 2,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Battleship/standard_01624cacb82f39f77a4e677a7b9fdf4df20dafd61f971f4b2d3e54c3065e2892.png',
tier: 0,
data: {}
}, {
text: 'Cruiser (CA)',
shortText: 'CA',
value: 3,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Cruiser/standard_874a3bdc3134b8da4fd6f52186f1b2b682f13ef78688732d3016785c0649a424.png',
tier: 0,
data: {}
}, {
text: 'Destroyer (DD)',
shortText: 'DD',
value: 4,
image: 'https://glossary-wows-global.gcdn.co/icons/vehicle/types/Destroyer/standard_357acc9fc0e2f7d98f047c99edffad359a8c45f2093024400fef2b9abbaf3a59.png',
tier: 0,
data: {}
}, ...gameShips.data.map((ship: Ship) => ({
text: `${ship.name} (${ship.tier})`,
shortText: ship.name,
value: ship.ship_id,
image: gameInfo.data.ship_type_images[ship.type][ship.is_special ? 'image_elite' : ship.is_premium ? 'image_premium' : 'image'],
tier: ship.tier,
data: {}
})).sort((x: Item, y: Item) => x.text > y.text ? 1 : -1)]
}
return []
}
async autoCompleteOnChangeHandler (shipItem: Item) {
if (shipItem && !this.entities.find((entity: Item) => entity.value === shipItem.value)) {
async autoCompleteOnChangeHandler (shipItem: Entity) {
if (shipItem && !this.entities.find((entity: Entity) => entity.value === shipItem.value)) {
this.entities.unshift(shipItem)
const response = await axios.get(`https://api.worldofwarships.eu/wows/encyclopedia/shipprofile/?ship_id=${shipItem.value}&application_id=d84a218b4fec37003e799f13777bf880`)
const headers: ApiHeader = {
'Authorization': this.jwt.encoded,
'X-Region': this.jwt.region,
'X-Game': GameName['WOWS']
}
const response = await axios.get(`${process.env.VUE_APP_MS_WG_API}/wows/encyclopedia/shipprofile/?ship_id=${shipItem.value}`, { headers })
const shipData = response.data.data[shipItem.value]
const foundNewEntity = this.entities.find((entity: Item) => entity.value === shipItem.value)
const foundNewEntity = this.entities.find((entity: Entity) => entity.value === shipItem.value)
if (foundNewEntity) {
foundNewEntity.data = shipData
}
Expand Down
Loading

0 comments on commit 66ac79f

Please sign in to comment.