///////////////////////////////////////////////// // Viewizard Game Engine ///////////////////////////////////////////////// // File: VFS.cpp ///////////////////////////////////////////////// // Copyright (c) 2001-2006, Michael Kurinnoy // All Rights Reserved. ///////////////////////////////////////////////// // Ver : 2.0 ///////////////////////////////////////////////// //------------------------------------------------------------------------------------ // include и lib... //------------------------------------------------------------------------------------ #include "vfs_var.h" //------------------------------------------------------------------------------------ // кодируем-декодируем //------------------------------------------------------------------------------------ int XORCount = 0; char XORKey[] = "VASW%YTgbsbnj9243itmwreGFGRHWHTGGFNWASSGSHGmkwoy245i5hykjlgsajnqiot403wigunwrewg-3940514342"; void CodeXOR(char *Text, int Size) { for (int i=0; i < Size; i++) { Text[i] = Text[i]^XORKey[XORCount]; XORCount++; // чтобы не было переполнения if (XORCount >= (int)strlen(XORKey)) XORCount=0; } } //------------------------------------------------------------------------------------ // Создание VFS //------------------------------------------------------------------------------------ int vw_CreateVFS(const char *Name, const char *nArhKey, bool WriteArhKey, int Ver) { XORCount = 0; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // выделяем память для имени //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VFSFileName = new char[strlen(Name)+1]; // не можем выделить память if (VFSFileName == 0) return 0; strcpy_s(VFSFileName, strlen(Name)+1, Name); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // открываем (создаем) на чтение-запись... //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // не можем записать if (fopen_s(&VFSFile, VFSFileName, "wb+") != 0) return 0; VFSFileWritable = true; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // выделяем память для ArhKeyVFS //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ArhKeyVFS = new char[strlen(nArhKey)+1]; if (ArhKeyVFS == 0) return 0; strcpy_s(ArhKeyVFS, strlen(nArhKey)+1, nArhKey); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // пишем VFS_ (4б) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ char tmp1[5] = "VFS_"; fwrite(tmp1,4,1,VFSFile); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // пишем версию (4б) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VFSversion = Ver; if (VFSversion == 3) fwrite("v1.3",4,1,VFSFile); if (VFSversion == 2) fwrite("v1.2",4,1,VFSFile); if (VFSversion == 1) fwrite("v1.1",4,1,VFSFile); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Пишем (если нужно) последовательность упаковки // 1-й байт - сколько символов в упаков.послед. 0 - если ее вообще нет //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (VFSversion == 1 || VFSversion == 2) { if ((!WriteArhKey) | ((ArhKeyVFS[0]=='0')&(strlen(ArhKeyVFS)==1)) ) { // ничего писать не нужно, пишем 0 в длину ArhKeyVFS byte tmp3 = 0; fwrite(&tmp3,1,1,VFSFile); // находим значения смещений для записи данных и файловой таблици HeaderOffsetVFS = 4+4+1+4+4;//VFS v offset lenght DataStartOffsetVFS = 4+4+1; } else { // Пишем последовательность... byte tmp3 = (byte)strlen(ArhKeyVFS); // пишем, какова длина ArhKeyVFS fwrite(&tmp3,1,1,VFSFile); // пишем ArhKeyVFS fwrite(ArhKeyVFS,strlen(ArhKeyVFS),1,VFSFile); // находим значения смещений для записи данных и файловой таблици HeaderOffsetVFS = 4+4+1+(int)strlen(ArhKeyVFS)+4+4;//VFS ver offset lenght DataStartOffsetVFS = 4+4+1+(int)strlen(ArhKeyVFS); } } if (VFSversion == 3) { HeaderOffsetVFS = 4+4+4+4;//VFS ver offset lenght DataStartOffsetVFS = 4+4; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // пишем смещение начала таблицы //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ NumberOfFilesVFS = 0; HeaderLengthVFS = 0; fwrite(&HeaderOffsetVFS,4,1,VFSFile); fwrite(&HeaderLengthVFS,4,1,VFSFile); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // VFS подключен - можно работать //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VFSFileOpen=true; return 0; } //------------------------------------------------------------------------------------ // Закрываем VFS //------------------------------------------------------------------------------------ void vw_CloseVFS(void) { //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // если VFS файл открыт, закрываем его //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (VFSFileOpen) { fclose(VFSFile); VFSFileWritable = false; VFSFileOpen = false; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // даже если файла не, все равно освобождаем память //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ for (int j = 0; j 0) fwrite(VFSdirArray[i].ArhKey, VFSdirArray[i].ArhKeyLen, 1, VFSFile); } fwrite(&VFSdirArray[i].NameLen, 2, 1, VFSFile); if (VFSversion == 3) CodeXOR(VFSdirArray[i].Name, VFSdirArray[i].NameLen); fwrite(VFSdirArray[i].Name, VFSdirArray[i].NameLen, 1, VFSFile); fwrite(&VFSdirArray[i].Offset, 4, 1, VFSFile); fwrite(&VFSdirArray[i].Length, 4, 1, VFSFile); if (VFSversion == 2 || VFSversion == 3) fwrite(&VFSdirArray[i].RealLength, 4, 1, VFSFile); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // дописываем новую запись в таблицу файла //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ int lenArhKeyVFS=0; if (VFSversion == 3) { if (ArhKeyVFS[0]=='0' && (strlen(ArhKeyVFS) == 1)) { // ничего писать не нужно, пишем 0 в длину ArhKeyVFS byte tmp3 = 0; fwrite(&tmp3,1,1,VFSFile); lenArhKeyVFS = 1; } else { // Пишем последовательность... byte tmp3 = (byte)strlen(ArhKeyVFS); // пишем, какова длина ArhKeyVFS fwrite(&tmp3,1,1,VFSFile); // пишем ArhKeyVFS fwrite(ArhKeyVFS,strlen(ArhKeyVFS),1,VFSFile); lenArhKeyVFS = (int)strlen(ArhKeyVFS)+1; } } DWORD len = (DWORD)strlen(Name); fwrite(&len, 2, 1, VFSFile); char FileName[MAX_PATH]; strcpy(FileName, Name); if (VFSversion == 3) CodeXOR(FileName, len); fwrite(FileName, len, 1, VFSFile); fwrite(&HeaderOffsetVFS, 4, 1, VFSFile); fwrite(&tmpLength, 4, 1, VFSFile); if (VFSversion == 2 || VFSversion == 3) fwrite(&RealLength, 4, 1, VFSFile); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // меняем данные //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HeaderOffsetVFS += tmpLength; if (VFSversion == 2 || VFSversion == 3) HeaderLengthVFS += lenArhKeyVFS+2+len+4+4+4; if (VFSversion == 1) HeaderLengthVFS += 2+len+4+4; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // переписываем смещение начала таблицы //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fseek( VFSFile, DataStartOffsetVFS, SEEK_SET ); fwrite(&HeaderOffsetVFS, 4, 1, VFSFile); fwrite(&HeaderLengthVFS, 4, 1, VFSFile); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // удаляем старый VFSdirArray //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ for (int j = 0; j 0) { VFSdirArray[i].ArhKey = new char[VFSdirArray[i].ArhKeyLen+1]; VFSdirArray[i].ArhKey[VFSdirArray[i].ArhKeyLen+1] = 0; fread( VFSdirArray[i].ArhKey, VFSdirArray[i].ArhKeyLen, 1, VFSFile ); } } VFSdirArray[i].NameLen = 0; fread( &VFSdirArray[i].NameLen, 2, 1, VFSFile ); VFSdirArray[i].Name = new char[VFSdirArray[i].NameLen+1]; VFSdirArray[i].Name[VFSdirArray[i].NameLen] = 0; fread( VFSdirArray[i].Name, VFSdirArray[i].NameLen, 1, VFSFile ); if (VFSversion == 3) CodeXOR(VFSdirArray[i].Name, VFSdirArray[i].NameLen); fread( &VFSdirArray[i].Offset, 4, 1, VFSFile ); fread( &VFSdirArray[i].Length, 4, 1, VFSFile ); if (VFSversion == 2 || VFSversion == 3) { fread( &VFSdirArray[i].RealLength, 4, 1, VFSFile ); } } return 0; }