Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

David Scherfgen

Administrator

  • »David Scherfgen« ist der Autor dieses Themas

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

1

02.08.2006, 21:05

Lesen/Schreiben von (verschlüsselten) Zip-Archiven

Einleitung

Die wenigsten Spieleentwickler möchten, dass die Daten ihres Spiels (Texturen, Modelle, Sounds, Levels …) für jeden einsehbar und veränderbar sind. Dieses Tutorial zeigt, wie man mit einfachen Mitteln Dateien aus verschlüsselten Zip-Archiven laden kann.
Natürlich wäre es auch möglich, sich sein eigenes Archivformat und die benötigten Tools zum Packen und Entpacken zu schreiben, aber wozu das Rad neu erfinden? Die Kompressionsrate von Zip reicht in den meisten Fällen aus, und es gibt gute Tools wie Sand am Meer.


Was wird gebraucht?

Alles, was zusätzlich zu einem Compiler noch benötigt wird, ist die völlig kostenlose zlib. Diese ist hier zu bekommen: http://www.zlib.net/ . Entweder lädst du dir eine bereits vorkompilierte Version der zlib herunter, oder du kompilierst sie dir selbst. Die Packages kommen zusammen mit Projektdateien für alle gängigen Compiler inklusive Visual C++.

In der zlib enthalten ist auch gleichzeitig minizip, was wir später noch brauchen werden.


Nur eine Funktion

In diesem Tutorial soll lediglich eine einzige Funktion programmiert werden. Diese zeigt, wie eine Datei aus einem verschlüsselten Zip-Archiv gelesen werden kann, und du kannst sie später beispielsweise in deinem selbstprogrammierten virtuellen Dateisystem einsetzen. Da dies nur der Demonstration dient, verzichte ich auf den Einsatz von Klassen. Unsere Funktion soll wie folgt aussehen:

C-/C++-Quelltext

1
2
3
4
5
int readArchivedFile(const std::string& archiveFilename,
                     const std::string& filename,
                     const std::string& password,
                     void** pp_dataOut,
                     unsigned int* p_dataSizeOut);


Im ersten Parameter werden wir den Dateinamen des Zip-Archivs übergeben (z.B. „data.zip“), im zweiten den Namen der darin archivierten Datei (z.B. „sprites.png“) und im dritten ein Passwort, falls das Archiv verschlüsselt ist. Im vierten Parameter übergeben wir die Adresse eines Zeigers, den die Funktion ausfüllt, so dass er anschließend auf die gelesenen Daten zeigt, und der letzte Parameter ist die Adresse eines ganzzahligen Werts, den die Funktion mit der Größe der gelesenen Daten ausfüllt. Für das spätere Löschen der gelesenen Daten mit delete[] ist der Programmierer selbst zuständig. Der Rückgabewert der Funktion zeigt an, ob alles glatt gelaufen ist, oder ob es einen Fehler gab.


Es geht zur Sache

Zuerst müssen wir das Archiv öffnen. Dazu verwenden wir die Funktion unzOpen, die – wie alle im folgenden verwendeten Funktionen – in der minizip-Library zu finden ist. Die minizip-Library befindet sich im Ordner contrib/minizip des zlib-Packages. Insbesondere benötigen wir die Funktionen aus der Datei unzip.c. In unzip.h befindet sich die Dokumentation der hier verwendeten Funktionen. Diese Datei muss per #include eingebunden werden. Du solltest neben unzip.c auch die anderen .c-Dateien aus dem minizip-Verzeichnis zum Projekt hinzufügen – außer minizip.c und miniunz.c, denn dabei handelt es sich um eigenständige Programme (zum Packen und Entpacken per Kommandozeile).

unzOpen erwartet lediglich den Dateinamen des zu öffnenden Archivs und liefert einen Rückgabewert vom Typ unzFile. Dies ist ein Handle, das wir für alle weiteren Operationen mit dem geöffneten Archiv brauchen werden. Gab es einen Fehler, ist der Rückgabewert null.

Als nächstes müssen wir den internen Lesezeiger des geöffneten Archivs auf die angeforderte archivierte Datei setzen. Dazu verwenden wir unzLocateFile. Diese Funktion erwartet als Parameter das Archiv-Handle und den Namen der archivierten Datei, die wir später lesen möchten. Der dritte Parameter gibt an, ob beim Suchen der Datei die Groß-/Kleinschreibung beachtet werden soll. Ein Rückgabewert von UNZ_OK signalisiert, dass es keine Fehler gab, also die Datei gefunden wurde.

Jetzt sind wir schon fast so weit, dass wir die Datei tatsächlich lesen können. Aber eines fehlt noch, denn zuvor sollten wir wissen, wie groß die Datei eigentlich ist, damit wir die richtige Speichermenge anfordern können. Diese und andere Informationen erhalten wir mit Hilfe der Funktion unzGetCurrentFileInfo. Diese erwartet viele Parameter, wovon für uns aber nur die ersten beiden interessant sind: das Archiv-Handle (wie immer) und einen Zeiger auf eine Variable vom Typ unz_file_info. Die Funktion wird diese Variable ausfüllen, und dort finden wir dann im Element uncompressed_size die Größe der entpackten Datei.
Nun können wir den benötigten Speicher reservieren und sind bereit für den entscheidenden Schritt: das Öffnen und Lesen der Datei. Hierzu verwenden wir entweder unzOpenCurrentFile oder unzOpenCurrentFilePassword, abhängig davon, ob wir es mit einer verschlüsselten Datei zu tun haben oder nicht. Als Parameter brauchen wir nur das Archiv-Handle und bei der zweiten Variante noch das Passwort zum Entschlüsseln zu übergeben. Auch hier zeigt ein Rückgabewert von UNZ_OK an, dass alles geklappt hat.

Das eigentliche Lesen der Daten erfolgt nun mit Hilfe der Funktion unzReadCurrentFile. Dieser übergeben wir das Archiv-Handle, die Adresse zum Ablegen der gelesenen Daten und die Anzahl der Bytes, die wir gerne lesen würden. Stimmt der Rückgabewert mit der Anzahl der angeforderten Bytes überein, war alles in Ordnung.

Nun müssen wir nur noch aufräumen, wozu wir unzCloseCurrentFile und unzClose aufrufen. Das war’s! Und hier kommt die Funktion, die genau das macht, was in den letzten Absätzen beschrieben wurde.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
int readArchivedFile(const std::string& archiveFilename,
                     const std::string& filename,
                     const std::string& password,
                     void** pp_dataOut,
                     unsigned int* p_dataSizeOut)
{
    // Archiv öffnen

    unzFile archive = unzOpen(archiveFilename.c_str());
    if(!archive)
    {
        // Fehler! Die Archivdatei existiert wahrscheinlich nicht oder ist beschädigt.

        return -1;
    }

    // die archivierte Datei aufspüren, Groß-/Kleinschreibung ignorieren

    int result = unzLocateFile(archive, filename.c_str(), 0);
    if(result != UNZ_OK)
    {
        // Fehler! Die Datei wurde wohl nicht gefunden.

        unzClose(archive);
        return -2;
    }

    // Dateiinformationen abfragen

    unz_file_info info;
    unzGetCurrentFileInfo(archive, &info, 0, 0, 0, 0, 0, 0);

    // die entsprechende Menge an Speicher reservieren

    unsigned int fileSize = static_cast<unsigned int>(info.uncompressed_size);
    char* p_data = new char[fileSize];
    if(!p_data)
    {
        // Fehler! Nicht genug Speicher. Die Datei müsste stückweise gelesen werden.

        unzClose(archive);
        return -3;
    }

    // Datei öffnen - mit Passwort oder ohne

    if(password.empty()) result = unzOpenCurrentFile(archive);
    else result = unzOpenCurrentFilePassword(archive, password.c_str());
    if(result != UNZ_OK)
    {
        // Fehler! Das Passwort könnte falsch sein.

        delete[] p_data;
        unzClose(archive);
        return -4;
    }

    // die komplette Datei lesen

    unsigned int numBytesRead = unzReadCurrentFile(archive, p_data, fileSize);
    if(numBytesRead != fileSize)
    {
        // Fehler! Das Archiv könnte beschädigt sein.

        delete[] p_data;
        unzCloseCurrentFile(archive);
        unzClose(archive);
        return -5;
    }

    // aufräumen

    unzCloseCurrentFile(archive);
    unzClose(archive);

    // Daten und Größe zurückliefern

    if(pp_dataOut) *pp_dataOut = p_data;
    if(p_dataSizeOut) *p_dataSizeOut = fileSize;

    // Alles OK!

    return 0;
}



Anwendungsbeispiel

Ich will hier noch ein kleines Beispiel für die Verwendung unserer Funktion zeigen. Wir lesen die Datei „test.txt“ aus dem Archiv „test.zip“, die mit dem Passwort „1337“ verschlüsselt wurde.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void* p_text = 0;
unsigned int textSize = 0;

// verschlüsselte Datei "test.txt" aus dem Archiv "test.zip" lesen, Passwort "1337"

int result = readArchivedFile("test.zip", "test.txt", "1337", &p_text, &textSize);
if(result)
{
    // Fehler!

    printf("Fehler! (Code: %d)\n", result);
}
else
{
    // Text ausgeben

    std::string text(static_cast<char*>(p_text), textSize);
    printf("Der gelesene Text: %s\n", text.c_str());

    // Speicher wieder freigeben

    delete[] p_text;
}



Und was ist mit Schreiben?

Die minizip-Bibliothek ermöglicht nicht nur das Lesen aus passwortverschlüsselten Zip-Archiven, sondern unterstützt auch Schreibvorgänge darin. Die entsprechenden Funktionen befinden sich in der Datei zip.c (Dokumentation in zip.h) und lassen sich ganz analog zu den hier benutzten Lesefunktionen verwenden.
Aufwändiger wird es, wenn eine bereits vorhandene Datei in einem Archiv überschrieben werden soll. Dann ist es zunächst erforderlich, die Datei komplett aus dem Archiv zu löschen. Leider bietet die minizip-Bibliothek hierzu keine Funktion. Darum möchte ich hier eine solche zur Verfügung stellen. Die Funktion deleteArchivedFile erwartet als Parameter den Dateinamen des Archivs und den Namen der zu löschenden Datei, die darin archiviert ist. Dazu wird das Archiv Datei für Datei in ein neues Archiv kopiert, wobei die zu löschende Datei einfach ausgelassen wird. Für den Fall, dass die zu löschende Datei die einzige Datei in dem Archiv ist, wird das gesamte Archiv gelöscht, da ein leeres Archiv beim Öffnen zu Problemen führt.
Die Informationen zum Aufbau des Zip-Dateiformats habe ich diesem Text entnommen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#pragma pack(push, 1)

int deleteArchivedFile(const std::string& archiveFilename,
                       const std::string& objectName)
{
    int result = 0;

    struct LocalFileHeader
    {
        unsigned int signature;
        unsigned short versionNeeded;
        unsigned short flags;
        unsigned short method;
        unsigned short modTime;
        unsigned short modDate;
        unsigned int crc;
        unsigned int compressedSize;
        unsigned int uncompressedSize;
        unsigned short filenameLength;
        unsigned short extraFieldLength;
    };

    struct EndOfCentralDirectory
    {
        unsigned int signature;
        unsigned short thisDisk;
        unsigned short centralRecordDisk;
        unsigned short entriesOnThisDisk;
        unsigned short totalEntries;
        unsigned int centralDirectorySize;
        unsigned int centralDirectoryOffset;
        unsigned short globalCommentLength;
    };

    struct CentralDirectoryEntry
    {
        unsigned int signature;
        unsigned short versionMadeBy;
        unsigned short versionNeeded;
        unsigned short flags;
        unsigned short method;
        unsigned short modTime;
        unsigned short modDate;
        unsigned int crc;
        unsigned int compressedSize;
        unsigned int uncompressedSize;
        unsigned short filenameLength;
        unsigned short extraFieldLength;
        unsigned short commentLength;
        unsigned short diskNumber;
        unsigned short intAttribs;
        unsigned int extAttribs;
        unsigned int localHeaderOffset;
    };

    FILE* p_in = fopen(archiveFilename.c_str(), "rb");
    FILE* p_out = fopen((archiveFilename + "_").c_str(), "wb");

    // zentrales Verzeichnis suchen

    while(true)
    {
        unsigned int signature;
        unsigned int pos = ftell(p_in);
        fread(&signature, 1, 4, p_in);
        fseek(p_in, pos, SEEK_SET);

        if(signature == 0x04034B50)
        {
            LocalFileHeader lfh;
            fread(&lfh, 1, sizeof(lfh), p_in);
            fseek(p_in, lfh.filenameLength + lfh.extraFieldLength + lfh.compressedSize, SEEK_CUR);
        }
        else if(signature == 0x02014B50)
        {
            CentralDirectoryEntry cde;
            fread(&cde, 1, sizeof(cde), p_in);
            fseek(p_in, cde.filenameLength + cde.extraFieldLength + cde.commentLength, SEEK_CUR);
        }
        else if(signature == 0x06054B50)
        {
            // Danach haben wir gesucht!

            break;
        }
        else
        {
            return false;
        }
    }

    EndOfCentralDirectory ecd, ecdOut;
    fread(&ecd, 1, sizeof(ecd), p_in);
    char* p_globalComment = 0;
    if(ecd.globalCommentLength) p_globalComment = new char[ecd.globalCommentLength];
    ecdOut = ecd;

    fseek(p_in, ecd.centralDirectoryOffset, SEEK_SET);

    std::vector<CentralDirectoryEntry> cdOut;
    std::vector<char*> filenameOut, extraFieldOut, commentOut;

    // Einträge lesen und schreiben

    for(unsigned int i = 0; i < ecd.totalEntries; i++)
    {
        CentralDirectoryEntry cde, cdeOut;
        fread(&cde, 1, sizeof(cde), p_in);
        cdeOut = cde;
        char* p_filename = new char[cde.filenameLength + 1];
        fread(p_filename, 1, cde.filenameLength, p_in);
        p_filename[cde.filenameLength] = 0;

        char* p_extraField = 0;
        if(cde.extraFieldLength)
        {
            p_extraField = new char[cde.extraFieldLength];
            fread(p_extraField, 1, cde.extraFieldLength, p_in);
        }
        char* p_comment = 0;
        if(cde.commentLength)
        {
            p_comment = new char[cde.commentLength];
            fread(p_comment, 1, cde.commentLength, p_in);
        }

        // merken, wo es nachher weitergeht

        unsigned int nextCDE = ftell(p_in);

        // Stimmt der Dateiname mit dem zu löschenden Dateinamen überein?

        if(!_stricmp(objectName.c_str(), p_filename))
        {
            ecdOut.entriesOnThisDisk--;
            ecdOut.totalEntries--;
            ecdOut.centralDirectorySize -= sizeof(cde) + cde.filenameLength + cde.extraFieldLength + cde.commentLength;
            result = 1;

            delete[] p_filename;
            delete[] p_extraField;
            delete[] p_comment;
        }
        else
        {
            // Diese Datei soll kopiert werden. Zuerst lesen wir ihren lokalen Header.

            LocalFileHeader lfh;
            fseek(p_in, cde.localHeaderOffset, SEEK_SET);
            fread(&lfh, sizeof(lfh), 1, p_in);

            // Dateiname und Extrafeld überspringen

            fseek(p_in, lfh.filenameLength + lfh.extraFieldLength, SEEK_CUR);

            // Daten lesen

            char* p_fileData = new char[lfh.compressedSize];
            fread(p_fileData, 1, lfh.compressedSize, p_in);

            // lokalen Header schreiben

            cdeOut.localHeaderOffset = ftell(p_out);
            fwrite(&lfh, 1, sizeof(lfh), p_out);
            fwrite(p_filename, 1, lfh.filenameLength, p_out);
            if(lfh.extraFieldLength) fwrite(p_extraField, 1, lfh.extraFieldLength, p_out);
            fwrite(p_fileData, 1, lfh.compressedSize, p_out);
            delete[] p_fileData;

            // Eintrag für das zentrale Verzeichnis merken

            cdOut.push_back(cdeOut);
            filenameOut.push_back(p_filename);
            extraFieldOut.push_back(p_extraField);
            commentOut.push_back(p_comment);
        }

        fseek(p_in, nextCDE, SEEK_SET);
    }

    // zentrales Verzeichnis schreiben

    ecdOut.centralDirectoryOffset = ftell(p_out);
    for(unsigned int i = 0; i < cdOut.size(); i++)
    {
        CentralDirectoryEntry& cde = cdOut[i];
        fwrite(&cde, 1, sizeof(cde), p_out);

        char* p_filename = filenameOut[i];
        char* p_extraField = extraFieldOut[i];
        char* p_comment = commentOut[i];

        fwrite(p_filename, 1, cde.filenameLength, p_out);
        if(cde.extraFieldLength) fwrite(p_extraField, 1, cde.extraFieldLength, p_out);
        if(cde.commentLength) fwrite(p_comment, 1, cde.commentLength, p_out);

        delete[] p_filename;
        delete[] p_extraField;
        delete[] p_comment;
    }

    // Ende schreiben

    fwrite(&ecdOut, 1, sizeof(ecdOut), p_out);
    if(ecdOut.globalCommentLength) fwrite(p_globalComment, 1, ecdOut.globalCommentLength, p_out);

    delete[] p_globalComment;

    fclose(p_in);
    fclose(p_out);

    // altes Archiv löschen

    remove(archiveFilename.c_str());

    if(ecdOut.totalEntries)
    {
        // neue Datei umbenennen

        rename((archiveFilename + "_").c_str(), archiveFilename.c_str());
    }
    else
    {
        // neue Datei löschen

        remove((archiveFilename + "_").c_str());
        result = -1;
    }

    return result;
}

#pragma pack(pop)



Weitere Anregungen

Die hier gezeigten Funktionen sind natürlich noch recht rudimentär. Richtig praktisch wird das ganze erst, wenn man es in ein virtuelles Dateisystem integriert. Dort könnte man Zip-Archive wie Verzeichnisse behandeln und beispielsweise Dateinamen wie „data.zip[passwort]/sprites.png“ verwenden. Das Dateisystem würde beim Analysieren des Pfads erkennen, dass es sich um ein verschlüsseltes Zip-Archiv handelt und dafür sorgen, dass die Datei „sprites.png“ mit dem Passwort „passwort“ entpackt wird. Das alles würde ganz transparent geschehen. Dem Benutzer (Programmierer) könnte es egal sein, ob sein Pfad auf eine gewöhnliche Datei oder auf eine archivierte Datei zeigt, denn das Dateisystem würde sich um alle nötigen Schritte kümmern.

Das ursprüngliche Ziel war ja, dass niemand einfach so in die Dateien des Spiels bzw. der Anwendung hereinsehen kann. Wenn das Passwort jedoch im Klartext, also unverschlüsselt, im Programmcode steht, dann wird es ohne weitere Maßnahmen auch unverschlüsselt in der ausführbaren Datei (.exe) stehen und könnte so herausgefischt werden. Darum könnte man alle Passwörter noch einmal separat verschlüsseln.

2

02.08.2006, 21:19

Evt. noch direkt hinzuschreiben wie es rechtlich mit der Lib steht ;)
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

3

02.08.2006, 22:35

C-/C++-Quelltext

1
2
if(password.empty()) result = unzOpenCurrentFilePassword(archive, password.c_str());
    else result = unzOpenCurrentFile(archive); 


hm, fehlt da ein " ! " ?

David Scherfgen

Administrator

  • »David Scherfgen« ist der Autor dieses Themas

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

02.08.2006, 22:37

Jo, oder vertauschen. Danke.

BlackSnake

Community-Fossil

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

5

17.10.2006, 20:12

ich habe hier eine kleinen fehler in bezug auf linken.
er gibt mir immer diese meldungen aus:
[list]
ZLIB.obj : error LNK2001: unresolved external symbol _unzLocateFile
ZLIB.obj : error LNK2001: unresolved external symbol _unzOpen
ZLIB.obj : error LNK2001: unresolved external symbol _unzCloseCurrentFile
ZLIB.obj : error LNK2001: unresolved external symbol _unzClose
ZLIB.obj : error LNK2001: unresolved external symbol _unzOpenCurrentFilePassword
ZLIB.obj : error LNK2001: unresolved external symbol _unzOpenCurrentFile
ZLIB.obj : error LNK2001: unresolved external symbol _unzGetCurrentFileInfo
[/list]
ich habe aber die libs gelinkt. und zwar die "zdll.lib" und die "zlib.lib". ich hoffe das sind die richtigen, aber andere habe ich nicht finden können. außerdem steht in einem Textfile ich soll die erst aufgeführte lib zu meinem project hinzufügen. so nehme ich an das sie richtig ist.

bitte um hilfe.
Danke

David Scherfgen

Administrator

  • »David Scherfgen« ist der Autor dieses Themas

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

17.10.2006, 21:25

Zitat von »"David Scherfgen"«

Du solltest neben unzip.c auch die anderen .c-Dateien aus dem minizip-Verzeichnis zum Projekt hinzufügen – außer minizip.c und miniunz.c, denn dabei handelt es sich um eigenständige Programme (zum Packen und Entpacken per Kommandozeile).

BlackSnake

Community-Fossil

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

7

17.10.2006, 22:02

habe ich (ich kann lesen). geht aber trotzdem nicht

David Scherfgen

Administrator

  • »David Scherfgen« ist der Autor dieses Themas

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

17.10.2006, 22:09

Ich dachte nur, weil du nur was von der .lib geschrieben hast.
Guck mal in die .C-Dateien rein. Da sollten die vermissten Funktionen definiert sein.
(Diese Dateien zu deinem Projekt hinzufügen, nicht zum Zlib-Projekt)

BlackSnake

Community-Fossil

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

9

18.10.2006, 12:12

also es funktioniert jetzt(halb).

wenn ich die funktion jetzt anwenden möchet
[list]
g_pLight->readArchivedFile("Test.zip", "Test.txt", "1234", &g_pLight->Zip_Data_Out, &g_pLight->Zip_Size_Out)
[/list]
kommen zwar keine fehler bezüglich "Archib nicht vorhanden","Datei nicht vorhanden" aber er liest irgendwie nicht.
wenn ich jetzt beispielsweise ein modell auslesen möchte zeigt er mir das modell im spiel nicht an und dann kommt eine fehler meldung, weil das modell nicht geladen wurde.

woran kann das liegen??

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

10

20.10.2006, 16:32

Hast Du mal debuggt und die entpackten Daten mit den unkomprimierten verglichen?
"Games are algorithmic entertainment."

Werbeanzeige