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.

245 lines
6.9 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Weapon data file parsing, shared by game & client dlls.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include <KeyValues.h>
  9. #include <tier0/mem.h>
  10. #include "filesystem.h"
  11. #include "utldict.h"
  12. #include "ammodef.h"
  13. #include "playerclass_info_parse.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. static CUtlDict< FilePlayerClassInfo_t*, unsigned short > m_PlayerClassInfoDatabase;
  17. #define MAX_PLAYERCLASSES 32
  18. #ifdef _DEBUG
  19. // used to track whether or not two player classes have been mistakenly assigned the same slot
  20. bool g_bUsedPlayerClassSlots[MAX_PLAYERCLASSES] = { 0 };
  21. #endif
  22. #ifdef DEBUG
  23. void CC_ReloadPlayerClasses_f (void)
  24. {
  25. //ResetFilePlayerClassInfoDatabase();
  26. }
  27. static ConCommand dod_reloadplayerclasses("dod_reloadplayerclasses", CC_ReloadPlayerClasses_f, "Reset player class info cache" );
  28. #endif
  29. //-----------------------------------------------------------------------------
  30. // Purpose:
  31. // Input : *name -
  32. // Output : FilePlayerClassInfo_t
  33. //-----------------------------------------------------------------------------
  34. static PLAYERCLASS_FILE_INFO_HANDLE FindPlayerClassInfoSlot( const char *name )
  35. {
  36. // Complain about duplicately defined metaclass names...
  37. unsigned short lookup = m_PlayerClassInfoDatabase.Find( name );
  38. if ( lookup != m_PlayerClassInfoDatabase.InvalidIndex() )
  39. {
  40. return lookup;
  41. }
  42. FilePlayerClassInfo_t *insert = CreatePlayerClassInfo();
  43. lookup = m_PlayerClassInfoDatabase.Insert( name, insert );
  44. Assert( lookup != m_PlayerClassInfoDatabase.InvalidIndex() );
  45. return lookup;
  46. }
  47. // Find a class slot, assuming the weapon's data has already been loaded.
  48. PLAYERCLASS_FILE_INFO_HANDLE LookupPlayerClassInfoSlot( const char *name )
  49. {
  50. return m_PlayerClassInfoDatabase.Find( name );
  51. }
  52. // FIXME, handle differently?
  53. static FilePlayerClassInfo_t gNullPlayerClassInfo;
  54. //-----------------------------------------------------------------------------
  55. // Purpose:
  56. // Input : handle -
  57. // Output : FilePlayerClassInfo_t
  58. //-----------------------------------------------------------------------------
  59. FilePlayerClassInfo_t *GetFilePlayerClassInfoFromHandle( PLAYERCLASS_FILE_INFO_HANDLE handle )
  60. {
  61. if ( handle == GetInvalidPlayerClassInfoHandle() )
  62. {
  63. Assert( !"bad index into playerclass info UtlDict" );
  64. return &gNullPlayerClassInfo;
  65. }
  66. return m_PlayerClassInfoDatabase[ handle ];
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose:
  70. // Output : PLAYERCLASS_FILE_INFO_HANDLE
  71. //-----------------------------------------------------------------------------
  72. PLAYERCLASS_FILE_INFO_HANDLE GetInvalidPlayerClassInfoHandle( void )
  73. {
  74. return (PLAYERCLASS_FILE_INFO_HANDLE)m_PlayerClassInfoDatabase.InvalidIndex();
  75. }
  76. void ResetFilePlayerClassInfoDatabase( void )
  77. {
  78. m_PlayerClassInfoDatabase.PurgeAndDeleteElements();
  79. #ifdef _DEBUG
  80. memset(g_bUsedPlayerClassSlots, 0, sizeof(g_bUsedPlayerClassSlots));
  81. #endif
  82. }
  83. KeyValues* ReadEncryptedKVPlayerClassFile( IFileSystem *filesystem, const char *szFilenameWithoutExtension, const unsigned char *pICEKey )
  84. {
  85. Assert( strchr( szFilenameWithoutExtension, '.' ) == NULL );
  86. char szFullName[512];
  87. // Open the weapon data file, and abort if we can't
  88. KeyValues *pKV = new KeyValues( "PlayerClassDatafile" );
  89. Q_snprintf(szFullName,sizeof(szFullName), "%s.txt", szFilenameWithoutExtension);
  90. if ( !pKV->LoadFromFile( filesystem, szFullName, "GAME" ) ) // try to load the normal .txt file first
  91. {
  92. if ( pICEKey )
  93. {
  94. Q_snprintf(szFullName,sizeof(szFullName), "%s.ctx", szFilenameWithoutExtension); // fall back to the .ctx file
  95. FileHandle_t f = filesystem->Open( szFullName, "rb", "GAME");
  96. if (!f)
  97. {
  98. pKV->deleteThis();
  99. return NULL;
  100. }
  101. // load file into a null-terminated buffer
  102. int fileSize = filesystem->Size(f);
  103. char *buffer = (char*)MemAllocScratch(fileSize + 1);
  104. Assert(buffer);
  105. filesystem->Read(buffer, fileSize, f); // read into local buffer
  106. buffer[fileSize] = 0; // null terminate file as EOF
  107. filesystem->Close( f ); // close file after reading
  108. UTIL_DecodeICE( (unsigned char*)buffer, fileSize, pICEKey );
  109. bool retOK = pKV->LoadFromBuffer( szFullName, buffer, filesystem );
  110. MemFreeScratch();
  111. if ( !retOK )
  112. {
  113. pKV->deleteThis();
  114. return NULL;
  115. }
  116. }
  117. else
  118. {
  119. pKV->deleteThis();
  120. return NULL;
  121. }
  122. }
  123. return pKV;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose: Read data on weapon from script file
  127. // Output: true - if data2 successfully read
  128. // false - if data load fails
  129. //-----------------------------------------------------------------------------
  130. bool ReadPlayerClassDataFromFileForSlot( IFileSystem* filesystem, const char *szPlayerClassName, PLAYERCLASS_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey )
  131. {
  132. if ( !phandle )
  133. {
  134. Assert( 0 );
  135. return false;
  136. }
  137. *phandle = FindPlayerClassInfoSlot( szPlayerClassName );
  138. FilePlayerClassInfo_t *pFileInfo = GetFilePlayerClassInfoFromHandle( *phandle );
  139. Assert( pFileInfo );
  140. if ( pFileInfo->m_bParsedScript )
  141. return true;
  142. char sz[128];
  143. Q_snprintf( sz, sizeof( sz ), "scripts/playerclass_%s", szPlayerClassName );
  144. KeyValues *pKV = ReadEncryptedKVFile( filesystem, sz, pICEKey );
  145. if ( !pKV )
  146. return false;
  147. pFileInfo->Parse( pKV, szPlayerClassName );
  148. pKV->deleteThis();
  149. return true;
  150. }
  151. //-----------------------------------------------------------------------------
  152. // FilePlayerClassInfo_t implementation.
  153. //-----------------------------------------------------------------------------
  154. FilePlayerClassInfo_t::FilePlayerClassInfo_t()
  155. {
  156. m_bParsedScript = false;
  157. m_szPlayerClassName[0] = 0;
  158. m_szPrintName[0] = 0;
  159. m_szPlayerModel[0] = 0;
  160. m_szSelectCmd[0] = 0;
  161. }
  162. void FilePlayerClassInfo_t::Parse( KeyValues *pKeyValuesData, const char *szPlayerClassName )
  163. {
  164. // Okay, we tried at least once to look this up...
  165. m_bParsedScript = true;
  166. // Classname
  167. Q_strncpy( m_szPlayerClassName, szPlayerClassName, MAX_WEAPON_STRING );
  168. // Printable name
  169. Q_strncpy( m_szPrintName, pKeyValuesData->GetString( "printname", "!! Missing printname on Player Class" ), MAX_PLAYERCLASS_NAME_LENGTH );
  170. // Player Model
  171. Q_strncpy( m_szPlayerModel, pKeyValuesData->GetString( "playermodel", "!! Missing playermodel on Player Class" ), MAX_PLAYERCLASS_NAME_LENGTH );
  172. // Select command
  173. Q_strncpy( m_szSelectCmd, pKeyValuesData->GetString( "selectcmd", "!! Missing selectcmd on Player Class" ), 32 );
  174. #if defined(_DEBUG) && defined(HL2_CLIENT_DLL)
  175. // Use this for class select keys
  176. /*
  177. // make sure two weapons aren't in the same slot & position
  178. if (g_bUsedPlayerClassSlots[iSlot])
  179. {
  180. Msg( "Weapon slot info: %s (%d, %d)\n", szPrintName, iSlot, iPosition );
  181. Warning( "Duplicately assigned weapon to slots in selection hud\n" );
  182. }
  183. g_bUsedPlayerClassSlots[iSlot][iPosition] = true;
  184. */
  185. #endif
  186. }