// CharacterStats.h : Declaration of the cCharacterStats #ifndef __CHARACTERSTATS_H_ #define __CHARACTERSTATS_H_ #include "DecalNetImpl.h" #include "resource.h" // main symbols #include "DecalFiltersCP.h" #include "DecalDat.h" // NEED THIS FOR THE PORTAL DATSTREAM! #include ///////////////////////////////////////////////////////////////////////////// // cCharacterStats //! cCharacterStats is the filter class used to monitor network traffic relating to your character's stats. /*! The Character Stats filter is a handy way of getting hold of many of your character's stats. It functions by monitoring all the network traffic relating to your character's stats, vitae, etc. It is still the definitive source of stat information in Decal, but if you are looking for something simple (like just one stat) you might want to look at ACHooks first; ACHooks now has some hooks that replace the functionality of this filter for Attributes/Vitals/Skills more reliably. */ class ATL_NO_VTABLE cCharacterStats : public CComObjectRootEx, public CComCoClass, public IConnectionPointContainerImpl, public IDispatchImpl, public INetworkFilter2, public CProxyICharacterStatsEvents< cCharacterStats > { public: cCharacterStats() { } DECLARE_REGISTRY_RESOURCEID(IDR_CHARACTERSTATS) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(cCharacterStats) COM_INTERFACE_ENTRY(INetworkFilter2) COM_INTERFACE_ENTRY(ICharacterStats) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(cCharacterStats) CONNECTION_POINT_ENTRY(DIID_ICharacterStatsEvents) END_CONNECTION_POINT_MAP() public: //! The Location_t structure is used by the Character Stats filter for storing information about your character's location. struct Location_t { //! Turbine-assigned landblock number (like using /loc). DWORD landblock; //! Coordinate offset to landblock base coordinates. float x,y,z; //! Component of the location quaternion. float a,b,c,w; }; //! The cEnchantment structure is used by the Character Stats filter for storing information about an enchantment. struct cEnchantment { //! The SpellID, unique to each spell. Can be found in Turbine's portal.dat. int iSpellID; //! The spell's layer. That is, a spell that "surpasses" another spell has a higher layer, so the highest layer is the "active" spell. int iLayer; //! A standard C++ time_t object representing the time at which this spell expires. time_t ExpireTime; //! Stored value representing what this spell affects (what skill/attribute/etc). DWORD dwAffected; //! Stored value obtained from the protocol. I forget what it represents. DWORD dwAffectMask; //! Stored value representing what "family" or grouping of spells this spell belongs to. Families may be found in the portal.dat. DWORD dwFamily; //! The actual adjustment that is the result of the spell. For instance, the value for Creature Enchantment Mastery VI would be 35. float fAdjustment; cEnchantment() { } cEnchantment( cEnchantment &right ) { iSpellID = right.iSpellID; iLayer = right.iLayer; ExpireTime = right.ExpireTime; dwAffected = right.dwAffected; dwAffectMask = right.dwAffectMask; dwFamily = right.dwFamily; fAdjustment = right.fAdjustment; } cEnchantment& operator= ( cEnchantment& right ) { if( this != &right ) { iSpellID = right.iSpellID; iLayer = right.iLayer; ExpireTime = right.ExpireTime; dwAffected = right.dwAffected; dwAffectMask = right.dwAffectMask; dwFamily = right.dwFamily; fAdjustment = right.fAdjustment; } return *this; } }; //! The cSkillInfo structure is generated for each skill your character has to store information on that skill. struct cSkillInfo { //! The skill's "friendly" name (i.e. - "War Magic") std::string m_szName; //! The index number of the first attribute that this skill is derived from. long m_nAttribute1; //! The index number of the second attribute that this skill is derived from. long m_nAttribute2; //! The divisor for the skill. For example, War Magic is Focus + Self / 4, so the denominator is 4. long m_nDenominator; //! The skill's offset from the "formula base." Think of this as the number of times you incremented the skill directly. long m_nOffset; //! The amount of experience put into this skill directly. long m_nExp; //! The bonus added to this skill (+10 for a specialized skill, +5 for a creation-time train). long m_nBonus; //! The way this skill is trained (i.e. - "Untrained," "Trained," or "Specialized") represented by the enumeration eTrainingType. eTrainingType m_trained; }; //! The cAttributeInfo structure is generated for each attribute your character has to store information on the attribute. struct cAttributeInfo { //! The attribute's "friendly" name (i.e. - "Strength") std::string m_szName; //! The attribute's "base" value, or value before buffs. long m_nBase; //! The amount of experience applied to this attribute. long m_nExp; //! The adjusted value of the attribute taking (de)buffs into effect. long m_nCurrent; }; //! The cAllegianceInfo structure is generated for each allegiance contact your character has to store information on that character. struct cAllegianceInfo { //! The GUID of this character's Patron. long TreeParent; //! This character's GUID. long GUID; //! The node type for this entry in relation to your character. long Type; //! The amount of xp you have passed up to this character/this character has passed to you. long XP; //! The character's gender. long Gender; //! The character's race. long Race; //! The character's allegiance rank. long Rank; //! The character's loyalty (as of the moment the data was received--when the allegiance panel was opened, including buffs). long Loyalty; //! The character's leadership (as of the moment the data was received--when the allegiance panel was opened, including buffs). long Leadership; //! Some unknown in the protocol. It's stored here so you can experiment with it! double Unknown; //! The character's name. char Name[32]; }; private: //! An internal pointer to decal's NetService interface. CComPtr< INetService > m_pService; //! An internal pointer to decal's main interface. CComPtr< IDecal > m_pDecal; //Bases //! Whether or not we've received login information for a character yet /*! Initially set to false, GotLogin is used internally to represent whether we've received login information for a character yet. Functions check this variable before doing any processing so that they may intentionally error as there is no information on the user's character before login information is received. \sa GotAlleg */ bool GotLogin; //! Our character's GUID. DWORD GUID; //! Our character's name. char Name[32]; //! Our character's gender. char Gender[32]; //! Our character's race. char Race[32]; //! Our character's class/title. char Class[32]; public: // DWORD array representing the values of our character's primary attributes. DWORD PrimStat[6]; // DWORD array representing the initial (creation) values of your character's primary attributes. DWORD PrimStatInitial[6]; // DWORD array representing the number of times our vitals have been directly incremented. DWORD SecStatInc[3]; // DWORD array representing the number of times our skills have been directly incremented. DWORD SkillInc[40]; // DWORD array representing the training status of each skill. (Current protocol: 1 = Untrained/Unusable, 2 = Trained, 3 = Specialized) DWORD SkillTrain[40]; // DWORD array representing the amount of experience applied directly to each skill. DWORD SkillXP[40]; // DWORD array representing the bonus each skill receives (+10 for specialization, +5 for creation-time train). DWORD SkillBonus[40]; private: //! An internal list used to store all the enchantments on the character. std::list< cEnchantment * > Enchantments; //! Internal storage for our character's total burden. DWORD TotalBurden; //! Internal storage for the number of pyreals our character owns. DWORD TotalPyreal; //! Internal storage for our character's total experience. DWORD TotalXP; //! Internal storage for our character's unsassigned experience. DWORD UnassignedXP; //! Internal storage for the number of skill points our character has available. DWORD SkillPoints; //! Internal storage for our character's level. DWORD Level; //! Internal storage for our character's allegiance rank. DWORD Rank; //! Internal storage for our character's burden percentage. (0-300%) float Burden; //! Internal Location_t for storing our character's location. Location_t Location; //Current Stuff //! Internal storage for our character's "current" or "adjusted" attributes. DWORD CurStat[6]; //! Internal storage for our character's "current" or "adjusted" vitals. DWORD CurSecStat[3]; //! Internal storage for our character's "current" or "adjusted" skills. DWORD CurSkill[40]; //! Internal storage originally allocated for our character's drain spell range. (Note by Eckzow on 7-31-03: I can't find record of this being set to anything useful...) double DrainRange; //! Internal storage originally allocated for our character's harm spell range. (Note by Eckzow on 7-31-03: I can't find record of this being set to anything useful...) double HarmRange; //! Internal storage allocated for our character's current number of health points. int Health; //! Internal storage allocated for our character's current number of stamina points. int Stamina; //! Internal storage allocated for our character's current number of mana points. int Mana; //! Internal storage for our percantage of vitae. float Vitae; void __stdcall onMessage(IMessage* pMsg); //! Internal function to add a spell to our (also internal) list of enchantments on the character. void AddEnchant(int SpellID, int Layer, double Duration, DWORD Family, double Elapsed, DWORD AffectMask, DWORD Affected, float Adjustment); //! Internal function called to remove a spell from our (also internal) list of enchantments on the character. void RemoveEnchant(int SpellID, int Layer); //! Internal function to trigger a recalculation of a specific stat. /*! \sa RecalcSecStat(), RecalcSkill() \param Stat Index of the stat to be recalculated. */ void RecalcStat(int Stat); //! Internal function to trigger a recalculation of all our character's vitals. /*! This function is necessary to keep our "adjusted" values up to date as an enchantment is cast, a spell expires, the user increments their stat, etc. \sa RecalcSkills() */ void RecalcSecStats(); //! Internal function to trigger a recalculation of a specific vital. /*! \sa RecalcStat(), RecalcSkill() \param SecStat Index of the vital to be recalculated. */ void RecalcSecStat(int SecStat); //! Internal function to trigger a recalculation of all our character's skills. /*! This function is necessary to keep our "adjusted" values up to date as an enchantment is cast, a spell expires, the user increments their stat, etc. \sa RecalcSecStats() */ void RecalcSkills(); //! Internal function to trigger a recalculation of a specific skill. /*! \sa RecalcSecStat(), RecalcSkill() \param Skill Index of the skill to be recalculated. */ void RecalcSkill(int Skill); //Other //! Internal storage for the name of the server we're on. char Server[50]; //! Internal storage for the id's of spells we've learned. std::set< DWORD > SpellsLearned; //! Internal storage for our monarch's allegiance information. cAllegianceInfo Monarch; //! Internal storage for our patron's allegiance information. cAllegianceInfo Patron; //! Internal storage for our own allegiance information. cAllegianceInfo MyAlleg; //! Internal storage array for each vassal's allegiance information. cAllegianceInfo Vassals[12]; //! Internal storage for the number of vassals our character has. int VassalCount; //! Internal storage for the number of followers you specifically have. DWORD Followers; //! Internal storage for the number of followers your monarchy has. DWORD MonarchFollowers; //! Whether or not we've received allegiance information for our character yet /*! Initially set to false, GotAlleg is used internally to represent whether we've received allegiance information for a character yet. Functions involving allegiance check this variable before doing any processing so that they may intentionally error as there is no allegiance information for the user's character before an allegiance information packet is received. \sa GotLogin */ bool GotAlleg; //! Internal storage for the number of deaths our character has. DWORD Deaths; //! Internal storage for the number of birthes our character has. DWORD Birth; //! Internal storage for the age of our characters (like /age this should not be taken as the gospel truth as it can be off by quite a bit) DWORD Age; public: STDMETHOD(Initialize)(INetService *pService); STDMETHOD(Terminate)(); STDMETHOD(DispatchServer)(IMessage2 *); STDMETHOD(DispatchClient)(IMessage2 *); //Old Stuff //! Function to get the number of spells our character has learned. /*! \param pVal Pointer to a long where the number of spells can be stored. \return E_FAIL if the character has not yet logged in, otherwise S_OK. \sa get_SpellLearned() */ STDMETHOD(get_TotalSpells)(/*[out, retval]*/ long *pVal); //! Function to find out if a specific spell is known to our character or not. /*! \param SpellID The id of the spell (from portal.dat) that you wish to check. \param pVal Pointer to a long where the status of the spell will be stored. pVal is set equal to false (0) if the spell is unknown or true (1) if it is. \return E_FAIL if the character is not logged in or if the spellID supplied was invalid. If sucessful, S_OK is returned. pVal will also be set to -1 if the spell id was invalid. \sa get_TotalSpells() */ STDMETHOD(get_SpellLearned)(long SpellID, /*[out, retval]*/ long *pVal); // ICharacterStats //! Function to get the class/title of our character. /*! \param pVal Pointer to a BSTR object where the class/title of the character may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_ClassTemplate)(/*[out, retval]*/ BSTR *pVal); //! Function to get the gender of our character. /*! \param pVal Pointer to a BSTR object where the gender of the character may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Gender)(/*[out, retval]*/ BSTR *pVal); //! Function to get the race of our character. /*! \param pVal Pointer to a BSTR object where the race of the character may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Race)(/*[out, retval]*/ BSTR *pVal); //! Function to get the name of our character. /*! \param pVal Pointer to a BSTR object where the name of the character may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Name)(/*[out, retval]*/ BSTR *pVal); //! Function to get the server our character is on. /*! \param pVal Pointer to a BSTR object where the name of the server our character is on may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Server)(/*[out, retval]*/ BSTR *pVal); //! Function to get the number of skill points available to our character. /*! \param pVal Pointer to a long where the number of skill points may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_SkillPoints)(/*[out, retval]*/ long *pVal); //! Function to get the amount of unassigned experience available to our character. /*! \param pVal Pointer to a long where the number of unassigned experience points may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_UnassignedExp)(/*[out, retval]*/ long *pVal); //! Function to get the amound of total experience our character has earned. /*! \param pVal Pointer to a long where the number experience points our character has earned may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_TotalExp)(/*[out, retval]*/ long *pVal); //! Function to get our character's allegiance rank. /*! \param pVal Pointer to a long where our character's allegiance rank may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Rank)(/*[out, retval]*/ long *pVal); //! Function to get our character's level. /*! \param pVal Pointer to a long where our character's level may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Level)(/*[out, retval]*/ long *pVal); //! Function to get our character's GUID. /*! \param pVal Pointer to a long where our character's GUID may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Character)(/*[out, retval]*/ long *pVal); //! Function to get the number of vitals that the filter is storing information for. /*! \param pVal Pointer to a long where the number of vitals the filter is tracking may be stored. \return S_OK if successful. */ STDMETHOD(get_VitalCount)(/*[out, retval]*/ long *pVal); //! Function to get the number of skills that the filter is storing information for. /*! \param pVal Pointer to a long where the number of skills the filter is tracking may be stored. \return S_OK if successful. */ STDMETHOD(get_SkillCount)(/*[out, retval]*/ long *pVal); //! Function to get the number of attributes that the filter is storing information for. /*! \param pVal Pointer to a long where the number of attributes the filter is tracking may be stored. \return S_OK if successful. */ STDMETHOD(get_AttributeCount)(/*[out, retval]*/ long *pVal); //! Function to get information on a given vital. /*! Using get_Vital to get in-depth information on a vital statistic is approved, however the function has been deprecated for simply getting the vital's value/it's base by the new GetVital ACHooks. \param Index A member of the eVitalID enumeration representing which vital you wish to obtain information for. \param pVal A pointer to an ISkillInfo in which the vital's information may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise the result of the ISkillInfo's QueryInterface. */ STDMETHOD(get_Vital)(enum eVitalID Index, /*[out, retval]*/ ISkillInfo ** pVal); //! Function to get information on a given skill. /*! Using get_Skill to get in-depth information on a skill is approved, however the function has been deprecated for simply getting the skill's value/it's base by the new GetSkill ACHooks. \param Index A member of the eSkillID enumeration representing which skill you wish to obtain information for. \param pVal A pointer to an ISkillInfo in which the vital's information may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise the result of the ISkillInfo's QueryInterface. */ STDMETHOD(get_Skill)(enum eSkillID Index, /*[out, retval]*/ ISkillInfo ** pVal); //! Function to get information on a given attribute. /*! Using get_Attribute to get in-depth information on an attribute is approved, however the function has been deprecated for simply getting the attribute's value/it's base by the new GetAttribute ACHooks. \param Index A member of the eAttributeID enumeration representing which vital you wish to obtain information for. \param pVal A pointer to an IAttributeInfo in which the vital's information may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise the result of the IAttributeInfo's QueryInterface. */ STDMETHOD(get_Attribute)(enum eAttributeID Index, /*[out, retval]*/ IAttributeInfo ** pVal); //New Stuff //! Function to get the allegiance information for your monarch. /*! \param pVal Pointer to an IAllegianceInfo into which the monarch's information may be stored. \return E_FAIL if an allegiance information packet has not been received or you have no monarch, otherwise the result of the IAllegianceInfo's QueryInterface. */ STDMETHOD(get_Monarch)(IAllegianceInfo ** pVal); //! Function to get the allegiance information for your patron. /*! \param pVal Pointer to an IAllegianceInfo into which your patron's information may be stored. \return E_FAIL if an allegiance information packet has not been received or you have no patron, otherwise the result of the IAllegianceInfo's QueryInterface. */ STDMETHOD(get_Patron)(IAllegianceInfo ** pVal); //! Function to get the allegiance information for your character. /*! \param pVal Pointer to an IAllegianceInfo into which the character's information may be stored. \return E_FAIL if an allegiance information packet has not been received or is invalid, otherwise the result of the IAllegianceInfo's QueryInterface. */ STDMETHOD(get_MyAllegiance)(IAllegianceInfo ** pVal); //! Function to get the allegiance information for one of your vassals. /*! \param VassalNum A long signifying the zero-based index of the vassal who's information you wish to retrieve. \param pVal Pointer to an IAllegianceInfo into which your vassal's information may be stored. \return E_FAIL if an allegiance information packet has not been received, the index you supplied was invalid, or you have no vassal at that index. Otherwise the result of the IAllegianceInfo's QueryInterface is returned. */ STDMETHOD(get_Vassal)(long VassalNum, IAllegianceInfo ** pVal); //! Function to get the number of vassals your character has. /*! \param pVal Pointer to a long into which the number of vassals may be stored. \return E_FAIL if an allegiance information packet has not been received, otherwise S_OK. */ STDMETHOD(get_VassalCount)(long *pVal); //! Function to get the number of followers your character has. /*! \param pVal Pointer to a long into which the number of followers may be stored. \return E_FAIL if an allegiance information packet has not been received, otherwise S_OK. */ STDMETHOD(get_Followers)(long *pVal); //! Function to get the number of followers your monarchy has. /*! \param pVal Pointer to a long into which the number of followers may be stored. \return E_FAIL if an allegiance information packet has not been received, otherwise S_OK. */ STDMETHOD(get_MonarchFollowers)(long *pVal); //! Function to get our character's birthtime. /*! \param pVal Pointer to a long where our character's birthtime (UNIX time) may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Birth)(long *pVal); //! Function to get our character's age. /*! \param pVal Pointer to a long where our character's age (in seconds) may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Age)(long *pVal); //! Function to get our character's death count. /*! \param pVal Pointer to a long where the number of times our character has died may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Deaths)(long *pVal); //! Function to get our character's current Health. /*! \param pVal Pointer to a long where our character's current Health may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Health)(long *pVal); //! Function to get our character's current Stamina. /*! \param pVal Pointer to a long where our character's current Stamina may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Stamina)(long *pVal); //! Function to get our character's current Mana. /*! \param pVal Pointer to a long where our character's current Mana may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Mana)(long *pVal); //! Function to get the number of enchantments currently affecting our character. /*! \param pVal Pointer to a long where the number of enchantments may be stored. \return E_FAIL if the character is not yet logged in, else S_OK. */ STDMETHOD(get_EnchantmentCount)(long *pVal); //! Function to get detailed information on an enchantment. /*! \param EnchantNum Zero-based index of the enchantment you wish to get information for. \param pVal Pointer to an IEnchantment where the enchantment's information may be stored. */ STDMETHOD(get_Enchantment)(long EnchantNum, IEnchantment **pVal); //! Function to get the value of a given vital. /*! Usage of this function has been deprecated due to the release of the new GetVital ACHook. \param Index A member of the eVitalID enumeration representing which vital you wish to obtain the value of. \param pVal A pointer to a long where the vital's value may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise S_OK. */ STDMETHOD(get_EffectiveVital)(enum eVitalID Index, /*[out, retval]*/ long *pVal); //! Function to get the value of a given skill. /*! Usage of this function has been deprecated due to the release of the new GetSkill ACHook. \param Index A member of the eSkillID enumeration representing which skill you wish to obtain the value of. \param pVal A pointer to a long where the skill's value may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise S_OK. */ STDMETHOD(get_EffectiveSkill)(enum eSkillID Index, /*[out, retval]*/ long *pVal); //! Function to get the value of a given attribute. /*! Usage of this function has been deprecated due to the release of the new GetAttribute ACHook. \param Index A member of the eAttributeID enumeration representing which vital you wish to obtain the value of. \param pVal A pointer to a long where the attribute's value may be stored. \return E_FAIL if the character is not logged in or if the Index parameter is out of range, otherwise S_OK. */ STDMETHOD(get_EffectiveAttribute)(enum eAttributeID Index, /*[out, retval]*/ long * pVal); //! Function to get our character's vitae percentage. /*! \param pVal Pointer to a long where the percentage vitae penalty our character has aquired may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Vitae)(/*[out, retval]*/ long *pVal); //! Function to get our character's current number of burden units. /*! \param pVal Pointer to a long where the number of burden units our character is carrying may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_BurdenUnits)(/*[out, retval]*/ long *pVal); //! Function to get our character's burden percentage. /*! \param pVal Pointer to a long where our character's current burden percentage may be stored. \return E_FAIL if the character is not logged in, otherwise S_OK. */ STDMETHOD(get_Burden)(/*[out, retval]*/ long *pVal); }; #endif //__CHARACTERSTATS_H_