diff --git a/.env.sample b/.env.sample index cf535779..02f70666 100644 --- a/.env.sample +++ b/.env.sample @@ -19,6 +19,7 @@ API_LEGACY_BATTLENET_KEY='' API_LEGACY_BATTLENET_SECRET='' API_BATTLENET_KEY='' API_BATTLENET_SECRET='' -API_BATTLENET_APIS_DISABLED='false' +API_BATTLENET_APIS_DISABLED_JANUARY_2020='false' API_TWITCH_EXTENSION_SHARED_SECRET='' API_TWITCH_EXTENSION_CLIENT_ID='' +API_SNAPSHOT_DATA_DIRECTORY='../sc2pte-data-snapshot' \ No newline at end of file diff --git a/src/config/battlenet.js b/src/config/battlenet.js index 0ae3afb0..58297c25 100644 --- a/src/config/battlenet.js +++ b/src/config/battlenet.js @@ -14,5 +14,6 @@ bnetConfig.apiKey = env.API_BATTLENET_KEY; /** Battle.net API secret */ bnetConfig.apiSecret = env.API_BATTLENET_SECRET; bnetConfig.apiDisabledJanuary2020 = env.API_BATTLENET_APIS_DISABLED_JANUARY_2020 === 'true'; +bnetConfig.snapshotDataDirectory = env.API_SNAPSHOT_DATA_DIRECTORY; module.exports = bnetConfig; diff --git a/src/index.js b/src/index.js index 09519425..3be0eba9 100644 --- a/src/index.js +++ b/src/index.js @@ -19,14 +19,15 @@ const appConfig = require('./config/app'); const dbConfig = require('./config/database'); const twitchConfig = require('./config/twitch'); const redisConfig = require('./config/redis'); +const bnetConfig = require('./config/battlenet'); const getViewerRoutes = require('./routes/v1.1/viewer/get'); const saveConfigRoutes = require('./routes/v1.1/config/save'); const getConfigRoutes = require('./routes/v1.1/config/get'); const db = require('./plugins/db'); - const sc2pte = require('./plugins/sc2pte'); +const snapshot = require('./plugins/snapshot'); const { env } = process; @@ -102,6 +103,12 @@ if (env.API_HOST_PROTOCOL === 'https') { server.register(tlsKeygen); } +/* Data snapshots for dark times in January 2020 when Battle.net API is down */ + +server.register(snapshot, { + dataDir: bnetConfig.snapshotDataDirectory, +}); + /* Routes */ server.register(getViewerRoutes); diff --git a/src/plugins/db.js b/src/plugins/db.js index ea91dba5..9e314d5a 100644 --- a/src/plugins/db.js +++ b/src/plugins/db.js @@ -32,6 +32,7 @@ module.exports = fp(async (server, opts, next) => { keepAlive: true, useFindAndModify: false, useCreateIndex: true, + useUnifiedTopology: true, }, ); diff --git a/src/plugins/snapshot.js b/src/plugins/snapshot.js new file mode 100644 index 00000000..821f9b48 --- /dev/null +++ b/src/plugins/snapshot.js @@ -0,0 +1,30 @@ +const fp = require('fastify-plugin'); +const fs = require('fs'); + +function snapshot(fastify, options, next) { // eslint-disable-line consistent-return + const { dataDir } = options; + + function getViewerData(channelId) { + try { + const content = fs.readFileSync(`${dataDir}/${channelId}.json`, 'utf8'); + const contentObject = JSON.parse(content); + if (contentObject.player && contentObject.ladders) { + return content; + } + return fs.readFileSync(`${dataDir}/blank.json`, 'utf8'); + } catch (error) { + return fs.readFileSync(`${dataDir}/blank.json`, 'utf8'); + } + } + + fastify.decorate('snapshot', { + getViewerData, + }); + + next(); +} + +module.exports = fp(snapshot, { + fastify: '>=2.0.0', + name: 'snapshot', +}); diff --git a/src/routes/v1.1/viewer/get/index.js b/src/routes/v1.1/viewer/get/index.js index 0238cf66..ddcb3c80 100644 --- a/src/routes/v1.1/viewer/get/index.js +++ b/src/routes/v1.1/viewer/get/index.js @@ -3,7 +3,7 @@ const fp = require('fastify-plugin'); const schema = require('./schema'); const redisConfig = require('../../../../config/redis'); -// const bnetConfig = require('../../../../config/battlenet'); +const bnetConfig = require('../../../../config/battlenet'); module.exports = fp(async (server, opts, next) => { server.route({ @@ -36,6 +36,13 @@ module.exports = fp(async (server, opts, next) => { return reply.code(200).send(cachedReply.item); } server.log.info('generating and caching response...'); + + if (bnetConfig.apiDisabledJanuary2020) { + const responseObject = server.snapshot.getViewerData(channelId); + await server.cache.set(redisKey, responseObject, redisConfig.replyCachePeriod); + return reply.code(200).send(responseObject); + } + const channelConfigObject = await server.db.models.ChannelConfig.findOne({ channelId }); if (channelConfigObject && channelConfigObject._doc) { // eslint-disable-line