Commit 5540afa2 authored by mycard's avatar mycard

Merge branch 'server' of https://github.com/purerosefallen/ygopro

parents b4f66ed2 021dc64c
......@@ -33,4 +33,4 @@ script:
- mkdir replay
- echo "select id from datas;" | sqlite3 $DATABASE_FILE | xargs -I {} ./ygopro {} 2>&1 | tee ./redtext.txt
- bash -c "exit $(cat ./redtext.txt | wc -l)"
\ No newline at end of file
- bash -c "exit $(cat ./redtext.txt | wc -l)"
No preview for this file type
......@@ -7,12 +7,38 @@ namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
wchar_t DataManager::strBuffer[4096];
byte DataManager::scriptBuffer[0x20000];
#ifndef YGOPRO_SERVER_MODE
IFileSystem* DataManager::FileSystem;
#endif
DataManager dataManager;
bool DataManager::LoadDB(const char* file) {
bool DataManager::LoadDB(const wchar_t* wfile) {
char file[256];
BufferIO::EncodeUTF8(wfile, file);
#ifdef YGOPRO_SERVER_MODE
sqlite3* pDB;
if(sqlite3_open_v2(file, &pDB, SQLITE_OPEN_READONLY, 0) != SQLITE_OK)
return Error(pDB);
#else
#ifdef _WIN32
IReadFile* reader = FileSystem->createAndOpenFile(wfile);
#else
IReadFile* reader = FileSystem->createAndOpenFile(file);
#endif
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';
if(spmemvfs_open_db(&db, file, mem) != SQLITE_OK)
return Error(&db);
sqlite3* pDB = db.handle;
#endif //YGOPRO_SERVER_MODE
sqlite3_stmt* pStmt;
#ifdef YGOPRO_SERVER_MODE
const char* sql = "select * from datas";
......@@ -20,14 +46,22 @@ bool DataManager::LoadDB(const char* file) {
const char* sql = "select * from datas,texts where datas.id=texts.id";
#endif
if(sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK)
#ifdef YGOPRO_SERVER_MODE
return Error(pDB);
#else
return Error(&db);
#endif
CardDataC cd;
CardString cs;
int step = 0;
do {
step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
#ifdef YGOPRO_SERVER_MODE
return Error(pDB, pStmt);
#else
return Error(&db, pStmt);
#endif
else if(step == SQLITE_ROW) {
cd.code = sqlite3_column_int(pStmt, 0);
cd.ot = sqlite3_column_int(pStmt, 1);
......@@ -69,49 +103,69 @@ bool DataManager::LoadDB(const char* file) {
}
} while(step != SQLITE_DONE);
sqlite3_finalize(pStmt);
#ifdef YGOPRO_SERVER_MODE
sqlite3_close(pDB);
#else
spmemvfs_close_db(&db);
spmemvfs_env_fini();
#endif
return true;
}
bool DataManager::LoadStrings(const char* file) {
#ifdef _WIN32
wchar_t fname[1024];
BufferIO::DecodeUTF8(file, fname);
FILE* fp = _wfopen(fname, L"r");
#else
FILE* fp = fopen(file, "r");
#endif // _WIN32
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;
}
#ifndef YGOPRO_SERVER_MODE
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;
}
#endif //YGOPRO_SERVER_MODE
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;
}
}
#ifdef YGOPRO_SERVER_MODE
bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB), strBuffer);
if(pStmt)
......@@ -119,6 +173,16 @@ bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
sqlite3_close(pDB);
return false;
}
#else
bool DataManager::Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt) {
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB->handle), strBuffer);
if(pStmt)
sqlite3_finalize(pStmt);
spmemvfs_close_db(pDB);
spmemvfs_env_fini();
return false;
}
#endif
bool DataManager::GetData(int code, CardData* pData) {
auto cdit = _datas.find(code);
if(cdit == _datas.end())
......@@ -331,51 +395,31 @@ byte* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer;
#ifndef YGOPRO_SERVER_MODE
if(!mainGame->gameConf.prefer_expansion_script) {
buffer = ScriptReaderExDirectry(".", script_name, slen);
buffer = ScriptReaderExSingle("", script_name, slen);
if(buffer)
return buffer;
}
#endif
buffer = ScriptReaderExDirectry("./specials", script_name, slen, 8);
if(buffer)
return buffer;
buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
buffer = ScriptReaderExSingle("specials/", script_name, slen, 9);
if(buffer)
return buffer;
buffer = ScriptReaderExDirectry("./beta", script_name, slen);
buffer = ScriptReaderExSingle("expansions/", script_name, slen);
if(buffer)
return buffer;
buffer = ScriptReaderExDirectry("./2pick", script_name, slen, 8);
buffer = ScriptReaderExSingle("2pick/", script_name, slen, 9);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return ScriptReader(script_name, slen);
return ScriptReaderExSingle("", script_name, slen);
}
byte* DataManager::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen, int pre_len) {
byte* DataManager::ScriptReaderExSingle(const char* path, const char* script_name, int* slen, int pre_len) {
char sname[256];
sprintf(sname, "%s%s", path, script_name + pre_len); //default script name: ./script/c%d.lua
return ScriptReader(sname, slen);
}
byte* DataManager::ScriptReader(const char* script_name, int* slen) {
FILE *fp;
#if defined(_WIN32) && !defined(YGOPRO_SERVER_MODE)
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
fp = _wfopen(fname, L"rb");
#else
#ifdef YGOPRO_SERVER_MODE
fp = fopen(script_name, "rb");
#endif
if(!fp)
return 0;
int len = fread(scriptBuffer, 1, sizeof(scriptBuffer), fp);
......@@ -383,6 +427,25 @@ byte* DataManager::ScriptReader(const char* script_name, int* slen) {
if(len >= sizeof(scriptBuffer))
return 0;
*slen = len;
#else
#ifdef _WIN32
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
IReadFile* reader = FileSystem->createAndOpenFile(fname);
#else
IReadFile* reader = FileSystem->createAndOpenFile(script_name);
#endif
if(reader == NULL)
return 0;
size_t size = reader->getSize();
if(size > sizeof(scriptBuffer)) {
reader->drop();
return 0;
}
reader->read(scriptBuffer, size);
reader->drop();
*slen = size;
#endif //YGOPRO_SERVER_MODE
return scriptBuffer;
}
......
......@@ -3,6 +3,9 @@
#include "config.h"
#include "sqlite3.h"
#ifndef YGOPRO_SERVER_MODE
#include "spmemvfs/spmemvfs.h"
#endif
#include "client_card.h"
#include <unordered_map>
......@@ -11,9 +14,16 @@ 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);
#ifndef YGOPRO_SERVER_MODE
bool LoadStrings(IReadFile* reader);
void ReadStringConfLine(const char* linebuf);
bool Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt = 0);
#else
void ReadStringConfLine(const char* linebuf);
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = 0);
#endif
bool GetData(int code, CardData* pData);
code_pointer GetCodePointer(int code);
bool GetString(int code, CardString* pStr);
......@@ -53,9 +63,11 @@ public:
static const wchar_t* unknown_string;
static int CardReader(int, void*);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen, int pre_len = 1);
static byte* ScriptReaderExSingle(const char* path, const char* script_name, int* slen, int pre_len = 2);
static byte* ScriptReader(const char* script_name, int* slen);
#ifndef YGOPRO_SERVER_MODE
static IFileSystem* FileSystem;
#endif
};
extern DataManager dataManager;
......
......@@ -10,13 +10,7 @@ DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) {
LFList* cur = NULL;
#ifdef _WIN32
wchar_t fname[1024];
BufferIO::DecodeUTF8(path, fname);
FILE* fp = _wfopen(fname, L"r");
#else
FILE* fp = fopen(path, "r");
#endif // _WIN32
char linebuf[256];
wchar_t strBuffer[256];
if(fp) {
......@@ -57,13 +51,6 @@ void DeckManager::LoadLFListSingle(const char* path) {
}
void DeckManager::LoadLFList() {
LoadLFListSingle("expansions/lflist.conf");
FileSystem::TraversalDir("./expansions", [this](const char* name, bool isdir) {
if(isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char fpath[1024];
sprintf(fpath, "./expansions/%s/lflist.conf", name);
LoadLFListSingle(fpath);
}
});
LoadLFListSingle("lflist.conf");
LFList nolimit;
myswprintf(nolimit.listName, L"N/A");
......
......@@ -984,6 +984,9 @@ void Game::DrawSpec() {
break;
}
}
if (auto_watch_mode && showcardcode < 8 && showcardcode > 0) {
mainGame->ShowCardInfo(showcardcode);
}
}
if(is_attacking) {
irr::core::matrix4 matk;
......
......@@ -1206,6 +1206,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
else
mainGame->dInfo.tag_player[0] = true;
}
mainGame->dInfo.duel_rule = BufferIO::ReadInt8(pbuf);
mainGame->dInfo.lp[mainGame->LocalPlayer(0)] = BufferIO::ReadInt32(pbuf);
mainGame->dInfo.lp[mainGame->LocalPlayer(1)] = BufferIO::ReadInt32(pbuf);
mainGame->dInfo.start_lp[0] = mainGame->dInfo.lp[0];
......@@ -2959,6 +2960,11 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->WaitFrameSignal(3);
}
}
if (auto_watch_mode) {
int code = mainGame->dField.chains[ct - 1].chain_card->code;
if (code > 0)
mainGame->ShowCardInfo(code);
}
mainGame->dField.last_chain = false;
return true;
}
......@@ -3029,6 +3035,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int s = BufferIO::ReadInt8(pbuf);
/*int ss = */BufferIO::ReadInt8(pbuf);
ClientCard* pcard = mainGame->dField.GetCard(c, l, s);
if (auto_watch_mode && i == 0 && pcard->code > 0 ) {
mainGame->ShowCardInfo(pcard->code);
}
pcard->is_highlighting = true;
mainGame->dField.current_chain.target.insert(pcard);
if(pcard->location & LOCATION_ONFIELD) {
......@@ -3393,6 +3402,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->atk_r = vector3df(0, 0, 3.1415926 - atan((xd - xa) / (yd - ya)));
}
matManager.GenArrow(sy);
if (auto_watch_mode) {
mainGame->ShowCardInfo(mainGame->dField.attacker->code);
}
mainGame->attack_sv = 0;
mainGame->is_attacking = true;
mainGame->WaitFrameSignal(40);
......
......@@ -18,7 +18,7 @@
#include <regex>
#endif //YGOPRO_SERVER_MODE
unsigned short PRO_VERSION = 0x1348;
unsigned short PRO_VERSION = 0x1349;
namespace ygo {
......@@ -32,10 +32,9 @@ HostInfo game_info;
void Game::MainServerLoop() {
initUtils();
deckManager.LoadLFList();
LoadBetaDB();
LoadExpansionDB();
dataManager.LoadDB("cards.cdb");
LoadExpansions();
dataManager.LoadDB(L"cards.cdb");
aServerPort = NetServer::StartServer(aServerPort);
NetServer::InitDuel();
printf("%u\n", aServerPort);
......@@ -50,44 +49,11 @@ void Game::MainServerLoop() {
}
}
void Game::MainTestLoop(int code) {
LoadBetaDB();
LoadExpansionDB();
dataManager.LoadDB("cards.cdb");
LoadExpansions();
dataManager.LoadDB(L"cards.cdb");
fflush(stdout);
NetServer::InitTestCard(code);
}
void Game::LoadBetaDB() {
LoadExpansionDBDirectry("./beta");
#ifdef _WIN32
char fpath[1000];
WIN32_FIND_DATAW fdataw;
HANDLE fh = FindFirstFileW(L"./beta/*", &fdataw);
if(fh != INVALID_HANDLE_VALUE) {
do {
if(wcscmp(L".",fdataw.cFileName) != 0 && wcscmp(L"..",fdataw.cFileName) != 0 && fdataw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
char fname[780];
BufferIO::EncodeUTF8(fdataw.cFileName, fname);
sprintf(fpath, "./beta/%s", fname);
LoadExpansionDBDirectry(fpath);
}
} while(FindNextFileW(fh, &fdataw));
FindClose(fh);
}
#else
DIR * dir;
struct dirent * dirp;
if((dir = opendir("./beta/")) != NULL) {
while((dirp = readdir(dir)) != NULL) {
if (strcmp(".", dirp->d_name) == 0 || strcmp("..", dirp->d_name) == 0 || dirp->d_type != DT_DIR)
continue;
char filepath[1000];
sprintf(filepath, "./beta/%s/", dirp->d_name);
LoadExpansionDBDirectry(filepath);
}
closedir(dir);
}
#endif
}
#else //YGOPRO_SERVER_MODE
bool Game::Initialize() {
srand(time(0));
......@@ -149,9 +115,10 @@ bool Game::Initialize() {
ErrorLog("Failed to load textures!");
return false;
}
LoadExpansionDB();
if(dataManager.LoadDB(GetLocaleDir("cards.cdb"))) {} else
if(!dataManager.LoadDB("cards.cdb")) {
dataManager.FileSystem = device->getFileSystem();
LoadExpansions();
if(dataManager.LoadDB(GetLocaleDirWide("cards.cdb"))) {} else
if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!");
return false;
}
......@@ -160,7 +127,7 @@ bool Game::Initialize() {
ErrorLog("Failed to load strings!");
return false;
}
LoadExpansionStrings();
dataManager.LoadStrings("./expansions/strings.conf");
env = device->getGUIEnvironment();
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12);
......@@ -1053,36 +1020,53 @@ void Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gu
pControl->setText(dataManager.strBuffer);
}
#endif //YGOPRO_SERVER_MODE
void Game::LoadExpansionDB() {
LoadExpansionDBDirectry("./expansions");
FileSystem::TraversalDir("./expansions", [this](const char* name, bool isdir) {
if(isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
LoadExpansionDBDirectry(subdir);
}
});
}
void Game::LoadExpansionDBDirectry(const char* path) {
FileSystem::TraversalDir(path, [path](const char* name, bool isdir) {
if(!isdir && strrchr(name, '.') && !mystrncasecmp(strrchr(name, '.'), ".cdb", 4)) {
char fpath[1024];
sprintf(fpath, "%s/%s", path, 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);
}
#ifdef YGOPRO_SERVER_MODE
});
}
#ifndef YGOPRO_SERVER_MODE
void Game::LoadExpansionStrings() {
dataManager.LoadStrings("./expansions/strings.conf");
FileSystem::TraversalDir("./expansions", [](const char* name, bool isdir) {
if(isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char fpath[1024];
sprintf(fpath, "./expansions/%s/strings.conf", name);
dataManager.LoadStrings(fpath);
#else
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".zip", 4)) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
#ifdef _WIN32
dataManager.FileSystem->addFileArchive(fpath, true, false);
#else
char upath[1024];
BufferIO::EncodeUTF8(fpath, upath);
dataManager.FileSystem->addFileArchive(upath, true, false);
#endif
}
});
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)) {
#ifdef _WIN32
IReadFile* reader = DataManager::FileSystem->createAndOpenFile(fname);
#else
IReadFile* reader = DataManager::FileSystem->createAndOpenFile(uname);
#endif
dataManager.LoadStrings(reader);
}
}
}
#endif //YGOPRO_SERVER_MODE
}
#ifndef YGOPRO_SERVER_MODE
void Game::RefreshDeck(irr::gui::IGUIComboBox* cbDeck) {
cbDeck->clear();
FileSystem::TraversalDir(L"./deck", [cbDeck](const wchar_t* name, bool isdir) {
......@@ -2057,6 +2041,8 @@ void Game::OnResize() {
lstLog->setRelativePosition(Resize(10, 10, 290, 290));
if(showingcode)
ShowCardInfo(showingcode, true);
else
ClearCardInfo();
btnClearLog->setRelativePosition(Resize(160, 300, 260, 325));
wPhase->setRelativePosition(Resize(480, 310, 855, 330));
......@@ -2237,13 +2223,18 @@ bool Game::CheckRegEx(const std::wstring& text, const std::wstring& exp, bool ex
const char* Game::GetLocaleDir(const char* dir) {
if(!gameConf.locale || !wcscmp(gameConf.locale, L"default"))
return dir;
wchar_t locale_buf[256];
wchar_t orig_dir[64];
BufferIO::DecodeUTF8(dir, orig_dir);
myswprintf(locale_buf, L"locales/%ls/%ls", gameConf.locale, orig_dir);
BufferIO::EncodeUTF8(locale_buf, locale_buf_utf8);
return locale_buf_utf8;
}
const wchar_t* Game::GetLocaleDirWide(const char* dir) {
BufferIO::DecodeUTF8(dir, orig_dir);
if(!gameConf.locale || !wcscmp(gameConf.locale, L"default"))
return orig_dir;
myswprintf(locale_buf, L"locales/%ls/%ls", gameConf.locale, orig_dir);
return locale_buf;
}
void Game::SetCursor(ECURSOR_ICON icon) {
ICursorControl* cursor = mainGame->device->getCursorControl();
if(cursor->getActiveIcon() != icon) {
......
......@@ -132,9 +132,7 @@ public:
#ifdef YGOPRO_SERVER_MODE
void MainServerLoop();
void MainTestLoop(int code);
void LoadExpansionDB();
void LoadExpansionDBDirectry(const char* path);
void LoadBetaDB();
void LoadExpansions();
void AddDebugMsg(const char* msgbuf);
void initUtils();
#else
......@@ -143,9 +141,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 LoadExpansionDBDirectry(const char* path);
void LoadExpansionStrings();
void LoadExpansions();
void RefreshDeck(irr::gui::IGUIComboBox* cbDeck);
void RefreshReplay();
void RefreshSingleplay();
......@@ -186,6 +182,7 @@ public:
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
const char* GetLocaleDir(const char* dir);
const wchar_t* GetLocaleDirWide(const char* dir);
bool CheckRegEx(const std::wstring& text, const std::wstring& exp, bool exact = false);
bool HasFocus(EGUI_ELEMENT_TYPE type) const {
......@@ -266,6 +263,8 @@ public:
float yScale;
CGUISkinSystem *skinSystem;
wchar_t locale_buf[256];
wchar_t orig_dir[64];
char locale_buf_utf8[256];
ClientField dField;
......
......@@ -133,17 +133,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
......
......@@ -274,55 +274,25 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
}
}
irr::video::ITexture* ImageManager::GetTextureFromFile(char* file, s32 width, s32 height) {
#ifdef _WIN32
wchar_t name[1024];
BufferIO::DecodeUTF8(file, name);
#else
char* name = file;
#endif // _WIN32
if(mainGame->gameConf.use_image_scale) {
irr::video::ITexture* texture;
irr::video::IImage* srcimg = driver->createImageFromFile(name);
irr::video::IImage* srcimg = driver->createImageFromFile(file);
if(srcimg == NULL)
return NULL;
if(srcimg->getDimension() == irr::core::dimension2d<u32>(width, height)) {
texture = driver->addTexture(name, srcimg);
texture = driver->addTexture(file, srcimg);
} else {
video::IImage *destimg = driver->createImage(srcimg->getColorFormat(), irr::core::dimension2d<u32>(width, height));
imageScaleNNAA(srcimg, destimg);
texture = driver->addTexture(name, destimg);
texture = driver->addTexture(file, destimg);
destimg->drop();
}
srcimg->drop();
return texture;
} else {
return driver->getTexture(name);
return driver->getTexture(file);
}
}
irr::video::ITexture* ImageManager::GetTextureExpansions(char* file, s32 width, s32 height) {
irr::video::ITexture* img = GetTextureExpansionsDirectry("./expansions", file, width, height);
if(img != NULL)
return img;
bool find = false;
FileSystem::TraversalDir("./expansions", [this, file, width, height, &img, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
img = GetTextureExpansionsDirectry(subdir, file, width, height);
if(img)
find = true;
}
});
if(find)
return img;
return img;
}
irr::video::ITexture* ImageManager::GetTextureExpansionsDirectry(const char* path, char* file, s32 width, s32 height) {
char fpath[1000];
sprintf(fpath, "%s/%s", path, file);
return GetTextureFromFile(fpath, width, height);
}
irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) {
if(code == 0)
return fit ? tUnknownFit : tUnknown;
......@@ -338,11 +308,11 @@ irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) {
auto tit = tMap[fit ? 1 : 0].find(code);
if(tit == tMap[fit ? 1 : 0].end()) {
char file[256];
sprintf(file, "pics/%d.png", code);
irr::video::ITexture* img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/%d.png", code);
irr::video::ITexture* img = GetTextureFromFile(file, width, height);
if(img == NULL) {
sprintf(file, "pics/%d.jpg", code);
img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/%d.png"), code);
......@@ -380,11 +350,11 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
int height = CARD_THUMB_HEIGHT * mainGame->yScale;
if(tit == tThumb.end()) {
char file[256];
sprintf(file, "pics/thumbnail/%d.png", code);
irr::video::ITexture* img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/thumbnail/%d.png", code);
irr::video::ITexture* img = GetTextureFromFile(file, width, height);
if(img == NULL) {
sprintf(file, "pics/thumbnail/%d.jpg", code);
img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/thumbnail/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/thumbnail/%d.png"), code);
......@@ -403,11 +373,11 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
img = GetTextureFromFile(file, width, height);
}
if(img == NULL && mainGame->gameConf.use_image_scale) {
sprintf(file, "pics/%d.png", code);
img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/%d.png", code);
img = GetTextureFromFile(file, width, height);
if(img == NULL) {
sprintf(file, "pics/%d.jpg", code);
img = GetTextureExpansions(file, width, height);
sprintf(file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/%d.png"), code);
......@@ -437,11 +407,11 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
auto tit = tFields.find(code);
if(tit == tFields.end()) {
char file[256];
sprintf(file, "pics/field/%d.png", code);
irr::video::ITexture* img = GetTextureExpansions(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
sprintf(file, "expansions/pics/field/%d.png", code);
irr::video::ITexture* img = GetTextureFromFile(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
if(img == NULL) {
sprintf(file, "pics/field/%d.jpg", code);
img = GetTextureExpansions(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
sprintf(file, "expansions/pics/field/%d.jpg", code);
img = GetTextureFromFile(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
}
if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/field/%d.png"), code);
......@@ -481,11 +451,11 @@ irr::video::ITexture* ImageManager::GetTextureField(int code) {
auto tit = tFields.find(code);
if(tit == tFields.end()) {
char file[256];
sprintf(file, "pics/field/%d.png", code);
irr::video::ITexture* img = GetTextureExpansions(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
sprintf(file, "expansions/pics/field/%d.png", code);
irr::video::ITexture* img = GetTextureFromFile(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
if(img == NULL) {
sprintf(file, "pics/field/%d.jpg", code);
img = GetTextureExpansions(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
sprintf(file, "expansions/pics/field/%d.jpg", code);
img = GetTextureFromFile(file, 512 * mainGame->xScale, 512 * mainGame->yScale);
}
if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/field/%d.png"), code);
......
......@@ -22,8 +22,6 @@ public:
void RemoveTexture(int code);
void ResizeTexture();
irr::video::ITexture* GetTextureFromFile(char* file, s32 width, s32 height);
irr::video::ITexture* GetTextureExpansions(char* file, s32 width, s32 height);
irr::video::ITexture* GetTextureExpansionsDirectry(const char* path, char* file, s32 width, s32 height);
irr::video::ITexture* GetTexture(int code, bool fit = false);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
......
......@@ -156,7 +156,7 @@ public:
#ifndef YGOPRO_SERVER_MODE
static bool TraversalDirSort(file_unit file1, file_unit file2) {
if(file1.is_dir != file2.is_dir) {
return file1.is_dir;
return file2.is_dir;
} else {
return file1.filename < file2.filename;
}
......
......@@ -25,7 +25,7 @@ private:
public:
static Replay cur_replay;
public:
static bool StartReplay(int skipturn);
static void StopReplay(bool is_exiting = false);
......@@ -38,7 +38,7 @@ public:
static void Restart(bool refresh);
static void Undo();
static bool ReplayAnalyze(char* msg, unsigned int len);
static void ReplayRefresh(int flag = 0xf81fff);
static void ReplayRefreshHand(int player, int flag = 0x781fff);
static void ReplayRefreshGrave(int player, int flag = 0x181fff);
......
......@@ -586,25 +586,26 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
char startbuf[32], *pbuf = startbuf;
BufferIO::WriteInt8(pbuf, MSG_START);
BufferIO::WriteInt8(pbuf, 0);
BufferIO::WriteInt8(pbuf, host_info.duel_rule);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x40));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x40));
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, startbuf, 19);
startbuf[1] = 1;
NetServer::SendBufferToPlayer(players[1], STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(players[1], STOC_GAME_MSG, startbuf, 19);
if(!swapped)
startbuf[1] = 0x10;
else startbuf[1] = 0x11;
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 19);
#ifdef YGOPRO_SERVER_MODE
if(cache_recorder)
NetServer::SendBufferToPlayer(cache_recorder, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(cache_recorder, STOC_GAME_MSG, startbuf, 19);
if(replay_recorder)
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19);
turn_player = 0;
phase = 1;
#endif
......
......@@ -17,7 +17,7 @@ public:
static void SetResponse(unsigned char* resp, unsigned int len);
static int SinglePlayThread(void* param);
static bool SinglePlayAnalyze(char* msg, unsigned int len);
static void SinglePlayRefresh(int flag = 0xf81fff);
static void SinglePlayRefreshHand(int player, int flag = 0x781fff);
static void SinglePlayRefreshGrave(int player, int flag = 0x181fff);
......
project "cspmemvfs"
kind "StaticLib"
files { "**.c", "**.h" }
configuration "windows"
includedirs { "../../sqlite3" }
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
......@@ -572,27 +572,28 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
char startbuf[32], *pbuf = startbuf;
BufferIO::WriteInt8(pbuf, MSG_START);
BufferIO::WriteInt8(pbuf, 0);
BufferIO::WriteInt8(pbuf, host_info.duel_rule);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x40));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x40));
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, startbuf, 19);
NetServer::ReSendToPlayer(players[1]);
startbuf[1] = 1;
NetServer::SendBufferToPlayer(players[2], STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(players[2], STOC_GAME_MSG, startbuf, 19);
NetServer::ReSendToPlayer(players[3]);
if(!swapped)
startbuf[1] = 0x10;
else startbuf[1] = 0x11;
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 19);
#ifdef YGOPRO_SERVER_MODE
if(cache_recorder)
NetServer::SendBufferToPlayer(cache_recorder, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(cache_recorder, STOC_GAME_MSG, startbuf, 19);
if(replay_recorder)
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 18);
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19);
turn_player = 0;
phase = 1;
#endif
......
......@@ -31,7 +31,7 @@ public:
virtual void RequestField(DuelPlayer* dp);
#endif
virtual void EndDuel();
void DuelEndProc();
void WaitforResponse(int playerid);
#ifdef YGOPRO_SERVER_MODE
......@@ -52,7 +52,7 @@ public:
static int MessageHandler(long fduel, int type);
static void TagTimer(evutil_socket_t fd, short events, void* arg);
protected:
DuelPlayer* players[4];
DuelPlayer* pplayer[4];
......
1 ICON "ygopro.ico"
1 VERSIONINFO
FILEVERSION 1, 0, 34, 8
PRODUCTVERSION 1, 0, 34, 8
FILEVERSION 1, 0, 34, 9
PRODUCTVERSION 1, 0, 34, 9
FILEOS 0x4
FILETYPE 0x1
......@@ -16,8 +16,8 @@ VALUE "InternalName", "YGOPRO Server Mode"
VALUE "LegalCopyright", "Copyright (C) 2018 Nanahira"
VALUE "OriginalFilename", "ygopro.exe"
VALUE "ProductName", "YGOPRO Server Mode"
VALUE "FileVersion", "1.034.8.Koishi"
VALUE "ProductVersion", "1.034.8.Koishi"
VALUE "FileVersion", "1.034.9.Koishi"
VALUE "ProductVersion", "1.034.9.Koishi"
END
END
BLOCK "VarFileInfo"
......
......@@ -577,6 +577,7 @@
!counter 0x104d 信号指示物
!counter 0x4e 指示物(魂之灵摆)
!counter 0x104f 蛊指示物
!counter 0x50 指示物(娱乐伙伴 掉头跑骑兵)
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......
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