Commit 1dd2fa99 authored by mercury233's avatar mercury233 Committed by GitHub

add zip support (#2167)

parent d9704b35
......@@ -7,23 +7,37 @@ namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
wchar_t DataManager::strBuffer[4096];
byte DataManager::scriptBuffer[0x20000];
IFileSystem* DataManager::FileSystem;
DataManager dataManager;
bool DataManager::LoadDB(const char* file) {
sqlite3* pDB;
if(sqlite3_open_v2(file, &pDB, SQLITE_OPEN_READONLY, 0) != SQLITE_OK)
return Error(pDB);
bool DataManager::LoadDB(const wchar_t* wfile) {
IReadFile* reader = FileSystem->createAndOpenFile(wfile);
if(reader == NULL)
return false;
spmemvfs_db_t db;
spmembuffer_t* mem = (spmembuffer_t*)calloc(sizeof(spmembuffer_t), 1);
spmemvfs_env_init();
mem->total = mem->used = reader->getSize();
mem->data = (char*)malloc(mem->total + 1);
reader->read(mem->data, mem->total);
reader->drop();
(mem->data)[mem->total] = '\0';
char file[256];
BufferIO::EncodeUTF8(wfile, file);
if(spmemvfs_open_db(&db, file, mem) != SQLITE_OK)
return Error(&db);
sqlite3* pDB = db.handle;
sqlite3_stmt* pStmt;
const char* sql = "select * from datas,texts where datas.id=texts.id";
if(sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK)
return Error(pDB);
return Error(&db);
CardDataC cd;
CardString cs;
int step = 0;
do {
step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
return Error(pDB, pStmt);
return Error(&db, pStmt);
else if(step == SQLITE_ROW) {
cd.code = sqlite3_column_int(pStmt, 0);
cd.ot = sqlite3_column_int(pStmt, 1);
......@@ -63,7 +77,8 @@ bool DataManager::LoadDB(const char* file) {
}
} while(step != SQLITE_DONE);
sqlite3_finalize(pStmt);
sqlite3_close(pDB);
spmemvfs_close_db(&db);
spmemvfs_env_fini();
return true;
}
bool DataManager::LoadStrings(const char* file) {
......@@ -71,40 +86,59 @@ bool DataManager::LoadStrings(const char* file) {
if(!fp)
return false;
char linebuf[256];
char strbuf[256];
int value;
while(fgets(linebuf, 256, fp)) {
if(linebuf[0] != '!')
continue;
sscanf(linebuf, "!%s", strbuf);
if(!strcmp(strbuf, "system")) {
sscanf(&linebuf[7], "%d %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_sysStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "victory")) {
sscanf(&linebuf[8], "%x %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_victoryStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "counter")) {
sscanf(&linebuf[8], "%x %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_counterStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "setname")) {
sscanf(&linebuf[8], "%x %240[^\t\n]", &value, strbuf);//using tab for comment
BufferIO::DecodeUTF8(strbuf, strBuffer);
_setnameStrings[value] = strBuffer;
}
ReadStringConfLine(linebuf);
}
fclose(fp);
for(int i = 0; i < 255; ++i)
myswprintf(numStrings[i], L"%d", i);
return true;
}
bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB), strBuffer);
bool DataManager::LoadStrings(IReadFile* reader) {
char ch[2] = " ";
char linebuf[256] = "";
while(reader->read(&ch[0], 1)) {
if(ch[0] == '\0')
break;
strcat(linebuf, ch);
if(ch[0] == '\n') {
ReadStringConfLine(linebuf);
linebuf[0] = '\0';
}
}
reader->drop();
return true;
}
void DataManager::ReadStringConfLine(const char* linebuf) {
if(linebuf[0] != '!')
return;
char strbuf[256];
int value;
sscanf(linebuf, "!%s", strbuf);
if(!strcmp(strbuf, "system")) {
sscanf(&linebuf[7], "%d %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_sysStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "victory")) {
sscanf(&linebuf[8], "%x %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_victoryStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "counter")) {
sscanf(&linebuf[8], "%x %240[^\n]", &value, strbuf);
BufferIO::DecodeUTF8(strbuf, strBuffer);
_counterStrings[value] = strBuffer;
} else if(!strcmp(strbuf, "setname")) {
sscanf(&linebuf[8], "%x %240[^\t\n]", &value, strbuf);//using tab for comment
BufferIO::DecodeUTF8(strbuf, strBuffer);
_setnameStrings[value] = strBuffer;
}
}
bool DataManager::Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt) {
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB->handle), strBuffer);
if(pStmt)
sqlite3_finalize(pStmt);
sqlite3_close(pDB);
spmemvfs_close_db(pDB);
spmemvfs_env_fini();
return false;
}
bool DataManager::GetData(int code, CardData* pData) {
......@@ -328,21 +362,19 @@ byte* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
return ScriptReader(second, slen);
}
byte* DataManager::ScriptReader(const char* script_name, int* slen) {
FILE *fp;
#ifdef _WIN32
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
fp = _wfopen(fname, L"rb");
#else
fp = fopen(script_name, "rb");
#endif
if(!fp)
IReadFile* reader = FileSystem->createAndOpenFile(fname);
if(reader == NULL)
return 0;
int len = fread(scriptBuffer, 1, sizeof(scriptBuffer), fp);
fclose(fp);
if(len >= sizeof(scriptBuffer))
size_t size = reader->getSize();
if(size > sizeof(scriptBuffer)) {
reader->drop();
return 0;
*slen = len;
}
reader->read(scriptBuffer, size);
reader->drop();
*slen = size;
return scriptBuffer;
}
......
......@@ -3,6 +3,7 @@
#include "config.h"
#include "sqlite3.h"
#include "spmemvfs.h"
#include "client_card.h"
#include <unordered_map>
......@@ -11,9 +12,11 @@ namespace ygo {
class DataManager {
public:
DataManager(): _datas(8192), _strings(8192) {}
bool LoadDB(const char* file);
bool LoadDB(const wchar_t* wfile);
bool LoadStrings(const char* file);
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = 0);
bool LoadStrings(IReadFile* reader);
void ReadStringConfLine(const char* linebuf);
bool Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt = 0);
bool GetData(int code, CardData* pData);
code_pointer GetCodePointer(int code);
bool GetString(int code, CardString* pStr);
......@@ -54,7 +57,7 @@ public:
static int CardReader(int, void*);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReader(const char* script_name, int* slen);
static IFileSystem* FileSystem;
};
extern DataManager dataManager;
......
......@@ -56,8 +56,9 @@ bool Game::Initialize() {
ErrorLog("Failed to load textures!");
return false;
}
LoadExpansionDB();
if(!dataManager.LoadDB("cards.cdb")) {
dataManager.FileSystem = device->getFileSystem();
LoadExpansions();
if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!");
return false;
}
......@@ -862,14 +863,37 @@ void Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gu
dataManager.strBuffer[pbuffer] = 0;
pControl->setText(dataManager.strBuffer);
}
void Game::LoadExpansionDB() {
FileSystem::TraversalDir("./expansions", [](const char* name, bool isdir) {
if(!isdir && strrchr(name, '.') && !mystrncasecmp(strrchr(name, '.'), ".cdb", 4)) {
char fpath[1024];
sprintf(fpath, "./expansions/%s", name);
void Game::LoadExpansions() {
FileSystem::TraversalDir(L"./expansions", [](const wchar_t* name, bool isdir) {
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".cdb", 4)) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
dataManager.LoadDB(fpath);
}
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".zip", 4)) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
dataManager.FileSystem->addFileArchive(fpath, true, false);
}
});
for(u32 i = 0; i < DataManager::FileSystem->getFileArchiveCount(); ++i) {
const IFileList* archive = DataManager::FileSystem->getFileArchive(i)->getFileList();
for(u32 j = 0; j < archive->getFileCount(); ++j) {
#ifdef _WIN32
const wchar_t* fname = archive->getFullFileName(j).c_str();
#else
wchar_t fname[1024];
const char* uname = archive->getFullFileName(j).c_str();
BufferIO::DecodeUTF8(uname, fname);
#endif
if(wcsrchr(fname, '.') && !mywcsncasecmp(wcsrchr(fname, '.'), L".cdb", 4))
dataManager.LoadDB(fname);
if(wcsrchr(fname, '.') && !mywcsncasecmp(wcsrchr(fname, '.'), L".conf", 5)) {
IReadFile* reader = DataManager::FileSystem->createAndOpenFile(fname);
dataManager.LoadStrings(reader);
}
}
}
}
void Game::RefreshDeck(irr::gui::IGUIComboBox* cbDeck) {
cbDeck->clear();
......
......@@ -108,7 +108,7 @@ public:
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
void InitStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, u32 cHeight, irr::gui::CGUITTFont* font, const wchar_t* text);
void SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, u32 pos = 0);
void LoadExpansionDB();
void LoadExpansions();
void RefreshDeck(irr::gui::IGUIComboBox* cbDeck);
void RefreshReplay();
void RefreshSingleplay();
......
......@@ -77,17 +77,13 @@ int main(int argc, char* argv[]) {
bool keep_on_return = false;
for(int i = 1; i < wargc; ++i) {
if(wargv[i][0] == L'-' && wargv[i][1] == L'e' && wargv[i][2] != L'\0') {
char param[128];
BufferIO::EncodeUTF8(&wargv[i][2], param);
ygo::dataManager.LoadDB(param);
ygo::dataManager.LoadDB(&wargv[i][2]);
continue;
}
if(!wcscmp(wargv[i], L"-e")) { // extra database
++i;
if(i < wargc) {
char param[128];
BufferIO::EncodeUTF8(wargv[i], param);
ygo::dataManager.LoadDB(param);
ygo::dataManager.LoadDB(wargv[i]);
}
continue;
} else if(!wcscmp(wargv[i], L"-n")) { // nickName
......
This diff is collapsed.
/*
* BSD 2-Clause License
*
* Copyright 2009 Stephen Liu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __spmemvfs_h__
#define __spmemvfs_h__
#ifdef __cplusplus
extern "C" {
#endif
#include "sqlite3.h"
#define SPMEMVFS_NAME "spmemvfs"
typedef struct spmembuffer_t {
char * data;
int used;
int total;
} spmembuffer_t;
typedef struct spmemvfs_db_t {
sqlite3 * handle;
spmembuffer_t * mem;
} spmemvfs_db_t;
int spmemvfs_env_init();
void spmemvfs_env_fini();
int spmemvfs_open_db( spmemvfs_db_t * db, const char * path, spmembuffer_t * mem );
int spmemvfs_close_db( spmemvfs_db_t * db );
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment