#include "stdafx.h" #include "file.h" #include "globaldata.h" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tdeStatus fn_eCreateDirectory( const char *_szDirectory ) { if ( (!CreateDirectory( _szDirectory, NULL )) && (GetLastError() != ERROR_ALREADY_EXISTS) ) { char *p_szCur; p_szCur = strchr( _szDirectory, '\\'); while (p_szCur != NULL) { *p_szCur = 0; if ((!CreateDirectory (_szDirectory, NULL)) && (GetLastError() != ERROR_ALREADY_EXISTS) ) { char szMessage[ 512 ]; sprintf( szMessage, "Can't create local path '%s'", _szDirectory ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } *p_szCur++ = '\\'; p_szCur = strchr( p_szCur, '\\'); }; if ((!CreateDirectory (_szDirectory, NULL)) && (GetLastError() != ERROR_ALREADY_EXISTS) ) { char szMessage[ 512 ]; sprintf( szMessage, "Can't create local path '%s'", _szDirectory ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } } return STATUS_C_OK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Copy a file or a directory (no '\' at end of directory name !) // Source may contain wilcards. Dest must be a path to a directory ! // If source is a directory, the copy is recursive tdeStatus fn_eCopyFileOrDirectory( const char *_szSource, const char *_szDest ) { HANDLE hCopyhandle; WIN32_FIND_DATA stFindData; int iNbCharactersForSourcePath; char szSource[512]; char szDest[512]; tdeStatus eStatus; if( (eStatus = fn_eCreateDirectory( _szDest )) != STATUS_C_OK ) return eStatus; // No file to copy, nothing to do... if( (hCopyhandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE ) return STATUS_C_OK; iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource); do { // Skip . and .. if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ( (strcmp( stFindData.cFileName, ".") == 0) || strcmp( stFindData.cFileName, "..") == 0) ) continue; strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 ); szSource[iNbCharactersForSourcePath+1] = 0; strcat( szSource, stFindData.cFileName ); sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName ); // If file is a directory if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { strcat( szSource, "\\*.*" ); if( (eStatus = fn_eCopyFileOrDirectory( szSource, szDest )) != STATUS_C_OK ) return eStatus; } else { if( ! CopyFile( szSource, szDest, FALSE ) ) { char szMessage[1024]; sprintf( szMessage, "Copy failed: '%s' to '%s", szSource, szDest ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } } // Test for end of work. if( g_stTheGlobalData.bStopWork ) return STATUS_C_UserBreak; } while( FindNextFile( hCopyhandle, &stFindData ) ); FindClose( hCopyhandle ); return STATUS_C_OK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Copy some files to a directory. Function will also seach for files in sub-dirs of source. // Source may contain wilcards. Dest must be a path to a directory ! tdeStatus fn_eRecursiveFileCopy( const char *_szSource, const char *_szDest ) { HANDLE hDirectoryHandle; WIN32_FIND_DATA stFindData; int iNbCharactersForSourcePath; char szSource[512]; char szDest[512]; tdeStatus eStatus; // Copy this level of directory if( (eStatus = fn_eCopyFileOrDirectory( _szSource, _szDest )) != STATUS_C_OK ) return eStatus; // Now we are going to check for subdirs. iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource); strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 ); szSource[iNbCharactersForSourcePath+1] = 0; strcat( szSource, "*.*" ); // No files in directory, nothing to do... if( (hDirectoryHandle = FindFirstFile( szSource, &stFindData )) == INVALID_HANDLE_VALUE ) return STATUS_C_OK; do { // Skip . and .. if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ( (strcmp( stFindData.cFileName, ".") == 0) || strcmp( stFindData.cFileName, "..") == 0) ) continue; // We treat only directories if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 ); szSource[iNbCharactersForSourcePath+1] = 0; strcat( szSource, stFindData.cFileName ); strcat( szSource, _szSource+iNbCharactersForSourcePath ); sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName ); if( (eStatus = fn_eRecursiveFileCopy( szSource, szDest )) != STATUS_C_OK ) return eStatus; } // Test for end of work. if( g_stTheGlobalData.bStopWork ) return STATUS_C_UserBreak; } while( FindNextFile( hDirectoryHandle, &stFindData ) ); FindClose( hDirectoryHandle ); return STATUS_C_OK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Moves file(s) or a directory (no '\' at end of directory name !) // Source may contain wilcards. Dest must be a path to a directory ! tdeStatus fn_eMoveFileOrDirectory( const char *_szSource, const char *_szDest ) { HANDLE hCopyhandle; WIN32_FIND_DATA stFindData; int iNbCharactersForSourcePath; char szSource[512], szDest[512]; tdeStatus eStatus; if( (eStatus = fn_eCreateDirectory( _szDest )) != STATUS_C_OK ) return eStatus; // No file to copy, nothing to do... if( (hCopyhandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE ) return STATUS_C_OK; iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource); do { // Skip . and .. if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ( (strcmp( stFindData.cFileName, ".") == 0) || strcmp( stFindData.cFileName, "..") == 0) ) continue; strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 ); szSource[iNbCharactersForSourcePath+1] = 0; strcat( szSource, stFindData.cFileName ); sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName ); if( ! MoveFile( szSource, szDest ) ) { char szMessage[1024]; sprintf( szMessage, "Move failed: '%s' to '%s", szSource, szDest ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } // Test for end of work. if( g_stTheGlobalData.bStopWork ) return STATUS_C_UserBreak; } while( FindNextFile( hCopyhandle, &stFindData ) ); FindClose( hCopyhandle ); return STATUS_C_OK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Deletes file(s) or directory (no '\' at end of directory name !) // Source may contain wilcards. // If source is a directory, the delete is recursive. tdeStatus fn_eDeleteFileOrDirectory( const char *_szSource ) { HANDLE hDeletehandle; WIN32_FIND_DATA stFindData; int iNbCharactersForSourcePath; char szSource[512]; tdeStatus eStatus; // No file to delete, nothing to do... if( (hDeletehandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE ) return STATUS_C_OK; iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource); do { // Skip . and .. if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ( (strcmp( stFindData.cFileName, ".") == 0) || strcmp( stFindData.cFileName, "..") == 0) ) continue; strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 ); szSource[iNbCharactersForSourcePath+1] = 0; strcat( szSource, stFindData.cFileName ); // If file is a directory if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { strcat( szSource, "\\*.*" ); if( (eStatus = fn_eDeleteFileOrDirectory( szSource )) != STATUS_C_OK ) return eStatus; *strrchr( szSource, '\\' ) = 0; if( ! RemoveDirectory( szSource ) ) { char szMessage[1024]; sprintf( szMessage, "Delete failed on '%s'", szSource ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } } else if( ! DeleteFile( szSource ) ) { char szMessage[1024]; sprintf( szMessage, "Delete failed on '%s'", szSource ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); return STATUS_C_Error; } // Test for end of work. if( g_stTheGlobalData.bStopWork ) return STATUS_C_UserBreak; } while( FindNextFile( hDeletehandle, &stFindData ) ); FindClose( hDeletehandle ); return STATUS_C_OK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // This part deals with batch copy/move of files : // Common files for all binarised maps (no files generated by binarisation nor sound or textures) // files relative to main directory char *g_a_szCommonFiles[] = { "Copy", "Gamedata\\Options\\current.cfg", "%bin%\\Options", "End" }; char *g_a_szFilesBeforeBinarize[] = { // Make sure main directory is clean "Delete", "fix*.sna", "Delete", "fix*.snd", "Delete", "fix*.ptx", "Delete", "fix*.gpt", "Delete", "fix.rt?", "Delete", "%level%*.sna", "Delete", "%level%*.snd", "Delete", "%level%*.ptx", "Delete", "%level%*.gpt", "Delete", "%level%.rt?", "End" }; char *g_a_szFilesAfterFirstPass[] = { // Get fix files from gamedata\world\levels "Move", "Gamedata\\World\\Levels\\fix*", "", "Rename", "Fix.sna", "Fix0.sna", "Rename", "Fix.snd", "Fix0.snd", "Rename", "Fix.ptx", "Fix0.ptx", "Rename", "Fix.gpt", "Fix0.gpt", // Get level files from gamedata\world\levels\ "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.sna", "%level%0.sna", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.snd", "%level%0.snd", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.ptx", "%level%0.ptx", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.gpt", "%level%0.gpt", "End" }; char *g_a_szFilesAfterSecondPass[] = { // Get fix files from gamedata\world\levels "Move", "Gamedata\\World\\Levels\\fix*", "", "Rename", "Fix.sna", "Fix1.sna", "Rename", "Fix.snd", "Fix1.snd", "Rename", "Fix.ptx", "Fix1.ptx", "Rename", "Fix.gpt", "Fix1.gpt", // Get level files from gamedata\world\levels\ "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.sna", "%level%1.sna", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.snd", "%level%1.snd", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.ptx", "%level%1.ptx", "Rename", "Gamedata\\World\\Levels\\%level%\\%level%.gpt", "%level%1.gpt", "End" }; char *g_a_szFixFilesAfterCRB[] = { // Delete previous fix files "Delete", "%bin%\\World\\Levels\\fix*", "Delete", "%bin%\\Game.dsb", // Delete files from second pass "Delete", "Fix1.*", // We will use files from first pass. "Rename", "Fix0.sna", "Fix.sna", "Rename", "Fix0.snd", "Fix.snd", "Rename", "Fix0.ptx", "Fix.ptx", "Rename", "Fix0.gpt", "Fix.gpt", "Move", "Fix.*", "%bin%\\World\\Levels", // "Move", "Fix.rt?", "%bin%\\World\\Levels", "Move", "Gamedata\\Game.dsb", "%bin%", "End" }; char *g_a_szDeleteFixFilesAfterCRB[] = { // Delete fix files "Delete", "fix*.sna", "Delete", "fix*.snd", "Delete", "fix*.ptx", "Delete", "fix*.gpt", "Delete", "fix.rt?", "End" }; char *g_a_szLevelFilesAfterCRB[] = { // Delete files from second pass "Delete", "%level%1.*", // We will use files from first pass. "Rename", "%level%0.sna", "%level%.sna", "Rename", "%level%0.snd", "%level%.snd", "Rename", "%level%0.ptx", "%level%.ptx", "Rename", "%level%0.gpt", "%level%.gpt", // Delete bin level directory "Delete", "%bin%\\World\\Levels\\%level%\\*.*", // Move all files to destination directory "Move", "%level%*", "%bin%\\World\\Levels\\%level%", "Move", "Gamedata\\World\\Levels\\%level%\\%level%.dsb", "%bin%\\World\\Levels\\%level%", "End" }; char *g_a_szDeleteFilesAfterBinarize[] = { // Delete all remaining files in main directory "Delete", "fix*.sna", "Delete", "fix*.snd", "Delete", "fix*.ptx", "Delete", "fix*.gpt", "Delete", "fix.rt?", "Delete", "%level%*.sna", "Delete", "%level%*.snd", "Delete", "%level%*.ptx", "Delete", "%level%*.gpt", "Delete", "%level%.rt?", // Also delete files in level "Delete", "Gamedata\\Game.dsb", "Delete", "Gamedata\\World\\Levels\\%level%\\%level%.dsb", "End" }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Analyse keyword // Used by fn_eTreatArrayOfFiles int fn_iGetKeyword( char *_szKeyword ) { if( stricmp( _szKeyword, "Copy" )==0 ) return 0; else if( stricmp( _szKeyword, "Move" )==0 ) return 1; else if( stricmp( _szKeyword, "Rename" )==0 ) return 2; else if( stricmp( _szKeyword, "Delete" )==0 ) return 3; else if( stricmp( _szKeyword, "End" )==0 ) return 4; return -1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Analyse parameter // Used by fn_eTreatArrayOfFiles void fn_vGetParameter( char *_szResult, char *_szParam, tdstCopyFileContext *_p_stContext ) { char *p_cSource = _szParam, *p_cDest = _szResult; // hack: if no %bin%, assume path is main directory if( strnicmp( p_cSource, "%bin%", 5 ) == 0 ) { strcpy( p_cDest, _p_stContext->csBinDirectory ); p_cDest += strlen( p_cDest ); p_cSource += 5; } else { strcpy( p_cDest, _p_stContext->csMainDirectory ); p_cDest += strlen( p_cDest ); if( *p_cSource ) *p_cDest++ = '\\'; } while( *p_cSource ) { if( strnicmp( p_cSource, "%level%", 7 ) == 0 ) { strcpy( p_cDest, _p_stContext->csLevelName ); p_cDest += strlen( p_cDest ); p_cSource += 7; } else { *p_cDest++ = *p_cSource++; } } *p_cDest = 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Execute copy/move/deletes/rename commands in given array // See above for exemples. // stContext contains strings used when replacing %bin%, %level%.... tdeStatus fn_eTreatArrayOfFiles( char *_a_szFileCommands[], tdstCopyFileContext *_p_stContext ) { char szSource[512], szDest[512]; int iKeyWord; tdeStatus eCommandOK; char **p_szCommand = _a_szFileCommands; do { switch( fn_iGetKeyword( *p_szCommand++ ) ) { case 0: // Copy fn_vGetParameter( szSource, *p_szCommand++, _p_stContext ); fn_vGetParameter( szDest, *p_szCommand++, _p_stContext ); eCommandOK = fn_eCopyFileOrDirectory( szSource, szDest ); break; case 1: // Move fn_vGetParameter( szSource, *p_szCommand++, _p_stContext ); fn_vGetParameter( szDest, *p_szCommand++, _p_stContext ); eCommandOK = fn_eMoveFileOrDirectory( szSource, szDest ); break; case 2: // Rename fn_vGetParameter( szSource, *p_szCommand++, _p_stContext ); fn_vGetParameter( szDest, *p_szCommand++, _p_stContext ); eCommandOK = STATUS_C_OK; if( ! MoveFile( szSource, szDest ) ) { char szMessage[1024]; sprintf( szMessage, "Move failed: '%s' to '%s", szSource, szDest ); AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); eCommandOK = STATUS_C_Error; } break; case 3: // Delete fn_vGetParameter( szSource, *p_szCommand++, _p_stContext ); eCommandOK = fn_eDeleteFileOrDirectory( szSource ); break; case 4: // End return STATUS_C_OK; break; default: // Error in array ! ASSERT(0); iKeyWord = -1; eCommandOK = STATUS_C_Error; break; } } while( eCommandOK == STATUS_C_OK ); return eCommandOK; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -