Commit 650f0ee2 authored by Chen Bill's avatar Chen Bill Committed by GitHub

Merge branch 'server' into merge-test

parents 4a4dafca 47efd8ab
#!/bin/bash
set -x
set -o errexit
# ygopro-database
apt update && apt -y install wget git libarchive-tools
git clone --depth=1 https://code.mycard.moe/mycard/ygopro-database
cp -rf ./ygopro-database/locales/$TARGET_LOCALE/* .
# ygopro-images
mkdir pics
wget -O - https://cdn01.moecube.com/images/ygopro-images-${TARGET_LOCALE}.zip | bsdtar -C pics -xf -
#!/bin/bash
set -x
set -o errexit
TARGET_PLATFORM=$(arch)
TARGET_YGOPRO_BINARY_PATH=./ygopro-platforms/ygopro-platform-$TARGET_PLATFORM
export EVENT_INCLUDE_DIR=$PWD/libevent-stable/include
export EVENT_LIB_DIR=$PWD/libevent-stable/lib
export IRRLICHT_INCLUDE_DIR=$PWD/irrlicht/include
export IRRLICHT_LIB_DIR=$PWD/irrlicht
./.ci/libevent-prebuild.sh
./premake5 gmake --cc=clang --build-freetype --build-sqlite --no-use-irrklang
cd build
make config=release -j4
cd ..
mkdir ygopro-platforms
mv bin/release/YGOPro.app $TARGET_YGOPRO_BINARY_PATH
#if [[ $TARGET_PLATFORM == "x86" ]]; then
# install_name_tool -change /usr/local/lib/libirrklang.dylib @executable_path/../Frameworks/libirrklang.dylib $TARGET_YGOPRO_BINARY_PATH
#fi
strip $TARGET_YGOPRO_BINARY_PATH
#!/bin/bash
set -x
set -o errexit
# PROCESSOR_COUNT=4
wget -O - https://cdn01.moecube.com/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx -
cd libevent-2.0.22-stable
./configure --prefix=$PWD/libevent-stable --disable-openssl --enable-static=yes --enable-shared=no
make -j$PROCESSOR_COUNT
make install
cd ..
mv libevent-2.0.22-stable/libevent-stable .
rm -rf libevent-2.0.22-stable
#!/bin/bash
set -x
set -o errexit
# TARGET_LOCALE
apt update && apt -y install tar git zstd
mkdir dist replay
tar --zstd -cf dist/ygopro-$CI_COMMIT_REF_NAME-linux-$TARGET_LOCALE.tar.zst --exclude='.git*' ygopro LICENSE README.md lib lflist.conf strings.conf system.conf cards.cdb script textures deck single pics replay sound windbot bot bot.conf pack
#!/bin/bash
set -x
set -o errexit
# TARGET_LOCALE
apt update && apt -y install tar git zstd
mkdir dist replay
tar --zstd -cf dist/ygopro-$CI_COMMIT_REF_NAME-darwin-$TARGET_LOCALE.tar.zst --exclude='.git*' ygopro.app LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures deck single pics replay windbot bot bot.conf pack
#!/bin/bash
set -x
set -o errexit
# TARGET_LOCALE
apt update && apt -y install tar git zstd
mkdir dist replay
tar --zstd -cf dist/ygopro-$CI_COMMIT_REF_NAME-win32-$TARGET_LOCALE.tar.zst --exclude='.git*' ygopro.exe LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures deck single pics replay sound bot.conf Bot.exe WindBot pack
#!/bin/bash
set -x
set -o errexit
echo "$MACOS_CERTIFICATE" | base64 --decode --output cert.p12
security create-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$MACOS_KEYCHAIN_NAME" || true
security list-keychains -s login.keychain "$MACOS_KEYCHAIN_NAME"
security default-keychain -s "$MACOS_KEYCHAIN_NAME"
security unlock-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$MACOS_KEYCHAIN_NAME"
security import cert.p12 -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k "$MACOS_KEYCHAIN_PASSWORD" "$MACOS_KEYCHAIN_NAME";
CERT_IDENTITY_NAME=$(security find-identity -v -p codesigning $MACOS_KEYCHAIN_NAME | head -1 | grep -o '".*"' | tr -d '"')
/usr/bin/codesign --deep --sign "$CERT_IDENTITY_NAME" ygopro.app
security lock-keychain "$MACOS_KEYCHAIN_NAME"
#!/bin/bash
set -o errexit
apt update; apt -y install curl jq
apiRoot=https://api.moecube.com
loginInfo=$(curl -sL -X POST $apiRoot/accounts/signin -d account=$MYCARD_USERNAME -d password=$MYCARD_PASSWORD)
token=$(echo $loginInfo | jq '.token' | sed 's/"//g')
header="Authorization: $token"
echo "Login succeeded."
appName="ygopro"
handleErrorMessage() {
rawJsonInput="$1"
successInfo=$(echo "$rawJsonInput" | jq '.success')
if [[ "$successInfo" != "true" ]]; then
echo "$rawJsonInput"
exit 1
fi
}
runForDepot() {
platform=$1
locale=$2
archivePath="./dist/$appName-$appVersion-$platform-$locale.tar.zst"
suffix="?platform=$platform&locale=$locale&arch=generic"
echo "Uploading $archivePath"
result=$(curl -H "$header" -X POST "$apiRoot/release/api/build/$appName/${appVersion}${suffix}" -F file=@$archivePath)
handleErrorMessage "$result"
echo "$result" | jq .
}
runForDepot win32 zh-CN
runForDepot linux zh-CN
runForDepot darwin zh-CN
runForDepot win32 en-US
runForDepot linux en-US
runForDepot darwin en-US
.DS_Store
/specials
/replay
/deck
/data
/expansions
/fonts
/icon
......
stages:
- prepare
- build
- combine
- pack
- deploy
variables:
GIT_DEPTH: "1"
mat_common:
stage: prepare
tags:
- linux
script:
# lua
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/lua-5.4.4.tar.gz | tar zfx -
- mv lua-5.4.4 lua
# sqlite3
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/sqlite-autoconf-3390300.tar.gz | tar zfx -
- mv sqlite-autoconf-3390300 sqlite3
# freetype
#- wget -O - https://cdn01.moecube.com/ygopro-build-materials/freetype-2.11.1.tar.gz | tar zfx -
#- mv freetype-2.11.1 freetype
# premake
- cp -rf premake/* .;
artifacts:
paths:
- lua
#- freetype
- sqlite3
mat_submodules:
stage: prepare
tags:
- linux
script:
- rm -rf ocgcore script
- mkdir ocgcore script
- git submodule update --init
artifacts:
paths:
- ocgcore
- script
mat_linux:
stage: prepare
tags:
- linux
script:
- apt update; apt -y install git wget tar
- git clone --depth=1 https://code.mycard.moe/mycard/irrlicht-new irrlicht
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/premake-5.0.0-beta2-linux.tar.gz | tar zfx -
- env PROCESSOR_COUNT=$(nproc) ./.ci/libevent-prebuild.sh
artifacts:
paths:
- premake5
- irrlicht
- libevent-stable
mat_windows:
stage: prepare
tags:
- linux
script:
- apt update; apt -y install wget tar patch p7zip-full
# premake5.exe
- wget https://cdn01.moecube.com/ygopro-build-materials/premake-5.0.0-beta2-windows.zip
- 7z x -y premake-5.0.0-beta2-windows.zip
# event
- wget -O - https://cdn01.moecube.com/ygopro-build-materials/libevent-2.0.22-stable.tar.gz | tar zfx -
- mv libevent-2.0.22-stable event
# irrlicht
- git clone --depth=1 https://code.mycard.moe/mycard/irrlicht-new irrlicht
artifacts:
paths:
- premake5.exe
- event
- irrlicht
._exec_build:
stage: build
#variables:
# NO_LUA_SAFE: '1' # on client no lua safe
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- bin/
- obj/
exec_windows:
extends: ._exec_build
tags:
- vs
dependencies:
- mat_common
- mat_windows
- mat_submodules
script:
- bash -c 'cp -rf premake/* .'
- '.\premake5.exe vs2019 --server-zip-support'
- cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" build\YGOPro.sln /m /p:Configuration=Release'
- copy bin\release\ygopro.exe .
artifacts:
paths:
- ygopro.exe
exec_linux:
extends: ._exec_build
tags:
- linux
dependencies:
- mat_common
- mat_linux
- mat_submodules
script:
- apt update; apt -y install git build-essential
- ./premake5 gmake --build-sqlite --server-zip-support
- cd build
- make config=release -j$(nproc)
- cd ..
- mv bin/release/ygopro ./ygopro
- strip ygopro
artifacts:
paths:
- ygopro
exec_debian:
extends: ._exec_build
tags:
- linux
dependencies:
- mat_common
- mat_linux
- mat_submodules
script:
- apt update; apt -y install git build-essential liblua5.3-dev libsqlite3-dev libevent-dev
- ./premake5 gmake --lua-deb
- cd build
- make config=release -j$(nproc)
- cd ..
- mv bin/release/ygopro ./ygopro
- strip ygopro
artifacts:
paths:
- ygopro
#win_server_pack:
# stage: pack
# dependencies:
# - exec_windows
# tags:
# - linux
# script:
# - apt update; apt -y install p7zip-full wget
# - wget https://nodejs.org/dist/v14.17.0/node-v14.17.0-win-x64.7z
[submodule "ocgcore"]
path = ocgcore
url = git@github.com:Fluorohydride/ygopro-core.git
url = https://github.com/mycard/ygopro-core
[submodule "script"]
path = script
url = git@github.com:Fluorohydride/ygopro-scripts.git
url = https://github.com/mycard/ygopro-scripts
language: cpp
dist: bionic
git:
submodules: false
addons:
ssh_known_hosts:
- github.com
apt:
# sources:
# - ubuntu-toolchain-r-test
packages:
# - gcc-6
# - g++-6
- libevent-dev
- libsqlite3-dev
- liblua5.3-dev
before_install:
- git submodule update --init --recursive
#- sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc
#- sudo ln -s /usr/bin/g++-6 /usr/local/bin/g++
#- g++ --version
- wget -O - https://github.com/premake/premake-core/releases/download/v5.0.0-beta1/premake-5.0.0-beta1-linux.tar.gz | tar zfx -
#- wget -O - https://www.lua.org/ftp/lua-5.3.6.tar.gz | tar zfx -; cd lua-5.3.6; sudo make linux install; cd ..
script:
- ./premake5 gmake
- cd build
- make config=release
## YGOPro
A script engine for "yu-gi-oh!" and sample gui
[中文说明](https://github.com/Fluorohydride/ygopro/wiki/%E4%B8%AD%E6%96%87%E8%AF%B4%E6%98%8E)
### Keys:
* ESC: Minimize the window.
* A: Holding down this button will let the system stop at every timing.
* S: Holding down this button will let the system skip every timing.
* D: Holding down this button will let the system stop at available timing.
* R: Fix the font glitch.
* F1~F4: Show the cards in your grave, banished zone, extra deck, xyz materials.
* F5~F8: Show the cards in your opponent's grave, banished zone, extra deck, xyz materials.
### Color in card list:
#### Background:
* White = your card, Grey = your opponent's card
#### Text:
Cards in deck, extra deck and banished zone:
* Black = face-up, Blue = face-down
Xyz materials:
* Black = default, Blue = the owner of the xyz material is different from its controller
### Sequence:
* Monster Zone: 1~5, starting from the left hand side.
* Spell & Trap Zone: 1~5, starting from the left hand side.
* Field Zone: 6
* Pendulum Zone: 0~1, starting from the left hand side.
* The others: 1~n, starting from the bottom.
### Deck edit page:
* All numeric textboxs: They support >, =, <, >=, <= signs.
* Card name: Search card names and texts by default, $foo will only search foo in card names, and @foo will search cards of "foo" archetype(due to translation, card name contains "foo" does not mean that card is "foo" card).
### Command-line options:
* `-e foo.cdb`: Load foo.cdb as the extra database.
* `-n nickname`: Set the nickname.
* `-h 192.168.0.2`: Set the host to join in LAN mode.
* `-p 7911`: Set the port to join in LAN mode.
* `-w abc`: Set the password to join in LAN mode.
* `-d`: Enter the deck edit page.
* `-d deck`: If used along with `-j` it mean select the deck, or it will open the deck to edit.
* `-c`: Create host with default settings.
* `-j`: Join the host specified in above, or if absent, lasthost in system.conf file.
* `-r`: Enter the replay mode page.
* `-r replay.yrp`: Load the replay.yrp in replay mode.
* `-s`: Enter the single mode page.
* `-s puzzle.lua`: Load the puzzle.lua in single mode.
* `-k`: Keep when duel finished. See below.
#### Note:
* `-c` `-j` `-e` `-r` `-s` shoule be the last parameter, because any parameters after it will get ignored.
* `-d` `-c` `-j` `-e` `-r` `-s` will make YGOPro automatically exit when the duel or deck editing is finished. This is useful for some launchers. If you want to keep it, add `-k` before them.
* `-d` `-r` `-s` support full path of file, or just filename. But remember deck filename should NOT have extension when replay and single filename MUST have extension.
### Directories:
* pics: .jpg card images(177*254).
* pics\thumbnail: .jpg thumbnail images(44*64).
* script: .lua script files.
* textures: Other image files.
* deck: .ydk deck files.
* replay: .yrp replay files.
* expansions: *.cdb will be loaded as extra databases.
## YGOPro(Server)
[![Build status](https://ci.appveyor.com/api/projects/status/qgkqi6o0wq7qn922/branch/server?svg=true)](https://ci.appveyor.com/project/zh99998/ygopro/branch/server)
[![Build Status](https://travis-ci.org/moecube/ygopro.svg?branch=server)](https://travis-ci.org/moecube/ygopro)
一个YGOPro的服务端版本,运行后自动建立主机,并开启端口供YGOPro客户端连接。
现用于[萌卡](https://mycard.moe/)[YGOPro 233服](http://mercury233.me/ygosrv233/)
### Linux下编译
* 需要以下组件或工具
* gcc
* premake5
* libevent
* lua5.3
* sqlite3
* 可参考本项目 [.travis.yml](https://github.com/mycard/ygopro/blob/server/.travis.yml) 中的脚本
### Windows下编译
* 需要以下组件或工具
* Visual Studio
* premake5
* libevent
* lua5.3
* sqlite3
* 可参考本项目 [appveyor.yml](https://github.com/mycard/ygopro/blob/server/appveyor.yml) 中的脚本
### MacOS下编译
* 需要以下组件或工具
* clang
* premake5
* libevent
* lua5.3
* sqlite3
* 参考步骤
* 安装libevent sqlite3
* 编译premake5
* wget https://www.lua.org/ftp/lua-5.4.3.tar.gz && tar xf lua-5.4.3.tar.gz && mv lua-5.4.3 lua && cp premake/lua/* lua/
* ./premake5 gmake --cc=clang
* cd build && make config=release
### 运行
* 使用[ygopro-server](https://github.com/mycard/ygopro-server)运行
* 手动运行的参数是
* `./ygopro 0 0 0 1 F F F 8000 5 1 180 0`
* 端口(0为随机)
* 禁卡表编号
* 卡片允许
* 决斗模式
* 决斗规则编号
* 不检查卡组
* 不洗切卡组
* 初始LP
* 初始手牌数
* 每回合抽卡
* 每回合时间
* 特殊选项,按位选择
* 0x1: 保存录像到 `./replay` 文件夹
* 0x2: 不向观战者发送录像
version: '{build}'
image: Visual Studio 2019
environment:
matrix:
- SERVER_MODE: true
- SERVER_PRO2_SUPPORT: true
install:
- git submodule update --init --recursive
# environment and system dependency
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-windows.zip ; exit 0"
- 7z x premake-5.0.0-beta2-windows.zip
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz ; exit 0"
- tar xf libevent-2.0.22-stable.tar.gz
- move libevent-2.0.22-stable event
- xcopy /E event\WIN32-Code event\include
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.lua.org/ftp/lua-5.4.4.tar.gz ; exit 0"
- tar xf lua-5.4.4.tar.gz
- move lua-5.4.4 lua
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.sqlite.org/2022/sqlite-amalgamation-3390300.zip ; exit 0"
- 7z x sqlite-amalgamation-3390300.zip
- move sqlite-amalgamation-3390300 sqlite3
before_build:
- xcopy /E premake\* .
- premake5 vs2019
configuration: Release
build:
project: build/YGOPro.sln
parallel: true
test: off
for:
-
matrix:
only:
- SERVER_PRO2_SUPPORT: true
before_build:
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name http://downloads.sourceforge.net/irrlicht/irrlicht-1.8.5.zip ; exit 0"
- 7z x irrlicht-1.8.5.zip
- move irrlicht-1.8.5 irrlicht
- xcopy /E premake\* .
- cd irrlicht
- patch -p1 < irrlicht.patch
- cd ..
- premake5 vs2019
after_build:
- ps: move bin\release\AI.Server.exe .
artifacts:
- path: AI.Server.exe
name: YGOPro server for YGOPro2 AI
cache:
- premake-5.0.0-beta2-windows.zip
- libevent-2.0.22-stable.tar.gz
- irrlicht-1.8.5.zip
- lua-5.4.4.tar.gz
- sqlite-amalgamation-3390300.zip
File added
......@@ -36,6 +36,7 @@ typedef std::unordered_map<unsigned int, CardDataC>::const_iterator code_pointer
class ClientCard {
public:
#ifndef YGOPRO_SERVER_MODE
irr::core::matrix4 mTransform;
irr::core::vector3df curPos;
irr::core::vector3df curRot;
......@@ -110,6 +111,7 @@ public:
static bool deck_sort_atk(code_pointer l1, code_pointer l2);
static bool deck_sort_def(code_pointer l1, code_pointer l2);
static bool deck_sort_name(code_pointer l1, code_pointer l2);
#endif //YGOPRO_SERVER_MODE
};
}
......
......@@ -56,6 +56,7 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
return swprintf(buf, N, fmt, args...);
}
#ifndef YGOPRO_SERVER_MODE
#include <irrlicht.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
......@@ -66,6 +67,7 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
#endif //__APPLE__
#include "CGUITTFont.h"
#include "CGUIImageButton.h"
#endif //YGOPRO_SERVER_MODE
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
......@@ -79,12 +81,20 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/common.h"
#ifndef YGOPRO_SERVER_MODE
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#endif //YGOPRO_SERVER_MODE
#ifdef SERVER_ZIP_SUPPORT
#include <irrlicht.h>
using namespace irr;
using namespace io;
#endif
typedef int BOOL;
......
......@@ -6,12 +6,19 @@ namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
byte DataManager::scriptBuffer[0x20000];
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
IFileSystem* DataManager::FileSystem;
#endif
DataManager dataManager;
bool DataManager::LoadDB(const wchar_t* wfile) {
char file[256];
BufferIO::EncodeUTF8(wfile, file);
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
sqlite3* pDB;
if(sqlite3_open_v2(file, &pDB, SQLITE_OPEN_READONLY, 0) != SQLITE_OK)
return Error(pDB);
#else
#ifdef _WIN32
IReadFile* reader = FileSystem->createAndOpenFile(wfile);
#else
......@@ -30,18 +37,33 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
if(spmemvfs_open_db(&db, file, mem) != SQLITE_OK)
return Error(&db);
sqlite3* pDB = db.handle;
#endif //YGOPRO_SERVER_MODE
sqlite3_stmt* pStmt;
#ifdef YGOPRO_SERVER_MODE
const char* sql = "select * from datas";
#else
const char* sql = "select * from datas,texts where datas.id=texts.id";
#endif
if(sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK)
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
return Error(pDB);
#else
return Error(&db);
#endif
CardDataC cd;
CardString cs;
#ifndef YGOPRO_SERVER_MODE
wchar_t strBuffer[4096];
#endif
int step = 0;
do {
step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
return Error(pDB, pStmt);
#else
return Error(&db, pStmt);
#endif
else if(step == SQLITE_ROW) {
cd.code = sqlite3_column_int(pStmt, 0);
cd.ot = sqlite3_column_int(pStmt, 1);
......@@ -63,6 +85,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
cd.attribute = sqlite3_column_int(pStmt, 9);
cd.category = sqlite3_column_int(pStmt, 10);
_datas[cd.code] = cd;
#ifndef YGOPRO_SERVER_MODE
if(const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.name = strBuffer;
......@@ -78,11 +101,16 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
}
}
_strings[cd.code] = cs;
#endif //YGOPRO_SERVER_MODE
}
} while(step != SQLITE_DONE);
sqlite3_finalize(pStmt);
#ifdef YGOPRO_SERVER_MODE
sqlite3_close(pDB);
#else
spmemvfs_close_db(&db);
spmemvfs_env_fini();
#endif
return true;
}
bool DataManager::LoadStrings(const char* file) {
......@@ -98,6 +126,7 @@ bool DataManager::LoadStrings(const char* file) {
myswprintf(numStrings[i], L"%d", i);
return true;
}
#ifndef YGOPRO_SERVER_MODE
bool DataManager::LoadStrings(IReadFile* reader) {
char ch[2] = " ";
char linebuf[256] = "";
......@@ -113,6 +142,7 @@ bool DataManager::LoadStrings(IReadFile* reader) {
reader->drop();
return true;
}
#endif //YGOPRO_SERVER_MODE
void DataManager::ReadStringConfLine(const char* linebuf) {
if(linebuf[0] != '!')
return;
......@@ -138,6 +168,16 @@ void DataManager::ReadStringConfLine(const char* linebuf) {
_setnameStrings[value] = strBuffer;
}
}
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
wchar_t strBuffer[4096];
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB), strBuffer);
if(pStmt)
sqlite3_finalize(pStmt);
sqlite3_close(pDB);
return false;
}
#else
bool DataManager::Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt) {
wchar_t strBuffer[4096];
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB->handle), strBuffer);
......@@ -147,6 +187,7 @@ bool DataManager::Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt) {
spmemvfs_env_fini();
return false;
}
#endif //YGOPRO_SERVER_MODE
bool DataManager::GetData(unsigned int code, CardData* pData) {
auto cdit = _datas.find(code);
if(cdit == _datas.end())
......@@ -366,6 +407,20 @@ uint32 DataManager::CardReader(uint32 code, card_data* pData) {
}
byte* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
// default script name: ./script/c%d.lua
#ifdef YGOPRO_SERVER_MODE
char first[256];
char second[256];
char third[256];
sprintf(first, "specials/%s", script_name + 9);
sprintf(second, "expansions/%s", script_name + 2);
sprintf(third, "%s", script_name + 2);
if(ScriptReader(first, slen))
return scriptBuffer;
else if(ScriptReader(second, slen))
return scriptBuffer;
else
return ScriptReader(third, slen);
#else
char first[256];
char second[256];
if(mainGame->gameConf.prefer_expansion_script) {
......@@ -379,8 +434,19 @@ byte* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
return scriptBuffer;
else
return ScriptReader(second, slen);
#endif //YGOPRO_SERVER_MODE
}
byte* DataManager::ScriptReader(const char* script_name, int* slen) {
#if defined(YGOPRO_SERVER_MODE) && !defined(SERVER_ZIP_SUPPORT)
FILE* fp = fopen(script_name, "rb");
if(!fp)
return 0;
int len = fread(scriptBuffer, 1, sizeof(scriptBuffer), fp);
fclose(fp);
if(len >= sizeof(scriptBuffer))
return 0;
*slen = len;
#else
#ifdef _WIN32
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
......@@ -398,6 +464,7 @@ byte* DataManager::ScriptReader(const char* script_name, int* slen) {
reader->read(scriptBuffer, size);
reader->drop();
*slen = size;
#endif //YGOPRO_SERVER_MODE
return scriptBuffer;
}
......
......@@ -3,7 +3,9 @@
#include "config.h"
#include "sqlite3.h"
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
#include "spmemvfs/spmemvfs.h"
#endif
#include "client_card.h"
#include <unordered_map>
......@@ -14,9 +16,15 @@ public:
DataManager(): _datas(16384), _strings(16384) {}
bool LoadDB(const wchar_t* wfile);
bool LoadStrings(const char* file);
#ifndef YGOPRO_SERVER_MODE
bool LoadStrings(IReadFile* reader);
#endif
void ReadStringConfLine(const char* linebuf);
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
bool Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt = 0);
#else
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = 0);
#endif //YGOPRO_SERVER_MODE
bool GetData(unsigned int code, CardData* pData);
code_pointer GetCodePointer(int code);
bool GetString(int code, CardString* pStr);
......@@ -56,7 +64,9 @@ public:
static uint32 CardReader(uint32, card_data*);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReader(const char* script_name, int* slen);
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
static IFileSystem* FileSystem;
#endif
};
extern DataManager dataManager;
......
......@@ -5,7 +5,9 @@
namespace ygo {
#ifndef YGOPRO_SERVER_MODE
char DeckManager::deckBuffer[0x10000];
#endif
DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) {
......@@ -49,6 +51,9 @@ void DeckManager::LoadLFListSingle(const char* path) {
}
}
void DeckManager::LoadLFList() {
#ifdef SERVER_PRO2_SUPPORT
LoadLFListSingle("config/lflist.conf");
#endif
LoadLFListSingle("expansions/lflist.conf");
LoadLFListSingle("lflist.conf");
LFList nolimit;
......@@ -204,6 +209,7 @@ bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) {
deck = ndeck;
return true;
}
#ifndef YGOPRO_SERVER_MODE
void DeckManager::GetCategoryPath(wchar_t* ret, int index, const wchar_t* text) {
wchar_t catepath[256];
switch(index) {
......@@ -369,4 +375,5 @@ bool DeckManager::DeleteCategory(const wchar_t* name) {
return false;
return FileSystem::DeleteDir(localname);
}
#endif //YGOPRO_SERVER_MODE
}
......@@ -5,7 +5,9 @@
#include "client_card.h"
#include <unordered_map>
#include <vector>
#ifndef YGOPRO_SERVER_MODE
#include <sstream>
#endif
namespace ygo {
......@@ -36,7 +38,9 @@ public:
Deck current_deck;
std::vector<LFList> _lfList;
#ifndef YGOPRO_SERVER_MODE
static char deckBuffer[0x10000];
#endif
void LoadLFListSingle(const char* path);
void LoadLFList();
......@@ -45,6 +49,7 @@ public:
int CheckDeck(Deck& deck, 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
void GetCategoryPath(wchar_t* ret, int index, const wchar_t* text);
void GetDeckFile(wchar_t* ret, irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBox* cbDeck);
bool LoadDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBox* cbDeck);
......@@ -57,6 +62,7 @@ public:
bool CreateCategory(const wchar_t* name);
bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
bool DeleteCategory(const wchar_t* name);
#endif //YGOPRO_SERVER_MODE
};
extern DeckManager deckManager;
......
#include "config.h"
#include "game.h"
#ifdef YGOPRO_SERVER_MODE
#include "data_manager.h"
#include "deck_manager.h"
#include "replay.h"
#ifdef SERVER_ZIP_SUPPORT
#include "CFileSystem.h"
namespace irr {
namespace core {
// taken from Irrlicht.cpp beacuse that file is not included
irr::core::stringc LOCALE_DECIMAL_POINTS(".");
}
}
#endif
#else
#include "image_manager.h"
#include "data_manager.h"
#include "deck_manager.h"
......@@ -9,6 +23,7 @@
#include "duelclient.h"
#include "netserver.h"
#include "single_mode.h"
#endif //YGOPRO_SERVER_MODE
const unsigned short PRO_VERSION = 0x1360;
......@@ -48,6 +63,33 @@ void DuelInfo::Clear() {
time_left[1] = 0;
}
#ifdef YGOPRO_SERVER_MODE
unsigned short server_port;
unsigned short replay_mode;
unsigned int pre_seed[3];
HostInfo game_info;
void Game::MainServerLoop() {
#ifdef SERVER_ZIP_SUPPORT
dataManager.FileSystem = new irr::io::CFileSystem();
#endif
deckManager.LoadLFList();
dataManager.LoadDB(L"cards.cdb");
LoadExpansions();
#ifdef SERVER_PRO2_SUPPORT
dataManager.FileSystem->addFileArchive("data/script.zip", true, false, EFAT_ZIP);
#endif
server_port = NetServer::StartServer(server_port);
NetServer::InitDuel();
printf("%u\n", server_port);
fflush(stdout);
while(NetServer::net_evbase) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
#else //YGOPRO_SERVER_MODE
bool Game::Initialize() {
LoadConfig();
irr::SIrrlichtCreationParameters params = irr::SIrrlichtCreationParameters();
......@@ -1137,18 +1179,31 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth,
ret.assign(strBuffer);
return ret;
}
#endif //YGOPRO_SERVER_MODE
void Game::LoadExpansions() {
#ifdef SERVER_PRO2_SUPPORT
FileSystem::TraversalDir(L"./cdb", [](const wchar_t* name, bool isdir) {
wchar_t fpath[1024];
myswprintf(fpath, L"./cdb/%ls", name);
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".cdb", 4)) {
dataManager.LoadDB(fpath);
}
});
#endif // SERVER_PRO2_SUPPORT
FileSystem::TraversalDir(L"./expansions", [](const wchar_t* name, bool isdir) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".cdb", 4)) {
dataManager.LoadDB(fpath);
}
#ifndef YGOPRO_SERVER_MODE
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".conf", 5)) {
char upath[1024];
BufferIO::EncodeUTF8(fpath, upath);
dataManager.LoadStrings(upath);
}
#endif // YGOPRO_SERVER_MODE
#if defined(SERVER_ZIP_SUPPORT) || !defined(YGOPRO_SERVER_MODE)
if(!isdir && wcsrchr(name, '.') && (!mywcsncasecmp(wcsrchr(name, '.'), L".zip", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".ypk", 4))) {
#ifdef _WIN32
dataManager.FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP);
......@@ -1158,7 +1213,9 @@ void Game::LoadExpansions() {
dataManager.FileSystem->addFileArchive(upath, true, false, EFAT_ZIP);
#endif
}
#endif //SERVER_ZIP_SUPPORT
});
#if defined(SERVER_ZIP_SUPPORT) || !defined(YGOPRO_SERVER_MODE)
for(u32 i = 0; i < DataManager::FileSystem->getFileArchiveCount(); ++i) {
const IFileList* archive = DataManager::FileSystem->getFileArchive(i)->getFileList();
for(u32 j = 0; j < archive->getFileCount(); ++j) {
......@@ -1171,6 +1228,7 @@ void Game::LoadExpansions() {
#endif
if(wcsrchr(fname, '.') && !mywcsncasecmp(wcsrchr(fname, '.'), L".cdb", 4))
dataManager.LoadDB(fname);
#ifndef YGOPRO_SERVER_MODE
if(wcsrchr(fname, '.') && !mywcsncasecmp(wcsrchr(fname, '.'), L".conf", 5)) {
#ifdef _WIN32
IReadFile* reader = DataManager::FileSystem->createAndOpenFile(fname);
......@@ -1182,9 +1240,12 @@ void Game::LoadExpansions() {
if(wcsrchr(fname, '.') && !mywcsncasecmp(wcsrchr(fname, '.'), L".ydk", 4)) {
deckBuilder.expansionPacks.push_back(fname);
}
#endif // YGOPRO_SERVER_MODE
}
}
#endif //SERVER_ZIP_SUPPORT
}
#ifndef YGOPRO_SERVER_MODE
void Game::RefreshCategoryDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBox* cbDeck, bool selectlastused) {
cbCategory->clear();
cbCategory->addItem(dataManager.GetSysString(1450));
......@@ -1729,7 +1790,11 @@ void Game::ClearChatMsg() {
chatTiming[i] = 0;
}
}
#endif //YGOPRO_SERVER_MODE
void Game::AddDebugMsg(const char* msg) {
#ifdef YGOPRO_SERVER_MODE
fprintf(stderr, "%s\n", msg);
#else
if (enable_log & 0x1) {
wchar_t wbuf[1024];
BufferIO::DecodeUTF8(msg, wbuf);
......@@ -1740,7 +1805,9 @@ void Game::AddDebugMsg(const char* msg) {
sprintf(msgbuf, "[Script Error]: %s", msg);
ErrorLog(msgbuf);
}
#endif //YGOPRO_SERVER_MODE
}
#ifndef YGOPRO_SERVER_MODE
void Game::ErrorLog(const char* msg) {
FILE* fp = fopen("error.log", "at");
if(!fp)
......@@ -2147,5 +2214,6 @@ void Game::SetCursor(ECURSOR_ICON icon) {
cursor->setActiveIcon(icon);
}
}
#endif //YGOPRO_SERVER_MODE
}
......@@ -2,15 +2,20 @@
#define GAME_H
#include "config.h"
#ifndef YGOPRO_SERVER_MODE
#include "client_field.h"
#include "deck_con.h"
#include "menu_handler.h"
#else
#include "netserver.h"
#endif //YGOPRO_SERVER_MODE
#include <unordered_map>
#include <vector>
#include <list>
namespace ygo {
#ifndef YGOPRO_SERVER_MODE
struct Config {
bool use_d3d;
bool use_image_scale;
......@@ -116,11 +121,17 @@ struct FadingUnit {
irr::core::vector2di fadingLR;
irr::core::vector2di fadingDiff;
};
#endif //YGOPRO_SERVER_MODE
class Game {
public:
bool Initialize();
#ifdef YGOPRO_SERVER_MODE
void MainServerLoop();
void LoadExpansions();
void AddDebugMsg(const char* msgbuf);
#else
void MainLoop();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
void InitStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, u32 cHeight, irr::gui::CGUITTFont* font, const wchar_t* text);
......@@ -589,10 +600,17 @@ public:
irr::gui::IGUIButton* btnBigCardZoomIn;
irr::gui::IGUIButton* btnBigCardZoomOut;
irr::gui::IGUIButton* btnBigCardClose;
#endif //YGOPRO_SERVER_MODE
};
extern Game* mainGame;
#ifdef YGOPRO_SERVER_MODE
extern unsigned short server_port;
extern unsigned short replay_mode;
extern HostInfo game_info;
extern unsigned int pre_seed[3];
#endif
}
#define SIZE_QUERY_BUFFER 0x4000
......
......@@ -8,6 +8,7 @@
#endif
int enable_log = 0;
#ifndef YGOPRO_SERVER_MODE
bool exit_on_return = false;
bool open_file = false;
wchar_t open_file_name[256] = L"";
......@@ -20,12 +21,13 @@ void ClickButton(irr::gui::IGUIElement* btn) {
event.GUIEvent.Caller = btn;
ygo::mainGame->device->postEventFromUser(event);
}
#endif //YGOPRO_SERVER_MODE
int main(int argc, char* argv[]) {
#ifndef _WIN32
setlocale(LC_CTYPE, "UTF-8");
#endif
#ifdef __APPLE__
#if defined __APPLE__ && !defined YGOPRO_SERVER_MODE
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef bundle_base_url = CFURLCreateCopyDeletingLastPathComponent(NULL, bundle_url);
CFRelease(bundle_url);
......@@ -57,6 +59,66 @@ int main(int argc, char* argv[]) {
evthread_use_pthreads();
#endif //_WIN32
ygo::Game _game;
#ifdef YGOPRO_SERVER_MODE
enable_log = 1;
ygo::server_port = 7911;
ygo::replay_mode = 0;
ygo::game_info.lflist = 0;
ygo::game_info.rule = 0;
ygo::game_info.mode = 0;
ygo::game_info.start_hand = 5;
ygo::game_info.start_lp = 8000;
ygo::game_info.draw_count = 1;
ygo::game_info.no_check_deck = false;
ygo::game_info.no_shuffle_deck = false;
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180;
for (int i = 0; i < 3; ++i)
ygo::pre_seed[i] = (unsigned int)0;
if (argc > 1) {
ygo::server_port = atoi(argv[1]);
int lflist = atoi(argv[2]);
if(lflist < 0)
lflist = 999;
ygo::game_info.lflist = lflist;
ygo::game_info.rule = atoi(argv[3]);
int mode = atoi(argv[4]);
if(mode > 2)
mode = 0;
ygo::game_info.mode = mode;
if(argv[5][0] == 'T')
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE - 1;
else if(argv[5][0] == 'F')
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
else {
int master_rule = atoi(argv[5]);
if(master_rule)
ygo::game_info.duel_rule = master_rule;
else
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
}
if(argv[6][0] == 'T')
ygo::game_info.no_check_deck = true;
else
ygo::game_info.no_check_deck = false;
if(argv[7][0] == 'T')
ygo::game_info.no_shuffle_deck = true;
else
ygo::game_info.no_shuffle_deck = false;
ygo::game_info.start_lp = atoi(argv[8]);
ygo::game_info.start_hand = atoi(argv[9]);
ygo::game_info.draw_count = atoi(argv[10]);
ygo::game_info.time_limit = atoi(argv[11]);
ygo::replay_mode = atoi(argv[12]);
for (int i = 13; (i < argc && i <= 15) ; ++i)
{
ygo::pre_seed[i - 13] = (unsigned int)atol(argv[i]);
}
}
ygo::mainGame = &_game;
ygo::mainGame->MainServerLoop();
return 0;
#else //YGOPRO_SERVER_MODE
ygo::mainGame = &_game;
if(!ygo::mainGame->Initialize())
return 0;
......@@ -197,5 +259,6 @@ int main(int argc, char* argv[]) {
#else
#endif //_WIN32
#endif //YGOPRO_SERVER_MODE
return EXIT_SUCCESS;
}
......@@ -193,10 +193,12 @@ public:
return success;
}
#ifndef YGOPRO_SERVER_MODE
struct file_unit {
std::string filename;
bool is_dir;
};
#endif
static void TraversalDir(const char* path, const std::function<void(const char*, bool)>& cb) {
DIR* dir = nullptr;
......@@ -204,26 +206,40 @@ public:
if((dir = opendir(path)) == nullptr)
return;
struct stat fileStat;
#ifndef YGOPRO_SERVER_MODE
std::vector<file_unit> file_list;
#endif
while((dirp = readdir(dir)) != nullptr) {
#ifndef YGOPRO_SERVER_MODE
file_unit funit;
#endif
char fname[1024];
strcpy(fname, path);
strcat(fname, "/");
strcat(fname, dirp->d_name);
stat(fname, &fileStat);
#ifdef YGOPRO_SERVER_MODE
bool is_dir = S_ISDIR(fileStat.st_mode);
if (is_dir && (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) || strcmp(dirp->d_name, ".git") == 0)
continue;
cb(dirp->d_name, is_dir);
#else
funit.filename = std::string(dirp->d_name);
funit.is_dir = S_ISDIR(fileStat.st_mode);
if(funit.is_dir && (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0))
continue;
file_list.push_back(funit);
#endif
}
closedir(dir);
#ifndef YGOPRO_SERVER_MODE
std::sort(file_list.begin(), file_list.end(), TraversalDirSort);
for (file_unit funit : file_list)
cb(funit.filename.c_str(), funit.is_dir);
#endif
}
#ifndef YGOPRO_SERVER_MODE
static bool TraversalDirSort(file_unit file1, file_unit file2) {
if(file1.is_dir != file2.is_dir) {
return file2.is_dir;
......@@ -231,6 +247,7 @@ public:
return file1.filename < file2.filename;
}
}
#endif
static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) {
char path[1024];
......
......@@ -13,7 +13,73 @@ unsigned char NetServer::net_server_read[0x2000];
unsigned char NetServer::net_server_write[0x2000];
unsigned short NetServer::last_sent = 0;
#ifdef YGOPRO_SERVER_MODE
extern unsigned short replay_mode;
extern HostInfo game_info;
void NetServer::InitDuel()
{
if(game_info.mode == MODE_SINGLE) {
duel_mode = new SingleDuel(false);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(game_info.mode == MODE_MATCH) {
duel_mode = new SingleDuel(true);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(game_info.mode == MODE_TAG) {
duel_mode = new TagDuel();
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, TagDuel::TagTimer, duel_mode);
}
CTOS_CreateGame* pkt = new CTOS_CreateGame;
pkt->info.mode = game_info.mode;
pkt->info.start_hand = game_info.start_hand;
pkt->info.start_lp = game_info.start_lp;
pkt->info.draw_count = game_info.draw_count;
pkt->info.no_check_deck = game_info.no_check_deck;
pkt->info.no_shuffle_deck = game_info.no_shuffle_deck;
pkt->info.duel_rule = game_info.duel_rule;
pkt->info.rule = game_info.rule;
pkt->info.time_limit = game_info.time_limit;
if(game_info.lflist == 999)
pkt->info.lflist = 0;
else if(game_info.lflist >= deckManager._lfList.size())
pkt->info.lflist = deckManager._lfList[0].hash;
else
pkt->info.lflist = deckManager._lfList[game_info.lflist].hash;
duel_mode->host_info = pkt->info;
BufferIO::CopyWStr(pkt->name, duel_mode->name, 20);
BufferIO::CopyWStr(pkt->pass, duel_mode->pass, 20);
}
bool NetServer::IsCanIncreaseTime(unsigned short gameMsg, void *pdata, unsigned int len) {
int32* ivalue = (int32*)pdata;
switch(gameMsg) {
case MSG_RETRY:
case MSG_SELECT_UNSELECT_CARD:
return false;
case MSG_SELECT_CHAIN:
return ivalue[0] != -1;
case MSG_SELECT_IDLECMD: {
int32 idleChoice = ivalue[0] & 0xffff;
return idleChoice <= 5; // no shuffle hand, enter other phases
}
case MSG_SELECT_BATTLECMD: {
int32 battleChoice = ivalue[0] & 0xffff;
return battleChoice <= 1; // attack only
}
default:
return true;
}
}
unsigned short NetServer::StartServer(unsigned short port) {
#else
bool NetServer::StartServer(unsigned short port) {
#endif //YGOPRO_SERVER_MODE
if(net_evbase)
return false;
net_evbase = event_base_new();
......@@ -23,7 +89,11 @@ bool NetServer::StartServer(unsigned short port) {
memset(&sin, 0, sizeof(sin));
server_port = port;
sin.sin_family = AF_INET;
#ifdef SERVER_PRO2_SUPPORT
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#else
sin.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
sin.sin_port = htons(port);
listener = evconnlistener_new_bind(net_evbase, ServerAccept, NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (sockaddr*)&sin, sizeof(sin));
......@@ -34,7 +104,15 @@ bool NetServer::StartServer(unsigned short port) {
}
evconnlistener_set_error_cb(listener, ServerAcceptError);
std::thread(ServerThread).detach();
#ifdef YGOPRO_SERVER_MODE
evutil_socket_t fd = evconnlistener_get_fd(listener);
socklen_t addrlen = sizeof(sockaddr);
sockaddr_in addr;
getsockname(fd, (sockaddr*)&addr, &addrlen);
return ntohs(addr.sin_port);
#else
return true;
#endif //YGOPRO_SERVER_MODE
}
bool NetServer::StartBroadcast() {
if(!net_evbase)
......@@ -61,7 +139,12 @@ void NetServer::StopServer() {
return;
if(duel_mode)
duel_mode->EndDuel();
#ifdef YGOPRO_SERVER_MODE // For solving the problem of connection lost after duel. See https://github.com/Fluorohydride/ygopro/issues/2067 for details.
timeval etv = { 0, 1 };
event_base_loopexit(net_evbase, &etv);
#else
event_base_loopexit(net_evbase, 0);
#endif
}
void NetServer::StopBroadcast() {
if(!net_evbase || !broadcast_ev)
......@@ -174,7 +257,11 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) {
void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned int len) {
auto pdata = data;
unsigned char pktType = BufferIO::ReadUInt8(pdata);
#ifdef YGOPRO_SERVER_MODE
if((pktType != CTOS_SURRENDER) && (pktType != CTOS_CHAT) && (pktType != CTOS_REQUEST_FIELD) && (dp->state == 0xff || (dp->state && dp->state != pktType)))
#else
if((pktType != CTOS_SURRENDER) && (pktType != CTOS_CHAT) && (dp->state == 0xff || (dp->state && dp->state != pktType)))
#endif
return;
switch(pktType) {
case CTOS_RESPONSE: {
......@@ -304,6 +391,14 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
duel_mode->StartDuel(dp);
break;
}
#ifdef YGOPRO_SERVER_MODE
case CTOS_REQUEST_FIELD: {
if(!dp->game || !duel_mode->pduel)
break;
duel_mode->RequestField(dp);
break;
}
#endif
}
}
......
......@@ -14,7 +14,9 @@ class NetServer {
private:
static std::unordered_map<bufferevent*, DuelPlayer> users;
static unsigned short server_port;
#ifndef YGOPRO_SERVER_MODE
static event_base* net_evbase;
#endif
static event* broadcast_ev;
static evconnlistener* listener;
static DuelMode* duel_mode;
......@@ -23,7 +25,14 @@ private:
static unsigned short last_sent;
public:
#ifdef YGOPRO_SERVER_MODE
static event_base* net_evbase;
static void InitDuel();
static unsigned short StartServer(unsigned short port);
static bool IsCanIncreaseTime(unsigned short gameMsg, void *pdata, unsigned int len);
#else
static bool StartServer(unsigned short port);
#endif //YGOPRO_SERVER_MODE
static bool StartBroadcast();
static void StopServer();
static void StopBroadcast();
......@@ -68,6 +77,14 @@ public:
if(dp)
bufferevent_write(dp->bev, net_server_write, last_sent);
}
#ifdef YGOPRO_SERVER_MODE
static void ReSendToPlayers(DuelPlayer* dp1, DuelPlayer* dp2) {
if(dp1)
bufferevent_write(dp1->bev, net_server_write, last_sent);
if(dp2)
bufferevent_write(dp2->bev, net_server_write, last_sent);
}
#endif //YGOPRO_SERVER_MODE
};
}
......
......@@ -129,6 +129,9 @@ public:
virtual void Surrender(DuelPlayer* dp) {}
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {}
virtual void TimeConfirm(DuelPlayer* dp) {}
#ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp) {}
#endif
virtual void EndDuel() {};
public:
......@@ -171,6 +174,9 @@ public:
#define CTOS_HS_NOTREADY 0x23
#define CTOS_HS_KICK 0x24
#define CTOS_HS_START 0x25
#ifdef YGOPRO_SERVER_MODE
#define CTOS_REQUEST_FIELD 0x30
#endif
#define STOC_GAME_MSG 0x1
#define STOC_ERROR_MSG 0x2
......@@ -193,6 +199,9 @@ public:
#define STOC_HS_PLAYER_ENTER 0x20
#define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22
#ifdef YGOPRO_SERVER_MODE
#define STOC_FIELD_FINISH 0x30
#endif
#define PLAYERCHANGE_OBSERVE 0x8
#define PLAYERCHANGE_READY 0x9
......
include "lzma/."
if (SERVER_ZIP_SUPPORT or not SERVER_MODE) then
include "spmemvfs/."
end
project "YGOPro"
project "ygopro"
if SERVER_MODE then
kind "ConsoleApp"
defines { "YGOPRO_SERVER_MODE" }
files { "gframe.cpp", "config.h",
"game.cpp", "game.h", "myfilesystem.h",
"deck_manager.cpp", "deck_manager.h",
"data_manager.cpp", "data_manager.h",
"replay.cpp", "replay.h",
"netserver.cpp", "netserver.h",
"single_duel.cpp", "single_duel.h",
"tag_duel.cpp", "tag_duel.h" }
includedirs { "../ocgcore" }
links { "ocgcore", "clzma", LUA_LIB_NAME, "sqlite3", "event" }
if SERVER_ZIP_SUPPORT then
defines { "SERVER_ZIP_SUPPORT" }
links { "irrlicht", "cspmemvfs" }
if BUILD_IRRLICHT then
includedirs { "../irrlicht/source/Irrlicht" }
end
end
if SERVER_PRO2_SUPPORT then
defines { "SERVER_PRO2_SUPPORT" }
end
else
kind "WindowedApp"
files { "*.cpp", "*.h" }
includedirs { "../ocgcore" }
links { "ocgcore", "clzma", "cspmemvfs", LUA_LIB_NAME, "sqlite3", "irrlicht", "freetype", "event" }
end
if BUILD_IKPMP3 then
links { "ikpmp3" }
......@@ -51,7 +80,12 @@ project "YGOPro"
filter "system:windows"
defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc"
if not SERVER_MODE then
libdirs { "$(DXSDK_DIR)Lib/x86" }
end
if SERVER_PRO2_SUPPORT then
targetname ("AI.Server")
end
if USE_IRRKLANG then
links { "irrKlang" }
if IRRKLANG_PRO then
......@@ -63,14 +97,20 @@ project "YGOPro"
filter {}
end
end
if SERVER_MODE then
links { "ws2_32" }
else
links { "opengl32", "ws2_32", "winmm", "gdi32", "kernel32", "user32", "imm32" }
end
filter "not action:vs*"
buildoptions { "-std=c++14", "-fno-rtti" }
filter "not system:windows"
links { "event_pthreads", "dl", "pthread" }
filter "system:macosx"
if not SERVER_MODE then
links { "z" }
defines { "GL_SILENCE_DEPRECATION" }
end
if MAC_ARM then
buildoptions { "--target=arm64-apple-macos12" }
linkoptions { "-arch arm64" }
......@@ -79,7 +119,9 @@ project "YGOPro"
links { "irrklang" }
end
filter "system:linux"
if not SERVER_MODE then
links { "GL", "X11", "Xxf86vm" }
end
if USE_IRRKLANG then
links { "IrrKlang" }
linkoptions{ IRRKLANG_LINK_RPATH }
......
......@@ -5,6 +5,10 @@
namespace ygo {
#ifdef YGOPRO_SERVER_MODE
extern unsigned short server_port;
extern unsigned short replay_mode;
#endif
Replay::Replay()
: fp(nullptr), pheader(), pdata(nullptr), replay_size(0), comp_size(0), is_recording(false), is_replaying(false) {
#ifdef _WIN32
......@@ -18,21 +22,47 @@ Replay::~Replay() {
delete[] comp_data;
}
void Replay::BeginRecord() {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode & REPLAY_MODE_SAVE_IN_SERVER) {
#endif
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return;
#ifdef _WIN32
if(is_recording)
CloseHandle(recording_fp);
#ifdef YGOPRO_SERVER_MODE
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
wchar_t tmppath[80];
wcsftime(tmppath, 80, L"./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
wchar_t path[80];
myswprintf(path, tmppath, server_port);
recording_fp = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
#else
recording_fp = CreateFileW(L"./replay/_LastReplay.yrp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
#endif //YGOPRO_SERVER_MODE
if(recording_fp == INVALID_HANDLE_VALUE)
return;
#else
if(is_recording)
fclose(fp);
#ifdef YGOPRO_SERVER_MODE
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
char tmppath[40];
strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
char path[40];
sprintf(path, tmppath, server_port);
fp = fopen(path, "wb");
#else
fp = fopen("./replay/_LastReplay.yrp", "wb");
#endif //YGOPRO_SERVER_MODE
if(!fp)
return;
#endif
#ifdef YGOPRO_SERVER_MODE
}
#endif //YGOPRO_SERVER_MODE
pdata = replay_data;
replay_size = 0;
comp_size = 0;
......@@ -41,6 +71,9 @@ void Replay::BeginRecord() {
}
void Replay::WriteHeader(ReplayHeader& header) {
pheader = header;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &header, sizeof(header), &size, NULL);
......@@ -56,6 +89,9 @@ void Replay::WriteData(const void* data, int length, bool flush) {
return;
memcpy(pdata, data, length);
pdata += length;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, data, length, &size, NULL);
......@@ -72,6 +108,9 @@ void Replay::WriteInt32(int data, bool flush) {
return;
*((int*)(pdata)) = data;
pdata += 4;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
......@@ -88,6 +127,9 @@ void Replay::WriteInt16(short data, bool flush) {
return;
*((short*)(pdata)) = data;
pdata += 2;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
......@@ -104,6 +146,9 @@ void Replay::WriteInt8(char data, bool flush) {
return;
*pdata = data;
pdata++;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
......@@ -116,6 +161,9 @@ void Replay::WriteInt8(char data, bool flush) {
void Replay::Flush() {
if(!is_recording)
return;
#ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif
#ifdef _WIN32
#else
fflush(fp);
......@@ -124,10 +172,16 @@ void Replay::Flush() {
void Replay::EndRecord() {
if(!is_recording)
return;
#ifdef YGOPRO_SERVER_MODE
if(replay_mode & REPLAY_MODE_SAVE_IN_SERVER) {
#endif
#ifdef _WIN32
CloseHandle(recording_fp);
#else
fclose(fp);
#endif
#ifdef YGOPRO_SERVER_MODE
}
#endif
if(pdata - replay_data > 0 && pdata - replay_data <= MAX_REPLAY_SIZE)
replay_size = pdata - replay_data;
......
......@@ -16,6 +16,12 @@ namespace ygo {
#define MAX_REPLAY_SIZE 0x20000
#define MAX_COMP_SIZE 0x2000
#ifdef YGOPRO_SERVER_MODE
#define REPLAY_MODE_SAVE_IN_SERVER 0x1
#define REPLAY_MODE_WATCHER_NO_SEND 0x2
#define REPLAY_MODE_INCLUDE_CHAT 0x4
#endif // YGOPRO_SERVER_MODE
struct ReplayHeader {
unsigned int id;
unsigned int version;
......
This diff is collapsed.
......@@ -27,15 +27,27 @@ public:
virtual int Analyze(unsigned char* msgbuffer, unsigned int len);
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len);
virtual void TimeConfirm(DuelPlayer* dp);
#ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp);
#endif
virtual void EndDuel();
void DuelEndProc();
void WaitforResponse(int playerid);
#ifdef YGOPRO_SERVER_MODE
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshHand(int player, int flag = 0x681fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshExtra(int player, int flag = 0xe81fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshRemoved(int player, int flag = 0x81fff, int use_cache = 1, DuelPlayer* dp = 0);
#else
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshHand(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshExtra(int player, int flag = 0xe81fff, int use_cache = 1);
#endif
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static uint32 MessageHandler(intptr_t fduel, uint32 type);
......@@ -52,6 +64,12 @@ protected:
unsigned char hand_result[2]{ 0 };
unsigned char last_response{ 0 };
std::set<DuelPlayer*> observers;
#ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder;
DuelPlayer* replay_recorder;
unsigned char turn_player;
unsigned short phase;
#endif
Replay last_replay;
bool match_mode{ false };
int match_kill{ 0 };
......@@ -60,9 +78,13 @@ protected:
unsigned char match_result[3]{ 0 };
short time_limit[2]{ 0 };
short time_elapsed{ 0 };
#ifdef YGOPRO_SERVER_MODE
short time_compensator[2];
short time_backed[2];
unsigned char last_game_msg;
#endif
};
}
#endif //SINGLE_DUEL_H
This diff is collapsed.
......@@ -27,15 +27,27 @@ public:
virtual int Analyze(unsigned char* msgbuffer, unsigned int len);
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len);
virtual void TimeConfirm(DuelPlayer* dp);
#ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp);
#endif
virtual void EndDuel();
void DuelEndProc();
void WaitforResponse(int playerid);
#ifdef YGOPRO_SERVER_MODE
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshHand(int player, int flag = 0x681fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshExtra(int player, int flag = 0xe81fff, int use_cache = 1, DuelPlayer* dp = 0);
void RefreshRemoved(int player, int flag = 0x81fff, int use_cache = 1, DuelPlayer* dp = 0);
#else
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshHand(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshExtra(int player, int flag = 0xe81fff, int use_cache = 1);
#endif
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static uint32 MessageHandler(intptr_t fduel, uint32 type);
......@@ -49,6 +61,12 @@ protected:
DuelPlayer* pplayer[4];
DuelPlayer* cur_player[2];
std::set<DuelPlayer*> observers;
#ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder;
DuelPlayer* replay_recorder;
int turn_player;
int phase;
#endif
bool ready[4];
Deck pdeck[4];
int deck_error[4];
......@@ -58,9 +76,13 @@ protected:
unsigned char turn_count;
short time_limit[2];
short time_elapsed;
#ifdef YGOPRO_SERVER_MODE
short time_compensator[2];
short time_backed[2];
unsigned char last_game_msg;
#endif
};
}
#endif //TAG_DUEL_H
Subproject commit feeaf9b3e889b8a87737efba8284e94d6d07415e
Subproject commit 6cb447a4032292f582f396ddeeceac3c3956f4bb
premake/gframe/ygopro.ico

205 KB | W: | H:

premake/gframe/ygopro.ico

17.1 KB | W: | H:

premake/gframe/ygopro.ico
premake/gframe/ygopro.ico
premake/gframe/ygopro.ico
premake/gframe/ygopro.ico
  • 2-up
  • Swipe
  • Onion skin
1 ICON "ygopro.ico"
1 VERSIONINFO
FILEVERSION 1, 0, 35, 3
PRODUCTVERSION 1, 0, 35, 3
FILEOS 0x4
FILETYPE 0x1
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "FileDescription", "YGOPro"
VALUE "InternalName", "YGOPro"
VALUE "LegalCopyright", "Copyright (C) 2022 Fluorohydride"
VALUE "OriginalFilename", "YGOPro.exe"
VALUE "ProductName", "YGOPro"
VALUE "FileVersion", "1.035.3"
VALUE "ProductVersion", "1.035.3"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
1 ICON "ygopro.ico"
1 VERSIONINFO
FILEVERSION 1, 0, 35, 3
PRODUCTVERSION 1, 0, 35, 3
FILEOS 0x4
FILETYPE 0x1
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "FileDescription", "YGOPro Server Mode"
VALUE "InternalName", "YGOPro Server Mode"
VALUE "LegalCopyright", "Copyright (C) 2022 Fluorohydride"
VALUE "OriginalFilename", "YGOPro.exe"
VALUE "ProductName", "YGOPro Server Mode"
VALUE "FileVersion", "1.035.3"
VALUE "ProductVersion", "1.035.3"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
project "irrlicht"
kind "StaticLib"
includedirs { "include", "source/Irrlicht", "source/Irrlicht/zlib" }
defines {
"_IRR_STATIC_LIB_",
"NO_IRR_COMPILE_WITH_ZIP_ENCRYPTION_",
"NO_IRR_COMPILE_WITH_BZIP2_",
"NO__IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_"
}
exceptionhandling "Off"
rtti "Off"
files {
"source/Irrlicht/os.cpp",
"source/Irrlicht/zlib/adler32.c",
"source/Irrlicht/zlib/crc32.c",
"source/Irrlicht/zlib/inffast.c",
"source/Irrlicht/zlib/inflate.c",
"source/Irrlicht/zlib/inftrees.c",
"source/Irrlicht/zlib/zutil.c",
"source/Irrlicht/CAttributes.cpp",
"source/Irrlicht/CFileList.cpp",
"source/Irrlicht/CFileSystem.cpp",
"source/Irrlicht/CLimitReadFile.cpp",
"source/Irrlicht/CMemoryFile.cpp",
"source/Irrlicht/CReadFile.cpp",
"source/Irrlicht/CWriteFile.cpp",
"source/Irrlicht/CXMLReader.cpp",
"source/Irrlicht/CXMLWriter.cpp",
"source/Irrlicht/CZipReader.cpp"
}
filter { "system:windows" }
defines { "_IRR_WCHAR_FILESYSTEM" }
......@@ -9,6 +9,11 @@ USE_IRRKLANG = true
IRRKLANG_PRO = false
LUA_LIB_NAME = "lua"
SERVER_MODE = true
SERVER_ZIP_SUPPORT = false
SERVER_PRO2_SUPPORT = false
USE_IRRKLANG = false
-- read settings from command line or environment variables
newoption { trigger = "build-lua", category = "YGOPro - lua", description = "" }
......@@ -16,6 +21,7 @@ newoption { trigger = "no-build-lua", category = "YGOPro - lua", description = "
newoption { trigger = "lua-include-dir", category = "YGOPro - lua", description = "", value = "PATH" }
newoption { trigger = "lua-lib-dir", category = "YGOPro - lua", description = "", value = "PATH" }
newoption { trigger = "lua-lib-name", category = "YGOPro - lua", description = "", value = "NAME", default = "lua" }
newoption { trigger = "lua-deb", category = "YGOPro - lua", description = "" }
newoption { trigger = "build-event", category = "YGOPro - event", description = "" }
newoption { trigger = "no-build-event", category = "YGOPro - event", description = "" }
......@@ -51,6 +57,10 @@ newoption { trigger = 'build-ikpmp3', category = "YGOPro - irrklang - ikpmp3", d
newoption { trigger = "winxp-support", category = "YGOPro", description = "" }
newoption { trigger = "mac-arm", category = "YGOPro", description = "M1" }
newoption { trigger = "server-mode", category = "YGOPro - server", description = "" }
newoption { trigger = "server-zip-support", category = "YGOPro - server", description = "" }
newoption { trigger = "server-pro2-support", category = "YGOPro - server", description = "" }
function GetParam(param)
return _OPTIONS[param] or os.getenv(string.upper(string.gsub(param,"-","_")))
end
......@@ -68,6 +78,13 @@ if not BUILD_LUA then
LUA_LIB_NAME = GetParam("lua-lib-name")
end
if GetParam("lua-deb") then
BUILD_LUA = false
LUA_LIB_DIR = "/usr/lib/x86_64-linux-gnu"
LUA_LIB_NAME = "lua5.3-c++"
LUA_INCLUDE_DIR = "/usr/include/lua5.3"
end
if GetParam("build-event") then
BUILD_EVENT = os.istarget("windows") -- only on windows for now
elseif GetParam("no-build-event") then
......@@ -150,6 +167,17 @@ end
if GetParam("mac-arm") and os.istarget("macosx") then
MAC_ARM = true
end
if GetParam("server-mode") then
SERVER_MODE = true
SERVER_ZIP_SUPPORT = false
end
if GetParam("server-zip-support") then
SERVER_ZIP_SUPPORT = true
end
if GetParam("server-pro2-support") then
SERVER_PRO2_SUPPORT = true
SERVER_ZIP_SUPPORT = true
end
workspace "YGOPro"
location "build"
......@@ -176,7 +204,9 @@ workspace "YGOPro"
if MAC_ARM then
buildoptions { "--target=arm64-apple-macos12" }
end
if not SERVER_MODE then
links { "OpenGL.framework", "Cocoa.framework", "IOKit.framework" }
end
filter "system:linux"
buildoptions { "-U_FORTIFY_SOURCE" }
......@@ -223,15 +253,18 @@ workspace "YGOPro"
if BUILD_EVENT then
include "event"
end
if BUILD_FREETYPE then
if BUILD_FREETYPE and not SERVER_MODE then
include "freetype"
end
if BUILD_IRRLICHT then
if BUILD_IRRLICHT and not SERVER_MODE then
include "irrlicht"
end
if BUILD_IRRLICHT and SERVER_MODE and SERVER_ZIP_SUPPORT then
include "irrlicht/premake5-only-zipreader.lua"
end
if BUILD_SQLITE then
include "sqlite3"
end
if BUILD_IKPMP3 then
if BUILD_IKPMP3 and not SERVER_MODE then
include "ikpmp3"
end
Subproject commit d5747ceb983d601d117a838139fe13b0ec502057
Subproject commit 52e79efa0da5294cf5218c107de224a0af264965
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