Commit 9b8ad166 authored by nanahira's avatar nanahira

Merge branch 'develop' into server-develop

parents 6f28e7b0 42772b77
...@@ -3,8 +3,8 @@ set -x ...@@ -3,8 +3,8 @@ set -x
set -o errexit set -o errexit
# ygopro-database # ygopro-database
apt update && apt -y install wget git libarchive-tools apt update && apt -y install wget git libarchive-tools
git clone --depth=1 https://code.mycard.moe/nanahira/ygopro-database git clone --depth=1 https://code.moenext.com/nanahira/ygopro-database
cp -rf ./ygopro-database/locales/$TARGET_LOCALE/* . cp -rf ./ygopro-database/locales/$TARGET_LOCALE/* .
# ygopro-images # ygopro-images
mkdir pics mkdir pics
wget -O - https://cdn01.moecube.com/images/ygopro-images-${TARGET_LOCALE}.zip | bsdtar -C pics -xf - wget -O - https://cdn02.moecube.com:444/images/ygopro-images-${TARGET_LOCALE}.zip | bsdtar -C pics -xf -
...@@ -6,8 +6,6 @@ TARGET_PLATFORM=$(arch) ...@@ -6,8 +6,6 @@ TARGET_PLATFORM=$(arch)
TARGET_YGOPRO_BINARY_PATH=./ygopro-platforms/ygopro-platform-$TARGET_PLATFORM TARGET_YGOPRO_BINARY_PATH=./ygopro-platforms/ygopro-platform-$TARGET_PLATFORM
export EVENT_INCLUDE_DIR=$PWD/libevent-stable/include export EVENT_INCLUDE_DIR=$PWD/libevent-stable/include
export EVENT_LIB_DIR=$PWD/libevent-stable/lib export EVENT_LIB_DIR=$PWD/libevent-stable/lib
export IRRLICHT_INCLUDE_DIR=$PWD/irrlicht/include
export IRRLICHT_LIB_DIR=$PWD/irrlicht/lib/$(arch)
export OPUS_INCLUDE_DIR=$PWD/miniaudio/external-built/include/opus export OPUS_INCLUDE_DIR=$PWD/miniaudio/external-built/include/opus
export OPUS_LIB_DIR=$PWD/miniaudio/external-built/lib export OPUS_LIB_DIR=$PWD/miniaudio/external-built/lib
export VORBIS_INCLUDE_DIR=$PWD/miniaudio/external-built/include export VORBIS_INCLUDE_DIR=$PWD/miniaudio/external-built/include
......
...@@ -8,7 +8,7 @@ if [ -d "libevent-stable" ]; then ...@@ -8,7 +8,7 @@ if [ -d "libevent-stable" ]; then
fi fi
if [ ! -d "libevent-2.0.22-stable" ]; then if [ ! -d "libevent-2.0.22-stable" ]; then
wget -O - https://cdn01.moecube.com/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx - wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx -
fi fi
install_path="$PWD/libevent-stable" install_path="$PWD/libevent-stable"
......
#!/bin/bash
set -x
set -o errexit
IRRLICHT_REPO_URL="https://code.moenext.com/mycard/irrlicht-new.git"
IRRLICHT_BRANCH_NAME="master"
# if $CI_COMMIT_REF_NAME includes develop or pre, then we use the develop branch
if [[ "$CI_COMMIT_REF_NAME" == *"develop"* || "$CI_COMMIT_REF_NAME" == *".pre"* ]]; then
IRRLICHT_BRANCH_NAME="develop"
fi
if [ ! -d "irrlicht" ]; then
git clone --depth=1 --branch "$IRRLICHT_BRANCH_NAME" "$IRRLICHT_REPO_URL" irrlicht
else
cd irrlicht
git fetch origin "$IRRLICHT_BRANCH_NAME"
git checkout "$IRRLICHT_BRANCH_NAME"
git reset --hard origin/"$IRRLICHT_BRANCH_NAME"
cd ..
fi
...@@ -33,9 +33,13 @@ runForDepot() { ...@@ -33,9 +33,13 @@ runForDepot() {
echo "$result" | jq . echo "$result" | jq .
} }
runForDepot win32 zh-CN if [[ "$CI_COMMIT_TAG" == *".pre"* ]]; then
runForDepot linux zh-CN echo "This is a pre-release, skipping upload."
runForDepot darwin zh-CN else
runForDepot win32 en-US runForDepot win32 zh-CN
runForDepot linux en-US runForDepot linux zh-CN
runForDepot darwin en-US runForDepot darwin zh-CN
runForDepot win32 en-US
runForDepot linux en-US
runForDepot darwin en-US
fi
...@@ -401,12 +401,6 @@ jobs: ...@@ -401,12 +401,6 @@ jobs:
run: | run: |
git clone --depth=1 https://github.com/mercury233/irrlicht git clone --depth=1 https://github.com/mercury233/irrlicht
- name: Build irrlicht
run: |
cd irrlicht/source/Irrlicht/MacOSX
xcodebuild -project MacOSX.xcodeproj
cd ../../../..
- name: Copy premake files - name: Copy premake files
run: | run: |
cp -r premake/* . cp -r premake/* .
...@@ -418,9 +412,7 @@ jobs: ...@@ -418,9 +412,7 @@ jobs:
./premake5 gmake \ ./premake5 gmake \
--cc=clang \ --cc=clang \
--freetype-include-dir="/usr/local/include/freetype2" \ --freetype-include-dir="/usr/local/include/freetype2" \
--opus-include-dir="/usr/local/include/opus" \ --opus-include-dir="/usr/local/include/opus"
--irrlicht-include-dir="../irrlicht/include" \
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release"
- name: Use premake to generate make files (ARM64) - name: Use premake to generate make files (ARM64)
if: runner.arch == 'ARM64' if: runner.arch == 'ARM64'
...@@ -438,9 +430,7 @@ jobs: ...@@ -438,9 +430,7 @@ jobs:
--opus-include-dir="/opt/homebrew/include/opus" \ --opus-include-dir="/opt/homebrew/include/opus" \
--opus-lib-dir="/opt/homebrew/lib" \ --opus-lib-dir="/opt/homebrew/lib" \
--vorbis-include-dir="/opt/homebrew/include" \ --vorbis-include-dir="/opt/homebrew/include" \
--vorbis-lib-dir="/opt/homebrew/lib" \ --vorbis-lib-dir="/opt/homebrew/lib"
--irrlicht-include-dir="../irrlicht/include" \
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release"
- name: Make - name: Make
run: | run: |
......
...@@ -14,14 +14,16 @@ mat_common: ...@@ -14,14 +14,16 @@ mat_common:
- linux - linux
script: script:
# lua # lua
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/lua-5.4.4.tar.gz | tar zfx - - wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/lua-5.4.4.tar.gz | tar zfx -
- mv lua-5.4.4 lua - mv lua-5.4.4 lua
# sqlite3 # sqlite3
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/sqlite-autoconf-3390300.tar.gz | tar zfx - - wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/sqlite-autoconf-3390300.tar.gz | tar zfx -
- mv sqlite-autoconf-3390300 sqlite3 - mv sqlite-autoconf-3390300 sqlite3
# freetype # freetype
#- wget -O - https://cdn01.moecube.com/ygopro-build-materials/freetype-2.11.1.tar.gz | tar zfx - #- wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/freetype-2.11.1.tar.gz | tar zfx -
#- mv freetype-2.11.1 freetype #- mv freetype-2.11.1 freetype
# irrlicht
- ./.ci/prepare-irrlicht.sh
# miniaudio # miniaudio
#- ./.ci/prepare-miniaudio.sh #- ./.ci/prepare-miniaudio.sh
# premake # premake
...@@ -31,6 +33,7 @@ mat_common: ...@@ -31,6 +33,7 @@ mat_common:
- lua - lua
#- freetype #- freetype
- sqlite3 - sqlite3
- irrlicht
#- miniaudio #- miniaudio
mat_submodules: mat_submodules:
...@@ -47,31 +50,29 @@ mat_submodules: ...@@ -47,31 +50,29 @@ mat_submodules:
- ocgcore - ocgcore
- script - script
mat_linux: #mat_linux:
stage: prepare # stage: prepare
tags: # tags:
- linux # - linux
image: git-registry.mycard.moe/mycard/docker-runner-base:debian11 # image: git-registry.mycard.moe/mycard/docker-runner-base:debian11
script: # script:
- apt update; apt -y install git wget tar # - apt update; apt -y install git wget tar
- git clone --depth=1 https://code.mycard.moe/mycard/irrlicht-new irrlicht # - ./.ci/prepare-irrlicht.sh
artifacts: # artifacts:
paths: # paths:
- irrlicht # - irrlicht
mat_macos: mat_macos:
stage: prepare stage: prepare
tags: tags:
- linux - linux
script: script:
- apt update; apt -y install wget tar git - apt update; apt -y install wget tar
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/premake-5.0.0-beta5-macosx.tar.gz | tar zfx - - wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/premake-5.0.0-beta5-macosx.tar.gz | tar zfx -
- chmod +x premake5 - chmod +x premake5
- git clone --depth=1 https://code.mycard.moe/mycard/irrlicht-new irrlicht
artifacts: artifacts:
paths: paths:
- premake5 - premake5
- irrlicht
mat_windows: mat_windows:
stage: prepare stage: prepare
...@@ -80,18 +81,15 @@ mat_windows: ...@@ -80,18 +81,15 @@ mat_windows:
script: script:
- apt update; apt -y install wget tar patch p7zip-full - apt update; apt -y install wget tar patch p7zip-full
# premake5.exe # premake5.exe
- wget https://cdn01.moecube.com/ygopro-build-materials/premake-5.0.0-beta5-windows.zip - wget https://cdn02.moecube.com:444/ygopro-build-materials/premake-5.0.0-beta5-windows.zip
- 7z x -y premake-5.0.0-beta5-windows.zip - 7z x -y premake-5.0.0-beta5-windows.zip
# event # event
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx - - wget -O - https://cdn02.moecube.com:444/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx -
- mv libevent-2.0.22-stable event - mv libevent-2.0.22-stable event
# irrlicht
- git clone --depth=1 https://code.mycard.moe/mycard/irrlicht-new irrlicht
artifacts: artifacts:
paths: paths:
- premake5.exe - premake5.exe
- event - event
- irrlicht
._exec_build: ._exec_build:
stage: build stage: build
...@@ -163,7 +161,7 @@ exec_windows_pro3: ...@@ -163,7 +161,7 @@ exec_windows_pro3:
image: git-registry.moenext.com/mycard/docker-ygopro-builder image: git-registry.moenext.com/mycard/docker-ygopro-builder
dependencies: dependencies:
- mat_common - mat_common
- mat_linux #- mat_linux
- mat_submodules - mat_submodules
.exec_linux: .exec_linux:
......
...@@ -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) {
...@@ -185,7 +185,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -185,7 +185,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;
...@@ -211,10 +211,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -211,10 +211,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;
...@@ -437,7 +437,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -437,7 +437,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;
...@@ -464,7 +464,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -464,7 +464,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);
...@@ -493,7 +493,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -493,7 +493,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;
...@@ -511,7 +511,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -511,7 +511,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;
...@@ -519,7 +519,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -519,7 +519,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());
} }
...@@ -576,7 +576,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -576,7 +576,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--;
...@@ -652,7 +652,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -652,7 +652,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();
...@@ -753,7 +753,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -753,7 +753,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)
...@@ -1048,7 +1048,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1048,7 +1048,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();
...@@ -1653,7 +1653,7 @@ void DeckBuilder::RefreshDeckList() { ...@@ -1653,7 +1653,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); });
} }
......
...@@ -16,6 +16,7 @@ void DeckManager::LoadLFListSingle(const char* path) { ...@@ -16,6 +16,7 @@ void DeckManager::LoadLFListSingle(const char* path) {
FILE* fp = myfopen(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] == '#')
...@@ -35,10 +36,11 @@ void DeckManager::LoadLFListSingle(const char* path) { ...@@ -35,10 +36,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)));
} }
...@@ -154,13 +156,12 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r ...@@ -154,13 +156,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;
...@@ -183,7 +184,7 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -183,7 +184,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;
...@@ -198,22 +199,21 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -198,22 +199,21 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
return errorcode; return errorcode;
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
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)
...@@ -223,16 +223,16 @@ int DeckManager::LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_pa ...@@ -223,16 +223,16 @@ 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);
} }
#endif #endif // YGOPRO_SERVER_MODE
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);
#ifndef YGOPRO_NO_SIDE_CHECK #ifndef YGOPRO_NO_SIDE_CHECK
...@@ -240,11 +240,11 @@ bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) { ...@@ -240,11 +240,11 @@ bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) {
return false; return false;
#endif #endif
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]++;
#ifndef YGOPRO_NO_SIDE_CHECK #ifndef YGOPRO_NO_SIDE_CHECK
for (auto& cdit : ncount) for (auto& cdit : ncount)
if (cdit.second != pcount[cdit.first]) if (cdit.second != pcount[cdit.first])
...@@ -321,8 +321,8 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) { ...@@ -321,8 +321,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];
...@@ -333,7 +333,7 @@ bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_na ...@@ -333,7 +333,7 @@ bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_na
mainGame->deckBuilder.RefreshPackListScroll(); mainGame->deckBuilder.RefreshPackListScroll();
return res; return res;
} }
bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) { bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
return false; return false;
FILE* fp = OpenDeckFile(file, "w"); FILE* fp = OpenDeckFile(file, "w");
...@@ -341,26 +341,18 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) { ...@@ -341,26 +341,18 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) {
return false; return false;
std::fprintf(fp, "#created by ...\n#main\n"); std::fprintf(fp, "#created by ...\n#main\n");
for(size_t i = 0; i < deck.main.size(); ++i) for(size_t i = 0; i < deck.main.size(); ++i)
std::fprintf(fp, "%d\n", deck.main[i]->first); std::fprintf(fp, "%u\n", deck.main[i]->first);
std::fprintf(fp, "#extra\n"); std::fprintf(fp, "#extra\n");
for(size_t i = 0; i < deck.extra.size(); ++i) for(size_t i = 0; i < deck.extra.size(); ++i)
std::fprintf(fp, "%d\n", deck.extra[i]->first); std::fprintf(fp, "%u\n", deck.extra[i]->first);
std::fprintf(fp, "!side\n"); std::fprintf(fp, "!side\n");
for(size_t i = 0; i < deck.side.size(); ++i) for(size_t i = 0; i < deck.side.size(); ++i)
std::fprintf(fp, "%d\n", deck.side[i]->first); std::fprintf(fp, "%u\n", deck.side[i]->first);
std::fclose(fp); std::fclose(fp);
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
} }
int DeckManager::TypeCount(std::vector<code_pointer> list, unsigned int ctype) { int DeckManager::TypeCount(std::vector<code_pointer> list, unsigned int ctype) {
int res = 0; int res = 0;
...@@ -378,7 +370,7 @@ bool DeckManager::LoadDeckFromCode(Deck& deck, const unsigned char *code, int le ...@@ -378,7 +370,7 @@ bool DeckManager::LoadDeckFromCode(Deck& deck, const unsigned char *code, int le
return false; return false;
int mainc = BufferIO::ReadInt32(pdeck); int mainc = BufferIO::ReadInt32(pdeck);
int sidec = BufferIO::ReadInt32(pdeck); int sidec = BufferIO::ReadInt32(pdeck);
int errorcode = LoadDeck(deck, (int*)pdeck, mainc, sidec); int errorcode = LoadDeck(deck, (uint32_t*)pdeck, mainc, sidec);
return (errorcode == 0); return (errorcode == 0);
} }
int DeckManager::SaveDeckToCode(Deck& deck, unsigned char* code) { int DeckManager::SaveDeckToCode(Deck& deck, unsigned char* code) {
......
...@@ -65,27 +65,30 @@ public: ...@@ -65,27 +65,30 @@ 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);
bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec);
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
int LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_packlist = false);
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);
wchar_t DeckFormatBuffer[128]; wchar_t DeckFormatBuffer[128];
int TypeCount(std::vector<code_pointer> list, unsigned int ctype); int TypeCount(std::vector<code_pointer> list, unsigned int ctype);
bool LoadDeckFromCode(Deck& deck, const unsigned char *code, int len); bool LoadDeckFromCode(Deck& deck, const unsigned char *code, int len);
int SaveDeckToCode(Deck &deck, unsigned char *code); int SaveDeckToCode(Deck &deck, unsigned char *code);
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);
#endif //YGOPRO_SERVER_MODE #endif // YGOPRO_SERVER_MODE
static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false);
static bool LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec);
#ifndef YGOPRO_SERVER_MODE
static uint32_t LoadDeckFromStream(Deck& deck, std::istringstream& deckStream, bool is_packlist = false);
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(const 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);
#endif // YGOPRO_SERVER_MODE
}; };
extern DeckManager deckManager; extern DeckManager deckManager;
......
...@@ -4127,7 +4127,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -4127,7 +4127,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break; break;
} }
case MSG_RELOAD_FIELD: { case MSG_RELOAD_FIELD: {
mainGame->gMutex.lock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.lock();
}
mainGame->dField.Clear(); mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadUInt8(pbuf); mainGame->dInfo.duel_rule = BufferIO::ReadUInt8(pbuf);
int val = 0; int val = 0;
...@@ -4233,7 +4235,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -4233,7 +4235,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code)); myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code));
mainGame->dField.last_chain = true; mainGame->dField.last_chain = true;
} }
mainGame->gMutex.unlock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.unlock();
}
break; break;
} }
} }
......
...@@ -199,6 +199,9 @@ bool Game::Initialize() { ...@@ -199,6 +199,9 @@ bool Game::Initialize() {
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16); numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(!numFont) { if(!numFont) {
const wchar_t* numFontPaths[] = { const wchar_t* numFontPaths[] = {
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf",
L"C:/Windows/Fonts/arialbd.ttf", L"C:/Windows/Fonts/arialbd.ttf",
L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf", L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf",
L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc",
...@@ -206,9 +209,6 @@ bool Game::Initialize() { ...@@ -206,9 +209,6 @@ bool Game::Initialize() {
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc", L"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc",
L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf", L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf",
L"/System/Library/Fonts/SFNS.ttf", L"/System/Library/Fonts/SFNS.ttf",
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf"
}; };
for(const wchar_t* path : numFontPaths) { for(const wchar_t* path : numFontPaths) {
BufferIO::CopyWideString(path, gameConf.numfont); BufferIO::CopyWideString(path, gameConf.numfont);
...@@ -220,6 +220,9 @@ bool Game::Initialize() { ...@@ -220,6 +220,9 @@ bool Game::Initialize() {
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(!textFont) { if(!textFont) {
const wchar_t* textFontPaths[] = { const wchar_t* textFontPaths[] = {
L"./fonts/textFont.ttf",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf",
L"C:/Windows/Fonts/msyh.ttc", L"C:/Windows/Fonts/msyh.ttc",
L"C:/Windows/Fonts/msyh.ttf", L"C:/Windows/Fonts/msyh.ttf",
L"C:/Windows/Fonts/simsun.ttc", L"C:/Windows/Fonts/simsun.ttc",
...@@ -231,9 +234,7 @@ bool Game::Initialize() { ...@@ -231,9 +234,7 @@ bool Game::Initialize() {
L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc", L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", L"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
L"/System/Library/Fonts/PingFang.ttc", L"/System/Library/Fonts/PingFang.ttc",
L"./fonts/textFont.ttf", L"/System/Library/Fonts/STHeiti Medium.ttc",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf"
}; };
for(const wchar_t* path : textFontPaths) { for(const wchar_t* path : textFontPaths) {
BufferIO::CopyWideString(path, gameConf.textfont); BufferIO::CopyWideString(path, gameConf.textfont);
...@@ -251,7 +252,7 @@ bool Game::Initialize() { ...@@ -251,7 +252,7 @@ bool Game::Initialize() {
} }
}); });
if(fpath[0] == 0) { if(fpath[0] == 0) {
ErrorLog("Failed to load font(s)!"); ErrorLog("No fonts found! Please place appropriate font file in the fonts directory, or edit system.conf manually.");
return false; return false;
} }
if(!numFont) { if(!numFont) {
...@@ -263,6 +264,10 @@ bool Game::Initialize() { ...@@ -263,6 +264,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);
...@@ -1425,7 +1430,7 @@ void Game::RefreshDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBo ...@@ -1425,7 +1430,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); });
} }
...@@ -1564,14 +1569,6 @@ bool Game::LoadConfigFromFile(const char* file) { ...@@ -1564,14 +1569,6 @@ bool Game::LoadConfigFromFile(const char* file) {
} else if(!std::strcmp(strbuf, "errorlog")) { } else if(!std::strcmp(strbuf, "errorlog")) {
unsigned int val = std::strtol(valbuf, nullptr, 10); unsigned int val = std::strtol(valbuf, nullptr, 10);
enable_log = val & 0xff; enable_log = val & 0xff;
} else if(!std::strcmp(strbuf, "textfont")) {
int textfontsize = 0;
if (std::sscanf(linebuf, "%63s = %959s %d", strbuf, valbuf, &textfontsize) != 3)
continue;
gameConf.textfontsize = textfontsize;
BufferIO::DecodeUTF8(valbuf, gameConf.textfont);
} else if(!std::strcmp(strbuf, "numfont")) {
BufferIO::DecodeUTF8(valbuf, gameConf.numfont);
} else if(!std::strcmp(strbuf, "serverport")) { } else if(!std::strcmp(strbuf, "serverport")) {
gameConf.serverport = std::strtol(valbuf, nullptr, 10); gameConf.serverport = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "lasthost")) { } else if(!std::strcmp(strbuf, "lasthost")) {
...@@ -1674,7 +1671,18 @@ bool Game::LoadConfigFromFile(const char* file) { ...@@ -1674,7 +1671,18 @@ bool Game::LoadConfigFromFile(const char* file) {
// options allowing multiple words // options allowing multiple words
if (std::sscanf(linebuf, "%63s = %959[^\n]", strbuf, valbuf) != 2) if (std::sscanf(linebuf, "%63s = %959[^\n]", strbuf, valbuf) != 2)
continue; continue;
if (!std::strcmp(strbuf, "nickname")) { if (!std::strcmp(strbuf, "textfont")) {
char* last_space = std::strrchr(valbuf, ' ');
if (last_space == nullptr)
continue;
int fontsize = std::strtol(last_space + 1, nullptr, 10);
if (fontsize > 0)
gameConf.textfontsize = fontsize;
*last_space = 0;
BufferIO::DecodeUTF8(valbuf, gameConf.textfont);
} else if (!std::strcmp(strbuf, "numfont")) {
BufferIO::DecodeUTF8(valbuf, gameConf.numfont);
} else if (!std::strcmp(strbuf, "nickname")) {
BufferIO::DecodeUTF8(valbuf, gameConf.nickname); BufferIO::DecodeUTF8(valbuf, gameConf.nickname);
} else if (!std::strcmp(strbuf, "gamename")) { } else if (!std::strcmp(strbuf, "gamename")) {
BufferIO::DecodeUTF8(valbuf, gameConf.gamename); BufferIO::DecodeUTF8(valbuf, gameConf.gamename);
...@@ -2101,6 +2109,11 @@ void Game::AddDebugMsg(const char* msg) { ...@@ -2101,6 +2109,11 @@ void Game::AddDebugMsg(const char* msg) {
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
void Game::ErrorLog(const char* msg) { void Game::ErrorLog(const char* msg) {
#ifdef _WIN32
OutputDebugStringA(msg);
#else
std::fprintf(stderr, "%s\n", msg);
#endif
FILE* fp = myfopen("error.log", "a"); FILE* fp = myfopen("error.log", "a");
if(!fp) if(!fp)
return; return;
......
...@@ -30,7 +30,7 @@ int main(int argc, char* argv[]) { ...@@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {
#if defined(FOPEN_WINDOWS_SUPPORT_UTF8) #if defined(FOPEN_WINDOWS_SUPPORT_UTF8)
std::setlocale(LC_CTYPE, ".UTF-8"); std::setlocale(LC_CTYPE, ".UTF-8");
#elif defined(__APPLE__) #elif defined(__APPLE__)
std::setlocale(LC_CTYPE, "C.UTF-8"); std::setlocale(LC_CTYPE, "UTF-8");
#elif !defined(_WIN32) #elif !defined(_WIN32)
std::setlocale(LC_CTYPE, ""); std::setlocale(LC_CTYPE, "");
#endif #endif
......
#include "image_manager.h" #include "image_manager.h"
#include "game.h" #include "game.h"
#include <thread>
#include "myfilesystem.h" #include "myfilesystem.h"
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
#include <thread>
#endif
#ifdef _OPENMP
#include <omp.h>
#endif
namespace ygo { namespace ygo {
...@@ -24,8 +29,10 @@ bool ImageManager::Initial() { ...@@ -24,8 +29,10 @@ bool ImageManager::Initial() {
tUnknownFit = nullptr; tUnknownFit = nullptr;
tUnknownThumb = nullptr; tUnknownThumb = nullptr;
tBigPicture = nullptr; tBigPicture = nullptr;
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
tLoading = nullptr; tLoading = nullptr;
tThumbLoadingThreadRunning = false; tThumbLoadingThreadRunning = false;
#endif
tAct = GetRandomImage(TEXTURE_ACTIVATE); tAct = GetRandomImage(TEXTURE_ACTIVATE);
tAttack = GetRandomImage(TEXTURE_ATTACK); tAttack = GetRandomImage(TEXTURE_ATTACK);
if(!tAct) if(!tAct)
...@@ -134,7 +141,11 @@ void ImageManager::ClearTexture() { ...@@ -134,7 +141,11 @@ void ImageManager::ClearTexture() {
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) { for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) {
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
if(tit->second && tit->second != tLoading) if(tit->second && tit->second != tLoading)
#else
if(tit->second)
#endif
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
if(tBigPicture != nullptr) { if(tBigPicture != nullptr) {
...@@ -144,12 +155,14 @@ void ImageManager::ClearTexture() { ...@@ -144,12 +155,14 @@ void ImageManager::ClearTexture() {
tMap[0].clear(); tMap[0].clear();
tMap[1].clear(); tMap[1].clear();
tThumb.clear(); tThumb.clear();
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
tThumbLoadingMutex.lock(); tThumbLoadingMutex.lock();
tThumbLoading.clear(); tThumbLoading.clear();
while(!tThumbLoadingCodes.empty()) while(!tThumbLoadingCodes.empty())
tThumbLoadingCodes.pop(); tThumbLoadingCodes.pop();
tThumbLoadingThreadRunning = false; tThumbLoadingThreadRunning = false;
tThumbLoadingMutex.unlock(); tThumbLoadingMutex.unlock();
#endif
tFields.clear(); tFields.clear();
} }
void ImageManager::RemoveTexture(int code) { void ImageManager::RemoveTexture(int code) {
...@@ -191,11 +204,13 @@ void ImageManager::ResizeTexture() { ...@@ -191,11 +204,13 @@ void ImageManager::ResizeTexture() {
driver->removeTexture(tUnknown); driver->removeTexture(tUnknown);
driver->removeTexture(tUnknownFit); driver->removeTexture(tUnknownFit);
driver->removeTexture(tUnknownThumb); driver->removeTexture(tUnknownThumb);
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
driver->removeTexture(tLoading); driver->removeTexture(tLoading);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
#endif
tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT); tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit); tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit);
tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb); tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
driver->removeTexture(tBackGround); driver->removeTexture(tBackGround);
tBackGround = GetRandomImage(TEXTURE_DUEL, bgWidth, bgHeight); tBackGround = GetRandomImage(TEXTURE_DUEL, bgWidth, bgHeight);
if(!tBackGround) if(!tBackGround)
...@@ -221,25 +236,27 @@ void ImageManager::ResizeTexture() { ...@@ -221,25 +236,27 @@ void ImageManager::ResizeTexture() {
} }
// function by Warr1024, from https://github.com/minetest/minetest/issues/2419 , modified // function by Warr1024, from https://github.com/minetest/minetest/issues/2419 , modified
void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) { void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa; const irr::core::dimension2d<irr::u32> srcDim = src->getDimension();
irr::u32 dy, dx; const irr::core::dimension2d<irr::u32> destDim = dest->getDimension();
irr::video::SColor pxl;
// Cache rectsngle boundaries. // Cache scale ratios.
double sw = src->getDimension().Width * 1.0; const double rx = (double)srcDim.Width / destDim.Width;
double sh = src->getDimension().Height * 1.0; const double ry = (double)srcDim.Height / destDim.Height;
// Walk each destination image pixel. #pragma omp parallel
// Note: loop y around x for better cache locality. {
irr::core::dimension2d<irr::u32> dim = dest->getDimension(); double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
for(dy = 0; dy < dim.Height; dy++) irr::video::SColor pxl, npxl;
for(dx = 0; dx < dim.Width; dx++) {
// Walk each destination image pixel.
#pragma omp for schedule(dynamic)
for(irr::s32 dy = 0; dy < destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds. // Calculate floating-point source rectangle bounds.
minsx = dx * sw / dim.Width; minsx = dx * rx;
maxsx = minsx + sw / dim.Width; maxsx = minsx + rx;
minsy = dy * sh / dim.Height; minsy = dy * ry;
maxsy = minsy + sh / dim.Height; maxsy = minsy + ry;
// Total area, and integral of r, g, b values over that area, // Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops. // initialized to zero, to be summed up in next loops.
...@@ -250,9 +267,8 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) { ...@@ -250,9 +267,8 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
aa = 0; aa = 0;
// Loop over the integral pixel positions described by those bounds. // Loop over the integral pixel positions described by those bounds.
for(sy = floor(minsy); sy < maxsy; sy++) for(sy = floor(minsy); sy < maxsy; sy++) {
for(sx = floor(minsx); sx < maxsx; sx++) { for(sx = floor(minsx); sx < maxsx; sx++) {
// Calculate width, height, then area of dest pixel // Calculate width, height, then area of dest pixel
// that's covered by this source pixel. // that's covered by this source pixel.
pw = 1; pw = 1;
...@@ -276,21 +292,20 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) { ...@@ -276,21 +292,20 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
ba += pa * pxl.getBlue(); ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha(); aa += pa * pxl.getAlpha();
} }
}
// Set the destination image pixel to the average color. // Set the destination image pixel to the average color.
if(area > 0) { if(area > 0) {
pxl.setRed(ra / area + 0.5); npxl.set((irr::u32)(aa / area + 0.5),
pxl.setGreen(ga / area + 0.5); (irr::u32)(ra / area + 0.5),
pxl.setBlue(ba / area + 0.5); (irr::u32)(ga / area + 0.5),
pxl.setAlpha(aa / area + 0.5); (irr::u32)(ba / area + 0.5));
} else { } else {
pxl.setRed(0); npxl.set(0);
pxl.setGreen(0);
pxl.setBlue(0);
pxl.setAlpha(0);
} }
dest->setPixel(dx, dy, pxl); dest->setPixel(dx, dy, npxl);
} }
}
} // end of parallel region
} }
irr::video::ITexture* ImageManager::GetTextureFromFile(const char* file, irr::s32 width, irr::s32 height) { irr::video::ITexture* ImageManager::GetTextureFromFile(const char* file, irr::s32 width, irr::s32 height) {
if(mainGame->gameConf.use_image_scale) { if(mainGame->gameConf.use_image_scale) {
...@@ -392,6 +407,7 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) { ...@@ -392,6 +407,7 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) {
tBigPicture = texture; tBigPicture = texture;
return texture; return texture;
} }
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
int ImageManager::LoadThumbThread() { int ImageManager::LoadThumbThread() {
while(true) { while(true) {
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
...@@ -479,9 +495,34 @@ int ImageManager::LoadThumbThread() { ...@@ -479,9 +495,34 @@ int ImageManager::LoadThumbThread() {
imageManager.tThumbLoadingMutex.unlock(); imageManager.tThumbLoadingMutex.unlock();
return 0; return 0;
} }
#endif // YGOPRO_USE_THUMB_LOAD_THERAD
irr::video::ITexture* ImageManager::GetTextureThumb(int code) { irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0) if(code == 0)
return tUnknownThumb; return tUnknownThumb;
#ifndef YGOPRO_USE_THUMB_LOAD_THERAD
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
char file[256];
std::snprintf(file, sizeof file, "expansions/pics/thumbnail/%d.jpg", code);
int width = CARD_THUMB_WIDTH * mainGame->xScale;
int height = CARD_THUMB_HEIGHT * mainGame->yScale;
irr::video::ITexture* img = GetTextureFromFile(file, width, height);
if(img == NULL) {
std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
if(img == NULL && mainGame->gameConf.use_image_scale) {
std::snprintf(file, sizeof file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
if(img == NULL) {
std::snprintf(file, sizeof file, "pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
}
tThumb[code] = img;
return (img == NULL) ? tUnknownThumb : img;
}
#else // YGOPRO_USE_THUMB_LOAD_THERAD
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code); auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) { if(lit != tThumbLoading.end()) {
...@@ -509,6 +550,7 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) { ...@@ -509,6 +550,7 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
imageManager.tThumbLoadingMutex.unlock(); imageManager.tThumbLoadingMutex.unlock();
return tLoading; return tLoading;
} }
#endif // YGOPRO_USE_THUMB_LOAD_THERAD
if(tit->second) if(tit->second)
return tit->second; return tit->second;
else else
......
#ifndef IMAGEMANAGER_H #ifndef IMAGEMANAGER_H
#define IMAGEMANAGER_H #define IMAGEMANAGER_H
#ifndef _OPENMP
#define YGOPRO_USE_THUMB_LOAD_THERAD
#endif
#include "config.h" #include "config.h"
#include "data_manager.h" #include "data_manager.h"
#include <unordered_map> #include <unordered_map>
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#endif
namespace ygo { namespace ygo {
...@@ -28,15 +34,19 @@ public: ...@@ -28,15 +34,19 @@ public:
irr::video::ITexture* GetBigPicture(int code, float zoom); irr::video::ITexture* GetBigPicture(int code, float zoom);
irr::video::ITexture* GetTextureThumb(int code); irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code); irr::video::ITexture* GetTextureField(int code);
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
static int LoadThumbThread(); static int LoadThumbThread();
#endif
std::unordered_map<int, irr::video::ITexture*> tMap[2]; std::unordered_map<int, irr::video::ITexture*> tMap[2];
std::unordered_map<int, irr::video::ITexture*> tThumb; std::unordered_map<int, irr::video::ITexture*> tThumb;
std::unordered_map<int, irr::video::ITexture*> tFields; std::unordered_map<int, irr::video::ITexture*> tFields;
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
std::unordered_map<int, irr::video::IImage*> tThumbLoading; std::unordered_map<int, irr::video::IImage*> tThumbLoading;
std::queue<int> tThumbLoadingCodes; std::queue<int> tThumbLoadingCodes;
std::mutex tThumbLoadingMutex; std::mutex tThumbLoadingMutex;
bool tThumbLoadingThreadRunning; bool tThumbLoadingThreadRunning;
#endif
irr::IrrlichtDevice* device; irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver; irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[4]; irr::video::ITexture* tCover[4];
...@@ -44,7 +54,9 @@ public: ...@@ -44,7 +54,9 @@ public:
irr::video::ITexture* tUnknownFit; irr::video::ITexture* tUnknownFit;
irr::video::ITexture* tUnknownThumb; irr::video::ITexture* tUnknownThumb;
irr::video::ITexture* tBigPicture; irr::video::ITexture* tBigPicture;
#ifdef YGOPRO_USE_THUMB_LOAD_THERAD
irr::video::ITexture* tLoading; irr::video::ITexture* tLoading;
#endif
irr::video::ITexture* tAct; irr::video::ITexture* tAct;
irr::video::ITexture* tAttack; irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated; irr::video::ITexture* tNegated;
......
...@@ -353,7 +353,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -353,7 +353,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
...@@ -372,7 +372,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -372,7 +372,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;
}
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
struct file_unit { struct file_unit {
std::string filename; std::string filename;
......
...@@ -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);
......
...@@ -47,6 +47,7 @@ project "ygopro" ...@@ -47,6 +47,7 @@ project "ygopro"
kind "WindowedApp" kind "WindowedApp"
cppdialect "C++14" cppdialect "C++14"
rtti "Off" rtti "Off"
openmp "On"
files { "*.cpp", "*.h" } files { "*.cpp", "*.h" }
includedirs { "../ocgcore" } includedirs { "../ocgcore" }
...@@ -111,9 +112,6 @@ end ...@@ -111,9 +112,6 @@ end
filter "system:windows" filter "system:windows"
defines { "_IRR_WCHAR_FILESYSTEM" } defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc" files "ygopro.rc"
if not SERVER_MODE then
libdirs { "$(DXSDK_DIR)Lib/x86" }
end
if SERVER_PRO2_SUPPORT then if SERVER_PRO2_SUPPORT then
targetname ("AI.Server") targetname ("AI.Server")
end end
...@@ -137,6 +135,7 @@ end ...@@ -137,6 +135,7 @@ end
links { "event_pthreads", "dl", "pthread", "resolv" } links { "event_pthreads", "dl", "pthread", "resolv" }
filter "system:macosx" filter "system:macosx"
if not SERVER_MODE then if not SERVER_MODE then
openmp "Off"
links { "z" } links { "z" }
defines { "GL_SILENCE_DEPRECATION" } defines { "GL_SILENCE_DEPRECATION" }
end end
...@@ -151,6 +150,7 @@ end ...@@ -151,6 +150,7 @@ end
linkoptions { "-static-libstdc++", "-static-libgcc" } linkoptions { "-static-libstdc++", "-static-libgcc" }
if not SERVER_MODE then if not SERVER_MODE then
links { "GL", "X11", "Xxf86vm" } links { "GL", "X11", "Xxf86vm" }
linkoptions { "-fopenmp" }
end end
if USE_AUDIO and AUDIO_LIB == "irrklang" then if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "IrrKlang" } links { "IrrKlang" }
......
...@@ -199,15 +199,7 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -199,15 +199,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];
......
...@@ -26,13 +26,13 @@ constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; ...@@ -26,13 +26,13 @@ constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#endif // YGOPRO_SERVER_MODE #endif // YGOPRO_SERVER_MODE
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 {
......
...@@ -419,9 +419,9 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -419,9 +419,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]) {
......
...@@ -404,7 +404,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -404,7 +404,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)
......
This diff is collapsed.
Subproject commit 8c8f4a9ca3f2844fe537ec7577af6d2e4dfcc711 Subproject commit ea1f4623b88d12998e548bf7fc06cc163ec823dc
...@@ -11,3 +11,4 @@ project "event" ...@@ -11,3 +11,4 @@ project "event"
filter "system:windows" filter "system:windows"
prebuildcommands { "xcopy /E /Y $(ProjectDir)..\\event\\WIN32-Code $(ProjectDir)..\\event\\include" } prebuildcommands { "xcopy /E /Y $(ProjectDir)..\\event\\WIN32-Code $(ProjectDir)..\\event\\include" }
files { "win32select.c", "evthread_win32.c", "buffer_iocp.c", "event_iocp.c", "bufferevent_async.c" } files { "win32select.c", "evthread_win32.c", "buffer_iocp.c", "event_iocp.c", "bufferevent_async.c" }
defines { "WIN32" } -- quirk of old libevent
defines {
"_IRR_STATIC_LIB_",
"NO_IRR_USE_NON_SYSTEM_BZLIB_",
"NO_IRR_COMPILE_WITH_BZIP2_",
"NO_IRR_COMPILE_WITH_CONSOLE_DEVICE_",
"NO_IRR_COMPILE_WITH_DIRECT3D_8_",
"NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_",
"NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_",
"NO_IRR_COMPILE_WITH_SOFTWARE_",
"NO_IRR_COMPILE_WITH_BURNINGSVIDEO_",
"NO_IRR_COMPILE_WITH_IRR_SCENE_LOADER_",
"NO_IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_",
"NO_IRR_COMPILE_WITH_IRR_MESH_LOADER_",
"NO_IRR_COMPILE_WITH_HALFLIFE_LOADER_",
"NO_IRR_COMPILE_WITH_MD2_LOADER_",
"NO_IRR_COMPILE_WITH_MD3_LOADER_",
"NO_IRR_COMPILE_WITH_3DS_LOADER_",
"NO_IRR_COMPILE_WITH_COLLADA_LOADER_",
"NO_IRR_COMPILE_WITH_CSM_LOADER_",
"NO_IRR_COMPILE_WITH_BSP_LOADER_",
"NO_IRR_COMPILE_WITH_DMF_LOADER_",
"NO_IRR_COMPILE_WITH_LMTS_LOADER_",
"NO_IRR_COMPILE_WITH_MY3D_LOADER_",
"NO_IRR_COMPILE_WITH_OBJ_LOADER_",
"NO_IRR_COMPILE_WITH_OCT_LOADER_",
"NO_IRR_COMPILE_WITH_LWO_LOADER_",
"NO_IRR_COMPILE_WITH_STL_LOADER_",
"NO_IRR_COMPILE_WITH_PLY_LOADER_",
"NO_IRR_COMPILE_WITH_SMF_LOADER_",
"NO_IRR_COMPILE_WITH_IRR_WRITER_",
"NO_IRR_COMPILE_WITH_COLLADA_WRITER_",
"NO_IRR_COMPILE_WITH_STL_WRITER_",
"NO_IRR_COMPILE_WITH_OBJ_WRITER_",
"NO_IRR_COMPILE_WITH_PLY_WRITER_",
"NO_IRR_COMPILE_WITH_PCX_LOADER_",
"NO_IRR_COMPILE_WITH_PPM_LOADER_",
"NO_IRR_COMPILE_WITH_PSD_LOADER_",
"NO_IRR_COMPILE_WITH_TGA_LOADER_",
"NO_IRR_COMPILE_WITH_WAL_LOADER_",
"NO_IRR_COMPILE_WITH_LMP_LOADER_",
"NO_IRR_COMPILE_WITH_RGB_LOADER_",
"NO_IRR_COMPILE_WITH_PCX_WRITER_",
"NO_IRR_COMPILE_WITH_PPM_WRITER_",
"NO_IRR_COMPILE_WITH_PSD_WRITER_",
"NO_IRR_COMPILE_WITH_TGA_WRITER_",
"NO__IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_",
}
This diff is collapsed.
...@@ -6,7 +6,7 @@ LUA_LIB_NAME = "lua" ...@@ -6,7 +6,7 @@ LUA_LIB_NAME = "lua"
BUILD_EVENT = os.istarget("windows") BUILD_EVENT = os.istarget("windows")
BUILD_FREETYPE = os.istarget("windows") BUILD_FREETYPE = os.istarget("windows")
BUILD_SQLITE = os.istarget("windows") BUILD_SQLITE = os.istarget("windows")
BUILD_IRRLICHT = not os.istarget("macosx") BUILD_IRRLICHT = true
USE_AUDIO = true USE_AUDIO = true
AUDIO_LIB = "miniaudio" AUDIO_LIB = "miniaudio"
...@@ -396,7 +396,6 @@ workspace "YGOPro" ...@@ -396,7 +396,6 @@ workspace "YGOPro"
end end
filter "system:windows" filter "system:windows"
defines { "WIN32", "_WIN32" }
if not SERVER_PRO3_SUPPORT then if not SERVER_PRO3_SUPPORT then
entrypoint "mainCRTStartup" entrypoint "mainCRTStartup"
end end
...@@ -414,7 +413,6 @@ end ...@@ -414,7 +413,6 @@ end
filter "system:macosx" filter "system:macosx"
libdirs { "/usr/local/lib" } libdirs { "/usr/local/lib" }
buildoptions { "-stdlib=libc++" }
if MAC_ARM then if MAC_ARM then
buildoptions { "--target=arm64-apple-macos12" } buildoptions { "--target=arm64-apple-macos12" }
end end
......
Subproject commit 1c8a21cd877e82b9bbdd95fe71f0a1b58b909797 Subproject commit 4b650142a9910444f420cd2c5e1039f7b39681ab
...@@ -1259,3 +1259,6 @@ ...@@ -1259,3 +1259,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