Commit cdfbcc08 authored by mercury233's avatar mercury233

Merge branch 'fh' into patch-miniaudio-v2

parents 21ec8503 9350f5d6
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
/pics /pics
/replay /replay
/single /single
/sound
!/sound/files.txt
/WindBot /WindBot
/cards.cdb /cards.cdb
/error.log /error.log
......
...@@ -72,6 +72,21 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) { ...@@ -72,6 +72,21 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
return fp; return fp;
} }
#if !defined(_WIN32)
#define myfopen std::fopen
#elif defined(WDK_NTDDI_VERSION) && (WDK_NTDDI_VERSION >= 0x0A000005) // Redstone 4, Version 1803, Build 17134.
#define FOPEN_WINDOWS_SUPPORT_UTF8
#define myfopen std::fopen
#else
inline FILE* myfopen(const char* filename, const char* mode) {
wchar_t wfilename[256]{};
BufferIO::DecodeUTF8(filename, wfilename);
wchar_t wmode[20]{};
BufferIO::CopyCharArray(mode, wmode);
return _wfopen(wfilename, wmode);
}
#endif
#include <irrlicht.h> #include <irrlicht.h>
extern const unsigned short PRO_VERSION; extern const unsigned short PRO_VERSION;
......
...@@ -108,7 +108,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) { ...@@ -108,7 +108,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
return ret; return ret;
} }
bool DataManager::LoadStrings(const char* file) { bool DataManager::LoadStrings(const char* file) {
FILE* fp = std::fopen(file, "r"); FILE* fp = myfopen(file, "r");
if(!fp) if(!fp)
return false; return false;
char linebuf[TEXT_LINE_SIZE]{}; char linebuf[TEXT_LINE_SIZE]{};
...@@ -431,9 +431,7 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl ...@@ -431,9 +431,7 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl
return scriptBuffer; return scriptBuffer;
} }
unsigned char* DataManager::ReadScriptFromFile(const char* script_name, int* slen) { unsigned char* DataManager::ReadScriptFromFile(const char* script_name, int* slen) {
wchar_t fname[256]{}; FILE* fp = myfopen(script_name, "rb");
BufferIO::DecodeUTF8(script_name, fname);
FILE* fp = mywfopen(fname, "rb");
if (!fp) if (!fp)
return nullptr; return nullptr;
size_t len = std::fread(scriptBuffer, 1, sizeof scriptBuffer, fp); size_t len = std::fread(scriptBuffer, 1, sizeof scriptBuffer, fp);
......
...@@ -47,7 +47,7 @@ static inline bool havePopupWindow() { ...@@ -47,7 +47,7 @@ static inline bool havePopupWindow() {
} }
static inline void get_deck_file(wchar_t* ret) { static inline void get_deck_file(wchar_t* ret) {
deckManager.GetDeckFile(ret, mainGame->cbDBCategory->getSelected(), mainGame->cbDBCategory->getText(), mainGame->cbDBDecks->getText()); DeckManager::GetDeckFile(ret, mainGame->cbDBCategory->getSelected(), mainGame->cbDBCategory->getText(), mainGame->cbDBDecks->getText());
} }
static inline void load_current_deck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBox* cbDeck) { static inline void load_current_deck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBox* cbDeck) {
...@@ -184,7 +184,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -184,7 +184,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
wchar_t filepath[256]; wchar_t filepath[256];
get_deck_file(filepath); get_deck_file(filepath);
if(deckManager.SaveDeck(deckManager.current_deck, filepath)) { if(DeckManager::SaveDeck(deckManager.current_deck, filepath)) {
mainGame->stACMessage->setText(dataManager.GetSysString(1335)); mainGame->stACMessage->setText(dataManager.GetSysString(1335));
mainGame->PopupElement(mainGame->wACMessage, 20); mainGame->PopupElement(mainGame->wACMessage, 20);
is_modified = false; is_modified = false;
...@@ -210,10 +210,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -210,10 +210,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} }
int catesel = mainGame->cbDBCategory->getSelected(); int catesel = mainGame->cbDBCategory->getSelected();
wchar_t catepath[256]; wchar_t catepath[256];
deckManager.GetCategoryPath(catepath, catesel, mainGame->cbDBCategory->getText()); DeckManager::GetCategoryPath(catepath, catesel, mainGame->cbDBCategory->getText());
wchar_t filepath[256]; wchar_t filepath[256];
myswprintf(filepath, L"%ls/%ls.ydk", catepath, dname); myswprintf(filepath, L"%ls/%ls.ydk", catepath, dname);
if(deckManager.SaveDeck(deckManager.current_deck, filepath)) { if(DeckManager::SaveDeck(deckManager.current_deck, filepath)) {
mainGame->stACMessage->setText(dataManager.GetSysString(1335)); mainGame->stACMessage->setText(dataManager.GetSysString(1335));
mainGame->PopupElement(mainGame->wACMessage, 20); mainGame->PopupElement(mainGame->wACMessage, 20);
is_modified = false; is_modified = false;
...@@ -393,7 +393,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -393,7 +393,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case BUTTON_NEW_CATEGORY: { case BUTTON_NEW_CATEGORY: {
int catesel = 0; int catesel = 0;
const wchar_t* catename = mainGame->ebDMName->getText(); const wchar_t* catename = mainGame->ebDMName->getText();
if(deckManager.CreateCategory(catename)) { if(DeckManager::CreateCategory(catename)) {
mainGame->cbDBCategory->addItem(catename); mainGame->cbDBCategory->addItem(catename);
mainGame->lstCategories->addItem(catename); mainGame->lstCategories->addItem(catename);
catesel = mainGame->lstCategories->getItemCount() - 1; catesel = mainGame->lstCategories->getItemCount() - 1;
...@@ -420,7 +420,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -420,7 +420,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
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)) {
mainGame->cbDBCategory->removeItem(catesel); mainGame->cbDBCategory->removeItem(catesel);
mainGame->cbDBCategory->addItem(newcatename); mainGame->cbDBCategory->addItem(newcatename);
mainGame->lstCategories->removeItem(catesel); mainGame->lstCategories->removeItem(catesel);
...@@ -449,7 +449,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -449,7 +449,7 @@ 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();
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 = 2;
...@@ -467,7 +467,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -467,7 +467,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case BUTTON_NEW_DECK: { case BUTTON_NEW_DECK: {
const wchar_t* deckname = mainGame->ebDMName->getText(); const wchar_t* deckname = mainGame->ebDMName->getText();
wchar_t catepath[256]; wchar_t catepath[256];
deckManager.GetCategoryPath(catepath, mainGame->cbDBCategory->getSelected(), mainGame->cbDBCategory->getText()); DeckManager::GetCategoryPath(catepath, mainGame->cbDBCategory->getSelected(), mainGame->cbDBCategory->getText());
wchar_t filepath[256]; wchar_t filepath[256];
myswprintf(filepath, L"%ls/%ls.ydk", catepath, deckname); myswprintf(filepath, L"%ls/%ls.ydk", catepath, deckname);
bool res = false; bool res = false;
...@@ -475,7 +475,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -475,7 +475,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
deckManager.current_deck.main.clear(); deckManager.current_deck.main.clear();
deckManager.current_deck.extra.clear(); deckManager.current_deck.extra.clear();
deckManager.current_deck.side.clear(); deckManager.current_deck.side.clear();
res = deckManager.SaveDeck(deckManager.current_deck, filepath); res = DeckManager::SaveDeck(deckManager.current_deck, filepath);
RefreshDeckList(); RefreshDeckList();
ChangeCategory(mainGame->lstCategories->getSelected()); ChangeCategory(mainGame->lstCategories->getSelected());
} }
...@@ -532,7 +532,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -532,7 +532,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int decksel = mainGame->lstDecks->getSelected(); int decksel = mainGame->lstDecks->getSelected();
wchar_t filepath[256]; wchar_t filepath[256];
get_deck_file(filepath); get_deck_file(filepath);
if(deckManager.DeleteDeck(filepath)) { if(DeckManager::DeleteDeck(filepath)) {
mainGame->lstDecks->removeItem(decksel); mainGame->lstDecks->removeItem(decksel);
mainGame->cbDBDecks->removeItem(decksel); mainGame->cbDBDecks->removeItem(decksel);
decksel--; decksel--;
...@@ -608,7 +608,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -608,7 +608,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} }
bool res = false; bool res = false;
if(!FileSystem::IsFileExists(newfilepath)) { if(!FileSystem::IsFileExists(newfilepath)) {
res = deckManager.SaveDeck(deckManager.current_deck, newfilepath); res = DeckManager::SaveDeck(deckManager.current_deck, newfilepath);
} }
mainGame->lstCategories->setSelected(newcatename); mainGame->lstCategories->setSelected(newcatename);
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
...@@ -709,7 +709,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -709,7 +709,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->cbDBDecks->setSelected(sel); mainGame->cbDBDecks->setSelected(sel);
wchar_t filepath[256]; wchar_t filepath[256];
get_deck_file(filepath); get_deck_file(filepath);
if(deckManager.DeleteDeck(filepath)) { if(DeckManager::DeleteDeck(filepath)) {
mainGame->cbDBDecks->removeItem(sel); mainGame->cbDBDecks->removeItem(sel);
int count = mainGame->cbDBDecks->getItemCount(); int count = mainGame->cbDBDecks->getItemCount();
if(sel >= count) if(sel >= count)
...@@ -1004,7 +1004,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1004,7 +1004,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
wchar_t filepath[256]; wchar_t filepath[256];
wchar_t catepath[256]; wchar_t catepath[256];
deckManager.GetCategoryPath(catepath, mainGame->lstCategories->getSelected(), mainGame->lstCategories->getListItem(mainGame->lstCategories->getSelected())); DeckManager::GetCategoryPath(catepath, mainGame->lstCategories->getSelected(), mainGame->lstCategories->getListItem(mainGame->lstCategories->getSelected()));
myswprintf(filepath, L"%ls/%ls.ydk", catepath, mainGame->lstDecks->getListItem(decksel)); myswprintf(filepath, L"%ls/%ls.ydk", catepath, mainGame->lstDecks->getListItem(decksel));
deckManager.LoadCurrentDeck(filepath, showing_pack); deckManager.LoadCurrentDeck(filepath, showing_pack);
RefreshPackListScroll(); RefreshPackListScroll();
...@@ -1608,7 +1608,7 @@ void DeckBuilder::RefreshDeckList() { ...@@ -1608,7 +1608,7 @@ void DeckBuilder::RefreshDeckList() {
irr::gui::IGUIListBox* lstCategories = mainGame->lstCategories; irr::gui::IGUIListBox* lstCategories = mainGame->lstCategories;
irr::gui::IGUIListBox* lstDecks = mainGame->lstDecks; irr::gui::IGUIListBox* lstDecks = mainGame->lstDecks;
wchar_t catepath[256]; wchar_t catepath[256];
deckManager.GetCategoryPath(catepath, lstCategories->getSelected(), lstCategories->getListItem(lstCategories->getSelected())); DeckManager::GetCategoryPath(catepath, lstCategories->getSelected(), lstCategories->getListItem(lstCategories->getSelected()));
lstDecks->clear(); lstDecks->clear();
mainGame->RefreshDeck(catepath, [lstDecks](const wchar_t* item) { lstDecks->addItem(item); }); mainGame->RefreshDeck(catepath, [lstDecks](const wchar_t* item) { lstDecks->addItem(item); });
} }
......
...@@ -10,9 +10,10 @@ DeckManager deckManager; ...@@ -10,9 +10,10 @@ DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) { void DeckManager::LoadLFListSingle(const char* path) {
auto cur = _lfList.rend(); auto cur = _lfList.rend();
FILE* fp = std::fopen(path, "r"); FILE* fp = myfopen(path, "r");
char linebuf[256]{}; char linebuf[256]{};
wchar_t strBuffer[256]{}; wchar_t strBuffer[256]{};
char str1[16]{};
if(fp) { if(fp) {
while(std::fgets(linebuf, sizeof linebuf, fp)) { while(std::fgets(linebuf, sizeof linebuf, fp)) {
if(linebuf[0] == '#') if(linebuf[0] == '#')
...@@ -32,10 +33,11 @@ void DeckManager::LoadLFListSingle(const char* path) { ...@@ -32,10 +33,11 @@ void DeckManager::LoadLFListSingle(const char* path) {
continue; continue;
unsigned int code = 0; unsigned int code = 0;
int count = -1; int count = -1;
if (std::sscanf(linebuf, "%9u%*[ ]%9d", &code, &count) != 2) if (std::sscanf(linebuf, "%10s%*[ ]%1d", str1, &count) != 2)
continue; continue;
if (count < 0 || count > 2) if (count < 0 || count > 2)
continue; continue;
code = std::strtoul(str1, nullptr, 10);
cur->content[code] = count; cur->content[code] = count;
cur->hash = cur->hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + count)) | (code >> (5 - count))); cur->hash = cur->hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + count)) | (code >> (5 - count)));
} }
...@@ -139,13 +141,12 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r ...@@ -139,13 +141,12 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
} }
return 0; return 0;
} }
int DeckManager::LoadDeck(Deck& deck, int* 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();
int code; uint32_t errorcode = 0;
int errorcode = 0;
CardData cd; CardData cd;
for(int i = 0; i < mainc; ++i) { for(int i = 0; i < mainc; ++i) {
code = dbuf[i]; auto code = dbuf[i];
if(!dataManager.GetData(code, &cd)) { if(!dataManager.GetData(code, &cd)) {
errorcode = code; errorcode = code;
continue; continue;
...@@ -168,7 +169,7 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -168,7 +169,7 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
} }
} }
for(int i = 0; i < sidec; ++i) { for(int i = 0; i < sidec; ++i) {
code = dbuf[mainc + i]; auto code = dbuf[mainc + i];
if(!dataManager.GetData(code, &cd)) { if(!dataManager.GetData(code, &cd)) {
errorcode = code; errorcode = code;
continue; continue;
...@@ -182,22 +183,21 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -182,22 +183,21 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
} }
return errorcode; return errorcode;
} }
int DeckManager::LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_packlist) { uint32_t DeckManager::LoadDeckFromStream(Deck& deck, std::istringstream& deckStream, bool is_packlist) {
size_t ct = 0; int ct = 0;
int mainc = 0, sidec = 0, code = 0; int mainc = 0, sidec = 0;
int cardlist[PACK_MAX_SIZE]{}; uint32_t cardlist[PACK_MAX_SIZE]{};
bool is_side = false; bool is_side = false;
std::string linebuf; std::string linebuf;
while (std::getline(deckStream, linebuf, '\n') && ct < (sizeof cardlist / sizeof cardlist[0])) { while (std::getline(deckStream, linebuf, '\n') && ct < PACK_MAX_SIZE) {
if (linebuf[0] == '!') { if (linebuf[0] == '!') {
is_side = true; is_side = true;
continue; continue;
} }
if (linebuf[0] < '0' || linebuf[0] > '9') if (linebuf[0] < '0' || linebuf[0] > '9')
continue; continue;
errno = 0; auto code = std::strtoul(linebuf.c_str(), nullptr, 10);
code = std::strtol(linebuf.c_str(), nullptr, 10); if (code >= UINT32_MAX)
if (errno == ERANGE)
continue; continue;
cardlist[ct++] = code; cardlist[ct++] = code;
if (is_side) if (is_side)
...@@ -207,25 +207,25 @@ int DeckManager::LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_pa ...@@ -207,25 +207,25 @@ int DeckManager::LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_pa
} }
return LoadDeck(deck, cardlist, mainc, sidec, is_packlist); return LoadDeck(deck, cardlist, mainc, sidec, is_packlist);
} }
bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) { bool DeckManager::LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec) {
std::unordered_map<int, int> pcount; std::unordered_map<uint32_t, int> pcount;
std::unordered_map<int, int> ncount; std::unordered_map<uint32_t, int> ncount;
for(size_t i = 0; i < deck.main.size(); ++i) for(size_t i = 0; i < deck.main.size(); ++i)
++pcount[deck.main[i]->first]; pcount[deck.main[i]->first]++;
for(size_t i = 0; i < deck.extra.size(); ++i) for(size_t i = 0; i < deck.extra.size(); ++i)
++pcount[deck.extra[i]->first]; pcount[deck.extra[i]->first]++;
for(size_t i = 0; i < deck.side.size(); ++i) for(size_t i = 0; i < deck.side.size(); ++i)
++pcount[deck.side[i]->first]; pcount[deck.side[i]->first]++;
Deck ndeck; Deck ndeck;
LoadDeck(ndeck, dbuf, mainc, sidec); LoadDeck(ndeck, dbuf, mainc, sidec);
if (ndeck.main.size() != deck.main.size() || ndeck.extra.size() != deck.extra.size() || ndeck.side.size() != deck.side.size()) if (ndeck.main.size() != deck.main.size() || ndeck.extra.size() != deck.extra.size() || ndeck.side.size() != deck.side.size())
return false; return false;
for(size_t i = 0; i < ndeck.main.size(); ++i) for(size_t i = 0; i < ndeck.main.size(); ++i)
++ncount[ndeck.main[i]->first]; ncount[ndeck.main[i]->first]++;
for(size_t i = 0; i < ndeck.extra.size(); ++i) for(size_t i = 0; i < ndeck.extra.size(); ++i)
++ncount[ndeck.extra[i]->first]; ncount[ndeck.extra[i]->first]++;
for(size_t i = 0; i < ndeck.side.size(); ++i) for(size_t i = 0; i < ndeck.side.size(); ++i)
++ncount[ndeck.side[i]->first]; ncount[ndeck.side[i]->first]++;
for (auto& cdit : ncount) for (auto& cdit : ncount)
if (cdit.second != pcount[cdit.first]) if (cdit.second != pcount[cdit.first])
return false; return false;
...@@ -299,8 +299,8 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) { ...@@ -299,8 +299,8 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) {
return false; return false;
} }
std::istringstream deckStream(deckBuffer); std::istringstream deckStream(deckBuffer);
LoadDeck(current_deck, deckStream, is_packlist); LoadDeckFromStream(current_deck, deckStream, is_packlist);
return true; // the above LoadDeck has return value but we ignore it here for now return true; // the above function has return value but we ignore it here for now
} }
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];
...@@ -330,15 +330,7 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) { ...@@ -330,15 +330,7 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) {
return true; return true;
} }
bool DeckManager::DeleteDeck(const wchar_t* file) { bool DeckManager::DeleteDeck(const wchar_t* file) {
#ifdef _WIN32 return FileSystem::RemoveFile(file);
BOOL result = DeleteFileW(file);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(file, filefn);
int result = unlink(filefn);
return result == 0;
#endif
} }
bool DeckManager::CreateCategory(const wchar_t* name) { bool DeckManager::CreateCategory(const wchar_t* name) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
......
...@@ -47,21 +47,22 @@ public: ...@@ -47,21 +47,22 @@ public:
const wchar_t* GetLFListName(unsigned int lfhash); const wchar_t* GetLFListName(unsigned int lfhash);
const LFList* GetLFList(unsigned int lfhash); const LFList* GetLFList(unsigned int lfhash);
unsigned int CheckDeck(const Deck& deck, unsigned int lfhash, int rule); unsigned int CheckDeck(const Deck& deck, unsigned int lfhash, int rule);
int LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_packlist = false);
int LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_packlist = false);
bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec);
void GetCategoryPath(wchar_t* ret, int index, const wchar_t* text);
void GetDeckFile(wchar_t* ret, int category_index, const wchar_t* category_name, const wchar_t* deckname);
FILE* OpenDeckFile(const wchar_t* file, const char* mode);
irr::io::IReadFile* OpenDeckReader(const wchar_t* file);
bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false); bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false);
bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname); bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname);
bool SaveDeck(Deck& deck, const wchar_t* file);
bool DeleteDeck(const wchar_t* file);
bool CreateCategory(const wchar_t* name);
bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
bool DeleteCategory(const wchar_t* name);
bool SaveDeckBuffer(const int deckbuf[], const wchar_t* name); bool SaveDeckBuffer(const int deckbuf[], const wchar_t* name);
static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false);
static uint32_t LoadDeckFromStream(Deck& deck, std::istringstream& deckStream, bool is_packlist = false);
static bool LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec);
static void GetCategoryPath(wchar_t* ret, int index, const wchar_t* text);
static void GetDeckFile(wchar_t* ret, int category_index, const wchar_t* category_name, const wchar_t* deckname);
static FILE* OpenDeckFile(const wchar_t* file, const char* mode);
static irr::io::IReadFile* OpenDeckReader(const wchar_t* file);
static bool SaveDeck(Deck& deck, const wchar_t* file);
static bool DeleteDeck(const wchar_t* file);
static bool CreateCategory(const wchar_t* name);
static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
static bool DeleteCategory(const wchar_t* name);
}; };
extern DeckManager deckManager; extern DeckManager deckManager;
......
...@@ -158,7 +158,7 @@ bool Game::Initialize() { ...@@ -158,7 +158,7 @@ bool Game::Initialize() {
} }
}); });
if(fpath[0] == 0) { if(fpath[0] == 0) {
ErrorLog("Failed to load font(s)!"); ErrorLog("No fonts found! Please manually edit system.conf or place appropriate font file in the fonts directory.");
return false; return false;
} }
if(!numFont) { if(!numFont) {
...@@ -170,6 +170,10 @@ bool Game::Initialize() { ...@@ -170,6 +170,10 @@ bool Game::Initialize() {
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
} }
} }
if(!numFont || !textFont) {
ErrorLog("Failed to load font(s)!");
return false;
}
adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12); adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12);
lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48); lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48);
guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
...@@ -1226,7 +1230,7 @@ void Game::RefreshDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBo ...@@ -1226,7 +1230,7 @@ void Game::RefreshDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBo
return; return;
} }
wchar_t catepath[256]; wchar_t catepath[256];
deckManager.GetCategoryPath(catepath, cbCategory->getSelected(), cbCategory->getText()); DeckManager::GetCategoryPath(catepath, cbCategory->getSelected(), cbCategory->getText());
cbDeck->clear(); cbDeck->clear();
RefreshDeck(catepath, [cbDeck](const wchar_t* item) { cbDeck->addItem(item); }); RefreshDeck(catepath, [cbDeck](const wchar_t* item) { cbDeck->addItem(item); });
} }
...@@ -1267,7 +1271,7 @@ void Game::RefreshBot() { ...@@ -1267,7 +1271,7 @@ void Game::RefreshBot() {
if(!gameConf.enable_bot_mode) if(!gameConf.enable_bot_mode)
return; return;
botInfo.clear(); botInfo.clear();
FILE* fp = std::fopen("bot.conf", "r"); FILE* fp = myfopen("bot.conf", "r");
char linebuf[256]{}; char linebuf[256]{};
char strbuf[256]{}; char strbuf[256]{};
if(fp) { if(fp) {
...@@ -1320,7 +1324,7 @@ void Game::RefreshBot() { ...@@ -1320,7 +1324,7 @@ void Game::RefreshBot() {
} }
} }
void Game::LoadConfig() { void Game::LoadConfig() {
FILE* fp = std::fopen("system.conf", "r"); FILE* fp = myfopen("system.conf", "r");
if(!fp) if(!fp)
return; return;
char linebuf[CONFIG_LINE_SIZE]{}; char linebuf[CONFIG_LINE_SIZE]{};
...@@ -1458,7 +1462,7 @@ void Game::LoadConfig() { ...@@ -1458,7 +1462,7 @@ void Game::LoadConfig() {
std::fclose(fp); std::fclose(fp);
} }
void Game::SaveConfig() { void Game::SaveConfig() {
FILE* fp = std::fopen("system.conf", "w"); FILE* fp = myfopen("system.conf", "w");
std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n"); std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n");
char linebuf[CONFIG_LINE_SIZE]; char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0); std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
...@@ -1711,7 +1715,7 @@ void Game::AddDebugMsg(const char* msg) { ...@@ -1711,7 +1715,7 @@ void Game::AddDebugMsg(const char* msg) {
} }
} }
void Game::ErrorLog(const char* msg) { void Game::ErrorLog(const char* msg) {
FILE* fp = std::fopen("error.log", "a"); FILE* fp = myfopen("error.log", "a");
if(!fp) if(!fp)
return; return;
time_t nowtime = std::time(nullptr); time_t nowtime = std::time(nullptr);
......
...@@ -23,8 +23,12 @@ void ClickButton(irr::gui::IGUIElement* btn) { ...@@ -23,8 +23,12 @@ void ClickButton(irr::gui::IGUIElement* btn) {
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
#ifndef _WIN32 #if defined(FOPEN_WINDOWS_SUPPORT_UTF8)
std::setlocale(LC_CTYPE, "UTF-8"); std::setlocale(LC_CTYPE, ".UTF-8");
#elif defined(__APPLE__)
std::setlocale(LC_CTYPE, "C.UTF-8");
#elif !defined(_WIN32)
std::setlocale(LC_CTYPE, "");
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
......
...@@ -367,7 +367,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -367,7 +367,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t arg1[512]; wchar_t arg1[512];
if(mainGame->botInfo[sel].select_deckfile) { if(mainGame->botInfo[sel].select_deckfile) {
wchar_t botdeck[256]; wchar_t botdeck[256];
deckManager.GetDeckFile(botdeck, mainGame->cbBotDeckCategory->getSelected(), mainGame->cbBotDeckCategory->getText(), mainGame->cbBotDeck->getText()); DeckManager::GetDeckFile(botdeck, mainGame->cbBotDeckCategory->getSelected(), mainGame->cbBotDeckCategory->getText(), mainGame->cbBotDeck->getText());
myswprintf(arg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, botdeck); myswprintf(arg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, botdeck);
} }
else else
...@@ -386,7 +386,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -386,7 +386,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t warg1[512]; wchar_t warg1[512];
if(mainGame->botInfo[sel].select_deckfile) { if(mainGame->botInfo[sel].select_deckfile) {
wchar_t botdeck[256]; wchar_t botdeck[256];
deckManager.GetDeckFile(botdeck, mainGame->cbBotDeckCategory->getSelected(), mainGame->cbBotDeckCategory->getText(), mainGame->cbBotDeck->getText()); DeckManager::GetDeckFile(botdeck, mainGame->cbBotDeckCategory->getSelected(), mainGame->cbBotDeckCategory->getText(), mainGame->cbBotDeck->getText());
myswprintf(warg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, botdeck); myswprintf(warg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, botdeck);
} }
else else
......
...@@ -86,6 +86,14 @@ public: ...@@ -86,6 +86,14 @@ public:
return DeleteDir(wdir); return DeleteDir(wdir);
} }
static bool RemoveFile(const wchar_t* wfile) {
return DeleteFileW(wfile);
}
static bool RemoveFile(const char* file) {
return DeleteFileA(file);
}
static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) { static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) {
wchar_t findstr[1024]; wchar_t findstr[1024];
std::swprintf(findstr, sizeof findstr / sizeof findstr[0], L"%ls/*", wpath); std::swprintf(findstr, sizeof findstr / sizeof findstr[0], L"%ls/*", wpath);
...@@ -195,6 +203,16 @@ public: ...@@ -195,6 +203,16 @@ public:
return success; return success;
} }
static bool RemoveFile(const wchar_t* wfile) {
char file[1024];
BufferIO::EncodeUTF8(wfile, file);
return RemoveFile(file);
}
static bool RemoveFile(const char* file) {
return unlink(file) == 0;
}
struct file_unit { struct file_unit {
std::string filename; std::string filename;
bool is_dir; bool is_dir;
......
...@@ -27,7 +27,7 @@ struct HostInfo { ...@@ -27,7 +27,7 @@ struct HostInfo {
uint8_t no_shuffle_deck{}; uint8_t no_shuffle_deck{};
// byte padding[3] // byte padding[3]
uint32_t start_lp{}; int32_t start_lp{};
uint8_t start_hand{}; uint8_t start_hand{};
uint8_t draw_count{}; uint8_t draw_count{};
uint16_t time_limit{}; uint16_t time_limit{};
...@@ -57,7 +57,7 @@ static_assert(sizeof(HostRequest) == 2, "size mismatch: HostRequest"); ...@@ -57,7 +57,7 @@ static_assert(sizeof(HostRequest) == 2, "size mismatch: HostRequest");
struct CTOS_DeckData { struct CTOS_DeckData {
int32_t mainc{}; int32_t mainc{};
int32_t sidec{}; int32_t sidec{};
int32_t list[MAINC_MAX + SIDEC_MAX]{}; uint32_t list[MAINC_MAX + SIDEC_MAX]{};
}; };
check_trivially_copyable(CTOS_DeckData); check_trivially_copyable(CTOS_DeckData);
......
...@@ -24,7 +24,7 @@ void Replay::BeginRecord() { ...@@ -24,7 +24,7 @@ void Replay::BeginRecord() {
#else #else
if(is_recording) if(is_recording)
std::fclose(fp); std::fclose(fp);
fp = std::fopen("./replay/_LastReplay.yrp", "wb"); fp = myfopen("./replay/_LastReplay.yrp", "wb");
if(!fp) if(!fp)
return; return;
#endif #endif
...@@ -154,15 +154,7 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -154,15 +154,7 @@ bool Replay::CheckReplay(const wchar_t* name) {
bool Replay::DeleteReplay(const wchar_t* name) { bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name); myswprintf(fname, L"./replay/%ls", name);
#ifdef _WIN32 return FileSystem::RemoveFile(fname);
BOOL result = DeleteFileW(fname);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(fname, filefn);
int result = unlink(filefn);
return result == 0;
#endif
} }
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 oldfname[256];
......
...@@ -17,13 +17,13 @@ constexpr int MAX_REPLAY_SIZE = 0x20000; ...@@ -17,13 +17,13 @@ constexpr int MAX_REPLAY_SIZE = 0x20000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
struct ReplayHeader { struct ReplayHeader {
unsigned int id{}; uint32_t id{};
unsigned int version{}; uint32_t version{};
unsigned int flag{}; uint32_t flag{};
unsigned int seed{}; uint32_t seed{};
unsigned int datasize{}; uint32_t datasize{};
unsigned int start_time{}; uint32_t start_time{};
unsigned char props[8]{}; uint8_t props[8]{};
}; };
class Replay { class Replay {
......
...@@ -297,9 +297,9 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -297,9 +297,9 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
return; return;
} }
if(duel_count == 0) { if(duel_count == 0) {
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec); deck_error[dp->type] = DeckManager::LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec);
} else { } else {
if(deckManager.LoadSide(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec)) { if(DeckManager::LoadSide(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec)) {
ready[dp->type] = true; ready[dp->type] = true;
NetServer::SendPacketToPlayer(dp, STOC_DUEL_START); NetServer::SendPacketToPlayer(dp, STOC_DUEL_START);
if(ready[0] && ready[1]) { if(ready[0] && ready[1]) {
......
...@@ -279,7 +279,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -279,7 +279,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec); deck_error[dp->type] = DeckManager::LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec);
} }
void TagDuel::StartDuel(DuelPlayer* dp) { void TagDuel::StartDuel(DuelPlayer* dp) {
if(dp != host_player) if(dp != host_player)
......
#[2025.1][2024.12 TCG][2024.10][2024.7][2024.4][2024.1][2023.10][2023.7][2023.4][2023.1][2022.10][2022.7][2022.4][2022.1][2021.10][2021.7][2021.4][2021.1][2020.10][2020.7][2020.4][2020.1][2019.10][2019.7][2019.4][2019.1][2018.10][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2024.9 TCG][2024.4 TCG][2024.1 TCG][2023.9 TCG][2023.6 TCG][2023.2 TCG][2022.12 TCG][2022.10 TCG][2022.5 TCG][2022.2 TCG][2021.10 TCG][2021.7 TCG][2021.3 TCG][2020.12 TCG][2020.9 TCG][2020.6 TCG][2020.4 TCG][2020.1 TCG][2019.10 TCG][2019.7 TCG][2019.4 TCG][2019.1 TCG][2018.12 TCG][2018.9 TCG][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1] #[2025.4][2024.12 TCG][2025.1][2024.10][2024.7][2024.4][2024.1][2023.10][2023.7][2023.4][2023.1][2022.10][2022.7][2022.4][2022.1][2021.10][2021.7][2021.4][2021.1][2020.10][2020.7][2020.4][2020.1][2019.10][2019.7][2019.4][2019.1][2018.10][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2024.9 TCG][2024.4 TCG][2024.1 TCG][2023.9 TCG][2023.6 TCG][2023.2 TCG][2022.12 TCG][2022.10 TCG][2022.5 TCG][2022.2 TCG][2021.10 TCG][2021.7 TCG][2021.3 TCG][2020.12 TCG][2020.9 TCG][2020.6 TCG][2020.4 TCG][2020.1 TCG][2019.10 TCG][2019.7 TCG][2019.4 TCG][2019.1 TCG][2018.12 TCG][2018.9 TCG][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1]
!2025.1 !2025.4
#forbidden #forbidden
20292186 0 --アーティファクト-デスサイズ
91869203 0 --アマゾネスの射手 91869203 0 --アマゾネスの射手
20663556 0 --イレカエル 20663556 0 --イレカエル
44910027 0 --ヴィクトリー・ドラゴン 44910027 0 --ヴィクトリー・ドラゴン
...@@ -79,6 +80,7 @@ ...@@ -79,6 +80,7 @@
05851097 0 --虚無空間 05851097 0 --虚無空間
93016201 0 --王宮の弾圧 93016201 0 --王宮の弾圧
61740673 0 --王宮の勅命 61740673 0 --王宮の勅命
23516703 0 --サモンリミッター
03280747 0 --第六感 03280747 0 --第六感
64697231 0 --ダスト・シュート 64697231 0 --ダスト・シュート
80604091 0 --血の代償 80604091 0 --血の代償
...@@ -86,14 +88,12 @@ ...@@ -86,14 +88,12 @@
17178486 0 --ライフチェンジャー 17178486 0 --ライフチェンジャー
28566710 0 --ラストバトル! 28566710 0 --ラストバトル!
#limit #limit
20292186 1 --アーティファクト-デスサイズ
76794549 1 --アストログラフ・マジシャン 76794549 1 --アストログラフ・マジシャン
34022970 1 --エクス・ライゼオル 34022970 1 --エクス・ライゼオル
29301450 1 --SPリトルナイト 29301450 1 --SPリトルナイト
68304193 1 --クシャトリラ・ユニコーン 68304193 1 --クシャトリラ・ユニコーン
72270339 1 --黒魔女ディアベルスター 72270339 1 --黒魔女ディアベルスター
99937011 1 --剣神官ムドラ 99937011 1 --剣神官ムドラ
34124316 1 --サイバーポッド
38814750 1 --PSYフレームギア・γ 38814750 1 --PSYフレームギア・γ
74586817 1 --PSYフレームロード・Ω 74586817 1 --PSYフレームロード・Ω
32731036 1 --深淵の獣ルベリオン 32731036 1 --深淵の獣ルベリオン
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
90241276 1 --蛇眼の炎燐 90241276 1 --蛇眼の炎燐
13533678 1 --スプライト・ジェット 13533678 1 --スプライト・ジェット
76145933 1 --スプライト・ブルー 76145933 1 --スプライト・ブルー
35844557 1 --ソード・ライゼオル
90361010 1 --超重武者装留イワトオシ 90361010 1 --超重武者装留イワトオシ
37818794 1 --超魔導竜騎士-ドラグーン・オブ・レッドアイズ 37818794 1 --超魔導竜騎士-ドラグーン・オブ・レッドアイズ
04928565 1 --ティアラメンツ・クシャトリラ 04928565 1 --ティアラメンツ・クシャトリラ
...@@ -113,6 +114,7 @@ ...@@ -113,6 +114,7 @@
37961969 1 --ティアラメンツ・ハゥフニス 37961969 1 --ティアラメンツ・ハゥフニス
74078255 1 --ティアラメンツ・メイルゥ 74078255 1 --ティアラメンツ・メイルゥ
73956664 1 --ティアラメンツ・レイノハート 73956664 1 --ティアラメンツ・レイノハート
91800273 1 --ディメンション・アトラクター
90953320 1 --TG ハイパー・ライブラリアン 90953320 1 --TG ハイパー・ライブラリアン
91810826 1 --天盃龍チュンドラ 91810826 1 --天盃龍チュンドラ
75433814 1 --No.40 ギミック・パペット-ヘブンズ・ストリングス 75433814 1 --No.40 ギミック・パペット-ヘブンズ・ストリングス
...@@ -128,6 +130,7 @@ ...@@ -128,6 +130,7 @@
70903634 1 --封印されし者の右腕 70903634 1 --封印されし者の右腕
94689206 1 --ブロックドラゴン 94689206 1 --ブロックドラゴン
24094258 1 --ヘビーメタルフォーゼ・エレクトラム 24094258 1 --ヘビーメタルフォーゼ・エレクトラム
32061192 1 --MLICEPDormouse
60764609 1 --魔を刻むデモンスミス 60764609 1 --魔を刻むデモンスミス
77103950 1 --壱世壊=ペルレイノ 77103950 1 --壱世壊=ペルレイノ
33782437 1 --一時休戦 33782437 1 --一時休戦
...@@ -142,13 +145,14 @@ ...@@ -142,13 +145,14 @@
30336082 1 --盃満ちる燦幻荘 30336082 1 --盃満ちる燦幻荘
83764718 1 --死者蘇生 83764718 1 --死者蘇生
15443125 1 --スプライト・スターター 15443125 1 --スプライト・スターター
07477101 1 --時空の七皇
52340444 1 --閃刀機-ホーネットビット 52340444 1 --閃刀機-ホーネットビット
32807846 1 --増援 32807846 1 --増援
72892473 1 --手札抹殺 72892473 1 --手札抹殺
98567237 1 --刻まれし魔の詠聖 98567237 1 --刻まれし魔の詠聖
73628505 1 --テラ・フォーミング 73628505 1 --テラ・フォーミング
11110587 1 --隣の芝刈り
18144506 1 --ハーピィの羽根帚 18144506 1 --ハーピィの羽根帚
21347668 1 --ピュアリィ・スリーピィメモリー
75500286 1 --封印の黄金櫃 75500286 1 --封印の黄金櫃
07394770 1 --ブリリアント・フュージョン 07394770 1 --ブリリアント・フュージョン
73468603 1 --盆回し 73468603 1 --盆回し
...@@ -162,32 +166,23 @@ ...@@ -162,32 +166,23 @@
02295440 1 --ワン・フォー・ワン 02295440 1 --ワン・フォー・ワン
90846359 1 --群雄割拠 90846359 1 --群雄割拠
53334471 1 --御前試合 53334471 1 --御前試合
23516703 1 --サモンリミッター
82732705 1 --スキルドレイン 82732705 1 --スキルドレイン
24207889 1 --センサー万別 24207889 1 --センサー万別
21076084 1 --トリックスター・リンカーネイション 21076084 1 --トリックスター・リンカーネイション
23002292 1 --レッド・リブート 23002292 1 --レッド・リブート
#semi limit #semi limit
02526224 2 --炎王神獣 キリン 34124316 2 --サイバーポッド
17330916 2 --EMモンキーボード
12289247 2 --クロノグラフ・マジシャン
21377582 2 --真竜剣皇マスターP
81275020 2 --SRベイゴマックス 81275020 2 --SRベイゴマックス
23434538 2 --増殖するG 23434538 2 --増殖するG
91800273 2 --ディメンション・アトラクター
33508719 2 --メタモルポット
65734501 2 --RACEエアホイスター 65734501 2 --RACEエアホイスター
35726888 2 --おろかな副葬 35726888 2 --おろかな副葬
67723438 2 --緊急テレポート 67723438 2 --緊急テレポート
45986603 2 --強奪
49238328 2 --強欲で金満な壺 49238328 2 --強欲で金満な壺
35261759 2 --強欲で貪欲な壺 35261759 2 --強欲で貪欲な壺
46060017 2 --十二獣の会局
07477101 2 --時空の七皇
48130397 2 --超融合 48130397 2 --超融合
11110587 2 --隣の芝刈り
93729896 2 --ナイトメア・スローン 93729896 2 --ナイトメア・スローン
24224830 2 --墓穴の指名者 24224830 2 --墓穴の指名者
21347668 2 --ピュアリィ・スリーピィメモリー
52947044 2 --フュージョン・デステニー 52947044 2 --フュージョン・デステニー
92714517 2 --ビッグウェルカム・ラビュリンス 92714517 2 --ビッグウェルカム・ラビュリンス
...@@ -392,6 +387,198 @@ ...@@ -392,6 +387,198 @@
21347668 2 --Purrely Sleepy Memory 21347668 2 --Purrely Sleepy Memory
92107604 2 --Runick Fountain 92107604 2 --Runick Fountain
!2025.1
#forbidden
91869203 0 --アマゾネスの射手
20663556 0 --イレカエル
44910027 0 --ヴィクトリー・ドラゴン
27552504 0 --永遠の淑女 ベアトリーチェ
51858306 0 --エクリプス・ワイバーン
62242678 0 --琰魔竜王 レッド・デーモン・カラミティ
34945480 0 --外神アザトート
95727991 0 --カタパルト・タートル
08903700 0 --儀式魔人リリーサー
11384280 0 --キャノン・ソルジャー
17412721 0 --旧神ノーデン
32909498 0 --クシャトリラ・フェンリル
50588353 0 --水晶機巧-ハリファイバー
62320425 0 --古衛兵アギド
25926710 0 --古尖兵ケルベク
03040496 0 --混沌魔龍 カオス・ルーラー
02563463 0 --流離のグリフォンライダー
88071625 0 --The tyrant NEPTUNE
52653092 0 --SNo.0 ホープ・ゼアル
85115440 0 --十二獣ブルホーン
59537380 0 --守護竜アガーペイン
86148577 0 --守護竜エルピィ
21044178 0 --深淵に潜む者
88581108 0 --真竜皇V.F.D.
27381364 0 --スプライト・エルフ
16923472 0 --ゼンマイハンター
15341821 0 --ダンディライオン
77679716 0 --超重武者装留ブレイク・アーマー
92731385 0 --ティアラメンツ・キトカロス
69015963 0 --デビル・フランケン
79875176 0 --トゥーン・キャノン・ソルジャー
75732622 0 --トーチ・ゴーレム
22593417 0 --トポロジック・ガンブラー・ドラゴン
39064822 0 --トロイメア・ゴブリン
03679218 0 --トロイメア・マーメイド
54719828 0 --No.16 色の支配者ショック・ルーラー
63504681 0 --No.86 HC ロンゴミアント
58820923 0 --No.95 ギャラクシーアイズ・ダークマター・ドラゴン
78706415 0 --ファイバーポッド
93369354 0 --フィッシュボーグ-ガンナー
23558733 0 --フェニキシアン・クラスター・アマリリス
09929398 0 --BF-朧影のゴウフウ
70369116 0 --捕食植物ヴェルテ・アナコンダ
63101919 0 --マジックテンペスター
34206604 0 --魔導サイエンティスト
14702066 0 --メガキャノン・ソルジャー
96782886 0 --メンタルマスター
90809975 0 --餅カエル
83152482 0 --ユニオン・キャリアー
34086406 0 --ラヴァルバル・チェイン
85243784 0 --リンクロス
73356503 0 --烈風の結界像
57421866 0 --レベル・スティーラー
41482598 0 --悪夢の蜃気楼
44763025 0 --いたずら好きな双子悪魔
17375316 0 --押収
35059553 0 --カイザーコロシアム
74191942 0 --苦渋の選択
42829885 0 --強引な番兵
55144522 0 --強欲な壺
23557835 0 --次元融合
31423101 0 --神剣-フェニックスブレード
57953380 0 --生還の宝札
54447022 0 --ソウル・チャージ
60682203 0 --大寒波
69243953 0 --蝶の短剣-エルマ
79571449 0 --天使の施し
63789924 0 --盗人の煙玉
70828912 0 --早すぎた埋葬
42703248 0 --ハリケーン
76375976 0 --魔鍾洞
34906152 0 --マスドライバー
46411259 0 --突然変異
85602018 0 --遺言状
27174286 0 --異次元からの帰還
05851097 0 --虚無空間
93016201 0 --王宮の弾圧
61740673 0 --王宮の勅命
03280747 0 --第六感
64697231 0 --ダスト・シュート
80604091 0 --血の代償
32723153 0 --マジカル・エクスプロージョン
17178486 0 --ライフチェンジャー
28566710 0 --ラストバトル!
#limit
20292186 1 --アーティファクト-デスサイズ
76794549 1 --アストログラフ・マジシャン
34022970 1 --エクス・ライゼオル
29301450 1 --SPリトルナイト
68304193 1 --クシャトリラ・ユニコーン
72270339 1 --黒魔女ディアベルスター
99937011 1 --剣神官ムドラ
34124316 1 --サイバーポッド
38814750 1 --PSYフレームギア・γ
74586817 1 --PSYフレームロード・Ω
32731036 1 --深淵の獣ルベリオン
36521307 1 --斬機サーキュラー
48905153 1 --十二獣ドランシア
78872731 1 --十二獣モルモラット
06602300 1 --重爆撃禽 ボム・フェネクス
63542003 1 --宿神像ケルドウ
09674034 1 --スネークアイ・エクセル
90241276 1 --蛇眼の炎燐
13533678 1 --スプライト・ジェット
76145933 1 --スプライト・ブルー
90361010 1 --超重武者装留イワトオシ
37818794 1 --超魔導竜騎士-ドラグーン・オブ・レッドアイズ
04928565 1 --ティアラメンツ・クシャトリラ
00572850 1 --ティアラメンツ・シェイレーン
37961969 1 --ティアラメンツ・ハゥフニス
74078255 1 --ティアラメンツ・メイルゥ
73956664 1 --ティアラメンツ・レイノハート
90953320 1 --TG ハイパー・ライブラリアン
91810826 1 --天盃龍チュンドラ
75433814 1 --No.40 ギミック・パペット-ヘブンズ・ストリングス
17266660 1 --朱光の宣告者
06637331 1 --深淵の獣ドルイドヴルム
72656408 1 --深淵の獣バルドレイク
33854624 1 --深淵の獣マグナムート
80453041 1 --ファントム・オブ・ユベル
33396948 1 --封印されしエクゾディア
44519536 1 --封印されし者の左足
07902349 1 --封印されし者の左腕
08124921 1 --封印されし者の右足
70903634 1 --封印されし者の右腕
94689206 1 --ブロックドラゴン
24094258 1 --ヘビーメタルフォーゼ・エレクトラム
60764609 1 --魔を刻むデモンスミス
77103950 1 --壱世壊=ペルレイノ
33782437 1 --一時休戦
01845204 1 --簡易融合
61292243 1 --EMERGENCY
19613556 1 --大嵐
81439173 1 --おろかな埋葬
85106525 1 --篝火
84211599 1 --金満で謙虚な壺
23701465 1 --原初の種
80845034 1 --“罪宝狩りの悪魔”
30336082 1 --盃満ちる燦幻荘
83764718 1 --死者蘇生
15443125 1 --スプライト・スターター
52340444 1 --閃刀機-ホーネットビット
32807846 1 --増援
72892473 1 --手札抹殺
98567237 1 --刻まれし魔の詠聖
73628505 1 --テラ・フォーミング
18144506 1 --ハーピィの羽根帚
21347668 1 --ピュアリィ・スリーピィメモリー
75500286 1 --封印の黄金櫃
07394770 1 --ブリリアント・フュージョン
73468603 1 --盆回し
93600443 1 --マスク・チェンジ・セカンド
65681983 1 --抹殺の指名者
71832012 1 --六世壊=パライゾス
01475311 1 --闇の誘惑
44362883 1 --烙印融合
92107604 1 --神碑の泉
27970830 1 --六武の門
02295440 1 --ワン・フォー・ワン
90846359 1 --群雄割拠
53334471 1 --御前試合
23516703 1 --サモンリミッター
82732705 1 --スキルドレイン
24207889 1 --センサー万別
21076084 1 --トリックスター・リンカーネイション
23002292 1 --レッド・リブート
#semi limit
02526224 2 --炎王神獣 キリン
17330916 2 --EMモンキーボード
12289247 2 --クロノグラフ・マジシャン
21377582 2 --真竜剣皇マスターP
81275020 2 --SRベイゴマックス
23434538 2 --増殖するG
91800273 2 --ディメンション・アトラクター
33508719 2 --メタモルポット
65734501 2 --RACEエアホイスター
35726888 2 --おろかな副葬
67723438 2 --緊急テレポート
45986603 2 --強奪
49238328 2 --強欲で金満な壺
35261759 2 --強欲で貪欲な壺
46060017 2 --十二獣の会局
07477101 2 --時空の七皇
48130397 2 --超融合
11110587 2 --隣の芝刈り
93729896 2 --ナイトメア・スローン
24224830 2 --墓穴の指名者
52947044 2 --フュージョン・デステニー
92714517 2 --ビッグウェルカム・ラビュリンス
!2024.10 !2024.10
#forbidden #forbidden
91869203 0 --アマゾネスの射手 91869203 0 --アマゾネスの射手
......
...@@ -1251,3 +1251,6 @@ ...@@ -1251,3 +1251,6 @@
!setname 0x1c6 统王 ドミナス !setname 0x1c6 统王 ドミナス
!setname 0x1c7 塞勒凯特 Serket !setname 0x1c7 塞勒凯特 Serket
!setname 0x1c8 阿匹卜 Apophis !setname 0x1c8 阿匹卜 Apophis
!setname 0x1c9 星辰 ドラゴンテイル
!setname 0x1ca 味美喵 ヤミー
!setname 0x1cb K9
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