• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

7. Функции vdfs, шифрование томов

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.271
Благодарности
4.574
Баллы
625
Виртуальная файловая система
Система представляет собой набор функций, обеспечивающих чтение файловых томов. Она позволяет группировать файлы и контролировать актуальность их версий - одноименный файл будет взят из тома по младшей временной метке.
Преимущества данной системы заключаются в наибольшей производительности, чем стандартные потоки. Обеспечивается это более быстрым поиском файлов (хеш-таблица) и оптимизацией чтения данных (кеширование).
Новые версии поддерживают формат звука OGG. Сжатый поток преобразуется в обычный методами VDFS без участия программиста.
Операции над потоками эквивалентны стандартным WinAPI: fopen, fread, fseek, ftell и тд.



Функции

Поиск файлов

long32 vdf_searchfile (text filename, text fullfilenames);
filename – имя файла, который следует найти в каталогах томов или каталогах игры.
fullfilename – все найденные вхождения. Это значение будет существовать, если функция вернет не 0.
Возвращаемое значение – True если найдено хотя бы одно совпадение. Список найденных файлов представляет собой группу полных путей, разделенных символом ‘|’.
C++:
  // Буффер, в который будут
  // записыны все найденные файлы
  char pathListBuff[1024];

  if( vdf_searchfile( "Union.patch", pathListBuff ) ) {
    string PathList = pathListBuff;

    // Выводим найденные файлы на экран
    for( uint i = 1; true; i++ ) {

      // Берем слово с порядковым номером i,
      // разделенное символом |
      string Path = PathList.GetWord( "|", i );

      // Выходим из цикла, если
      // следующий файл не существует
      if( Path.IsEmpty() )
        break;

      // Пример вывода
      // 1  System\Union.patch
      // 2  System\Patches\Union.patch
      cmd << i << tab << Path << endl;
    }
  }



Проверка наличия файла
long32 vdf_fexists( text fullfname, long32 flags );
fullfname – полное имя файла (относительно пути игры).
fullfname – предпочитаемые потоки поиска.
Возвращаемое значение – потоки, в которых обнаружен файл.
Потоки описываются флагами: VDF_VIRTUAL – поток файлового тома. VDF_PHYSICAL – потоки физических файлов. VDF_PHYSICALFIRST – дополнительный параметр, при котором сначала выполняется поиск в физических каталогах.
Поскольку одноименный файл может существовать как в виртуальных, так и в физических каталогах, то функция вернет флаг, принимающих сразу два значения.
C++:
  // Искать файл как в физических, так и в виртуальных потоках
  long flags = vdf_fexists( "System\\Union.ini", VDF_PHYSICAL | VDF_VIRTUAL );

  // Проверяем где был найден файл
  if( flags & VDF_PHYSICAL && flags & VDF_VIRTUAL ) {
    Message::Info( "Файл найден как в физических, так и в виртуальных каталогах." );
  }
  else if( flags & VDF_PHYSICAL ) {
    Message::Info( "Файл найден в физических каталогах." );
  }
  else if( flags & VDF_VIRTUAL ) {
    Message::Info( "Файл найден в виртуальных каталогах." );
  }
  else // flags == 0
    Message::Info( "Файл не найден." );

Открытие потока чтения
long32 vdf_fopen( text fullfname, long32 flags );
fullfname – полное имя файла.
flags – потоки, в которых следует произвести поиск.
Возвращаемое значение – хендлер файла. Если файл невозможно открыть, значение будет Invalid.
По умолчанию сначала программа ищет файл внутри файловых томов. И, соответственно, при наличии файлов в нескольких потоках, первичным будет виртуальный. Для установки приоритета на физические потоки используется флаг VDF_PHYSICALFIRST.
C++:
  // Искать файл как в физических, так и в виртуальных потоках. Но сначала искать в физических.
  long handler = vdf_fopen( "System\\Union.ini", VDF_PHYSICAL | VDF_VIRTUAL | VDF_PHYSICALFIRST );
  if( handler != Invalid ) {
    // TO DO
  }
  else
    Message::Error( "Невозможно открыть файл" );



Определение размера файла
long32 vdf_ffilesize( long32 handle );
handle – хендлер файла.
Возвращаемое значение – размер файла.
Функция возвращает реальный размер файла, доступный для чтения.
C++:
  // Читаем размер файла по его хендлеру
  long size = vdf_ffilesize( handler );
  if( size != Invalid ) {
    // TO DO
  }
  else
    Message::Error( "Указатель на файл поврежден" );


Прочитать данные файла
long32 vdf_fread( long32 handle, HBuffer buffer, long32 size );
handle – хендлер файла.
buffer – источник, куда следует поместить данные.
Size – количество читаемых байтов.
Возвращаемое значение – реальное количество считанных байтов. Если это значение меньше чем Size, то дальнейшее чтение будет невозможно.
Каждый поток имеет курсор, указывающий место в документе с которого fread начинает считывать байты. При открытии потока его значение сбрасывается на ноль. При каждом вызове функции fread курсор автоматически смещается на size байтов вперед.
C++:
  // Определяем буфер, в который
  // будем писать считанные байты
  long  size   = 1024;
  char* buffer = new char[size];

  // Чтение всего файла по кусочкам
  while( true ) {
    // Считываем байты в буфер
    long readed = vdf_fread( handler, buffer, size );

    // TO DO

    // Если считанное значение меньше запрошенного,
    // то завершаем процедуру чтения
    if( readed < size )
      break;
  }
  // Удаляем буфер из памяти
  delete buffer;



Сдвиг курсора
long32 vdf_fseek( long32 handle, long32 pos );
handle – хендлер файла.
pos – новая позиция курсора.
Перемещая курсор, функция vdf_fread продолжит чтение данных с заданной позиции. Предел значения pos ограничивается размером файла.
C++:
  vdf_fseek( handler, 0 );            // Перемещаем курсор в начало
  vdf_fread( handler, buffer, 24 );   // Считываем первые 24 байта в файле

  vdf_fseek( handler, 128 );          // Перемещаем курсор на 128 байт в файле
  vdf_fread( handler, buffer, size ); // Читаем size байт в файле начиная со 128



Получение позиции курсора
long32 vdf_ftell( long32 handle );
handle – хендлер файла.
Возвращаемое значение – текущая позиция курсора.
C++:
  long pos_old = vdf_ftell( handler );               // Запоминаем значение курсора до чтения
  long readed  = vdf_fread( handler, buffer, size ); // Считываем size байт
  long pos_new = vdf_ftell( handler );               // Запоминаем новое значение курсора
  // Если readed == size, то и pos_new - pos_old равен предыдущему равенству


Закрытие файла
long32 vdf_fclose( long32 handle );
handle – хендлер файла.
Обязательная процедура! После завершения работы с файлом, поток необходимо закрыть.
C++:
  long handler = vdf_fopen( fileName, flags );
  if( handler != Invalid ) {
    // TO DO
   
    vdf_fclose( handler );
  }


Защита тома
ВАЖНО!!!Далее представлен материал, предназначенный исключительно для защиты авторских ресурсов от нежелательной публикации в других источниках. Это значит, что категорически запрещается шифровать коммерческие ресурсы без одобрения правообладателей, ресурсы Gothic MDK или любые другие, публикация которых может задеть чувства или права их авторов.


Иметь в видуШифрование тома дело простое, но небезопасное. Всегда следует иметь запасную копию тома на случай утери к нему доступа. В противном случае восстановить его будет невозможно, поскольку даже я не имею ключей для дешифровки томов.
К каждому тому привязывается Ваш личный плагин. Если плагин перекомпилировать, то том, привязанный к предыдущей его версии, станет недоступным!!!


Если все предыдущие утверждения Вас не пугают, то перейдем к реализации :)
long32 vdf_regvol( char* volName );
В любом месте плагина вызывается функция vdf_regvol с именем тома. После отработки этой функции процесс станет необратим и том будет незамедлительно зашифрован. Любая попытка прочитать данные не из целевой dll приведет к получению неинформативной кучи байтов.
Шифровка тестировалась на родных томах готики и могу сказать с уверенностью, что отличий в производительности я не заметил. Поэтому каким бы сложным или большим не был ресурс, за скорость и стабильность можно не беспокоиться.
И на последок повторюсь – все действия с помощью данного инструмента остаются на вашей совести. Он разработан для вас из уважения к вашему труду. Также надеюсь и на ваше уважение друг к другу.
 
Последнее редактирование:

Trazege

Участник форума
Регистрация
20 Фев 2008
Сообщения
1.760
Благодарности
1.394
Баллы
340
Есть вопрос - long32 vdf_regvol( char* volName ); Имя плагина указывается в каком регистре? Указывается только имя или вместе с расширением? Попробовал вызвать функцию в таком формате - vdf_regvol("out_textures_01"); Как текстуры через гоман читались, так и читаются спокойно. Мб что то не так делаю?
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.271
Благодарности
4.574
Баллы
625
Расширение файла никто не отменял. Файловой системе как-то же надо различить .vdf и .mod.
 

Trazege

Участник форума
Регистрация
20 Фев 2008
Сообщения
1.760
Благодарности
1.394
Баллы
340
Расширение файла никто не отменял. Файловой системе как-то же надо различить .vdf и .mod.

Указываю const char* tex1 = "OUT_TEXTURES_01.VDF";
вызываю в Game_loop vdf_regvol(tex1); Запуская игру, но том не шифруется. :confused:
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.271
Благодарности
4.574
Баллы
625
Trazege, ах да, в одном из билдов я поставил запрет на открытие тома в режиме записи
 

Вложения

  • Vdfs32g.7z
    134,6 KB · Просмотры: 18

Trazege

Участник форума
Регистрация
20 Фев 2008
Сообщения
1.760
Благодарности
1.394
Баллы
340
а можно это опцией вывести в ини, например? Чтобы не кастомизировать общую базу библиотек Юниона
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.271
Благодарности
4.574
Баллы
625

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.271
Благодарности
4.574
Баллы
625
Ещё раз пробуй :) вызови регистрацию из гейм инита и все
 

Trazege

Участник форума
Регистрация
20 Фев 2008
Сообщения
1.760
Благодарности
1.394
Баллы
340
Ещё раз пробуй :) вызови регистрацию из гейм инита и все

Неа
1604039724940.png
1604039776359.png
 
Сверху Снизу