Конференция "Игры" » Большой файл для хранения данных [Delphi, DirectX 9]
 
  • ElectriC © (26.05.07 20:29) [0]
    Как создать большой файл для хранения файлов(графических, текстовых, музыкальных и пр.), а потом из загружать в программу из
    этого файла, как это сделано в, например, FlatOut и пр?
    P.S. По возможности сделать файл, чтобы его нельзя было просматривать/редактировать!!!
  • XProger © (26.05.07 21:40) [1]
    Придумать и сделать. Самое простое - zip сжатие под паролем ;)
  • @!!ex © (26.05.07 21:50) [2]
    У меня есть модулек для таких целей.
    Просто создает гигантских архив, умеет читать из него.
    В начале таблица с файлами:
    Имя, смещение, размер, тип сжатия(На данный момент сжатие еще не сделал).
    Ну и соответственно сделано чтение из него по принципу:
    Проис классик в память прочитать конкретный файлих из арзива, потом по этому участку памяти создаем TMemoryStream и работаем с ним как со стримом(правда я не стримы юзаю, но принцип тот же).
  • homm © (26.05.07 22:32) [3]
    > По возможности сделать файл, чтобы его нельзя было просматривать/редактир
    > овать!!!

    Выделить в проводнике, нажать кнопку shift, и не отпуская ее delete.
  • @!!ex © (26.05.07 22:58) [4]
    Если стоят Нортоновские утилиты, то не поможет. :)
    У меня тут было, херакс и начинает винда матерится, что ей места мала... Ладно, думаю, ща. Нахожу "лишние" файлики, убиваю...
    Через пару дней обращаю внимания, что она опять матерится... При чем места стало еще меньше.. Уже буквально несколько десятков метров..
    Нахожу еще "лишних" файликов, скрипя сердцем удаляю или перемещаю на другие диски... Проверяю... Места больше не стало... Чо за на?
    А это Нортон, скотина файлики хапрещает удалять, вернее он их у себя сохраняет.... Сколько ни удаляй, места не прибавится, и всегда их можно восстановить мля... ПРишло его отключить на системном диске....
  • homm © (26.05.07 23:17) [5]
    ПРишло его отключить на системном диске....

    Правый клик на корзине/Очистить корзину Norton.
  • ElectriC © (26.05.07 23:32) [6]

    > У меня есть модулек для таких целей.Просто создает гигантских
    > архив, умеет читать из него.В начале таблица с файлами:Имя,
    >  смещение, размер, тип сжатия(На данный момент сжатие еще
    > не сделал).Ну и соответственно сделано чтение из него по
    > принципу:Проис классик в память прочитать конкретный файлих
    > из арзива, потом по этому участку памяти создаем TMemoryStream
    > и работаем с ним как со стримом(правда я не стримы юзаю,
    >  но принцип тот же).

    Можешь скинуть!;))
    Или хотя бы подскажи, где почитать об этом?
  • ElectriC © (26.05.07 23:33) [7]

    > Выделить в проводнике, нажать кнопку shift, и не отпуская
    > ее delete.

    И при чём тут это???
  • Vovan #2 (26.05.07 23:43) [8]
    Удалено модератором
  • homm © (27.05.07 00:01) [9]
    > И при чём тут это???

    Это то о чем сказано в сабже, делает непросматриваемым и не редактируемым. Кроме физического удаления носителей, это единственный способ.
  • homm © (27.05.07 00:04) [10]
    Удалено модератором
  • Vovan #2 (27.05.07 00:05) [11]
    Удалено модератором
  • ANTPro © (27.05.07 00:06) [12]
    > [7] ElectriC ©   (26.05.07 23:33)

    У Vga спроси у него пакман с LZMA, UCL есть.
    Его SVN: http://vgasoft.googlecode.com/svn/PakManDLL
  • Vga © (27.05.07 00:56) [13]
    Бинарник с бредовым хелпом: http://vgasoft.googlecode.com/svn/Binaries/PakManDLL
  • Yashin © (27.05.07 22:24) [14]
    В GlScene модуль есть GLVfsPak. Я сам тоже писал такой модуль как у @!!ex, но я таблицу файлов делал в конце, так удобнее можно потом добавлять файлы, и у меня было сжатие через zlib. Но жаль после формата редко что выживает. Будет время перепишу заного это не сложно.
    Вот вам модуль с примерчиком, не знаю будет работать. претензии не предъявлять, не нравится качайте GlScene.
    http://ifolder.ru/2152922
  • ElectriC © (28.05.07 15:18) [15]

    > Yashin ©

    Спасибо!
  • @!!ex © (28.05.07 19:39) [16]
    > Правый клик на корзине/Очистить корзину Norton.

    Знаим, знаим. Но винда постоянно темповскими файлами ворочает. Поэтому место забивалось за один-два дня. Вот и отключил. Тем более что нафиг не надо.


    > [14] Yashin ©   (27.05.07 22:24)

    Да, у меня надо перепаковывать, чтобы файлик добавить. Но это вообщем то не критично для проекта, ведь там статичные ресурсы.

    Вот код модуля:
    unit Extractor;

    interface
    uses Windows, SysUtils;

    var
     VERSION:byte = 1;
     BufferSize:DWORD = 1048576;
     ArchiveIsPriority:boolean = false;

     //  Файл_есть_в_архиве & (Архив_приоеритетен | !Файл_есть_на_диске)

    type
     PTextFile = ^TTextFile;

     TArchiveItem = record
       Name:array[0..255] of char;
       State:DWORD;                 //2 - Normal, 3 - LZW
       Offset:DWORD;
       Size:DWORD;
     end;

     TExtractor = class
     public
       Constructor Create;                                     //Создаем экземпляр объекта
       Destructor  Destroy; override;                          //Освобождением данных
       Procedure   LoadFromFile(const FileName:string);        //Загружаем архив
       Procedure   SetPath(const Path:string);                 //Устанавливаем абсолютный путь нахождения архива
       Function    GetCount:integer;                           //Получаем количество файлов в архиве
       Function    GetFileIndex(const FileName:string):integer;//Получаем индекс файла. Если файла в архиве нет, то -1
       Function    GetData(FileIndex:integer):Pointer;         //Получаем указатель на данные файла. Потом их надо освободить!
       Function    GetSize(FileIndex:integer):DWORD;           //Получаем размер файла
       Function    GetName(FileIndex:integer):string;          //получаем имя файла
     protected
       AbsolutePath:string;
       Count:integer;
       Items:array of TArchiveItem;
       FileHandle:integer;
     end;

     TSimpleFile = class
     public
       Constructor Create(const FileName:string);
       Destructor  Destroy();override;
       Function    EoF:boolean;
     protected
       Data:Pointer;
       Position:PByte;
       Size:DWORD;
     end;

     TTextFile = class(TSimpleFile)
     public
       Function    ReadString:string;
       Function    ReadTrimString:string;
     end;

     TIntegerFile = class(TSimpleFile)
     public
       Function    ReadInteger:integer;
     end;

    implementation
    uses Data;

    { TExtractor }

    const
     ERR_OUTOFRANGE = 'File Index in DPG archive out of range';
     ERR_ENDOFFILE = 'Riched End Of File';

    constructor TExtractor.Create;
    begin
     FileHandle:=0;
     Count:=0;
     SetLength(Items,Count);
    end;

    destructor TExtractor.Destroy;
    begin
     Count:=0;
     SetLength(Items,Count);
     if FileHandle<>0 then CloseHandle(FileHandle);
    end;

    function TExtractor.GetCount: integer;
    begin
     Result:=Count;
    end;

    function TExtractor.GetData(FileIndex: integer): Pointer;
    begin
     if (FileIndex<0) or (FileIndex>Count-1) then
       raise Exception.Create(ERR_OUTOFRANGE);
     Result:=AllocMem(Items[FileIndex].Size);
     FileSeek(FileHandle,Items[FileIndex].Offset,0);
     FileRead(FileHandle,Result^,Items[FileIndex].Size);
    end;

    function TExtractor.GetFileIndex(const FileName: string): integer;
    var
     Index:integer;
     S:string;
    begin
     S:=UpperCase(FileName);
     Result:=-1;
     for Index:=0 to Count-1 do
       if AbsolutePath+Items[Index].Name=S then begin
         Result:=Index;
         exit;
       end;
    end;

    function TExtractor.GetName(FileIndex:integer): string;
    begin
     if (FileIndex<0) or (FileIndex>Count-1) then
       raise Exception.Create(ERR_OUTOFRANGE);
     Result:=Items[FileIndex].Name;
    end;

    function TExtractor.GetSize(FileIndex: integer): DWORD;
    begin
     if (FileIndex<0) or (FileIndex>Count-1) then
       raise Exception.Create(ERR_OUTOFRANGE);
     Result:=Items[FileIndex].Size;
    end;

    procedure TExtractor.SetPath(const Path: string);
    begin
     AbsolutePath:=UpperCase(Path);
    end;

    procedure TExtractor.LoadFromFile(const FileName: string);
    var
     Vers:byte;
     Index:DWORD;
     S:string;
    begin
     if FileHandle<>0 then begin
       FileClose(FileHandle);
       Count:=0;
       SetLength(Items,Count);
       AbsolutePath:='';
     end;

     FileHandle:=FileOpen(FileName,fmOpenRead);
     FileRead(FileHandle,Vers,sizeof(Vers));
     FileRead(FileHandle,Count,sizeof(Count));
     SetLength(Items,Count);

     for Index:=0 to Count-1 do begin
       FileRead(FileHandle,Items[Index],sizeof(TArchiveItem));
       S:=UpperCase(Items[Index].Name);
       CopyMemory(@Items[Index].Name[0],@S[1],Length(S));
     end;
    end;

    { TTextFile }

    constructor TSimpleFile.Create(const FileName: string);
    var
     Index:integer;
     Handle:integer;
    begin
     Index:=Archive.GetFileIndex(FileName);
     if (Index>-1) and (ArchiveIsPriority or not FileExists(FileName)) then begin
       Data:=Archive.GetData(Index);
       Size:=Archive.GetSize(Index);
     end
     else
     if FileExists(FileName) then
     begin
       Handle:=FileOpen(FileName,fmOpenRead);
       Size:=FileSeek(Handle,0,2);
       FileSeek(Handle,0,0);

       Data:=AllocMem(Size);
       FileRead(Handle,Data^,Size);
       FileClose(Handle);
     end
     else
       raise Exception.Create('File not found: \"'+FileName+'\"');
     Position:=Data;
    end;

    destructor TSimpleFile.Destroy;
    begin
     FreeMem(Data,Size);
     inherited;
    end;

    function TSimpleFile.EoF: boolean;
    begin
     Result:=Integer(Position)-Integer(Data)>=Size;
    end;

    function TTextFile.ReadString: string;
    begin
     Result:='';
     if not EoF then begin
       while (not EoF) and (Position^<>13) do begin
         Result:=Result+chr(Position^);
         inc(Position);
       end;
       if not EoF then
         inc(Position,2);
     end
     else
       raise Exception.Create(ERR_ENDOFFILE);
    end;

    function TTextFile.ReadTrimString: string;
    begin
     Result:=Trim(ReadString);
    end;

    { TIntegerFile }

    function TIntegerFile.ReadInteger: integer;
    begin
     Result:=0;
     if not EoF then begin
       Result:=PInteger(Position)^;
       inc(Position,sizeof(Integer));
     end
     else
       raise Exception.Create(ERR_ENDOFFILE);
    end;

    end.



    Если надо, есть софт для запаковки/распаковки, запаковка - с поддержкой плагинов.
  • @!!ex © (28.05.07 19:43) [17]
    P.S>
    Строчки
    VERSION:byte = 1;
    BufferSize:DWORD = 1048576;


    можно убить, они не юзаются.
  • ElectriC © (29.05.07 00:05) [18]

    > @!!ex

    Спасибо за исходник ;)))
  • Vga © (02.06.07 08:20) [19]
    Кстати, о редактировании. При минимальном навыке файлы типа @llex'овского вскрываются за 5 минут. Плюс некоторое время на нахождение и извлечение декодеров, если такие есть (сжатие, шифрование). VSPak (выше посты про PakMan) чуть сложнее, но в принципе тоже достаточно просто вскрывается.
  • @!!ex © (02.06.07 08:27) [20]
    > Vga ©   (02.06.07 08:20)

    LOL. Кодирования то нету. еще бы он не вскрывался.
  • Vga © (02.06.07 09:07) [21]
    Ну здесь еще и очень простая структура. Что до кодирования - как я уже сказал, оно извлекается за время от пары часов и выше (смотря по сложности и подлянкам)
  • Vga © (02.06.07 09:11) [22]
    А вот скажем с паками Steam я пока не разобрался, хотя они не кодированные. Там структура данных посложнее.
  • Rial © (02.06.07 18:31) [23]
    > [22] Vga ©   (02.06.07 09:11)

    Вообще то ни о какой попытке защитить эти
    файлы от вскрытия у @!!ex даже и речь не шла.

    Все гениальное - просто...
    А то, что тебе такой файл вскрыть запросто -
    это мы поняли уже. :)
  • antonn © (02.06.07 18:36) [24]
    делай кластерную структуру файла, будет немного больше в размерах, зато заколебешься выдирать:)
    хотя можно и это побороть...
  • Vga © (02.06.07 19:25) [25]
    [23]
    Речь шла в [0] :)

    [24]
    Ну методов-то хватает :) Тока лично мне это не надо... Мои паки вообще защиты лишены.
  • @!!ex_ (02.06.07 19:35) [26]
    > Речь шла в [0] :)

    Я привел модуль, который я использую. Прикрутить на него кучу защит ничего не стоит. Просто лично мне это пока не надо. И врядли понадобится. я ЗА любые моды.
  • Vga © (02.06.07 20:20) [27]

    > я ЗА любые моды.

    +1
  • Yashin © (02.06.07 21:17) [28]
    Главное интересно что вы в них прячите? Сверх секретные коды к игре, или супер сложные и красивые модели - текстуры к игре, которые вы не хотите, чтобы кто-то использовал. Помоему шифрование здесь совсем лишнее. Можно шифровать шейдеры, но это уже отдельно.
  • Vga © (02.06.07 21:27) [29]
    Я в них ничего не прячу. Сложно что то прятать в паке, сорцы работы с которым общедоступны :)
  • Vga © (02.06.07 21:30) [30]
    Ну и соответственно утилита работы с паками тоже общедоступна (функционал - list, extract, create)
  • gray_falcon © (03.06.07 00:13) [31]
    Покажите API для LZMA-желательно со справкой
  • Vga © (03.06.07 00:31) [32]
    На сайте архивера 7 zip (7zip.org, 7-zip.org или sevenzip.org - не помню) LZMA SDK (C, C++). Там же ссылки на перевод на дельфи. Я использую наработки Jordan Russel (Inno Setup, jrsoftware.org). Там используется для распаковки C-декомпрессор из LZMA SDK, статически линкуемый в виде объектника, а для упаковки - dll, скомпиленая из кодера LZMA из той же SDK. Хелп отсутствует, но там и так все ясно и прозрачно. Файл LZMA.pas из сорцов Inno Setup, и все потрошка, которые он юзает. Так же можно глянуть его же в версии под AvL, у меня в репозитории http://vgasoft.googlecode.com/svn/AvL/avlLZMA (нужны библиотеки на папку выше). Рядом есть и урезанный апи для NRV2E из UCL (выдрал из DIUCL).
  • Домик (04.06.07 22:43) [33]
    > Главное интересно что вы в них прячите?

    На одной из выставок смотрим казуальную игру, открываем папку с игрой, все ресурсы игры в распакованном виде лежат себе, бири не хочу. Спрашиваем у разработчиков, почему вы не упаковали все, а оставили все в открытом виде. Ответ был следующий: "Мы не параноики..." :)))

    Сам лично так же просто сшиваю все файлы в один без сжатия и шифровки, просто потому что не люблю большого количества папок и файлов в дистрибутиве с игрой.
  • Yashin © (05.06.07 00:21) [34]
    Ну это понятно, просто некоторые захотели зачем то прикрутить шифрование. Мне нравится как все сделано у DOOm 3,Prey,Quake 4. Там все архивы запакованы в обычный zip архив, часто таскаю оттуда текстуры.
  • @!!ex_ (05.06.07 09:58) [35]
    > часто таскаю оттуда текстуры.

    Вот и для этого тоже. :))
  • @!!ex_ (05.06.07 09:59) [36]
    Лично я последнее время пользую большие файлы, т.к. работа с ними быстрее, чем с кучей мелких. И копируется быстрее, и сама игра его быстрее читает.
  • имя (29.12.07 03:18) [37]
    Удалено модератором
  • имя (29.12.07 03:18) [38]
    Удалено модератором
  • имя (11.01.08 01:16) [39]
    Удалено модератором
  • имя (11.01.08 01:16) [40]
    Удалено модератором
  • имя (16.01.08 22:38) [41]
    Удалено модератором
  • Joffa © (18.01.08 15:47) [42]

    > @!!ex ©   (26.05.07 21:50) [2]
    > У меня есть модулек для таких целей.Просто создает гигантских
    > архив, умеет читать из него.В начале таблица с файлами:Имя,
    >  смещение, размер, тип сжатия(На данный момент сжатие еще
    > не сделал).Ну и соответственно сделано чтение из него по
    > принципу:Проис классик в память прочитать конкретный файлих
    > из арзива, потом по этому участку памяти создаем TMemoryStream
    > и работаем с ним как со стримом(правда я не стримы юзаю,
    >  но принцип тот же).


    абсолютная альтернатива %-) конкурировать не буду. но если не жалко, вышли на мыло ^__^'
  • имя (25.01.08 07:02) [43]
    Удалено модератором
  • ketmar © (27.01.08 13:17) [44]
    интересно, как это относится к DirectX.

    зыж особо интересующиеся могут поискать мой SFC. где-то в сети точно должно лежать. такая себе «заточка» для универсального пак-процессора. там около десятка форматов от разных игрушек хавается, да zip-архивы. API, конечно, бредовенький, но оно работает. %-)
  • grisme (28.01.08 10:57) [45]
    Кейт, чего прикрыл avalon-group.hocom.ua? >.<
  • ketmar © (28.01.08 11:30) [46]
    >[45] grisme(28.01.08 10:57)
    а обломился клацать «пролонгировать хостинг». всё равно в планах переезд в другое место. как только протрезвею, попробую слепить новый «сцайт». следите за анкетами. %-)
  • имя (09.04.08 10:55) [47]
    Удалено модератором
 
Конференция "Игры" » Большой файл для хранения данных [Delphi, DirectX 9]
Есть новые Нет новых   [134430   +4][b:0.001][p:0.005]