diff --git a/handlers.js b/handlers.js index 1d57bbf..3be3f23 100644 --- a/handlers.js +++ b/handlers.js @@ -1,5 +1,8 @@ const ByteBuffer = require('bytebuffer'); +const {Agent:HttpAgent} = require('http'); +const {Agent:HttpsAgent} = require('https'); const {HttpClient} = require('@doctormckay/stdlib/http'); +const {Semaphore} = require('@doctormckay/stdlib/concurrency.js'); const SteamID = require('steamid'); const VDF = require('kvparser'); @@ -7,6 +10,11 @@ const TeamFortress2 = require('./index.js'); const Language = require('./language.js'); const Schema = require('./protobufs/generated/_load.js'); +const httpClient = new HttpClient({ + httpAgent: new HttpAgent({ keepAlive: true, timeout: 10000 }), + httpsAgent: new HttpsAgent({ keepAlive: true, timeout: 10000 }) +}); + const handlers = TeamFortress2.prototype._handlers; // ClientWelcome, ServerWelcome, ClientGoodbye, and ServerGoodbye @@ -45,26 +53,44 @@ handlers[Language.ServerGoodbye] = function(body) { }; // Item schema +let g_ItemSchema = null; +let g_ItemSchemaVersion = null; +let g_ItemSchemaRetrievalSemaphore = new Semaphore(); + handlers[Language.UpdateItemSchema] = async function(body) { + let release = await g_ItemSchemaRetrievalSemaphore.waitAsync(); + try { let proto = decodeProto(Schema.CMsgUpdateItemSchema, body); - this.emit('itemSchema', proto.item_schema_version.toString(16).toUpperCase(), proto.items_game_url); - let client = new HttpClient(); - let result = await client.request({ - method: 'get', - url: proto.items_game_url - }); + let schemaVersion = proto.item_schema_version.toString(16).toUpperCase(); + let schemaUrl = proto.items_game_url; + + this.emit('itemSchema', schemaVersion, schemaUrl); - if (result.statusCode != 200) { - throw new Error(`HTTP error ${result.statusCode}`); + if (schemaVersion !== g_ItemSchemaVersion) { + let result = await httpClient.request({ + method: 'get', + url: schemaUrl + }); + + if (result.statusCode != 200) { + throw new Error(`HTTP error ${result.statusCode}`); + } + + g_ItemSchema = VDF.parse(result.textBody).items_game; + g_ItemSchemaVersion = schemaVersion; } - this.itemSchema = VDF.parse(result.textBody).items_game; + this.itemSchema = g_ItemSchema; + this.itemSchemaVersion = g_ItemSchemaVersion; + this.emit('itemSchemaLoaded'); } catch (err) { this.emit('debug', `Unable to download items_game.txt: ${err.message}`); this.emit('itemSchemaError', err); + } finally { + release(); } }; diff --git a/package.json b/package.json index 810b9bd..92ae661 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "url": "https://github.com/DoctorMcKay/node-tf2.git" }, "dependencies": { - "@doctormckay/stdlib": "^2.7.1", + "@doctormckay/stdlib": "^2.9.1", "bytebuffer": "^5.0.1", "kvparser": "^1.0.2", "protobufjs": "^7.2.5",