UNPKG

soulbound-node-dota2

Version:
287 lines (260 loc) 12 kB
'use strict'; var Dota2 = require("../index"); var cacheTypeIDs = { // Legacy values LOBBY: 2004, PARTY: 2003, PARTY_INVITE: 2006, LOBBY_INVITE: 2011, // Actual values CSOEconItem : 1, CSOItemRecipe : 5, CSOEconGameAccountClient : 7, CSOSelectedItemPreset : 35, // no longer exists in game files CSOEconItemPresetInstance : 36, // no longer exists in game files CSOEconItemDropRateBonus : 38, CSOEconItemLeagueViewPass : 39, CSOEconItemEventTicket : 40, CSOEconItemTournamentPassport : 42, CSODOTAGameAccountClient : 2002, CSODOTAParty : 2003, CSODOTALobby : 2004, CSODOTAPartyInvite : 2006, CSODOTAGameHeroFavorites : 2007, CSODOTAMapLocationState : 2008, CMsgDOTATournament : 2009, CSODOTAPlayerChallenge : 2010, CSODOTALobbyInvite : 2011 }; // Handlers function handleCreateType(obj_type, object_data) { switch(obj_type) { case cacheTypeIDs.CSOEconItem: this.Logger.debug("Got an item traded"); var item = Dota2.schema.lookupType("CSOEconItem").decode(object_data); this.emit("gotItem", item); this.Inventory.push(item); break; } } function handleDestroyType(obj_type, object_data) { switch(obj_type) { case cacheTypeIDs.CSODOTAPartyInvite: this.Logger.debug("Party invite cleared"); this.PartyInvite = null; this.emit("partyInviteCleared"); break; case cacheTypeIDs.CSODOTALobbyInvite: this.Logger.debug("Lobby invite cleared"); this.LobbyInvite = null; this.emit("lobbyInviteCleared"); break; case cacheTypeIDs.CSOEconItem: this.Logger.debug("Traded item away"); var item = Dota2.schema.lookupType("CSOEconItem").decode(object_data); this.emit("gaveItem", item); this.Inventory = this.Inventory.filter(i => item.id.notEquals(i.id)); break; } } function handleSubscribedType(obj_type, object_data, isDelete) { switch (obj_type) { // Inventory item case cacheTypeIDs.CSOEconItem: this.Logger.debug("Received inventory snapshot"); // Parse items var items = object_data.map(obj => Dota2.schema.lookupType("CSOEconItem").decode(obj)); // Remove updated items from inventory var inv = this.Inventory.filter(item => items.reduce((acc, val) => acc && item.id.notEquals(val.id)), true); if (!isDelete) { // Put them back if it's not a delete inv = inv.concat(items); } this.emit("inventoryUpdate", inv); this.Inventory = inv; break; // Lobby snapshot. case cacheTypeIDs.CSODOTALobby: // object_data is an array when called from onCacheSubscribed // but an object when called from onUpdateMultiple var lobby = Dota2.schema.lookupType("CSODOTALobby").decode([].concat(object_data)[0]); this.Logger.debug("Received lobby snapshot for lobby ID " + lobby.lobby_id); this.emit("practiceLobbyUpdate", lobby); this.Lobby = lobby; break; // Lobby invite snapshot. case cacheTypeIDs.CSODOTALobbyInvite: var lobbyInvite = Dota2.schema.lookupType("CSODOTALobbyInvite").decode(object_data[0]); this.Logger.debug("Received lobby invite snapshot for group ID " + lobbyInvite.group_id); this.emit("lobbyInviteUpdate", lobbyInvite); this.LobbyInvite = lobbyInvite; break; // Party snapshot. case cacheTypeIDs.CSODOTAParty: var party = Dota2.schema.lookupType("CSODOTAParty").decode([].concat(object_data)[0]); this.Logger.debug("Received party snapshot for party ID " + party.party_id); this.emit("partyUpdate", party); this.Party = party; break; // Party invite snapshot. case cacheTypeIDs.CSODOTAPartyInvite: var party = Dota2.schema.lookupType("CSODOTAPartyInvite").decode(object_data[0]); this.Logger.debug("Received party invite snapshot for group ID " + party.group_id); this.emit("partyInviteUpdate", party); this.PartyInvite = party; break; default: this.Logger.warn("Unhandled cache ID: " + obj_type); break; } }; Dota2.Dota2Client.prototype._handleWelcomeCaches = function handleWelcomeCaches(message) { var welcome = Dota2.schema.lookupType("CMsgClientWelcome").decode(message); var _self = this; if (welcome.outofdate_subscribed_caches) welcome.outofdate_subscribed_caches.forEach(function(cache) { cache.objects.forEach(function(obj) { handleSubscribedType.call(_self, obj.type_id, obj.object_data[0]); }); }); }; // Events /** * Emitted when the GC sends an inventory snapshot. The GC is incredibly * inefficient and will send the entire object even if it's a minor update. * You can use this to detect when a change was made to your inventory (e.g. drop) * Note that the {@link module:Dota2.Dota2Client#Inventory|Inventory} property will be the old value until after this event * completes to allow comparison between the two. * @event module:Dota2.Dota2Client#inventoryUpdate * @param {CSOEconItem[]} inventory - A list of `CSOEconItem` objects */ /** * Emitted when you receive an item through a trade. * Note that the {@link module:Dota2.Dota2Client#Inventory|Inventory} property will be the old value until after this event * completes to allow comparison between the two. * @event module:Dota2.Dota2Client#gotItem * @param {CSOEconItem} item - `CSOEconItem` object describing the received item **/ /** * Emitted when you trade away an item. * Note that the {@link module:Dota2.Dota2Client#Inventory|Inventory} property will be the old value until after this event * completes to allow comparison between the two. * @event module:Dota2.Dota2Client#gaveItem * @param {CSOEconItem} item - `CSOEconItem` object describing the traded item **/ /** * Emitted when the GC sends a lobby snapshot. The GC is incredibly * inefficient and will send the entire object even if it's a minor update. * You can use this to detect when a lobby has been entered / created * successfully as well. Note that the {@link module:Dota2.Dota2Client#Lobby|Lobby} property will be the old * value until after this event completes to allow comparison between the * two. * @event module:Dota2.Dota2Client#practiceLobbyUpdate * @param {CSODOTALobby} lobby - The new state of the lobby. */ /** * Emitted when leaving a lobby (aka, the lobby is cleared). This can * happen when kicked, upon leaving a lobby, etc. There are other events * to tell when the bot has been kicked. * @event module:Dota2.Dota2Client#practiceLobbyCleared */ /** * Emitted when the bot received an invite to a lobby * @event module:Dota2.Dota2Client#lobbyInviteUpdate * @param {CSODOTALobbyInvite} lobbyInvite - The invitation to a lobby. */ /** * Emitted when the Lobby Invite is cleared, for example when * accepting/rejecting it or when the lobby is closed. * @event module:Dota2.Dota2Client#lobbyInviteCleared */ /** * Emitted when the GC sends a party snapshot. The GC is incredibly * inefficient and will send the entire object even if it's a minor update. * You can use this to detect when a party has been entered / created * successfully as well. Note that the {@link module:Dota2.Dota2Client#Party|Party} property will be the old * value until after this event completes to allow comparison between the * two. * @event module:Dota2.Dota2Client#partyUpdate * @param {CSODOTAParty} party - The new state of the party. */ /** * Emitted when leaving a party (aka, the party is cleared). This can * happen when kicked, upon leaving a party, etc. There are other callbacks * to tell when the bot has been kicked. * @event module:Dota2.Dota2Client#partyCleared */ /** * Emitted when the GC sends a party invite snapshot. The GC is incredibly * inefficient and will send the entire object even if it's a minor update. * You can use this to detect when an incoming party invite has been sent. * Note that the {@link module:Dota2.Dota2Client#PartyInvite|PartyInvite} property will be the old * value until after this event completes to allow comparison between the two. * @event module:Dota2.Dota2Client#partyInviteUpdate * @param {CSODOTAPartyInvite} partyInvite - The invitation to a party. */ /** * Emitted when the Party Invite is cleared, for example when * accepting/rejecting it or when the party is closed * @event module:Dota2.Dota2Client#partyInviteCleared */ var handlers = Dota2.Dota2Client.prototype._handlers; var onCacheSubscribed = function onCacheSubscribed(message) { var subscribe = Dota2.schema.lookupType("CMsgSOCacheSubscribed").decode(message); var _self = this; this.Logger.debug("Cache(s) subscribed, type(s): " + subscribe.objects.map(obj=>obj.type_id).toString()); subscribe.objects.forEach(function(obj) { handleSubscribedType.call(_self, obj.type_id, obj.object_data); }); }; handlers[Dota2.schema.lookupEnum("ESOMsg").values.k_ESOMsg_CacheSubscribed] = onCacheSubscribed; var onUpdateMultiple = function onUpdateMultiple(message) { var multi = Dota2.schema.lookup("CMsgSOMultipleObjects").decode(message); var _self = this; let multi_types = ["objects_modified", "objects_added", "objects_removed"]; multi_types.map((type, i) => { if (multi[type]) { let updates = {}; multi[type].forEach(obj => { if (updates[obj.type_id]) updates[obj.type_id] = updates[obj.type_id].concat(obj.object_data); else updates[obj.type_id] = [obj.object_data]; }); for (let type in updates) handleSubscribedType.call(_self, parseInt(type), updates[type], i==2); } }); }; handlers[Dota2.schema.lookupEnum("ESOMsg").values.k_ESOMsg_UpdateMultiple] = onUpdateMultiple; var onCreate = function onCreate(message) { var single = Dota2.schema.lookup("CMsgSOSingleObject").decode(message); var _self = this; this.Logger.debug("Create, type " + single.type_id); handleCreateType.call(_self, single.type_id, single.object_data); } handlers[Dota2.schema.lookupEnum("ESOMsg").values.k_ESOMsg_Create] = onCreate; var onCacheUnsubscribed = function onCacheUnsubscribed(message) { var unsubscribe = Dota2.schema.lookup("CMsgSOCacheUnsubscribed").decode(message); var _self = this; this.Logger.debug("Cache unsubscribed, " + unsubscribe.owner_soid.id); if (this.Lobby && unsubscribe.owner_soid.id.eq(this.Lobby.lobby_id)) { this.Lobby = null; this.emit("practiceLobbyCleared"); } else if (this.LobbyInvite && unsubscribe.owner_soid.id.eq(this.LobbyInvite.group_id)) { this.LobbyInvite = null; this.emit("lobbyInviteCleared"); } else if (this.Party && unsubscribe.owner_soid.id.eq(this.Party.party_id)) { this.Party = null; this.emit("partyCleared"); } else if (this.PartyInvite && unsubscribe.owner_soid.id.eq(this.PartyInvite.group_id)) { this.PartyInvite = null; this.emit("partyInviteCleared"); } }; handlers[Dota2.schema.lookupEnum("ESOMsg").values.k_ESOMsg_CacheUnsubscribed] = onCacheUnsubscribed; var onCacheDestroy = function onCacheDestroy(message) { var single = Dota2.schema.lookup("CMsgSOSingleObject").decode(message); var _self = this; this.Logger.debug("Cache destroy, " + single.type_id); handleDestroyType.call(_self, single.type_id, single.object_data); }; handlers[Dota2.schema.lookupEnum("ESOMsg").values.k_ESOMsg_Destroy] = onCacheDestroy;