Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

588 lines
24 KiB

  1. //====== Copyright �, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: CEconItem, a shared object for econ items
  4. //
  5. //=============================================================================
  6. #ifndef ECONITEM_H
  7. #define ECONITEM_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "gcsdk/gcclientsdk.h"
  12. #include "base_gcmessages.pb.h"
  13. #include "econ_item_constants.h"
  14. #include "econ_item_interface.h"
  15. #include "econ_item_schema.h"
  16. #include <typeinfo> // needed for typeid()
  17. #define ENABLE_TYPED_ATTRIBUTE_PARANOIA 1
  18. namespace GCSDK
  19. {
  20. class CColumnSet;
  21. };
  22. class CEconItem;
  23. class CSOEconItem;
  24. class CEconItemCustomData;
  25. class CEconSessionItemAudit;
  26. //-----------------------------------------------------------------------------
  27. // Stats tracking for the attributes attached to CEconItem instances.
  28. //-----------------------------------------------------------------------------
  29. struct schema_attribute_stat_bucket_t
  30. {
  31. const schema_attribute_stat_bucket_t *m_pNext;
  32. const char *m_pszDesc;
  33. uint64 m_unLiveInlineCount;
  34. uint64 m_unLifetimeInlineCount;
  35. uint64 m_unLiveHeapCount;
  36. uint64 m_unLifetimeHeapCount;
  37. void OnAllocateInlineInstance() { m_unLiveInlineCount++; m_unLifetimeInlineCount++; }
  38. void OnFreeInlineInstance() { /* temporarily disabling to avoid spew until the rest of the minor attribute changelists are brought from TF to Dota: -> Assert( m_unLiveInlineCount > 0 ); */ m_unLiveInlineCount--; }
  39. void OnAllocateHeapInstance() { m_unLiveHeapCount++; m_unLifetimeHeapCount++; }
  40. void OnFreeHeapInstance() { Assert( m_unLiveHeapCount ); m_unLiveHeapCount--; }
  41. };
  42. class CSchemaAttributeStats
  43. {
  44. public:
  45. template < typename TAttribStatsStorageClass, typename TAttribInMemoryType >
  46. static void RegisterAttributeType()
  47. {
  48. TAttribStatsStorageClass::s_InstanceStats.m_pszDesc = typeid( TAttribInMemoryType ).name();
  49. TAttribStatsStorageClass::s_InstanceStats.m_pNext = m_pHead;
  50. m_pHead = &TAttribStatsStorageClass::s_InstanceStats;
  51. }
  52. static const schema_attribute_stat_bucket_t *GetFirstStatBucket()
  53. {
  54. return m_pHead;
  55. }
  56. private:
  57. static const schema_attribute_stat_bucket_t *m_pHead;
  58. };
  59. //-----------------------------------------------------------------------------
  60. // Base class interface for attributes of a certain in-memory type.
  61. //-----------------------------------------------------------------------------
  62. template < typename T >
  63. unsigned int GetAttributeTypeUniqueIdentifier();
  64. template < typename TAttribInMemoryType >
  65. class ISchemaAttributeTypeBase : public ISchemaAttributeType
  66. {
  67. friend class CSchemaAttributeStats;
  68. public:
  69. ISchemaAttributeTypeBase()
  70. {
  71. CSchemaAttributeStats::RegisterAttributeType< ISchemaAttributeTypeBase<TAttribInMemoryType>, TAttribInMemoryType >();
  72. }
  73. virtual void LoadEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const union attribute_data_union_t& value ) const OVERRIDE;
  74. // Returns a unique identifier per run based on the type of <TAttribInMemoryType>.
  75. virtual unsigned int GetTypeUniqueIdentifier() const OVERRIDE
  76. {
  77. return GetAttributeTypeUniqueIdentifier<TAttribInMemoryType>();
  78. }
  79. // ...
  80. void ConvertTypedValueToEconAttributeValue( const TAttribInMemoryType& typedValue, attribute_data_union_t *out_pValue ) const
  81. {
  82. // If our type is smaller than an int, we don't know how to copy the memory into our flat structure. We could write
  83. // this code but we have no use case for it now so this is set up to fail so if someone does come up with a use case
  84. // they know where to fix.
  85. COMPILE_TIME_ASSERT( sizeof( TAttribInMemoryType ) >= sizeof( uint32 ) );
  86. // Do we fit in the bottom 32-bits?
  87. if ( sizeof( TAttribInMemoryType ) <= sizeof( uint32 ) )
  88. {
  89. *reinterpret_cast<TAttribInMemoryType *>( &out_pValue->asUint32 ) = typedValue;
  90. }
  91. // What about in the full 64-bits (if we're running a 64-bit build)?
  92. else if ( sizeof( TAttribInMemoryType ) <= sizeof( void * ) )
  93. {
  94. *reinterpret_cast<TAttribInMemoryType *>( &out_pValue->asBlobPointer ) = typedValue;
  95. }
  96. // We're too big for our flat structure. We need to allocate space somewhere outside our attribute instance and point
  97. // to that.
  98. else
  99. {
  100. if ( !out_pValue->asBlobPointer )
  101. {
  102. InitializeNewEconAttributeValue( out_pValue );
  103. }
  104. *reinterpret_cast<TAttribInMemoryType *>( out_pValue->asBlobPointer ) = typedValue;
  105. }
  106. }
  107. // Guaranteed to return a valid reference (or assert/crash if calling code is behaving inappropriately and calling
  108. // this before an attribute value is allocated/set).
  109. const TAttribInMemoryType& GetTypedValueContentsFromEconAttributeValue( const attribute_data_union_t& value ) const
  110. {
  111. COMPILE_TIME_ASSERT( sizeof( TAttribInMemoryType ) >= sizeof( uint32 ) );
  112. // Do we fit in the bottom 32-bits?
  113. if ( sizeof( TAttribInMemoryType ) <= sizeof( uint32 ) )
  114. return *reinterpret_cast<const TAttribInMemoryType *>( &value.asUint32 );
  115. // What about in the full 64-bits (if we're running a 64-bit build)?
  116. if ( sizeof( TAttribInMemoryType ) <= sizeof( void * ) )
  117. return *reinterpret_cast<const TAttribInMemoryType *>( &value.asBlobPointer );
  118. // We don't expect to get to a "read value" call without having written a value, which would
  119. // have allocated this memory.
  120. Assert( value.asBlobPointer );
  121. return *reinterpret_cast<const TAttribInMemoryType *>( value.asBlobPointer );
  122. }
  123. void ConvertEconAttributeValueToTypedValue( const attribute_data_union_t& value, TAttribInMemoryType *out_pTypedValue ) const
  124. {
  125. Assert( out_pTypedValue );
  126. *out_pTypedValue = GetTypedValueContentsFromEconAttributeValue( value );
  127. }
  128. void InitializeNewEconAttributeValue( attribute_data_union_t *out_pValue ) const OVERRIDE
  129. {
  130. if ( sizeof( TAttribInMemoryType ) <= sizeof( uint32 ) )
  131. {
  132. new( &out_pValue->asUint32 ) TAttribInMemoryType;
  133. s_InstanceStats.OnAllocateInlineInstance();
  134. }
  135. else if ( sizeof( TAttribInMemoryType ) <= sizeof( void * ) )
  136. {
  137. new( &out_pValue->asBlobPointer ) TAttribInMemoryType;
  138. s_InstanceStats.OnAllocateInlineInstance();
  139. }
  140. else
  141. {
  142. out_pValue->asBlobPointer = reinterpret_cast<byte *>( new TAttribInMemoryType );
  143. s_InstanceStats.OnAllocateHeapInstance();
  144. }
  145. }
  146. virtual void UnloadEconAttributeValue( attribute_data_union_t *out_pValue ) const OVERRIDE
  147. {
  148. COMPILE_TIME_ASSERT( sizeof( TAttribInMemoryType ) >= sizeof( uint32 ) );
  149. // For smaller types, anything that fits inside the bits of a void pointer, we store the contents
  150. // inline and only have to worry about calling the correct destructor. We check against the small-/
  151. // size/medium-size values separately to not worry about which bits we're storing the uint32 in.
  152. if ( sizeof( TAttribInMemoryType ) <= sizeof( uint32 ) )
  153. {
  154. (reinterpret_cast<TAttribInMemoryType *>( &out_pValue->asUint32 ))->~TAttribInMemoryType();
  155. s_InstanceStats.OnFreeInlineInstance();
  156. }
  157. else if ( sizeof( TAttribInMemoryType ) <= sizeof( void * ) )
  158. {
  159. (reinterpret_cast<TAttribInMemoryType *>( &out_pValue->asBlobPointer ))->~TAttribInMemoryType();
  160. s_InstanceStats.OnFreeInlineInstance();
  161. }
  162. // For larger types, we have the memory stored on the heap somewhere. We don't have to manually
  163. // destruct, but we do have to manually free.
  164. else
  165. {
  166. if ( !out_pValue->asBlobPointer )
  167. return;
  168. delete reinterpret_cast<TAttribInMemoryType *>( out_pValue->asBlobPointer );
  169. s_InstanceStats.OnFreeHeapInstance();
  170. }
  171. }
  172. virtual bool OnIterateAttributeValue( IEconItemAttributeIterator *pIterator, const CEconItemAttributeDefinition *pAttrDef, const attribute_data_union_t& value ) const OVERRIDE
  173. {
  174. Assert( pIterator );
  175. Assert( pAttrDef );
  176. // Call the appropriate virtual function on our iterator based on whatever type we represent.
  177. return pIterator->OnIterateAttributeValue( pAttrDef, GetTypedValueContentsFromEconAttributeValue( value ) );
  178. }
  179. virtual void LoadByteStreamToEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const std::string& sBytes ) const OVERRIDE;
  180. virtual void ConvertEconAttributeValueToByteStream( const attribute_data_union_t& value, ::std::string *out_psBytes ) const;
  181. virtual void ConvertTypedValueToByteStream( const TAttribInMemoryType& typedValue, ::std::string *out_psBytes ) const = 0;
  182. virtual void ConvertByteStreamToTypedValue( const ::std::string& sBytes, TAttribInMemoryType *out_pTypedValue ) const = 0;
  183. private:
  184. static schema_attribute_stat_bucket_t s_InstanceStats;
  185. };
  186. template < typename TAttribInMemoryType >
  187. schema_attribute_stat_bucket_t ISchemaAttributeTypeBase<TAttribInMemoryType>::s_InstanceStats;
  188. class CEconItem : public GCSDK::CSharedObject, public IEconItemInterface
  189. {
  190. public:
  191. typedef GCSDK::CSharedObject BaseClass;
  192. struct attribute_t
  193. {
  194. attrib_definition_index_t m_unDefinitionIndex; // stored as ints here for memory efficiency on the GC
  195. attribute_data_union_t m_value;
  196. private:
  197. void operator=( const attribute_t& rhs );
  198. };
  199. struct EquippedInstance_t
  200. {
  201. EquippedInstance_t() : m_unEquippedClass( 0 ), m_unEquippedSlot( INVALID_EQUIPPED_SLOT ) {}
  202. EquippedInstance_t( equipped_class_t unClass, equipped_slot_t unSlot ) : m_unEquippedClass( unClass ), m_unEquippedSlot( unSlot ) {}
  203. equipped_class_t m_unEquippedClass;
  204. equipped_slot_t m_unEquippedSlot;
  205. };
  206. struct CustomDataOptimizedObject_t
  207. {
  208. // This is preceding the attributes block, attributes tightly packed and follow immediately
  209. // 25% of CS:GO items have no attributes and don't allocate anything here
  210. // one attribute case = [uint16] + [uint16+uint32] = 8 bytes (SBH bucket 8)
  211. // 2 attributes case = [uint16]+2x[uint16+uint32] = 14 bytes (SBH bucket 16)
  212. // 3 attributes case = [uint16]+3x[uint16+uint32] = 20 bytes (SBH bucket 24) (60% of CS:GO items)
  213. // 4 attributes case = [uint16]+4x[uint16+uint32] = 26 bytes (SBH bucket 32)
  214. // 5 attributes case = [uint16]+4x[uint16+uint32] = 26 bytes (SBH bucket 32)
  215. uint16 m_equipInstanceSlot1 : 6; // Equip Instance Slot #6 // if equipped
  216. uint16 m_equipInstanceClass1 : 3; // Equip Instance Class #9
  217. uint16 m_equipInstanceClass2Bit : 1; // Whether the item is equipped for complementary class #10
  218. uint16 m_numAttributes : 6; // Length of following attributes #16
  219. // 32-bit GC size = 2 bytes!
  220. inline attribute_t * GetAttribute( uint32 j ) { return ( reinterpret_cast< attribute_t * >( this + 1 ) ) + j ; }
  221. inline const attribute_t * GetAttribute( uint32 j ) const { return ( reinterpret_cast< const attribute_t * >( this + 1 ) ) + j ; }
  222. private: // forbid all operations including constructor/destructor
  223. CustomDataOptimizedObject_t();
  224. CustomDataOptimizedObject_t( const CustomDataOptimizedObject_t & );
  225. ~CustomDataOptimizedObject_t();
  226. CustomDataOptimizedObject_t & operator=( const CustomDataOptimizedObject_t & );
  227. public:
  228. static CustomDataOptimizedObject_t *Alloc( uint32 numAttributes ); // allocates enough memory to include attributes
  229. static attribute_t * AddAttribute( CustomDataOptimizedObject_t * &rptr ); // reallocs the ptr
  230. void RemoveAndFreeAttrMemory( uint32 idxAttributeInArray ); // keeps the memory allocated
  231. void FreeObjectAndAttrMemory();
  232. };
  233. // Set only the top 16 bits for field ID types! These will be or'd into the index of
  234. // the field itself and then pulled apart later.
  235. enum
  236. {
  237. kUpdateFieldIDType_FieldID = 0x00000000, // this must stay as 0 for legacy code
  238. kUpdateFieldIDType_AttributeID = 0x00010000, // this will modify existing attribute in the database
  239. };
  240. const static int k_nTypeID = k_EEconTypeItem;
  241. virtual int GetTypeID() const { return k_nTypeID; }
  242. CEconItem();
  243. virtual ~CEconItem();
  244. private:
  245. CEconItem( const CEconItem &copy ); // no impl - don't want to allow accidental pass-by-value
  246. public:
  247. CEconItem &operator=( const CEconItem& rhs );
  248. // IEconItemInterface interface.
  249. const GameItemDefinition_t *GetItemDefinition() const;
  250. public:
  251. #ifndef GC_DLL
  252. virtual void SetSOUpdateFrame( int nNewValue ) const { m_bSOUpdateFrame = nNewValue; }
  253. virtual int GetSOUpdateFrame( void ) const { return m_bSOUpdateFrame; }
  254. #endif
  255. virtual void IterateAttributes( class IEconItemAttributeIterator *pIterator ) const;
  256. // Accessors/Settors
  257. virtual itemid_t GetItemID() const { return m_ulID; }
  258. void SetItemID( uint64 ulID );
  259. itemid_t GetOriginalID() const;
  260. void SetOriginalID( uint64 ulOriginalID );
  261. uint32 GetAccountID() const { return m_unAccountID; }
  262. void SetAccountID( uint32 unAccountID ) { m_unAccountID = unAccountID; }
  263. item_definition_index_t GetDefinitionIndex() const { return m_unDefIndex; }
  264. void SetDefinitionIndex( uint32 unDefinitionIndex ) { m_unDefIndex = unDefinitionIndex; }
  265. uint32 GetItemLevel() const { return m_unLevel; }
  266. void SetItemLevel( uint32 unItemLevel ) { m_unLevel = unItemLevel; }
  267. int32 GetQuality() const { return m_nQuality; }
  268. void SetQuality( int32 nQuality ) { m_nQuality = nQuality; }
  269. int32 GetRarity() const;
  270. void SetRarity( int32 nRarity ) { m_nRarity = nRarity; }
  271. uint32 GetInventoryToken() const { return m_unInventory; }
  272. void SetInventoryToken( uint32 unToken ) { m_unInventory = unToken; }
  273. uint16 GetQuantity() const;
  274. void SetQuantity( uint16 unQuantity );
  275. uint8 GetFlags() const { return m_unFlags; }
  276. void SetFlags( uint8 unFlags ) { m_unFlags = unFlags; }
  277. void SetFlag( uint8 unFlag ) { m_unFlags |= unFlag; }
  278. void ClearFlag( uint8 unFlag ) { m_unFlags &= ~unFlag; }
  279. bool CheckFlags( uint8 unFlags ) const { return ( m_unFlags & unFlags ) != 0; }
  280. eEconItemOrigin GetOrigin() const { return (eEconItemOrigin)m_unOrigin; }
  281. void SetOrigin( eEconItemOrigin unOrigin ) { m_unOrigin = unOrigin; Assert( m_unOrigin == unOrigin ); }
  282. bool IsForeign() const { return m_unOrigin == kEconItemOrigin_Foreign; }
  283. const char *GetCustomName() const;
  284. void SetCustomName( const char *pName );
  285. const char *GetCustomDesc() const;
  286. void SetCustomDesc( const char *pDesc );
  287. virtual int GetItemSetIndex() const;
  288. void InitAttributesDroppedFromListEntry( item_list_entry_t const *pEntryInfo );
  289. bool IsEquipped() const;
  290. bool IsEquippedForClass( equipped_class_t unClass ) const;
  291. equipped_slot_t GetEquippedPositionForClass( equipped_class_t unClass ) const;
  292. void UpdateEquippedState( equipped_class_t unClass, equipped_slot_t unSlot ) { UpdateEquippedState( EquippedInstance_t( unClass, unSlot ) ); }
  293. void UpdateEquippedState( EquippedInstance_t equipInstance );
  294. virtual bool GetInUse() const;
  295. void SetInUse( bool bInUse );
  296. bool IsTradable() const;
  297. bool IsMarketable() const;
  298. bool IsUsableInCrafting() const;
  299. // --------------------------------------------------------------------------------------------
  300. // Typed attributes. These are methods for accessing and setting values of attributes with
  301. // some semblance of type information and type safety.
  302. // --------------------------------------------------------------------------------------------
  303. // Assign the value of the attribute [pAttrDef] to [value]. Passing in a type for [value] that
  304. // doesn't match the storage type specified by the attribute definition will fail asserts a bunch
  305. // of asserts all the way down the stack and may or may not crash -- it would be nice to make this
  306. // fail asserts at compile time.
  307. //
  308. // This function has undefined results (besides asserting) if called to add a dynamic version of
  309. // an attrib that's already specified statically.
  310. template < typename T >
  311. void SetDynamicAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const T& value )
  312. {
  313. Assert( pAttrDef );
  314. const ISchemaAttributeTypeBase<T> *pAttrType = GetTypedAttributeType<T>( pAttrDef );
  315. Assert( pAttrType );
  316. if ( !pAttrType )
  317. return;
  318. // Fail right off the bat if we're trying to write a dynamic attribute value for an item that already
  319. // has this as a static value.
  320. /*
  321. AssertMsg( !::FindAttribute( GetItemDefinition(), pAttrDef ),
  322. "Item id %llu (%s) attempting to set dynamic attribute value for '%s' (%d) when static attribute exists!",
  323. GetItemID(), GetItemDefinition()->GetDefinitionName(), pAttrDef->GetDefinitionName(), pAttrDef->GetDefinitionIndex() );
  324. */
  325. // Alright, we have a data type match so we can safely store data. Some types may need to initialize
  326. // their data to a current state if it's the first time we're writing to this value (as opposed to
  327. // updating an existing value).
  328. attribute_t *pEconAttrib = FindDynamicAttributeInternal( pAttrDef );
  329. if ( !pEconAttrib )
  330. {
  331. pEconAttrib = &(AddDynamicAttributeInternal());
  332. pEconAttrib->m_unDefinitionIndex = pAttrDef->GetDefinitionIndex();
  333. pAttrType->InitializeNewEconAttributeValue( &pEconAttrib->m_value );
  334. }
  335. pAttrType->ConvertTypedValueToEconAttributeValue( value, &pEconAttrib->m_value );
  336. #if ENABLE_TYPED_ATTRIBUTE_PARANOIA
  337. // Paranoia!: make sure that our read/write functions are mirrored correctly, and that if we attempt
  338. // to read back a value we get something identical to what we just wrote. We do this via converting
  339. // to strings and then comparing those because there may or not be equality comparisons for our type
  340. // T that make sense (ie., protobufs).
  341. {
  342. T readValue;
  343. DbgVerify( FindAttribute( pAttrDef, &readValue ) );
  344. std::string sBytes, sReadBytes;
  345. pAttrType->ConvertTypedValueToByteStream( value, &sBytes );
  346. pAttrType->ConvertTypedValueToByteStream( readValue, &sReadBytes );
  347. AssertMsg1( sBytes == sReadBytes, "SetDynamicAttributeValue(): read/write mismatch for attribute '%s'.", pAttrDef->GetDefinitionName() );
  348. }
  349. #endif // ENABLE_TYPED_ATTRIBUTE_PARANOIA
  350. }
  351. // Remove an instance of an attribute from this item. This will also free any dynamic memory associated
  352. // with that instance if any was allocated.
  353. void RemoveDynamicAttribute( const CEconItemAttributeDefinition *pAttrDef );
  354. // Copy all attributes and values in a type-safe way from [source] to ourself. Attributes that we have
  355. // that don't exist on [source] will maintain their current values. All other attributes will get their
  356. // values set to whatever [source] specifies.
  357. void CopyAttributesFrom( const CEconItem& source );
  358. // Copy everything about the item without the attributes
  359. void CopyWithoutAttributesFrom( const CEconItem& source );
  360. private:
  361. template < typename T >
  362. static const ISchemaAttributeTypeBase<T> *GetTypedAttributeType( const CEconItemAttributeDefinition *pAttrDef )
  363. {
  364. // Make sure the type of data we're passing in matches the type of data we're claiming that we can
  365. // store in the attribute definition.
  366. const ISchemaAttributeType *pIAttr = pAttrDef->GetAttributeType();
  367. Assert( pIAttr );
  368. Assert( pIAttr->GetTypeUniqueIdentifier() == GetAttributeTypeUniqueIdentifier<T>() );
  369. #if ENABLE_TYPED_ATTRIBUTE_PARANOIA
  370. return dynamic_cast<const ISchemaAttributeTypeBase<T> *>( pIAttr );
  371. #else
  372. return static_cast<const ISchemaAttributeTypeBase<T> *>( pIAttr );
  373. #endif
  374. }
  375. public:
  376. void AddCustomAttribute( uint16 usDefinitionIndex, float flValue );
  377. void AddOrSetCustomAttribute( uint16 usDefinitionIndex, float flValue );
  378. bool BDeserializeFromKV( KeyValues *pKVItem, const CEconItemSchema &pschema, CUtlVector<CUtlString> *pVecErrors = NULL );
  379. virtual bool BParseFromMessage( const CUtlBuffer &buffer ) OVERRIDE;
  380. virtual bool BParseFromMessage( const std::string &buffer ) OVERRIDE;
  381. virtual bool BUpdateFromNetwork( const CSharedObject & objUpdate ) OVERRIDE;
  382. virtual bool BAddToMessage( std::string *pBuffer ) const OVERRIDE; // short cut to remove an extra copy
  383. virtual bool BAddDestroyToMessage( std::string *pBuffer ) const OVERRIDE;
  384. virtual bool BIsKeyLess( const CSharedObject & soRHS ) const ;
  385. virtual void Copy( const CSharedObject & soRHS );
  386. virtual void Dump() const;
  387. void SerializeToProtoBufItem( CSOEconItem &msgItem ) const;
  388. void DeserializeFromProtoBufItem( const CSOEconItem &msgItem );
  389. typedef CUtlVectorFixed< CEconItem::EquippedInstance_t, 2 > EquippedInstanceArray_t;
  390. int GetEquippedInstanceArray( EquippedInstanceArray_t &equips ) const;
  391. protected:
  392. // CSharedObject
  393. // adapted from CSchemaSharedObject
  394. void GetDirtyColumnSet( const CUtlVector< int > &fields, GCSDK::CColumnSet &cs ) const;
  395. void OnTransferredOwnership();
  396. // Internal attribute interface.
  397. friend class CWebAPIStringExporterAttributeIterator;
  398. attribute_t& AddDynamicAttributeInternal(); // add another chunk of data to our internal storage to store a new attribute -- initialization is the responsibility of the caller
  399. attribute_t *FindDynamicAttributeInternal( const CEconItemAttributeDefinition *pAttrDef ); // search for an instance of a dynamic attribute with this definition -- ignores static properties, etc. and will return NULL if not found
  400. int GetDynamicAttributeCountInternal() const; // how many attributes are there attached to this instance?
  401. const attribute_t & GetDynamicAttributeInternal( int iAttrIndexIntoArray ) const;
  402. public:
  403. //
  404. // GC object data breakdown (32-bit build)
  405. //
  406. // already starting with TWO VTBLS due to multiple inheritance :(
  407. // 8 bytes spent on VTBLS
  408. //
  409. // data that is most commonly changed
  410. uint64 m_ulID; // Item ID
  411. uint64 m_ulOriginalID; // Original ID is often different from item ID itself
  412. // optional data (custom name, additional attributes, etc.)
  413. CustomDataOptimizedObject_t *m_pCustomDataOptimizedObject;
  414. uint32 m_unAccountID; // Item Owner
  415. uint32 m_unInventory; // App managed int representing inventory placement
  416. // === + 7*4 = 36 bytes here already, uint16 packing below ===
  417. item_definition_index_t m_unDefIndex; // Item definition index +16
  418. uint16 m_unOrigin : 5; // Origin (eEconItemOrigin) (0-31) #5
  419. uint16 m_nQuality : 4; // Item quality (0-14) #9
  420. uint16 m_unLevel:2; // Item Level (0-1-2-3) #11
  421. uint16 m_nRarity:4; // Item rarity (0-14) #15
  422. uint16 m_dirtybitInUse:1; // In Use #16
  423. protected:
  424. mutable int16 m_iItemSet; // packs it tightly with defindex field
  425. mutable int m_bSOUpdateFrame;
  426. public:
  427. uint8 m_unFlags; // Flags
  428. // + 6 bytes = 42 bytes total (in 32-bit build)
  429. static void FreeAttributeMemory( CEconItem::attribute_t *pAttrib );
  430. };
  431. //-----------------------------------------------------------------------------
  432. // Purpose:
  433. //-----------------------------------------------------------------------------
  434. template < typename TAttribInMemoryType >
  435. /*virtual*/ void ISchemaAttributeTypeBase<TAttribInMemoryType>::LoadByteStreamToEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const std::string& sBytes ) const
  436. {
  437. Assert( pTargetItem );
  438. Assert( pAttrDef );
  439. TAttribInMemoryType typedValue;
  440. ConvertByteStreamToTypedValue( sBytes, &typedValue );
  441. pTargetItem->SetDynamicAttributeValue( pAttrDef, typedValue );
  442. }
  443. //-----------------------------------------------------------------------------
  444. // Purpose:
  445. //-----------------------------------------------------------------------------
  446. template < typename TAttribInMemoryType >
  447. /*virtual*/ void ISchemaAttributeTypeBase<TAttribInMemoryType>::ConvertEconAttributeValueToByteStream( const attribute_data_union_t& value, ::std::string *out_psBytes ) const
  448. {
  449. ConvertTypedValueToByteStream( GetTypedValueContentsFromEconAttributeValue( value ), out_psBytes );
  450. }
  451. bool ItemsMatch( CEconItemView *pCurItem, CEconItemView *pNewItem );
  452. class CEconDefaultEquippedDefinitionInstanceClient : public GCSDK::CProtoBufSharedObject< CSOEconDefaultEquippedDefinitionInstanceClient, k_EEconTypeDefaultEquippedDefinitionInstanceClient >
  453. {
  454. public:
  455. const static int k_nTypeID = k_EEconTypeDefaultEquippedDefinitionInstanceClient;
  456. virtual int GetTypeID() const { return k_nTypeID; }
  457. };
  458. void YieldingAddAuditRecord( GCSDK::CSQLAccess *sqlAccess, const CEconItem *pItem, uint32 unOwnerID, EItemAction eAction, uint32 unData, CEconSessionItemAudit* pItemAudit = NULL );
  459. void YieldingAddAuditRecord( GCSDK::CSQLAccess *sqlAccess, uint64 ulItemID, uint32 unOwnerID, EItemAction eAction, uint32 unData, CEconSessionItemAudit* pItemAudit = NULL );
  460. void YieldingAddAttributeChangeAuditRecord( GCSDK::CSQLAccess *sqlAccess, uint64 ulItemID, uint32 unOwnerID, uint16 unAttributeDefIndex, uint32 uiOriginalValue, EItemAction eAction, uint32 unData );
  461. bool YieldingAddItemToDatabase( CEconItem *pItem, const CSteamID & steamID, EItemAction eAction, uint32 unData, CEconSessionItemAudit* pItemAudit = NULL );
  462. template < typename TAttribInMemoryType >
  463. void ISchemaAttributeTypeBase<TAttribInMemoryType>::LoadEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const union attribute_data_union_t& value ) const
  464. {
  465. pTargetItem->SetDynamicAttributeValue( pAttrDef, GetTypedValueContentsFromEconAttributeValue( value ) );
  466. }
  467. #endif // ECONITEM_H