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.

147 lines
5.0 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ============
  2. //
  3. // Functions to help with map instancing.
  4. //
  5. //===============================================================================
  6. #ifndef INSTANCINGHELPER_H
  7. #define INSTANCINGHELPER_H
  8. #if defined( COMPILER_MSVC )
  9. #pragma once
  10. #endif
  11. class CInstancingHelper
  12. {
  13. public:
  14. //-----------------------------------------------------------------------------
  15. // Attempts to locate an instance by its filename, given the
  16. // location of the root-level VMF file, the instance directory specified in
  17. // the gameinfo.txt file, and the GAME directory.
  18. //
  19. // pFileSystem - pointer to file system object
  20. // pBaseFilename - path of the file including the instance
  21. // pInstanceFilename - relative filename of the instance, as read from
  22. // a func_instance entity
  23. // pInstanceDirectory - instance directory, specified by gameinfo.txt
  24. // pResolvedInstanceFilename - pointer to buffer to receive resolved
  25. // filename (only valid if function returns true)
  26. // nBufferSize - size of the buffer. Should be at least MAX_PATH.
  27. //
  28. // Returns true on success, false on failure.
  29. //-----------------------------------------------------------------------------
  30. static bool ResolveInstancePath( IFileSystem *pFileSystem, const char *pBaseFilename, const char *pInstanceFilename, const char *pInstanceDirectory, char *pResolvedInstanceFilename, int nBufferSize )
  31. {
  32. Assert( nBufferSize >= MAX_PATH );
  33. char fixedInstanceFilename[MAX_PATH];
  34. Q_strncpy( fixedInstanceFilename, pInstanceFilename, MAX_PATH );
  35. Q_SetExtension( fixedInstanceFilename, ".vmf", MAX_PATH );
  36. Q_FixSlashes( fixedInstanceFilename );
  37. V_FixDoubleSlashes( fixedInstanceFilename );
  38. // Try to locate the instance file relative to the current file's path
  39. Q_strncpy( pResolvedInstanceFilename, pBaseFilename, nBufferSize );
  40. Q_StripFilename( pResolvedInstanceFilename );
  41. Q_strncat( pResolvedInstanceFilename, "\\", nBufferSize );
  42. Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize );
  43. Q_RemoveDotSlashes( pResolvedInstanceFilename );
  44. V_FixDoubleSlashes( pResolvedInstanceFilename );
  45. Q_FixSlashes( pResolvedInstanceFilename );
  46. if ( pFileSystem->FileExists( pResolvedInstanceFilename ) )
  47. {
  48. return true;
  49. }
  50. #ifdef __IN_HAMMER
  51. if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true )
  52. {
  53. return true;
  54. }
  55. #endif // #ifdef __IN_HAMMER
  56. // Try to locate the instance file relative to the "maps\" directory
  57. const char *pMapPath = "\\maps\\";
  58. char *pMapPathPosition = Q_stristr( pResolvedInstanceFilename, pMapPath );
  59. if ( pMapPathPosition != NULL )
  60. {
  61. pMapPathPosition += Q_strlen( pMapPath );
  62. }
  63. else if ( pMapPathPosition == NULL && Q_strnicmp( pResolvedInstanceFilename, "maps\\", 5 ) == 0 )
  64. {
  65. pMapPathPosition = pResolvedInstanceFilename + 5;
  66. }
  67. // Assuming we found a maps\ directory of some kind
  68. if ( pMapPathPosition != NULL )
  69. {
  70. *pMapPathPosition = 0;
  71. Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize );
  72. if ( pFileSystem->FileExists( pResolvedInstanceFilename ) )
  73. {
  74. return true;
  75. }
  76. #ifdef __IN_HAMMER
  77. if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true )
  78. {
  79. return true;
  80. }
  81. #endif // #ifdef __IN_HAMMER
  82. }
  83. if ( pInstanceDirectory[0] != '\0' )
  84. {
  85. char instanceDirectoryRelativeFilename[MAX_PATH];
  86. Q_snprintf( instanceDirectoryRelativeFilename, nBufferSize, "%s/%s", pInstanceDirectory, fixedInstanceFilename );
  87. Q_SetExtension( instanceDirectoryRelativeFilename, ".vmf", MAX_PATH );
  88. Q_FixSlashes( instanceDirectoryRelativeFilename );
  89. Q_RemoveDotSlashes( instanceDirectoryRelativeFilename );
  90. V_FixDoubleSlashes( instanceDirectoryRelativeFilename );
  91. pFileSystem->RelativePathToFullPath( instanceDirectoryRelativeFilename, "CONTENT", pResolvedInstanceFilename, nBufferSize );
  92. if ( pFileSystem->FileExists( instanceDirectoryRelativeFilename, "CONTENT" ) )
  93. {
  94. return true;
  95. }
  96. #ifdef __IN_HAMMER
  97. if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true )
  98. {
  99. return true;
  100. }
  101. #endif // #ifdef __IN_HAMMER
  102. }
  103. int searchPathLen = pFileSystem->GetSearchPath( "CONTENT", true, NULL, 0 );
  104. char *searchPaths = (char *)stackalloc( searchPathLen + 1 );
  105. pFileSystem->GetSearchPath( "CONTENT", true, searchPaths, searchPathLen );
  106. for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) )
  107. {
  108. Q_strncpy( pResolvedInstanceFilename, path, nBufferSize );
  109. Q_strncat( pResolvedInstanceFilename, "maps\\", nBufferSize );
  110. Q_strncat( pResolvedInstanceFilename, fixedInstanceFilename, nBufferSize );
  111. if ( pFileSystem->FileExists( pResolvedInstanceFilename ) )
  112. {
  113. return true;
  114. }
  115. }
  116. #ifdef __IN_HAMMER
  117. if ( CMapInstance::IsMapInVersionControl( pResolvedInstanceFilename ) == true )
  118. {
  119. return true;
  120. }
  121. #endif // #ifdef __IN_HAMMER
  122. if ( nBufferSize > 0 )
  123. {
  124. pResolvedInstanceFilename[0] = '\0';
  125. }
  126. return false;
  127. }
  128. };
  129. #endif // INSTANCINGHELPER_H