You need to sign in or sign up before continuing.
Commit d4be967f authored by wind2009's avatar wind2009

Merge branch 'server' into server-develop

parents 16c5a77a 98b077cc
...@@ -437,8 +437,8 @@ jobs: ...@@ -437,8 +437,8 @@ jobs:
- name: Copy premake files - name: Copy premake files
run: | run: |
cp -r premake/* . cp -pr premake/* .
cp -r resource/* . cp -pr resource/* .
- name: Use premake to generate make files (apt packages) - name: Use premake to generate make files (apt packages)
if: matrix.static-link != true if: matrix.static-link != true
...@@ -472,21 +472,15 @@ jobs: ...@@ -472,21 +472,15 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
name: name:
- macos-13-intel - macos-15-intel
# - macos-13-arm-cross-compile-static-link - macos-15-universal-static-link
- macos-13-universal-static-link
- macos-15-arm - macos-15-arm
# - macos-15-intel-cross-compile-static-link # - macos-15-intel-cross-compile-static-link
# - macos-15-universal-static-link
include: include:
- name: macos-13-intel - name: macos-15-intel
os: macos-13 os: macos-15-intel
# - name: macos-13-arm-cross-compile-static-link - name: macos-15-universal-static-link
# os: macos-13 os: macos-15
# cross-build-arm: true
# static-link: true
- name: macos-13-universal-static-link
os: macos-13
cross-build-intel: true cross-build-intel: true
cross-build-arm: true cross-build-arm: true
static-link: true static-link: true
...@@ -495,11 +489,6 @@ jobs: ...@@ -495,11 +489,6 @@ jobs:
# - name: macos-15-intel-cross-compile-static-link # - name: macos-15-intel-cross-compile-static-link
# os: macos-15 # os: macos-15
# cross-build-intel: true # cross-build-intel: true
# static-link: true
# - name: macos-15-universal-static-link
# os: macos-15
# cross-build-intel: true
# cross-build-arm: true
# static-link: true # static-link: true
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
...@@ -664,8 +653,8 @@ jobs: ...@@ -664,8 +653,8 @@ jobs:
- name: Copy premake files - name: Copy premake files
run: | run: |
cp -r premake/* . cp -pr premake/* .
cp -r resource/* . cp -pr resource/* .
- name: Use premake to generate make files (Homebrew packages) - name: Use premake to generate make files (Homebrew packages)
if: matrix.static-link != true if: matrix.static-link != true
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
/deck /deck
/data /data
.DS_Store
/deck
/expansions /expansions
/fonts /fonts
/icon /icon
...@@ -25,9 +29,10 @@ ...@@ -25,9 +29,10 @@
/ikpMP3.dll /ikpMP3.dll
/irrKlang.dll /irrKlang.dll
/bin /.vscode/
/bin/
/build /build
/obj /obj/
/event /event
/freetype /freetype
/irrlicht /irrlicht
......
...@@ -93,7 +93,8 @@ mat_windows: ...@@ -93,7 +93,8 @@ mat_windows:
._exec_build: ._exec_build:
stage: build stage: build
#variables: variables:
GIT_STRATEGY: 'clone'
# NO_LUA_SAFE: '1' # on client no lua safe # NO_LUA_SAFE: '1' # on client no lua safe
#cache: #cache:
# key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" # key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
......
No preview for this file type
...@@ -27,13 +27,11 @@ ClientField::~ClientField() { ...@@ -27,13 +27,11 @@ ClientField::~ClientField() {
} }
hand[i].clear(); hand[i].clear();
for (auto& card : mzone[i]) { for (auto& card : mzone[i]) {
if (card) delete card;
delete card;
card = nullptr; card = nullptr;
} }
for (auto& card : szone[i]) { for (auto& card : szone[i]) {
if (card) delete card;
delete card;
card = nullptr; card = nullptr;
} }
for (auto& card : grave[i]) { for (auto& card : grave[i]) {
...@@ -44,7 +42,6 @@ ClientField::~ClientField() { ...@@ -44,7 +42,6 @@ ClientField::~ClientField() {
delete card; delete card;
} }
remove[i].clear(); remove[i].clear();
for (auto& card : extra[i]) { for (auto& card : extra[i]) {
delete card; delete card;
} }
...@@ -57,30 +54,33 @@ ClientField::~ClientField() { ...@@ -57,30 +54,33 @@ ClientField::~ClientField() {
} }
void ClientField::Clear() { void ClientField::Clear() {
for(int i = 0; i < 2; ++i) { for(int i = 0; i < 2; ++i) {
for(auto cit = deck[i].begin(); cit != deck[i].end(); ++cit) for (auto& card : deck[i]) {
delete *cit; delete card;
}
deck[i].clear(); deck[i].clear();
for(auto cit = hand[i].begin(); cit != hand[i].end(); ++cit) for (auto& card : hand[i]) {
delete *cit; delete card;
}
hand[i].clear(); hand[i].clear();
for(auto cit = mzone[i].begin(); cit != mzone[i].end(); ++cit) { for (auto& card : mzone[i]) {
if(*cit) delete card;
delete *cit; card = nullptr;
*cit = 0; }
} for (auto& card : szone[i]) {
for(auto cit = szone[i].begin(); cit != szone[i].end(); ++cit) { delete card;
if(*cit) card = nullptr;
delete *cit; }
*cit = 0; for (auto& card : grave[i]) {
} delete card;
for(auto cit = grave[i].begin(); cit != grave[i].end(); ++cit) }
delete *cit;
grave[i].clear(); grave[i].clear();
for(auto cit = remove[i].begin(); cit != remove[i].end(); ++cit) for (auto& card : remove[i]) {
delete *cit; delete card;
}
remove[i].clear(); remove[i].clear();
for(auto cit = extra[i].begin(); cit != extra[i].end(); ++cit) for (auto& card : extra[i]) {
delete *cit; delete card;
}
extra[i].clear(); extra[i].clear();
deck_act[i] = false; deck_act[i] = false;
grave_act[i] = false; grave_act[i] = false;
...@@ -88,8 +88,9 @@ void ClientField::Clear() { ...@@ -88,8 +88,9 @@ void ClientField::Clear() {
extra_act[i] = false; extra_act[i] = false;
pzone_act[i] = false; pzone_act[i] = false;
} }
for(auto sit = overlay_cards.begin(); sit != overlay_cards.end(); ++sit) for (auto& card : overlay_cards) {
delete *sit; delete card;
}
overlay_cards.clear(); overlay_cards.clear();
extra_p_count[0] = 0; extra_p_count[0] = 0;
extra_p_count[1] = 0; extra_p_count[1] = 0;
...@@ -417,7 +418,8 @@ void ClientField::ClearChainSelect() { ...@@ -417,7 +418,8 @@ void ClientField::ClearChainSelect() {
conti_act = false; conti_act = false;
} }
// needs to be synchronized with EGET_SCROLL_BAR_CHANGED // needs to be synchronized with EGET_SCROLL_BAR_CHANGED
void ClientField::ShowSelectCard(bool buttonok, bool chain) { void ClientField::ShowSelectCard(bool buttonok, bool is_continuous) {
select_continuous = is_continuous;
if(cant_check_grave) { if(cant_check_grave) {
bool has_card_in_grave = false; bool has_card_in_grave = false;
for (auto& pcard : selectable_cards) { for (auto& pcard : selectable_cards) {
...@@ -444,7 +446,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) { ...@@ -444,7 +446,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
// image // image
if(selectable_cards[i]->code) if(selectable_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code)); mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code));
else if(conti_selecting) else if(select_continuous)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->chain_code)); mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->chain_code));
else else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i]->controler + 2]); mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i]->controler + 2]);
...@@ -454,8 +456,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) { ...@@ -454,8 +456,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
if(mainGame->dInfo.curMsg != MSG_SORT_CARD) { if(mainGame->dInfo.curMsg != MSG_SORT_CARD) {
// text // text
wchar_t formatBuffer[2048]; wchar_t formatBuffer[2048];
if(conti_selecting) if(select_continuous)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string); myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE) else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0)); myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i]->location == LOCATION_OVERLAY) else if(selectable_cards[i]->location == LOCATION_OVERLAY)
...@@ -470,7 +472,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) { ...@@ -470,7 +472,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
if (selectable_cards[i]->is_selected) if (selectable_cards[i]->is_selected)
mainGame->stCardPos[i]->setBackgroundColor(0xffffff00); mainGame->stCardPos[i]->setBackgroundColor(0xffffff00);
else { else {
if(conti_selecting) if(select_continuous)
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff); mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
else if(selectable_cards[i]->location == LOCATION_OVERLAY) { else if(selectable_cards[i]->location == LOCATION_OVERLAY) {
if(selectable_cards[i]->owner != selectable_cards[i]->overlayTarget->controler) if(selectable_cards[i]->owner != selectable_cards[i]->overlayTarget->controler)
...@@ -1547,7 +1549,8 @@ void ClientField::UpdateDeclarableList() { ...@@ -1547,7 +1549,8 @@ void ClientField::UpdateDeclarableList() {
int trycode = BufferIO::GetVal(pname); int trycode = BufferIO::GetVal(pname);
CardData cd; CardData cd;
if (dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) { if (dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
auto it = dataManager.GetStringPointer(trycode); auto& _strings = dataManager.GetStringTable();
auto it = _strings.find(trycode);
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
mainGame->lstANCard->addItem(it->second.name.c_str()); mainGame->lstANCard->addItem(it->second.name.c_str());
...@@ -1560,19 +1563,23 @@ void ClientField::UpdateDeclarableList() { ...@@ -1560,19 +1563,23 @@ void ClientField::UpdateDeclarableList() {
} }
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
for(auto cit = dataManager.strings_begin(); cit != dataManager.strings_end(); ++cit) { auto& _datas = dataManager.GetDataTable();
if(cit->second.name.find(pname) != std::wstring::npos) { auto& _strings = dataManager.GetStringTable();
auto cp = dataManager.GetCodePointer(cit->first); for(auto& entry : _strings) {
if (cp == dataManager.datas_end()) auto& code = entry.first;
auto& str = entry.second;
if(str.name.find(pname) != std::wstring::npos) {
auto cp = _datas.find(code);
if (cp == _datas.end())
continue; continue;
//datas.alias can be double card names or alias //datas.alias can be double card names or alias
if(is_declarable(cp->second, declare_opcodes)) { if(is_declarable(cp->second, declare_opcodes)) {
if(pname == cit->second.name || trycode == cit->first) { //exact match or last used if(pname == str.name || trycode == code) { //exact match or last used
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1); mainGame->lstANCard->insertItem(0, str.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first); ancard.insert(ancard.begin(), code);
} else { } else {
mainGame->lstANCard->addItem(cit->second.name.c_str()); mainGame->lstANCard->addItem(str.name.c_str());
ancard.push_back(cit->first); ancard.push_back(code);
} }
} }
} }
......
...@@ -86,14 +86,14 @@ public: ...@@ -86,14 +86,14 @@ public:
ChainInfo current_chain; ChainInfo current_chain;
bool last_chain{ false }; bool last_chain{ false };
bool deck_reversed{ false }; bool deck_reversed{ false };
bool conti_selecting{ false }; bool select_continuous{ false };
bool cant_check_grave{ false }; bool cant_check_grave{ false };
bool tag_surrender{ false }; bool tag_surrender{ false };
bool tag_teammate_surrender{ false }; bool tag_teammate_surrender{ false };
std::mt19937 rnd; std::mt19937 rnd;
ClientField(); ClientField();
~ClientField(); ~ClientField() override;
void Clear(); void Clear();
void Initial(int player, int deckc, int extrac, int sidec = 0); void Initial(int player, int deckc, int extrac, int sidec = 0);
void ResetSequence(std::vector<ClientCard*>& list, bool reset_height); void ResetSequence(std::vector<ClientCard*>& list, bool reset_height);
...@@ -105,7 +105,7 @@ public: ...@@ -105,7 +105,7 @@ public:
void ClearCommandFlag(); void ClearCommandFlag();
void ClearSelect(); void ClearSelect();
void ClearChainSelect(); void ClearChainSelect();
void ShowSelectCard(bool buttonok = false, bool chain = false); void ShowSelectCard(bool buttonok = false, bool is_continuous = false);
void ShowChainCard(); void ShowChainCard();
void ShowLocationCard(); void ShowLocationCard();
void ShowSelectOption(int select_hint = 0); void ShowSelectOption(int select_hint = 0);
......
...@@ -82,7 +82,7 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) { ...@@ -82,7 +82,7 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
#include <irrlicht.h> #include <irrlicht.h>
#endif #endif
extern const unsigned short PRO_VERSION; constexpr uint16_t PRO_VERSION = 0x1362;
extern unsigned int enable_log; extern unsigned int enable_log;
extern bool exit_on_return; extern bool exit_on_return;
extern bool open_file; extern bool open_file;
......
...@@ -6,11 +6,7 @@ ...@@ -6,11 +6,7 @@
namespace ygo { namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
unsigned char DataManager::scriptBuffer[0x100000] = {}; unsigned char DataManager::scriptBuffer[0x100000] = {};
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
irr::io::IFileSystem* DataManager::FileSystem = nullptr;
#endif
DataManager dataManager; DataManager dataManager;
DataManager::DataManager() : _datas(32768), _strings(32768) { DataManager::DataManager() : _datas(32768), _strings(32768) {
...@@ -328,7 +324,7 @@ std::wstring DataManager::FormatAttribute(unsigned int attribute) const { ...@@ -328,7 +324,7 @@ std::wstring DataManager::FormatAttribute(unsigned int attribute) const {
if (attribute & (0x1U << i)) { if (attribute & (0x1U << i)) {
if (!buffer.empty()) if (!buffer.empty())
buffer.push_back(L'|'); buffer.push_back(L'|');
buffer.append(GetSysString(1010 + i)); buffer.append(GetSysString(STRING_ID_ATTRIBUTE + i));
} }
} }
if (buffer.empty()) if (buffer.empty())
...@@ -341,7 +337,7 @@ std::wstring DataManager::FormatRace(unsigned int race) const { ...@@ -341,7 +337,7 @@ std::wstring DataManager::FormatRace(unsigned int race) const {
if(race & (0x1U << i)) { if(race & (0x1U << i)) {
if (!buffer.empty()) if (!buffer.empty())
buffer.push_back(L'|'); buffer.push_back(L'|');
buffer.append(GetSysString(1020 + i)); buffer.append(GetSysString(STRING_ID_RACE + i));
} }
} }
if (buffer.empty()) if (buffer.empty())
...@@ -350,12 +346,11 @@ std::wstring DataManager::FormatRace(unsigned int race) const { ...@@ -350,12 +346,11 @@ std::wstring DataManager::FormatRace(unsigned int race) const {
} }
std::wstring DataManager::FormatType(unsigned int type) const { std::wstring DataManager::FormatType(unsigned int type) const {
std::wstring buffer; std::wstring buffer;
int i = 1050; for (int i = 0; i < TYPES_COUNT; ++i) {
for (unsigned filter = TYPE_MONSTER; filter <= TYPE_LINK; filter <<= 1, ++i) { if (type & (0x1U << i)) {
if (type & filter) {
if (!buffer.empty()) if (!buffer.empty())
buffer.push_back(L'|'); buffer.push_back(L'|');
buffer.append(GetSysString(i)); buffer.append(GetSysString(STRING_ID_TYPE + i));
} }
} }
if (buffer.empty()) if (buffer.empty())
...@@ -446,9 +441,9 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl ...@@ -446,9 +441,9 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl
#ifdef _WIN32 #ifdef _WIN32
wchar_t fname[256]{}; wchar_t fname[256]{};
BufferIO::DecodeUTF8(script_name, fname); BufferIO::DecodeUTF8(script_name, fname);
auto reader = FileSystem->createAndOpenFile(fname); auto reader = dataManager.FileSystem->createAndOpenFile(fname);
#else #else
auto reader = FileSystem->createAndOpenFile(script_name); auto reader = dataManager.FileSystem->createAndOpenFile(script_name);
#endif #endif
if (!reader) if (!reader)
return nullptr; return nullptr;
......
...@@ -15,6 +15,7 @@ namespace irr { ...@@ -15,6 +15,7 @@ namespace irr {
} }
namespace ygo { namespace ygo {
constexpr int MAX_STRING_ID = 0x7ff; constexpr int MAX_STRING_ID = 0x7ff;
constexpr uint32_t MIN_CARD_ID = (uint32_t)(MAX_STRING_ID + 1) >> 4; constexpr uint32_t MIN_CARD_ID = (uint32_t)(MAX_STRING_ID + 1) >> 4;
constexpr uint32_t MAX_CARD_ID = 0x0fffffffU; constexpr uint32_t MAX_CARD_ID = 0x0fffffffU;
...@@ -71,19 +72,15 @@ public: ...@@ -71,19 +72,15 @@ public:
code_pointer GetCodePointer(uint32_t code) const; code_pointer GetCodePointer(uint32_t code) const;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
string_pointer GetStringPointer(uint32_t code) const; string_pointer GetStringPointer(uint32_t code) const;
code_pointer datas_begin() const noexcept { #endif
return _datas.cbegin(); const std::unordered_map<uint32_t, CardDataC>& GetDataTable() const {
} return _datas;
code_pointer datas_end() const noexcept {
return _datas.cend();
}
string_pointer strings_begin() const noexcept {
return _strings.cbegin();
} }
string_pointer strings_end() const noexcept { #ifndef YGOPRO_SERVER_MODE
return _strings.cend(); const std::unordered_map<uint32_t, CardString>& GetStringTable() const {
return _strings;
} }
#endif //YGOPRO_SERVER_MODE #endif
bool GetData(uint32_t code, CardData* pData) const; bool GetData(uint32_t code, CardData* pData) const;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool GetString(uint32_t code, CardString* pStr) const; bool GetString(uint32_t code, CardString* pStr) const;
...@@ -109,9 +106,17 @@ public: ...@@ -109,9 +106,17 @@ public:
std::unordered_map<unsigned int, std::wstring> _sysStrings; std::unordered_map<unsigned int, std::wstring> _sysStrings;
#endif #endif
char errmsg[512]{}; char errmsg[512]{};
const wchar_t* unknown_string{ L"???" };
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
irr::io::IFileSystem* FileSystem{};
#endif
static constexpr int STRING_ID_ATTRIBUTE = 1010;
static constexpr int STRING_ID_RACE = 1020;
static constexpr int STRING_ID_TYPE = 1050;
static constexpr int TYPES_COUNT = 27;
static unsigned char scriptBuffer[0x100000]; static unsigned char scriptBuffer[0x100000];
static const wchar_t* unknown_string;
static uint32_t CardReader(uint32_t, card_data*); static uint32_t CardReader(uint32_t, card_data*);
static unsigned char* ScriptReaderEx(const char* script_path, int* slen); static unsigned char* ScriptReaderEx(const char* script_path, int* slen);
...@@ -121,10 +126,6 @@ public: ...@@ -121,10 +126,6 @@ public:
#endif #endif
//read by fread //read by fread
static unsigned char* ReadScriptFromFile(const char* script_name, int* slen); static unsigned char* ReadScriptFromFile(const char* script_name, int* slen);
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
static irr::io::IFileSystem* FileSystem;
#endif
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
static bool deck_sort_lv(code_pointer l1, code_pointer l2); static bool deck_sort_lv(code_pointer l1, code_pointer l2);
......
...@@ -141,6 +141,7 @@ void DeckBuilder::Terminate() { ...@@ -141,6 +141,7 @@ void DeckBuilder::Terminate() {
bool DeckBuilder::OnEvent(const irr::SEvent& event) { bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if(mainGame->dField.OnCommonEvent(event)) if(mainGame->dField.OnCommonEvent(event))
return false; return false;
auto& _datas = dataManager.GetDataTable();
switch(event.EventType) { switch(event.EventType) {
case irr::EET_GUI_EVENT: { case irr::EET_GUI_EVENT: {
irr::s32 id = event.GUIEvent.Caller->getID(); irr::s32 id = event.GUIEvent.Caller->getID();
...@@ -428,7 +429,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -428,7 +429,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->lstCategories->addItem(catename); mainGame->lstCategories->addItem(catename);
catesel = mainGame->lstCategories->getItemCount() - 1; catesel = mainGame->lstCategories->getItemCount() - 1;
} else { } else {
for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) { for(int i = DECK_CATEGORY_CUSTOM; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) { if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -448,6 +449,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -448,6 +449,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} }
case BUTTON_RENAME_CATEGORY: { case BUTTON_RENAME_CATEGORY: {
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
if (catesel < DECK_CATEGORY_CUSTOM)
break;
const wchar_t* oldcatename = mainGame->lstCategories->getListItem(catesel); const wchar_t* oldcatename = mainGame->lstCategories->getListItem(catesel);
const wchar_t* newcatename = mainGame->ebDMName->getText(); const wchar_t* newcatename = mainGame->ebDMName->getText();
if(DeckManager::RenameCategory(oldcatename, newcatename)) { if(DeckManager::RenameCategory(oldcatename, newcatename)) {
...@@ -458,7 +461,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -458,7 +461,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
catesel = mainGame->lstCategories->getItemCount() - 1; catesel = mainGame->lstCategories->getItemCount() - 1;
} else { } else {
catesel = 0; catesel = 0;
for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) { for(int i = DECK_CATEGORY_CUSTOM; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) { if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -478,11 +481,13 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -478,11 +481,13 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} }
case BUTTON_DELETE_CATEGORY: { case BUTTON_DELETE_CATEGORY: {
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
if (catesel < DECK_CATEGORY_CUSTOM)
break;
const wchar_t* catename = mainGame->lstCategories->getListItem(catesel); const wchar_t* catename = mainGame->lstCategories->getListItem(catesel);
if(DeckManager::DeleteCategory(catename)) { if(DeckManager::DeleteCategory(catename)) {
mainGame->cbDBCategory->removeItem(catesel); mainGame->cbDBCategory->removeItem(catesel);
mainGame->lstCategories->removeItem(catesel); mainGame->lstCategories->removeItem(catesel);
catesel = 2; catesel = DECK_CATEGORY_NONE;
mainGame->lstCategories->setSelected(catesel); mainGame->lstCategories->setSelected(catesel);
RefreshDeckList(); RefreshDeckList();
mainGame->lstDecks->setSelected(0); mainGame->lstDecks->setSelected(0);
...@@ -1074,8 +1079,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1074,8 +1079,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
dragx = event.MouseInput.X; dragx = event.MouseInput.X;
dragy = event.MouseInput.Y; dragy = event.MouseInput.Y;
draging_pointer = dataManager.GetCodePointer(hovered_code); draging_pointer = _datas.find(hovered_code);
if(draging_pointer == dataManager.datas_end()) if (draging_pointer == _datas.end())
break; break;
if(hovered_pos == 4) { if(hovered_pos == 4) {
if(!check_limit(draging_pointer)) if(!check_limit(draging_pointer))
...@@ -1128,8 +1133,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1128,8 +1133,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
if(hovered_pos == 0 || hovered_seq == -1) if(hovered_pos == 0 || hovered_seq == -1)
break; break;
auto pointer = dataManager.GetCodePointer(hovered_code); auto pointer = _datas.find(hovered_code);
if(pointer == dataManager.datas_end()) if (pointer == _datas.end())
break; break;
soundManager.PlaySoundEffect(SOUND_CARD_DROP); soundManager.PlaySoundEffect(SOUND_CARD_DROP);
if(hovered_pos == 1) { if(hovered_pos == 1) {
...@@ -1163,8 +1168,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1163,8 +1168,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} else if(hovered_pos == 3) { } else if(hovered_pos == 3) {
pop_side(hovered_seq); pop_side(hovered_seq);
} else { } else {
auto pointer = dataManager.GetCodePointer(hovered_code); auto pointer = _datas.find(hovered_code);
if(pointer == dataManager.datas_end()) if (pointer == _datas.end())
break; break;
if(!check_limit(pointer)) if(!check_limit(pointer))
break; break;
...@@ -1198,8 +1203,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1198,8 +1203,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
if (is_draging) if (is_draging)
break; break;
auto pointer = dataManager.GetCodePointer(hovered_code); auto pointer = _datas.find(hovered_code);
if (pointer == dataManager.datas_end()) if (pointer == _datas.end())
break; break;
if(!check_limit(pointer)) if(!check_limit(pointer))
break; break;
...@@ -1468,10 +1473,13 @@ void DeckBuilder::FilterCards() { ...@@ -1468,10 +1473,13 @@ void DeckBuilder::FilterCards() {
query_elements.push_back(element); query_elements.push_back(element);
} }
} }
for(code_pointer ptr = dataManager.datas_begin(); ptr != dataManager.datas_end(); ++ptr) { auto& _datas = dataManager.GetDataTable();
const CardDataC& data = ptr->second; auto& _strings = dataManager.GetStringTable();
auto strpointer = dataManager.GetStringPointer(ptr->first); for (code_pointer ptr = _datas.begin(); ptr != _datas.end(); ++ptr) {
if (strpointer == dataManager.strings_end()) auto& code = ptr->first;
auto& data = ptr->second;
auto strpointer = _strings.find(code);
if (strpointer == _strings.end())
continue; continue;
const CardString& strings = strpointer->second; const CardString& strings = strpointer->second;
if(data.type & TYPE_TOKEN) if(data.type & TYPE_TOKEN)
...@@ -1877,16 +1885,16 @@ bool DeckBuilder::check_limit(code_pointer pointer) { ...@@ -1877,16 +1885,16 @@ bool DeckBuilder::check_limit(code_pointer pointer) {
auto flit = filterList->content.find(limitcode); auto flit = filterList->content.find(limitcode);
if(flit != filterList->content.end()) if(flit != filterList->content.end())
limit = flit->second; limit = flit->second;
for(auto it = deckManager.current_deck.main.begin(); it != deckManager.current_deck.main.end(); ++it) { for (auto& card : deckManager.current_deck.main) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode) if (card->first == limitcode || card->second.alias == limitcode)
limit--; limit--;
} }
for(auto it = deckManager.current_deck.extra.begin(); it != deckManager.current_deck.extra.end(); ++it) { for (auto& card : deckManager.current_deck.extra) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode) if (card->first == limitcode || card->second.alias == limitcode)
limit--; limit--;
} }
for(auto it = deckManager.current_deck.side.begin(); it != deckManager.current_deck.side.end(); ++it) { for (auto& card : deckManager.current_deck.side) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode) if (card->first == limitcode || card->second.alias == limitcode)
limit--; limit--;
} }
return limit > 0; return limit > 0;
......
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
namespace ygo { namespace ygo {
#ifndef YGOPRO_SERVER_MODE
char DeckManager::deckBuffer[0x10000]{};
#endif
DeckManager deckManager; DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) { void DeckManager::LoadLFListSingle(const char* path) {
...@@ -155,42 +152,46 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r ...@@ -155,42 +152,46 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
uint32_t DeckManager::LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist) { uint32_t DeckManager::LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist) {
deck.clear(); deck.clear();
uint32_t errorcode = 0; uint32_t errorcode = 0;
CardData cd; auto& _datas = dataManager.GetDataTable();
for(int i = 0; i < mainc; ++i) { for(int i = 0; i < mainc; ++i) {
auto code = dbuf[i]; auto code = dbuf[i];
if(!dataManager.GetData(code, &cd)) { auto it = _datas.find(code);
if(it == _datas.end()) {
errorcode = code; errorcode = code;
continue; continue;
} }
auto& cd = it->second;
if (cd.type & TYPE_TOKEN) { if (cd.type & TYPE_TOKEN) {
errorcode = code; errorcode = code;
continue; continue;
} }
if(is_packlist) { if(is_packlist) {
deck.main.push_back(dataManager.GetCodePointer(code)); deck.main.push_back(it);
continue; continue;
} }
if (cd.type & TYPES_EXTRA_DECK) { if (cd.type & TYPES_EXTRA_DECK) {
if (deck.extra.size() < EXTRA_MAX_SIZE) if (deck.extra.size() < EXTRA_MAX_SIZE)
deck.extra.push_back(dataManager.GetCodePointer(code)); deck.extra.push_back(it);
} }
else { else {
if (deck.main.size() < DECK_MAX_SIZE) if (deck.main.size() < DECK_MAX_SIZE)
deck.main.push_back(dataManager.GetCodePointer(code)); deck.main.push_back(it);
} }
} }
for(int i = 0; i < sidec; ++i) { for(int i = 0; i < sidec; ++i) {
auto code = dbuf[mainc + i]; auto code = dbuf[mainc + i];
if(!dataManager.GetData(code, &cd)) { auto it = _datas.find(code);
if(it == _datas.end()) {
errorcode = code; errorcode = code;
continue; continue;
} }
auto& cd = it->second;
if (cd.type & TYPE_TOKEN) { if (cd.type & TYPE_TOKEN) {
errorcode = code; errorcode = code;
continue; continue;
} }
if(deck.side.size() < SIDE_MAX_SIZE) if(deck.side.size() < SIDE_MAX_SIZE)
deck.side.push_back(dataManager.GetCodePointer(code)); deck.side.push_back(it);
} }
return errorcode; return errorcode;
} }
...@@ -252,15 +253,15 @@ bool DeckManager::LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec) { ...@@ -252,15 +253,15 @@ bool DeckManager::LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec) {
void DeckManager::GetCategoryPath(wchar_t* ret, int index, const wchar_t* text) { void DeckManager::GetCategoryPath(wchar_t* ret, int index, const wchar_t* text) {
wchar_t catepath[256]; wchar_t catepath[256];
switch(index) { switch(index) {
case 0: case DECK_CATEGORY_PACK:
myswprintf(catepath, L"./pack"); myswprintf(catepath, L"./pack");
break; break;
case 1: case DECK_CATEGORY_BOT:
BufferIO::CopyWideString(mainGame->gameConf.bot_deck_path, catepath); BufferIO::CopyWideString(mainGame->gameConf.bot_deck_path, catepath);
break; break;
case -1: case -1:
case 2: case DECK_CATEGORY_NONE:
case 3: case DECK_CATEGORY_SEPARATOR:
myswprintf(catepath, L"./deck"); myswprintf(catepath, L"./deck");
break; break;
default: default:
...@@ -286,11 +287,11 @@ FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) { ...@@ -286,11 +287,11 @@ FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) {
} }
irr::io::IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) { irr::io::IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) {
#ifdef _WIN32 #ifdef _WIN32
auto reader = DataManager::FileSystem->createAndOpenFile(file); auto reader = dataManager.FileSystem->createAndOpenFile(file);
#else #else
char file2[256]; char file2[256];
BufferIO::EncodeUTF8(file, file2); BufferIO::EncodeUTF8(file, file2);
auto reader = DataManager::FileSystem->createAndOpenFile(file2); auto reader = dataManager.FileSystem->createAndOpenFile(file2);
#endif #endif
return reader; return reader;
} }
...@@ -300,6 +301,9 @@ bool DeckManager::LoadCurrentDeck(std::istringstream& deckStream, bool is_packli ...@@ -300,6 +301,9 @@ bool DeckManager::LoadCurrentDeck(std::istringstream& deckStream, bool is_packli
} }
bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) { bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) {
current_deck.clear(); current_deck.clear();
if (!file[0])
return false;
char deckBuffer[MAX_YDK_SIZE]{};
auto reader = OpenDeckReader(file); auto reader = OpenDeckReader(file);
if(!reader) { if(!reader) {
wchar_t localfile[256]; wchar_t localfile[256];
...@@ -326,11 +330,12 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) { ...@@ -326,11 +330,12 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) {
bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname) { bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname) {
wchar_t filepath[256]; wchar_t filepath[256];
GetDeckFile(filepath, category_index, category_name, deckname); GetDeckFile(filepath, category_index, category_name, deckname);
bool is_packlist = (category_index == 0); bool is_packlist = (category_index == DECK_CATEGORY_PACK);
bool res = LoadCurrentDeck(filepath, is_packlist); if(!LoadCurrentDeck(filepath, is_packlist))
if (res && mainGame->is_building) return false;
if (mainGame->is_building)
mainGame->deckBuilder.RefreshPackListScroll(); mainGame->deckBuilder.RefreshPackListScroll();
return res; return true;
} }
void DeckManager::SaveDeck(const Deck& deck, std::stringstream& deckStream) { void DeckManager::SaveDeck(const Deck& deck, std::stringstream& deckStream) {
deckStream << "#created by ..." << std::endl; deckStream << "#created by ..." << std::endl;
...@@ -352,7 +357,7 @@ bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) { ...@@ -352,7 +357,7 @@ bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) {
return false; return false;
std::stringstream deckStream; std::stringstream deckStream;
SaveDeck(deck, deckStream); SaveDeck(deck, deckStream);
std::fwrite(deckStream.str().c_str(), 1, deckStream.str().length(), fp); std::fputs(deckStream.str().c_str(), fp);
std::fclose(fp); std::fclose(fp);
return true; return true;
} }
......
...@@ -23,14 +23,21 @@ ...@@ -23,14 +23,21 @@
#endif #endif
namespace ygo { namespace ygo {
constexpr int DECK_MAX_SIZE = YGOPRO_MAX_DECK;
constexpr int DECK_MIN_SIZE = YGOPRO_MIN_DECK;
constexpr int EXTRA_MAX_SIZE = YGOPRO_MAX_EXTRA;
constexpr int SIDE_MAX_SIZE = YGOPRO_MAX_SIDE;
constexpr int PACK_MAX_SIZE = 1000;
constexpr int MAINC_MAX = 250; // the limit of card_state constexpr int DECK_MAX_SIZE = YGOPRO_MAX_DECK;
constexpr int SIDEC_MAX = MAINC_MAX; constexpr int DECK_MIN_SIZE = YGOPRO_MIN_DECK;
constexpr int EXTRA_MAX_SIZE = YGOPRO_MAX_EXTRA;
constexpr int SIDE_MAX_SIZE = YGOPRO_MAX_SIDE;
constexpr int PACK_MAX_SIZE = 1000;
constexpr int MAINC_MAX = 250; // the limit of card_state
constexpr int SIDEC_MAX = MAINC_MAX;
constexpr int DECK_CATEGORY_PACK = 0;
constexpr int DECK_CATEGORY_BOT = 1;
constexpr int DECK_CATEGORY_NONE = 2;
constexpr int DECK_CATEGORY_SEPARATOR = 3;
constexpr int DECK_CATEGORY_CUSTOM = 4;
struct LFList { struct LFList {
unsigned int hash{}; unsigned int hash{};
...@@ -62,11 +69,13 @@ struct DeckArray { ...@@ -62,11 +69,13 @@ struct DeckArray {
class DeckManager { class DeckManager {
public: public:
#ifndef YGOPRO_SERVER_MODE
Deck current_deck; Deck current_deck;
#endif
std::vector<LFList> _lfList; std::vector<LFList> _lfList;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
static char deckBuffer[0x10000]; static constexpr int MAX_YDK_SIZE = 0x10000;
#endif #endif
void LoadLFListSingle(const char* path); void LoadLFListSingle(const char* path);
......
...@@ -1095,7 +1095,6 @@ void Game::HideElement(irr::gui::IGUIElement * win, bool set_action) { ...@@ -1095,7 +1095,6 @@ void Game::HideElement(irr::gui::IGUIElement * win, bool set_action) {
if(win == wCardSelect) { if(win == wCardSelect) {
for(int i = 0; i < 5; ++i) for(int i = 0; i < 5; ++i)
btnCardSelect[i]->setDrawImage(false); btnCardSelect[i]->setDrawImage(false);
dField.conti_selecting = false;
stCardListTip->setVisible(false); stCardListTip->setVisible(false);
for(auto& pcard : dField.selectable_cards) for(auto& pcard : dField.selectable_cards)
dField.SetShowMark(pcard, false); dField.SetShowMark(pcard, false);
...@@ -1307,8 +1306,9 @@ void Game::DrawDeckBd() { ...@@ -1307,8 +1306,9 @@ void Game::DrawDeckBd() {
else else
myswprintf(adBuffer, L"%d/-", ptr->second.attack); myswprintf(adBuffer, L"%d/-", ptr->second.attack);
} }
myswprintf(textBuffer, L"%ls/%ls %ls%d", dataManager.FormatAttribute(ptr->second.attribute).c_str(), dataManager.FormatRace(ptr->second.race).c_str(), const auto& attribute = dataManager.FormatAttribute(ptr->second.attribute);
form, ptr->second.level); const auto& race = dataManager.FormatRace(ptr->second.race);
myswprintf(textBuffer, L"%ls/%ls %ls%d", attribute.c_str(), race.c_str(), form, ptr->second.level);
DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0)); DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0));
if(ptr->second.type & TYPE_PENDULUM) { if(ptr->second.type & TYPE_PENDULUM) {
myswprintf(scaleBuffer, L" %d/%d", ptr->second.lscale, ptr->second.rscale); myswprintf(scaleBuffer, L" %d/%d", ptr->second.lscale, ptr->second.rscale);
...@@ -1318,7 +1318,8 @@ void Game::DrawDeckBd() { ...@@ -1318,7 +1318,8 @@ void Game::DrawDeckBd() {
} else { } else {
myswprintf(textBuffer, L"%ls", dataManager.GetName(ptr->first)); myswprintf(textBuffer, L"%ls", dataManager.GetName(ptr->first));
DrawShadowText(textFont, textBuffer, Resize(860, 165 + i * 66, 955, 185 + i * 66), Resize(1, 1, 0, 0)); DrawShadowText(textFont, textBuffer, Resize(860, 165 + i * 66, 955, 185 + i * 66), Resize(1, 1, 0, 0));
myswprintf(textBuffer, L"%ls", dataManager.FormatType(ptr->second.type).c_str()); const auto& type = dataManager.FormatType(ptr->second.type);
myswprintf(textBuffer, L"%ls", type.c_str());
DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0)); DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0));
myswprintf(textBuffer, L"%ls", availBuffer); myswprintf(textBuffer, L"%ls", availBuffer);
DrawShadowText(textFont, textBuffer, Resize(860, 209 + i * 66, 955, 229 + i * 66), Resize(1, 1, 0, 0)); DrawShadowText(textFont, textBuffer, Resize(860, 209 + i * 66, 955, 229 + i * 66), Resize(1, 1, 0, 0));
......
...@@ -762,8 +762,11 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -762,8 +762,11 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
prep += sizeof new_replay.pheader; prep += sizeof new_replay.pheader;
std::memcpy(new_replay.comp_data, prep, len - sizeof new_replay.pheader - 1); std::memcpy(new_replay.comp_data, prep, len - sizeof new_replay.pheader - 1);
new_replay.comp_size = len - sizeof new_replay.pheader - 1; new_replay.comp_size = len - sizeof new_replay.pheader - 1;
if(mainGame->actionParam) if (mainGame->actionParam) {
new_replay.SaveReplay(mainGame->ebRSName->getText()); bool save_result = new_replay.SaveReplay(mainGame->ebRSName->getText());
if (!save_result)
new_replay.SaveReplay(L"_LastReplay");
}
else else
new_replay.SaveReplay(L"_LastReplay"); new_replay.SaveReplay(L"_LastReplay");
} }
...@@ -1113,7 +1116,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -1113,7 +1116,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break; break;
} }
case HINT_RACE: { case HINT_RACE: {
myswprintf(textBuffer, dataManager.GetSysString(1511), dataManager.FormatRace(data).c_str()); const auto& race = dataManager.FormatRace(data);
myswprintf(textBuffer, dataManager.GetSysString(1511), race.c_str());
mainGame->AddLog(textBuffer); mainGame->AddLog(textBuffer);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer); mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer);
...@@ -1123,7 +1127,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -1123,7 +1127,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break; break;
} }
case HINT_ATTRIB: { case HINT_ATTRIB: {
myswprintf(textBuffer, dataManager.GetSysString(1511), dataManager.FormatAttribute(data).c_str()); const auto& attribute = dataManager.FormatAttribute(data);
myswprintf(textBuffer, dataManager.GetSysString(1511), attribute.c_str());
mainGame->AddLog(textBuffer); mainGame->AddLog(textBuffer);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer); mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer);
......
...@@ -404,7 +404,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -404,7 +404,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
} }
} else { } else {
selectable_cards.clear(); selectable_cards.clear();
conti_selecting = false; bool is_continuous = false;
switch(command_location) { switch(command_location) {
case LOCATION_DECK: { case LOCATION_DECK: {
for(size_t i = 0; i < deck[command_controler].size(); ++i) for(size_t i = 0; i < deck[command_controler].size(); ++i)
...@@ -431,15 +431,15 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -431,15 +431,15 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
break; break;
} }
case POSITION_HINT: { case POSITION_HINT: {
is_continuous = true;
selectable_cards = conti_cards; selectable_cards = conti_cards;
std::sort(selectable_cards.begin(), selectable_cards.end()); std::sort(selectable_cards.begin(), selectable_cards.end());
auto eit = std::unique(selectable_cards.begin(), selectable_cards.end()); auto eit = std::unique(selectable_cards.begin(), selectable_cards.end());
selectable_cards.erase(eit, selectable_cards.end()); selectable_cards.erase(eit, selectable_cards.end());
conti_selecting = true;
break; break;
} }
} }
if(!conti_selecting) { if (!is_continuous) {
mainGame->wCardSelect->setText(dataManager.GetSysString(566)); mainGame->wCardSelect->setText(dataManager.GetSysString(566));
list_command = COMMAND_ACTIVATE; list_command = COMMAND_ACTIVATE;
} else { } else {
...@@ -447,7 +447,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -447,7 +447,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
list_command = COMMAND_OPERATION; list_command = COMMAND_OPERATION;
} }
std::sort(selectable_cards.begin(), selectable_cards.end(), ClientCard::client_card_sort); std::sort(selectable_cards.begin(), selectable_cards.end(), ClientCard::client_card_sort);
ShowSelectCard(true, true); ShowSelectCard(true, is_continuous);
} }
break; break;
} }
...@@ -892,7 +892,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -892,7 +892,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
// image // image
if(selectable_cards[i + pos]->code) if(selectable_cards[i + pos]->code)
mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->code)); mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->code));
else if(conti_selecting) else if(select_continuous)
mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->chain_code)); mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->chain_code));
else else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i + pos]->controler + 2]); mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i + pos]->controler + 2]);
...@@ -905,8 +905,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -905,8 +905,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
else else
myswprintf(formatBuffer, L""); myswprintf(formatBuffer, L"");
} else { } else {
if(conti_selecting) if(select_continuous)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string); myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE) else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0)); myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY) else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY)
...@@ -919,7 +919,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -919,7 +919,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
} }
mainGame->stCardPos[i]->setText(formatBuffer); mainGame->stCardPos[i]->setText(formatBuffer);
// color // color
if(conti_selecting) if(select_continuous)
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff); mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY) { else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY) {
if(selectable_cards[i + pos]->owner != selectable_cards[i + pos]->overlayTarget->controler) if(selectable_cards[i + pos]->owner != selectable_cards[i + pos]->overlayTarget->controler)
...@@ -1597,7 +1597,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -1597,7 +1597,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"\nLINK-%d", mcard->link); myswprintf(formatBuffer, L"\nLINK-%d", mcard->link);
str.append(formatBuffer); str.append(formatBuffer);
} }
myswprintf(formatBuffer, L" %ls/%ls", dataManager.FormatRace(mcard->race).c_str(), dataManager.FormatAttribute(mcard->attribute).c_str()); const auto& race = dataManager.FormatRace(mcard->race);
const auto& attribute = dataManager.FormatAttribute(mcard->attribute);
myswprintf(formatBuffer, L" %ls/%ls", race.c_str(), attribute.c_str());
str.append(formatBuffer); str.append(formatBuffer);
if(mcard->location == LOCATION_HAND && (mcard->type & TYPE_PENDULUM)) { if(mcard->location == LOCATION_HAND && (mcard->type & TYPE_PENDULUM)) {
myswprintf(formatBuffer, L"\n%d/%d", mcard->lscale, mcard->rscale); myswprintf(formatBuffer, L"\n%d/%d", mcard->lscale, mcard->rscale);
...@@ -1622,10 +1624,14 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -1622,10 +1624,14 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(211), mcard->chValue); myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(211), mcard->chValue);
else if(mcard->cHint == CHINT_CARD) else if(mcard->cHint == CHINT_CARD)
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(212), dataManager.GetName(mcard->chValue)); myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(212), dataManager.GetName(mcard->chValue));
else if(mcard->cHint == CHINT_RACE) else if(mcard->cHint == CHINT_RACE) {
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(213), dataManager.FormatRace(mcard->chValue).c_str()); const auto& race = dataManager.FormatRace(mcard->chValue);
else if(mcard->cHint == CHINT_ATTRIBUTE) myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(213), race.c_str());
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(214), dataManager.FormatAttribute(mcard->chValue).c_str()); }
else if(mcard->cHint == CHINT_ATTRIBUTE) {
const auto& attribute = dataManager.FormatAttribute(mcard->chValue);
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(214), attribute.c_str());
}
else if(mcard->cHint == CHINT_NUMBER) else if(mcard->cHint == CHINT_NUMBER)
myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(215), mcard->chValue); myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(215), mcard->chValue);
str.append(formatBuffer); str.append(formatBuffer);
......
This diff is collapsed.
...@@ -26,16 +26,16 @@ ...@@ -26,16 +26,16 @@
#include <mutex> #include <mutex>
#include <functional> #include <functional>
namespace ygo {
#ifndef YGOPRO_DEFAULT_DUEL_RULE #ifndef YGOPRO_DEFAULT_DUEL_RULE
#define YGOPRO_DEFAULT_DUEL_RULE 5 constexpr int DEFAULT_DUEL_RULE = CURRENT_RULE;
#else
constexpr int DEFAULT_DUEL_RULE = YGOPRO_DEFAULT_DUEL_RULE;
#endif #endif
#define DEFAULT_DUEL_RULE YGOPRO_DEFAULT_DUEL_RULE
constexpr int CONFIG_LINE_SIZE = 1024; constexpr int CONFIG_LINE_SIZE = 1024;
constexpr int TEXT_LINE_SIZE = 256; constexpr int TEXT_LINE_SIZE = 256;
namespace ygo {
template<size_t N> template<size_t N>
bool IsExtension(const wchar_t* filename, const wchar_t(&extension)[N]) { bool IsExtension(const wchar_t* filename, const wchar_t(&extension)[N]) {
auto flen = std::wcslen(filename); auto flen = std::wcslen(filename);
......
...@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { ...@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) {
ygo::game_info.draw_count = 1; ygo::game_info.draw_count = 1;
ygo::game_info.no_check_deck = false; ygo::game_info.no_check_deck = false;
ygo::game_info.no_shuffle_deck = false; ygo::game_info.no_shuffle_deck = false;
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE; ygo::game_info.duel_rule = ygo::DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180; ygo::game_info.time_limit = 180;
std::memset(ygo::pre_seed, 0, sizeof(ygo::pre_seed)); std::memset(ygo::pre_seed, 0, sizeof(ygo::pre_seed));
std::memset(ygo::pre_seed_specified, 0, sizeof(ygo::pre_seed_specified)); std::memset(ygo::pre_seed_specified, 0, sizeof(ygo::pre_seed_specified));
...@@ -103,15 +103,15 @@ int main(int argc, char* argv[]) { ...@@ -103,15 +103,15 @@ int main(int argc, char* argv[]) {
mode = 0; mode = 0;
ygo::game_info.mode = mode; ygo::game_info.mode = mode;
if(argv[5][0] == 'T') if(argv[5][0] == 'T')
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE - 1; ygo::game_info.duel_rule = ygo::DEFAULT_DUEL_RULE - 1;
else if(argv[5][0] == 'F') else if(argv[5][0] == 'F')
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE; ygo::game_info.duel_rule = ygo::DEFAULT_DUEL_RULE;
else { else {
int master_rule = atoi(argv[5]); int master_rule = atoi(argv[5]);
if(master_rule) if(master_rule)
ygo::game_info.duel_rule = master_rule; ygo::game_info.duel_rule = master_rule;
else else
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE; ygo::game_info.duel_rule = ygo::DEFAULT_DUEL_RULE;
} }
if(argv[6][0] == 'T') if(argv[6][0] == 'T')
ygo::game_info.no_check_deck = true; ygo::game_info.no_check_deck = true;
......
...@@ -487,7 +487,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -487,7 +487,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(prev_operation == BUTTON_RENAME_REPLAY) { if(prev_operation == BUTTON_RENAME_REPLAY) {
wchar_t newname[256]; wchar_t newname[256];
BufferIO::CopyWideString(mainGame->ebRSName->getText(), newname); BufferIO::CopyWideString(mainGame->ebRSName->getText(), newname);
if(mywcsncasecmp(newname + std::wcslen(newname) - 4, L".yrp", 4)) { if (!IsExtension(newname, L".yrp")) {
myswprintf(newname, L"%ls.yrp", mainGame->ebRSName->getText()); myswprintf(newname, L"%ls.yrp", mainGame->ebRSName->getText());
} }
if(Replay::RenameReplay(mainGame->lstReplayList->getListItem(prev_sel), newname)) { if(Replay::RenameReplay(mainGame->lstReplayList->getListItem(prev_sel), newname)) {
......
...@@ -21,7 +21,7 @@ class FileSystem { ...@@ -21,7 +21,7 @@ class FileSystem {
public: public:
static void SafeFileName(wchar_t* wfile) { static void SafeFileName(wchar_t* wfile) {
while((wfile = std::wcspbrk(wfile, L"<>:\"/\\|?*")) != nullptr) while((wfile = std::wcspbrk(wfile, L"<>:\"/\\|?*")) != nullptr)
*wfile++ = '_'; *wfile++ = L'_';
} }
static bool IsFileExists(const wchar_t* wfile) { static bool IsFileExists(const wchar_t* wfile) {
...@@ -125,7 +125,7 @@ class FileSystem { ...@@ -125,7 +125,7 @@ class FileSystem {
public: public:
static void SafeFileName(wchar_t* wfile) { static void SafeFileName(wchar_t* wfile) {
while((wfile = std::wcspbrk(wfile, L"/")) != nullptr) while((wfile = std::wcspbrk(wfile, L"/")) != nullptr)
*wfile++ = '_'; *wfile++ = L'_';
} }
static bool IsFileExists(const char* file) { static bool IsFileExists(const char* file) {
......
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
#define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true && std::is_standard_layout<T>::value == true, "not trivially copyable") #define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true && std::is_standard_layout<T>::value == true, "not trivially copyable")
namespace ygo { namespace ygo {
constexpr int SIZE_NETWORK_BUFFER = 0x20000;
constexpr int MAX_DATA_SIZE = UINT16_MAX - 1; constexpr int SIZE_NETWORK_BUFFER = 0x20000;
constexpr int MAX_DATA_SIZE = UINT16_MAX - 1;
struct HostInfo { struct HostInfo {
uint32_t lflist{}; uint32_t lflist{};
......
...@@ -98,24 +98,30 @@ void Replay::EndRecord() { ...@@ -98,24 +98,30 @@ void Replay::EndRecord() {
} }
is_recording = false; is_recording = false;
} }
void Replay::SaveReplay(const wchar_t* name) { bool Replay::SaveReplay(const wchar_t* base_name) {
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay")) if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return; return false;
wchar_t fname[256]; wchar_t filename[256]{};
myswprintf(fname, L"./replay/%ls.yrp", name); wchar_t path[256]{};
FILE* rfp = mywfopen(fname, "wb"); BufferIO::CopyWideString(base_name, filename);
FileSystem::SafeFileName(filename);
if (myswprintf(path, L"./replay/%ls.yrp", filename) <= 0)
return false;
FILE* rfp = mywfopen(path, "wb");
if(!rfp) if(!rfp)
return; return false;
std::fwrite(&pheader, sizeof pheader, 1, rfp); std::fwrite(&pheader, sizeof pheader, 1, rfp);
std::fwrite(comp_data, comp_size, 1, rfp); std::fwrite(comp_data, comp_size, 1, rfp);
std::fclose(rfp); std::fclose(rfp);
return true;
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool Replay::OpenReplay(const wchar_t* name) { bool Replay::OpenReplay(const wchar_t* name) {
FILE* rfp = mywfopen(name, "rb"); FILE* rfp = mywfopen(name, "rb");
if(!rfp) { if(!rfp) {
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name); if (myswprintf(fname, L"./replay/%ls", name) <= 0)
return false;
rfp = mywfopen(fname, "rb"); rfp = mywfopen(fname, "rb");
} }
if(!rfp) if(!rfp)
...@@ -167,19 +173,28 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -167,19 +173,28 @@ bool Replay::OpenReplay(const wchar_t* name) {
return true; return true;
} }
bool Replay::DeleteReplay(const wchar_t* name) { bool Replay::DeleteReplay(const wchar_t* name) {
if (std::wcschr(name, L'/') || std::wcschr(name, L'\\'))
return false;
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name); if(myswprintf(fname, L"./replay/%ls", name) <= 0)
return false;
return FileSystem::RemoveFile(fname); return FileSystem::RemoveFile(fname);
} }
bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) { bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t oldfname[256]; wchar_t old_path[256];
wchar_t newfname[256]; wchar_t new_path[256];
myswprintf(oldfname, L"./replay/%ls", oldname); if (std::wcschr(oldname, L'/') || std::wcschr(oldname, L'\\'))
myswprintf(newfname, L"./replay/%ls", newname); return false;
if (std::wcschr(newname, L'/') || std::wcschr(newname, L'\\'))
return false;
if (myswprintf(old_path, L"./replay/%ls", oldname) <= 0)
return false;
if (myswprintf(new_path, L"./replay/%ls", newname) <= 0)
return false;
char oldfilefn[1024]; char oldfilefn[1024];
char newfilefn[1024]; char newfilefn[1024];
BufferIO::EncodeUTF8(oldfname, oldfilefn); BufferIO::EncodeUTF8(old_path, oldfilefn);
BufferIO::EncodeUTF8(newfname, newfilefn); BufferIO::EncodeUTF8(new_path, newfilefn);
int result = std::rename(oldfilefn, newfilefn); int result = std::rename(oldfilefn, newfilefn);
return result == 0; return result == 0;
} }
......
...@@ -71,7 +71,7 @@ public: ...@@ -71,7 +71,7 @@ public:
void WriteInt32(int32_t data, bool flush = true); void WriteInt32(int32_t data, bool flush = true);
void Flush(); void Flush();
void EndRecord(); void EndRecord();
void SaveReplay(const wchar_t* name); bool SaveReplay(const wchar_t* base_name);
// play // play
static bool DeleteReplay(const wchar_t* name); static bool DeleteReplay(const wchar_t* name);
......
This diff is collapsed.
Subproject commit efcf37aa269c17a60eb260a54bf8a837d2267265 Subproject commit 682ffa3c2db0443fd3afb725a1089a33077b1dc7
Subproject commit 68cf0aecab0d2c97f65186ba8ca7c072cf630a90 Subproject commit bb696eb5dc009d4b708bc9f85a29fd46fd6577cf
...@@ -669,6 +669,8 @@ ...@@ -669,6 +669,8 @@
!counter 0x6e 四季指示物 !counter 0x6e 四季指示物
!counter 0x6f 龋齿指示物 !counter 0x6f 龋齿指示物
!counter 0x70 盘子指示物 !counter 0x70 盘子指示物
!counter 0x71 纠罪指示物
!counter 0x1072 少女指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -1238,7 +1240,7 @@ ...@@ -1238,7 +1240,7 @@
!setname 0x1b4 时空 タキオン !setname 0x1b4 时空 タキオン
!setname 0x1b5 蓝泪 青い涙 !setname 0x1b5 蓝泪 青い涙
!setname 0x1b6 石版 !setname 0x1b6 石版
!setname 0x1b7 拟箱掳尸 Mimighoul !setname 0x1b7 迷拟宝箱鬼 ミミグル
!setname 0x1b8 鲨 シャーク !setname 0x1b8 鲨 シャーク
!setname 0x11b8 鲨龙兽 シャーク・ドレイク !setname 0x11b8 鲨龙兽 シャーク・ドレイク
!setname 0x1b9 原石 !setname 0x1b9 原石
...@@ -1251,12 +1253,12 @@ ...@@ -1251,12 +1253,12 @@
!setname 0x1c0 龙华 竜華 !setname 0x1c0 龙华 竜華
!setname 0x1c1 阿尔戈☆群星 ARGS !setname 0x1c1 阿尔戈☆群星 ARGS
!setname 0x1c2 喷水引擎 アクア・ジェット !setname 0x1c2 喷水引擎 アクア・ジェット
!setname 0x1c3 巳剑 Mitsurugi !setname 0x1c3 巳剑 巳剣
!setname 0x1c4 征龙 征竜 !setname 0x1c4 征龙 征竜
!setname 0x1c5 再世 リジェネシス !setname 0x1c5 再世 リジェネシス
!setname 0x1c6 统王 ドミナス !setname 0x1c6 统王 ドミナス
!setname 0x1c7 塞勒凯特 Serket !setname 0x1c7 塞勒凯特 セルケト
!setname 0x1c8 阿匹卜 Apophis !setname 0x1c8 阿匹卜 アポピス
!setname 0x1c9 星辰 ドラゴンテイル !setname 0x1c9 星辰 ドラゴンテイル
!setname 0x1ca 味美喵 ヤミー !setname 0x1ca 味美喵 ヤミー
!setname 0x1cb K9 !setname 0x1cb K9
...@@ -1267,3 +1269,7 @@ ...@@ -1267,3 +1269,7 @@
!setname 0x1d0 死伟王 死偉王 !setname 0x1d0 死伟王 死偉王
!setname 0x1d1 绚岚 絢嵐 !setname 0x1d1 绚岚 絢嵐
!setname 0x1d2 终刻 ドゥームズ !setname 0x1d2 终刻 ドゥームズ
!setname 0x1d3 不可见之手 ヘカトンケイル
!setname 0x1d4 纠罪巧 糾罪巧
!setname 0x1d5 杀手级调整曲 キラーチューン
!setname 0x1d6 树熊 コアラ
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