Commit 91d38707 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro into server

parents 26eb016b 5532faad
......@@ -20,6 +20,8 @@
/ygopro
/ygopro.exe
/ygopro.app
/ikpMP3.dll
/irrKlang.dll
/bin
/build
......
......@@ -11,21 +11,9 @@
namespace ygo {
using CardData = card_data;
struct CardDataC {
unsigned int code;
unsigned int alias;
unsigned long long setcode;
unsigned int type;
unsigned int level;
unsigned int attribute;
unsigned int race;
int attack;
int defense;
unsigned int lscale;
unsigned int rscale;
unsigned int link_marker;
unsigned int ot;
unsigned int category;
struct CardDataC : card_data {
unsigned int ot{};
unsigned int category{};
};
struct CardString {
std::wstring name;
......
......@@ -1489,15 +1489,7 @@ static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
if (stack.size() >= 1) {
int set_code = stack.top();
stack.pop();
unsigned long long sc = cd.setcode;
bool res = false;
int settype = set_code & 0xfff;
int setsubtype = set_code & 0xf000;
while (sc) {
if ((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
bool res = cd.is_setcode(set_code);
stack.push(res);
}
break;
......
......@@ -11,6 +11,13 @@ IFileSystem* DataManager::FileSystem;
#endif
DataManager dataManager;
DataManager::DataManager() : _datas(16384), _strings(16384) {
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
extra_setcode = { {8512558u, {0x8f, 0x54, 0x59, 0x82, 0x13a}}, };
}
bool DataManager::LoadDB(const wchar_t* wfile) {
char file[256];
BufferIO::EncodeUTF8(wfile, file);
......@@ -50,13 +57,13 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
#else
return Error(&db);
#endif
CardDataC cd;
CardString cs;
#ifndef YGOPRO_SERVER_MODE
wchar_t strBuffer[4096];
#endif
int step = 0;
do {
CardDataC cd;
CardString cs;
step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
......@@ -68,7 +75,19 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
cd.code = sqlite3_column_int(pStmt, 0);
cd.ot = sqlite3_column_int(pStmt, 1);
cd.alias = sqlite3_column_int(pStmt, 2);
cd.setcode = sqlite3_column_int64(pStmt, 3);
auto setcode = sqlite3_column_int64(pStmt, 3);
if (setcode) {
auto it = extra_setcode.find(cd.code);
if (it != extra_setcode.end()) {
int len = it->second.size();
if (len > SIZE_SETCODE)
len = SIZE_SETCODE;
if (len)
memcpy(cd.setcode, it->second.data(), len * sizeof(uint16_t));
}
else
cd.set_setcode(setcode);
}
cd.type = sqlite3_column_int(pStmt, 4);
cd.attack = sqlite3_column_int(pStmt, 5);
cd.defense = sqlite3_column_int(pStmt, 6);
......@@ -200,7 +219,7 @@ bool DataManager::GetData(unsigned int code, CardData* pData) {
if (pData) {
pData->code = data.code;
pData->alias = data.alias;
pData->setcode = data.setcode;
memcpy(pData->setcode, data.setcode, SIZE_SETCODE);
pData->type = data.type;
pData->level = data.level;
pData->attribute = data.attribute;
......@@ -370,10 +389,12 @@ const wchar_t* DataManager::FormatType(int type) {
return unknown_string;
return tpBuffer;
}
const wchar_t* DataManager::FormatSetName(unsigned long long setcode) {
const wchar_t* DataManager::FormatSetName(const uint16_t setcode[]) {
wchar_t* p = scBuffer;
for(int i = 0; i < 4; ++i) {
const wchar_t* setname = GetSetName((setcode >> i * 16) & 0xffff);
for(int i = 0; i < 10; ++i) {
if (!setcode[i])
break;
const wchar_t* setname = GetSetName(setcode[i]);
if(setname) {
BufferIO::CopyWStrRef(setname, p, 32);
*p = L'|';
......
......@@ -13,12 +13,7 @@ namespace ygo {
class DataManager {
public:
DataManager(): _datas(16384), _strings(16384) {
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
}
DataManager();
bool LoadDB(const wchar_t* wfile);
bool LoadStrings(const char* file);
#ifndef YGOPRO_SERVER_MODE
......@@ -47,7 +42,7 @@ public:
const wchar_t* FormatAttribute(int attribute);
const wchar_t* FormatRace(int race);
const wchar_t* FormatType(int type);
const wchar_t* FormatSetName(unsigned long long setcode);
const wchar_t* FormatSetName(const uint16_t setcode[]);
const wchar_t* FormatLinkMarker(int link_marker);
std::unordered_map<unsigned int, std::wstring> _counterStrings;
......@@ -79,6 +74,7 @@ public:
private:
std::unordered_map<unsigned int, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings;
std::unordered_map<unsigned int, std::vector<uint16_t>> extra_setcode;
};
extern DataManager dataManager;
......
......@@ -40,23 +40,6 @@ static int parse_filter(const wchar_t* pstr, unsigned int* type) {
return 0;
}
static bool check_set_code(const CardDataC& data, int set_code) {
unsigned long long sc = data.setcode;
if (data.alias) {
auto aptr = dataManager.GetCodePointer(data.alias);
if (aptr != dataManager.datas_end)
sc = aptr->second.setcode;
}
bool res = false;
int settype = set_code & 0xfff;
int setsubtype = set_code & 0xf000;
while (sc) {
if ((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
return res;
}
static inline bool havePopupWindow() {
return mainGame->wQuery->isVisible() || mainGame->wCategories->isVisible() || mainGame->wLinkMarks->isVisible() || mainGame->wDeckManage->isVisible() || mainGame->wDMQuery->isVisible();
......@@ -1353,7 +1336,7 @@ void DeckBuilder::FilterCards() {
results.clear();
struct element_t {
std::wstring keyword;
int setcode;
unsigned int setcode;
enum class type_t {
all,
name,
......@@ -1506,14 +1489,14 @@ void DeckBuilder::FilterCards() {
if (elements_iterator->type == element_t::type_t::name) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str());
} else if (elements_iterator->type == element_t::type_t::setcode) {
match = elements_iterator->setcode && check_set_code(data, elements_iterator->setcode);
match = elements_iterator->setcode && data.is_setcode(elements_iterator->setcode);
} else {
int trycode = BufferIO::GetVal(elements_iterator->keyword.c_str());
bool tryresult = dataManager.GetData(trycode, 0);
if(!tryresult) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str())
|| text.text.find(elements_iterator->keyword) != std::wstring::npos
|| (elements_iterator->setcode && check_set_code(data, elements_iterator->setcode));
|| (elements_iterator->setcode && data.is_setcode(elements_iterator->setcode));
} else {
match = data.code == trycode || data.alias == trycode;
}
......
......@@ -12,8 +12,8 @@
namespace ygo {
unsigned DuelClient::connect_state = 0;
unsigned char DuelClient::response_buf[64];
unsigned char DuelClient::response_len = 0;
unsigned char DuelClient::response_buf[SIZE_RETURN_VALUE];
unsigned int DuelClient::response_len = 0;
unsigned int DuelClient::watching = 0;
unsigned char DuelClient::selftype = 0;
bool DuelClient::is_host = false;
......@@ -1748,7 +1748,7 @@ int DuelClient::ClientAnalyze(unsigned char* msg, unsigned int len) {
if(selecting_player == mainGame->LocalPlayer(1))
mainGame->dField.selectable_field = (mainGame->dField.selectable_field >> 16) | (mainGame->dField.selectable_field << 16);
mainGame->dField.selected_field = 0;
unsigned char respbuf[64];
unsigned char respbuf[SIZE_RETURN_VALUE];
int pzone = 0;
if (mainGame->dInfo.curMsg == MSG_SELECT_PLACE) {
if (select_hint) {
......@@ -3935,7 +3935,9 @@ void DuelClient::SetResponseI(int respI) {
*((int*)response_buf) = respI;
response_len = 4;
}
void DuelClient::SetResponseB(void* respB, unsigned char len) {
void DuelClient::SetResponseB(void* respB, unsigned int len) {
if (len > SIZE_RETURN_VALUE)
len = SIZE_RETURN_VALUE;
memcpy(response_buf, respB, len);
response_len = len;
}
......
......@@ -20,8 +20,8 @@ namespace ygo {
class DuelClient {
private:
static unsigned int connect_state;
static unsigned char response_buf[64];
static unsigned char response_len;
static unsigned char response_buf[SIZE_RETURN_VALUE];
static unsigned int response_len;
static unsigned int watching;
static unsigned char selftype;
static bool is_host;
......@@ -49,7 +49,7 @@ public:
static int ClientAnalyze(unsigned char* msg, unsigned int len);
static void SwapField();
static void SetResponseI(int respI);
static void SetResponseB(void* respB, unsigned char len);
static void SetResponseB(void* respB, unsigned int len);
static void SendResponse();
static void SendPacketToServer(unsigned char proto) {
auto p = duel_client_write;
......
......@@ -771,7 +771,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"%d", select_min);
mainGame->stCardPos[id - BUTTON_CARD_0]->setText(formatBuffer);
if(select_min == select_max) {
unsigned char respbuf[64];
unsigned char respbuf[SIZE_RETURN_VALUE];
for(int i = 0; i < select_max; ++i)
respbuf[i] = sort_list[i] - 1;
DuelClient::SetResponseB(respbuf, select_max);
......@@ -2477,7 +2477,7 @@ void ClientField::ShowCardInfoInList(ClientCard* pcard, irr::gui::IGUIElement* e
}
}
void ClientField::SetResponseSelectedCards() const {
unsigned char respbuf[64];
unsigned char respbuf[SIZE_RETURN_VALUE];
respbuf[0] = selected_cards.size();
for (size_t i = 0; i < selected_cards.size(); ++i)
respbuf[i + 1] = selected_cards[i]->select_seq;
......
......@@ -1581,32 +1581,41 @@ void Game::SaveConfig() {
void Game::ShowCardInfo(int code, bool resize) {
if(showingcode == code && !resize)
return;
CardData cd;
wchar_t formatBuffer[256];
dataManager.GetData(code, &cd);
auto cit = dataManager.GetCodePointer(code);
bool is_valid = (cit != dataManager.datas_end);
imgCard->setImage(imageManager.GetTexture(code, true));
if(cd.alias != 0 && (cd.alias - code < CARD_ARTWORK_VERSIONS_OFFSET || code - cd.alias < CARD_ARTWORK_VERSIONS_OFFSET))
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
if (is_valid) {
auto& cd = cit->second;
if (cd.is_alternative())
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
else {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
stName->setText(formatBuffer);
int offset = 0;
if(!gameConf.hide_setname) {
unsigned long long sc = cd.setcode;
if(cd.alias) {
auto aptr = dataManager.GetCodePointer(cd.alias);
if(aptr != dataManager.datas_end)
sc = aptr->second.setcode;
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
auto target = cit;
if (cd.alias && dataManager.GetCodePointer(cd.alias) != dataManager.datas_end) {
target = dataManager.GetCodePointer(cd.alias);
}
if(sc) {
if (target->second.setcode[0]) {
offset = 23;// *yScale;
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), dataManager.FormatSetName(sc));
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), dataManager.FormatSetName(target->second.setcode));
stSetName->setText(formatBuffer);
} else
}
else
stSetName->setText(L"");
} else {
}
else {
stSetName->setText(L"");
}
if(cd.type & TYPE_MONSTER) {
if(is_valid && cit->second.type & TYPE_MONSTER) {
auto& cd = cit->second;
myswprintf(formatBuffer, L"[%ls] %ls/%ls", dataManager.FormatType(cd.type), dataManager.FormatRace(cd.race), dataManager.FormatAttribute(cd.attribute));
stInfo->setText(formatBuffer);
int offset_info = 0;
......@@ -1652,8 +1661,12 @@ void Game::ShowCardInfo(int code, bool resize) {
stSetName->setRelativePosition(rect<s32>(15, (83 + offset_arrows), 296 * xScale, (83 + offset_arrows) + offset));
stText->setRelativePosition(rect<s32>(15, (83 + offset_arrows) + offset, 287 * xScale, 324 * yScale));
scrCardText->setRelativePosition(rect<s32>(287 * xScale - 20, (83 + offset_arrows) + offset, 287 * xScale, 324 * yScale));
} else {
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(cd.type));
}
else {
if (is_valid)
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(cit->second.type));
else
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(0));
stInfo->setText(formatBuffer);
stDataInfo->setText(L"");
stSetName->setRelativePosition(rect<s32>(15, 60, 296 * xScale, 60 + offset));
......
......@@ -848,6 +848,5 @@ extern unsigned int pre_seed[3];
#define AVAIL_SC 0x8
#define AVAIL_OCGTCG (AVAIL_OCG|AVAIL_TCG)
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#define MAX_LAYER_COUNT 6
#endif // GAME_H
......@@ -267,7 +267,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
case CTOS_RESPONSE: {
if(!dp->game || !duel_mode->pduel)
return;
duel_mode->GetResponse(dp, pdata, len > 64 ? 64 : len - 1);
duel_mode->GetResponse(dp, pdata, len - 1);
break;
}
case CTOS_TIME_CONFIRM: {
......
......@@ -314,11 +314,11 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
return result == 0;
#endif
}
bool Replay::ReadNextResponse(unsigned char resp[64]) {
bool Replay::ReadNextResponse(unsigned char resp[]) {
if(pdata - replay_data >= (int)replay_size)
return false;
int len = *pdata++;
if(len > 64)
if(len > SIZE_RETURN_VALUE)
return false;
memcpy(resp, pdata, len);
pdata += len;
......
......@@ -56,7 +56,7 @@ public:
static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name);
static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname);
bool ReadNextResponse(unsigned char resp[64]);
bool ReadNextResponse(unsigned char resp[]);
void ReadName(wchar_t* data);
//void ReadHeader(ReplayHeader& header);
void ReadData(void* data, int length);
......
......@@ -49,7 +49,7 @@ void ReplayMode::Pause(bool is_pause, bool is_step) {
}
}
bool ReplayMode::ReadReplayResponse() {
unsigned char resp[64];
unsigned char resp[SIZE_RETURN_VALUE];
bool result = cur_replay.ReadNextResponse(resp);
if(result)
set_responseb(pduel, resp);
......
......@@ -1768,7 +1768,9 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
return 0;
}
void SingleDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
byte resb[64];
byte resb[SIZE_RETURN_VALUE];
if (len > SIZE_RETURN_VALUE)
len = SIZE_RETURN_VALUE;
memcpy(resb, pdata, len);
last_replay.WriteInt8(len);
last_replay.WriteData(resb, len);
......
......@@ -1839,7 +1839,9 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
return 0;
}
void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
byte resb[64];
byte resb[SIZE_RETURN_VALUE];
if (len > SIZE_RETURN_VALUE)
len = SIZE_RETURN_VALUE;
memcpy(resb, pdata, len);
last_replay.WriteInt8(len);
last_replay.WriteData(resb, len);
......
......@@ -1207,3 +1207,7 @@
!setname 0x1a6 肃声 粛声
!setname 0x1a7 白斗气 ホワイト・オーラ
!setname 0x1a8 玩具 トイ
!setname 0x1a9 灿幻 燦幻
!setname 0x1aa 天杯龙 天盃龍
!setname 0x1ab 蕾祸 蕾禍
!setname 0x1ac 飞龙炎 Salamandra
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