import buildUrl from 'build-url' export default (context, inject) => { const engine = { context, lastFetched: [0, 0, 0, 0, 0], isActive: false, shouldStop: false, async start() { const { store, redirect } = this.context if (!store.state.engine.user) { if (!await this.fetchUserInfo()) { redirect('/') } } if (this.isActive) { console.warn('attempt to start already running engine!') return } this.isActive = true this.fetchUpdate() }, stop() { if (!this.isActive) return this.shouldStop = true }, async fetchUpdate() { const { store, $axios, $config } = this.context if (this.shouldStop || !this.isActive) { this.isActive = false this.shouldStop = false return } let delay = 0 try { const url = buildUrl($config.serverBaseUrl, { path: '/api/sync', queryParams: { v: store.state.engine.version + 1, g: store.state.engine.user?.game, }, }) const response = await $axios.get(url) store.commit('engine/setJson', response.data) } catch (e) { const { status, statusText } = e.response if (status != 200) { console.warn(`HTTP ${status} ${statusText}`) delay = 5000 store.commit('engine/setVersion', -1) } } const now = new Date().getTime() const last = this.lastFetched.splice(0, 1) this.lastFetched.push(now) if (now - last < 1000) { console.warn('engine: respawning too fast, throttling down') delay = 5000 } window.setTimeout(() => { this.fetchUpdate() }, delay) }, async fetchUserInfo() { const { store, $axios } = this.context try { const response = await $axios.get('/api/userinfo') store.commit('engine/setUser', response.data) } catch(e) { store.commit('engine/setUser', undefined) return false } return true }, } inject('engine', engine) }