Commit 4d045555 authored by nanahira's avatar nanahira

read lflist in ypk

parent 64a6b8ee
Pipeline #37523 failed with stages
in 9 minutes and 1 second
......@@ -9,44 +9,41 @@ namespace ygo {
char DeckManager::deckBuffer[0x10000]{};
DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) {
auto cur = _lfList.rend();
void DeckManager::LoadLFListSingle(const char* path, bool insert) {
FILE* fp = myfopen(path, "r");
char linebuf[256]{};
wchar_t strBuffer[256]{};
char str1[16]{};
if(fp) {
while(std::fgets(linebuf, sizeof linebuf, fp)) {
if(linebuf[0] == '#')
continue;
if(linebuf[0] == '!') {
auto len = std::strcspn(linebuf, "\r\n");
linebuf[len] = 0;
BufferIO::DecodeUTF8(&linebuf[1], strBuffer);
LFList newlist;
newlist.listName = strBuffer;
newlist.hash = 0x7dfcee6a;
_lfList.push_back(newlist);
cur = _lfList.rbegin();
continue;
}
if (cur == _lfList.rend())
continue;
unsigned int code = 0;
int count = -1;
if (std::sscanf(linebuf, "%10s%*[ ]%1d", str1, &count) != 2)
continue;
if (count < 0 || count > 2)
continue;
code = std::strtoul(str1, nullptr, 10);
cur->content[code] = count;
cur->hash = cur->hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + count)) | (code >> (5 - count)));
}
if (!fp) return;
_LoadLFListFromLineProvider([&](char* buf, size_t sz) {
return std::fgets(buf, sz, fp) != nullptr;
}, insert);
std::fclose(fp);
}
void DeckManager::LoadLFListSingle(const wchar_t* path, bool insert) {
FILE* fp = mywfopen(path, "r");
if (!fp) return;
_LoadLFListFromLineProvider([&](char* buf, size_t sz) {
return std::fgets(buf, sz, fp) != nullptr;
}, insert);
std::fclose(fp);
}
void DeckManager::LoadLFListSingle(irr::io::IReadFile* reader, bool insert) {
std::string linebuf;
char ch{};
_LoadLFListFromLineProvider([&](char* buf, size_t sz) {
while (reader->read(&ch, 1)) {
if (ch == '\0') break;
linebuf.push_back(ch);
if (ch == '\n' || linebuf.size() >= sz - 1) {
std::strncpy(buf, linebuf.c_str(), sz - 1);
buf[sz - 1] = '\0';
linebuf.clear();
return true;
}
}
return false;
}, insert);
reader->drop();
}
void DeckManager::LoadLFList() {
LoadLFListSingle("expansions/lflist.conf");
LoadLFListSingle("specials/lflist.conf");
LoadLFListSingle("lflist.conf");
LFList nolimit;
......
......@@ -5,6 +5,7 @@
#include <vector>
#include <sstream>
#include "data_manager.h"
#include "bufferio.h"
#ifndef YGOPRO_MAX_DECK
#define YGOPRO_MAX_DECK 60
......@@ -64,7 +65,9 @@ public:
static char deckBuffer[0x10000];
void LoadLFListSingle(const char* path);
void LoadLFListSingle(const char* path, bool insert = false);
void LoadLFListSingle(const wchar_t* path, bool insert = false);
void LoadLFListSingle(irr::io::IReadFile* reader, bool insert = false);
void LoadLFList();
const wchar_t* GetLFListName(unsigned int lfhash);
const LFList* GetLFList(unsigned int lfhash);
......@@ -89,6 +92,49 @@ public:
static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
static bool DeleteCategory(const wchar_t* name);
static bool SaveDeckArray(const DeckArray& deck, const wchar_t* name);
private:
template<typename LineProvider>
void _LoadLFListFromLineProvider(LineProvider getLine, bool insert = false) {
std::vector<LFList> loadedLists;
auto cur = loadedLists.rend(); // 注意:在临时 list 上操作
char line[256]{};
wchar_t strBuffer[256]{};
char str1[16]{};
while (getLine(line, sizeof(line))) {
if (line[0] == '#')
continue;
if (line[0] == '!') {
auto len = std::strcspn(line, "\r\n");
line[len] = 0;
BufferIO::DecodeUTF8(&line[1], strBuffer);
LFList newlist;
newlist.listName = strBuffer;
newlist.hash = 0x7dfcee6a;
loadedLists.push_back(newlist);
cur = loadedLists.rbegin();
continue;
}
if (cur == loadedLists.rend())
continue;
unsigned int code = 0;
int count = -1;
if (std::sscanf(line, "%10s%*[ ]%1d", str1, &count) != 2)
continue;
if (count < 0 || count > 2)
continue;
code = std::strtoul(str1, nullptr, 10);
cur->content[code] = count;
cur->hash = cur->hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + count)) | (code >> (5 - count)));
}
if (insert) {
_lfList.insert(_lfList.begin(), loadedLists.begin(), loadedLists.end());
} else {
_lfList.insert(_lfList.end(), loadedLists.begin(), loadedLists.end());
}
}
};
extern DeckManager deckManager;
......
......@@ -1239,12 +1239,16 @@ void Game::LoadExpansions() {
dataManager.LoadDB(fpath);
return;
}
if (IsExtension(name, L".conf")) {
if (IsExtension(name, L".conf") && std::wcscmp(name, L"lflist.conf")) {
char upath[1024];
BufferIO::EncodeUTF8(fpath, upath);
dataManager.LoadStrings(upath);
return;
}
if (!std::wcscmp(name, L"lflist.conf")) {
deckManager.LoadLFListSingle(fpath, true);
return;
}
if (IsExtension(name, L".zip") || IsExtension(name, L".ypk")) {
#ifdef _WIN32
DataManager::FileSystem->addFileArchive(fpath, true, false, irr::io::EFAT_ZIP);
......@@ -1276,6 +1280,9 @@ void Game::LoadExpansions() {
#else
auto reader = DataManager::FileSystem->createAndOpenFile(uname);
#endif
if(!std::wcscmp(fname, L"lflist.conf"))
deckManager.LoadLFListSingle(reader, true);
else
dataManager.LoadStrings(reader);
continue;
}
......
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