Commit 38d27919 authored by nanahira's avatar nanahira

Merge branch 'server' into duplicate

parents b49909c8 54136b93
Pipeline #40284 canceled with stages
in 19 seconds
...@@ -144,7 +144,7 @@ jobs: ...@@ -144,7 +144,7 @@ jobs:
uses: mercury233/action-cache-download-file@v1.0.0 uses: mercury233/action-cache-download-file@v1.0.0
with: with:
url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz
- name: Extract opus - name: Extract opus
if: matrix.audiolib == 'miniaudio' if: matrix.audiolib == 'miniaudio'
run: | run: |
...@@ -398,7 +398,7 @@ jobs: ...@@ -398,7 +398,7 @@ jobs:
uses: mercury233/action-cache-download-file@v1.0.0 uses: mercury233/action-cache-download-file@v1.0.0
with: with:
url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz
- name: Extract opus - name: Extract opus
if: matrix.static-link == true if: matrix.static-link == true
run: | run: |
...@@ -437,8 +437,8 @@ jobs: ...@@ -437,8 +437,8 @@ jobs:
- name: Copy premake files - name: Copy premake files
run: | run: |
cp -r premake/* . cp -pr premake/* .
cp -r resource/* . cp -pr resource/* .
- name: Use premake to generate make files (apt packages) - name: Use premake to generate make files (apt packages)
if: matrix.static-link != true if: matrix.static-link != true
...@@ -625,7 +625,7 @@ jobs: ...@@ -625,7 +625,7 @@ jobs:
uses: mercury233/action-cache-download-file@v1.0.0 uses: mercury233/action-cache-download-file@v1.0.0
with: with:
url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz
- name: Extract opus - name: Extract opus
if: matrix.static-link == true if: matrix.static-link == true
run: | run: |
...@@ -664,8 +664,8 @@ jobs: ...@@ -664,8 +664,8 @@ jobs:
- name: Copy premake files - name: Copy premake files
run: | run: |
cp -r premake/* . cp -pr premake/* .
cp -r resource/* . cp -pr resource/* .
- name: Use premake to generate make files (Homebrew packages) - name: Use premake to generate make files (Homebrew packages)
if: matrix.static-link != true if: matrix.static-link != true
...@@ -679,7 +679,7 @@ jobs: ...@@ -679,7 +679,7 @@ jobs:
--build-event \ --build-event \
--build-freetype \ --build-freetype \
--build-sqlite \ --build-sqlite \
--build-opus-vorbis --build-opus-vorbis
- name: Make - name: Make
run: | run: |
......
...@@ -93,8 +93,9 @@ mat_windows: ...@@ -93,8 +93,9 @@ mat_windows:
._exec_build: ._exec_build:
stage: build stage: build
#variables: variables:
# NO_LUA_SAFE: '1' # on client no lua safe # NO_LUA_SAFE: '1' # on client no lua safe
GIT_STRATEGY: clone
#cache: #cache:
# key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" # key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
# paths: # paths:
...@@ -124,6 +125,15 @@ exec_windows: ...@@ -124,6 +125,15 @@ exec_windows:
- mkdir dist\windows - mkdir dist\windows
- copy bin\release\x64\ygopro.exe dist\windows\ygopro.exe - copy bin\release\x64\ygopro.exe dist\windows\ygopro.exe
exec_windows_pro2:
extends: .exec_windows
script:
- '.\premake5.exe vs2019 --server-pro2-support'
- cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" build\YGOPro.sln /m /p:Configuration=Release /p:Platform=x64'
- mkdir dist
- mkdir dist\windows
- copy bin\release\x64\AI.Server.exe dist\windows\AI.Server.exe
exec_windows_pro3: exec_windows_pro3:
extends: .exec_windows extends: .exec_windows
script: script:
...@@ -133,12 +143,24 @@ exec_windows_pro3: ...@@ -133,12 +143,24 @@ exec_windows_pro3:
- mkdir dist\windows - mkdir dist\windows
- copy bin\release\x64\ygoserver.dll dist\windows\ygoserver.dll - copy bin\release\x64\ygoserver.dll dist\windows\ygoserver.dll
exec_windows_mdpro2:
extends: .exec_windows
script:
- '.\premake5.exe vs2019 --server-pro3-support --log-in-chat --server-pro2-support'
- cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" build\YGOPro.sln /m /p:Configuration=Release /p:Platform=x64'
- mkdir dist
- mkdir dist\windows
- copy bin\release\x64\ygoserver.dll dist\windows\ygoserver-mdpro2.dll
.exec_unix_common: .exec_unix_common:
extends: ._exec_build extends: ._exec_build
variables: variables:
RELEASE_DIR: '' RELEASE_DIR: ''
TARGET_FILE: ygopro TARGET_FILE: ygopro
PREMAKE5_BIN: premake5 PREMAKE5_BIN: premake5
BUILD_EVENT: '1'
BUILD_IRRLICHT: '1'
BUILD_SQLITE: '1'
script: script:
- ./.ci/configure-libevent.sh - ./.ci/configure-libevent.sh
- $PREMAKE5_BIN gmake - $PREMAKE5_BIN gmake
...@@ -318,6 +340,8 @@ upload_to_minio: ...@@ -318,6 +340,8 @@ upload_to_minio:
- exec_linux - exec_linux
- exec_linuxarm - exec_linuxarm
- exec_windows_pro3 - exec_windows_pro3
- exec_windows_pro2
- exec_windows_mdpro2
- exec_linux_pro3 - exec_linux_pro3
- exec_linuxarm_pro3 - exec_linuxarm_pro3
- exec_debian - exec_debian
......
No preview for this file type
...@@ -2,37 +2,52 @@ ...@@ -2,37 +2,52 @@
#define BUFFERIO_H #define BUFFERIO_H
#include <cstdint> #include <cstdint>
#include <cstring>
#include <cwchar> #include <cwchar>
#include "../ocgcore/buffer.h"
class BufferIO { class BufferIO {
public: public:
static int ReadInt32(unsigned char*& p) { template<typename T>
return buffer_read<int32_t>(p); static T Read(unsigned char*& p) {
T ret{};
std::memcpy(&ret, p, sizeof(T));
p += sizeof(T);
return ret;
} }
static unsigned int ReadUInt32(unsigned char*& p) { template<typename T>
return buffer_read<uint32_t>(p); static void Write(unsigned char*& p, T value) {
std::memcpy(p, &value, sizeof(T));
p += sizeof(T);
} }
static short ReadInt16(unsigned char*& p) {
return buffer_read<int16_t>(p); // for compatibility
[[deprecated]]
static int32_t ReadInt32(unsigned char*& p) {
return Read<int32_t>(p);
} }
static unsigned short ReadUInt16(unsigned char*& p) { [[deprecated]]
return buffer_read<uint16_t>(p); static short ReadInt16(unsigned char*& p) {
return Read<int16_t>(p);
} }
[[deprecated]]
static char ReadInt8(unsigned char*& p) { static char ReadInt8(unsigned char*& p) {
return buffer_read<char>(p); return Read<char>(p);
} }
[[deprecated]]
static unsigned char ReadUInt8(unsigned char*& p) { static unsigned char ReadUInt8(unsigned char*& p) {
return buffer_read<unsigned char>(p); return Read<unsigned char>(p);
} }
static void WriteInt32(unsigned char*& p, int val) { [[deprecated]]
buffer_write<int32_t>(p, val); static void WriteInt32(unsigned char*& p, int32_t val) {
Write<int32_t>(p, val);
} }
static void WriteInt16(unsigned char*& p, short val) { [[deprecated]]
buffer_write<int16_t>(p, val); static void Write<uint16_t>(unsigned char*& p, short val) {
Write<int16_t>(p, val);
} }
[[deprecated]]
static void WriteInt8(unsigned char*& p, char val) { static void WriteInt8(unsigned char*& p, char val) {
buffer_write<char>(p, val); Write<char>(p, val);
} }
/** /**
* @brief Copy a C-style string to another C-style string. * @brief Copy a C-style string to another C-style string.
...@@ -67,64 +82,18 @@ public: ...@@ -67,64 +82,18 @@ public:
return CopyWStr(src, dst, N); return CopyWStr(src, dst, N);
} }
template<size_t N> template<size_t N>
static void CopyString(const char* src, char(&dst)[N]) { static void CopyString(const char* src, char(&dst)[N], size_t len = N - 1) {
std::strncpy(dst, src, N - 1); if(len >= N)
dst[N - 1] = 0; len = N - 1;
std::strncpy(dst, src, len);
dst[len] = 0;
} }
template<size_t N> template<size_t N>
static void CopyWideString(const wchar_t* src, wchar_t(&dst)[N]) { static void CopyWideString(const wchar_t* src, wchar_t(&dst)[N], size_t len = N - 1) {
std::wcsncpy(dst, src, N - 1); if(len >= N)
dst[N - 1] = 0; len = N - 1;
} std::wcsncpy(dst, src, len);
template<typename T> dst[len] = 0;
static bool CheckUTF8Byte(const T* str, int len) {
for (int i = 1; i < len; ++i) {
if ((str[i] & 0xc0U) != 0x80U)
return false;
}
return true;
}
static unsigned int ConvertUTF8(const char*& p) {
unsigned int cur = 0;
if ((p[0] & 0x80U) == 0) {
cur = p[0] & 0xffU;
p++;
}
else if ((p[0] & 0xe0U) == 0xc0U) {
if (!CheckUTF8Byte(p, 2)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0x1fU) << 6) | (p[1] & 0x3fU);
p += 2;
if(cur < 0x80U)
return UINT32_MAX;
}
else if ((p[0] & 0xf0U) == 0xe0U) {
if (!CheckUTF8Byte(p, 3)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0xfU) << 12) | ((p[1] & 0x3fU) << 6) | (p[2] & 0x3fU);
p += 3;
if (cur < 0x800U)
return UINT32_MAX;
}
else if ((p[0] & 0xf8U) == 0xf0U) {
if (!CheckUTF8Byte(p, 4)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0x7U) << 18) | ((p[1] & 0x3fU) << 12) | ((p[2] & 0x3fU) << 6) | (p[3] & 0x3fU);
p += 4;
if (cur < 0x10000U)
return UINT32_MAX;
}
else {
p++;
return UINT32_MAX;
}
return cur;
} }
static bool IsHighSurrogate(unsigned int c) { static bool IsHighSurrogate(unsigned int c) {
return (c >= 0xd800U && c <= 0xdbffU); return (c >= 0xd800U && c <= 0xdbffU);
...@@ -143,111 +112,31 @@ public: ...@@ -143,111 +112,31 @@ public:
} }
// UTF-16/UTF-32 to UTF-8 // UTF-16/UTF-32 to UTF-8
// return: string length // return: string length
static int EncodeUTF8String(const wchar_t* wsrc, char* str, int size) { static int EncodeUTF8String(const wchar_t* wsrc, char* str, size_t len) {
auto pw = wsrc; if (len == 0) {
auto pstr = str; str[0] = 0;
while (*pw != 0) { return 0;
unsigned cur = 0;
int codepoint_size = 0;
if (sizeof(wchar_t) == 2) {
if (IsHighSurrogate(pw[0])) {
if (pw[1] == 0)
break;
if (IsLowSurrogate(pw[1])) {
cur = ((pw[0] & 0x3ffU) << 10) | (pw[1] & 0x3ffU);
cur += 0x10000;
pw += 2;
}
else {
pw++;
continue;
}
}
else if (IsLowSurrogate(pw[0])) {
pw++;
continue;
}
else {
cur = *pw;
pw++;
}
}
else {
cur = *pw;
pw++;
}
if (!IsUnicodeChar(cur))
continue;
if (cur < 0x80U)
codepoint_size = 1;
else if (cur < 0x800U)
codepoint_size = 2;
else if (cur < 0x10000U)
codepoint_size = 3;
else
codepoint_size = 4;
if ((int)(pstr - str) + codepoint_size > size - 1)
break;
switch (codepoint_size) {
case 1:
*pstr = (char)cur;
break;
case 2:
pstr[0] = ((cur >> 6) & 0x1f) | 0xc0;
pstr[1] = (cur & 0x3f) | 0x80;
break;
case 3:
pstr[0] = ((cur >> 12) & 0xf) | 0xe0;
pstr[1] = ((cur >> 6) & 0x3f) | 0x80;
pstr[2] = (cur & 0x3f) | 0x80;
break;
case 4:
pstr[0] = ((cur >> 18) & 0x7) | 0xf0;
pstr[1] = ((cur >> 12) & 0x3f) | 0x80;
pstr[2] = ((cur >> 6) & 0x3f) | 0x80;
pstr[3] = (cur & 0x3f) | 0x80;
break;
default:
break;
}
pstr += codepoint_size;
} }
*pstr = 0; std::mbstate_t state{};
return (int)(pstr - str); size_t result_len = std::wcsrtombs(str, &wsrc, len - 1, &state);
if (result_len == static_cast<size_t>(-1))
result_len = 0;
str[result_len] = 0;
return static_cast<int>(result_len);
} }
// UTF-8 to UTF-16/UTF-32 // UTF-8 to UTF-16/UTF-32
// return: string length // return: string length
static int DecodeUTF8String(const char* src, wchar_t* wstr, int size) { static int DecodeUTF8String(const char* src, wchar_t* wstr, size_t len) {
const char* p = src; if (len == 0) {
wchar_t* wp = wstr; wstr[0] = 0;
while(*p != 0) { return 0;
unsigned int cur = ConvertUTF8(p);
int codepoint_size = 0;
if (!IsUnicodeChar(cur))
continue;
if (cur >= 0x10000) {
if (sizeof(wchar_t) == 2)
codepoint_size = 2;
else
codepoint_size = 1;
}
else
codepoint_size = 1;
if ((int)(wp - wstr) + codepoint_size > size - 1)
break;
if (codepoint_size == 1) {
wp[0] = cur;
wp++;
}
else {
cur -= 0x10000U;
wp[0] = (cur >> 10) | 0xd800;
wp[1] = (cur & 0x3ff) | 0xdc00;
wp += 2;
}
} }
*wp = 0; std::mbstate_t state{};
return wp - wstr; size_t result_len = std::mbsrtowcs(wstr, &src, len - 1, &state);
if (result_len == static_cast<size_t>(-1))
result_len = 0;
wstr[result_len] = 0;
return static_cast<int>(result_len);
} }
template<size_t N> template<size_t N>
static int EncodeUTF8(const wchar_t* src, char(&dst)[N]) { static int EncodeUTF8(const wchar_t* src, char(&dst)[N]) {
...@@ -273,7 +162,6 @@ public: ...@@ -273,7 +162,6 @@ public:
} }
else else
return 0; return 0;
} }
}; };
......
...@@ -35,27 +35,27 @@ void ClientCard::SetCode(unsigned int x) { ...@@ -35,27 +35,27 @@ void ClientCard::SetCode(unsigned int x) {
if((location == LOCATION_HAND) && (code != x)) { if((location == LOCATION_HAND) && (code != x)) {
code = x; code = x;
mainGame->dField.MoveCard(this, 5); mainGame->dField.MoveCard(this, 5);
} else } else {
if (x == 0 && code != 0) {
chain_code = code;
}
code = x; code = x;
}
} }
void ClientCard::UpdateInfo(unsigned char* buf) { void ClientCard::UpdateInfo(unsigned char* buf) {
int flag = BufferIO::ReadInt32(buf); int flag = BufferIO::Read<int32_t>(buf);
if (flag == 0) { if (flag == 0) {
ClearData(); ClearData();
return; return;
} }
if(flag & QUERY_CODE) { if(flag & QUERY_CODE) {
int pdata = BufferIO::ReadInt32(buf); int pdata = BufferIO::Read<int32_t>(buf);
if (!pdata) if (!pdata)
ClearData(); ClearData();
if((location == LOCATION_HAND) && ((unsigned int)pdata != code)) { SetCode(pdata);
code = pdata;
mainGame->dField.MoveCard(this, 5);
} else
code = pdata;
} }
if(flag & QUERY_POSITION) { if(flag & QUERY_POSITION) {
int pdata = (BufferIO::ReadInt32(buf) >> 24) & 0xff; int pdata = (BufferIO::Read<int32_t>(buf) >> 24) & 0xff;
if((location & (LOCATION_EXTRA | LOCATION_REMOVED)) && pdata != position) { if((location & (LOCATION_EXTRA | LOCATION_REMOVED)) && pdata != position) {
position = pdata; position = pdata;
mainGame->dField.MoveCard(this, 1); mainGame->dField.MoveCard(this, 1);
...@@ -63,29 +63,29 @@ void ClientCard::UpdateInfo(unsigned char* buf) { ...@@ -63,29 +63,29 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
position = pdata; position = pdata;
} }
if(flag & QUERY_ALIAS) if(flag & QUERY_ALIAS)
alias = BufferIO::ReadInt32(buf); alias = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_TYPE) if(flag & QUERY_TYPE)
type = BufferIO::ReadInt32(buf); type = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_LEVEL) { if(flag & QUERY_LEVEL) {
int pdata = BufferIO::ReadInt32(buf); int pdata = BufferIO::Read<int32_t>(buf);
if(level != (unsigned int)pdata) { if(level != (unsigned int)pdata) {
level = pdata; level = pdata;
myswprintf(lvstring, L"L%d", level); myswprintf(lvstring, L"L%d", level);
} }
} }
if(flag & QUERY_RANK) { if(flag & QUERY_RANK) {
int pdata = BufferIO::ReadInt32(buf); int pdata = BufferIO::Read<int32_t>(buf);
if(pdata && rank != (unsigned int)pdata) { if(pdata && rank != (unsigned int)pdata) {
rank = pdata; rank = pdata;
myswprintf(lvstring, L"R%d", rank); myswprintf(lvstring, L"R%d", rank);
} }
} }
if(flag & QUERY_ATTRIBUTE) if(flag & QUERY_ATTRIBUTE)
attribute = BufferIO::ReadInt32(buf); attribute = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_RACE) if(flag & QUERY_RACE)
race = BufferIO::ReadInt32(buf); race = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_ATTACK) { if(flag & QUERY_ATTACK) {
attack = BufferIO::ReadInt32(buf); attack = BufferIO::Read<int32_t>(buf);
if(attack < 0) { if(attack < 0) {
atkstring[0] = '?'; atkstring[0] = '?';
atkstring[1] = 0; atkstring[1] = 0;
...@@ -93,7 +93,7 @@ void ClientCard::UpdateInfo(unsigned char* buf) { ...@@ -93,7 +93,7 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
myswprintf(atkstring, L"%d", attack); myswprintf(atkstring, L"%d", attack);
} }
if(flag & QUERY_DEFENSE) { if(flag & QUERY_DEFENSE) {
defense = BufferIO::ReadInt32(buf); defense = BufferIO::Read<int32_t>(buf);
if(type & TYPE_LINK) { if(type & TYPE_LINK) {
defstring[0] = '-'; defstring[0] = '-';
defstring[1] = 0; defstring[1] = 0;
...@@ -104,18 +104,18 @@ void ClientCard::UpdateInfo(unsigned char* buf) { ...@@ -104,18 +104,18 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
myswprintf(defstring, L"%d", defense); myswprintf(defstring, L"%d", defense);
} }
if(flag & QUERY_BASE_ATTACK) if(flag & QUERY_BASE_ATTACK)
base_attack = BufferIO::ReadInt32(buf); base_attack = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_BASE_DEFENSE) if(flag & QUERY_BASE_DEFENSE)
base_defense = BufferIO::ReadInt32(buf); base_defense = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_REASON) if(flag & QUERY_REASON)
reason = BufferIO::ReadInt32(buf); reason = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_REASON_CARD) if(flag & QUERY_REASON_CARD)
buf += 4; buf += 4;
if(flag & QUERY_EQUIP_CARD) { if(flag & QUERY_EQUIP_CARD) {
int c = BufferIO::ReadUInt8(buf); int c = BufferIO::Read<uint8_t>(buf);
unsigned int l = BufferIO::ReadUInt8(buf); unsigned int l = BufferIO::Read<uint8_t>(buf);
int s = BufferIO::ReadUInt8(buf); int s = BufferIO::Read<uint8_t>(buf);
BufferIO::ReadUInt8(buf); BufferIO::Read<uint8_t>(buf);
ClientCard* ecard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s); ClientCard* ecard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
if (ecard) { if (ecard) {
equipTarget = ecard; equipTarget = ecard;
...@@ -123,12 +123,12 @@ void ClientCard::UpdateInfo(unsigned char* buf) { ...@@ -123,12 +123,12 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
} }
} }
if(flag & QUERY_TARGET_CARD) { if(flag & QUERY_TARGET_CARD) {
int count = BufferIO::ReadInt32(buf); int count = BufferIO::Read<int32_t>(buf);
for(int i = 0; i < count; ++i) { for(int i = 0; i < count; ++i) {
int c = BufferIO::ReadUInt8(buf); int c = BufferIO::Read<uint8_t>(buf);
unsigned int l = BufferIO::ReadUInt8(buf); unsigned int l = BufferIO::Read<uint8_t>(buf);
int s = BufferIO::ReadUInt8(buf); int s = BufferIO::Read<uint8_t>(buf);
BufferIO::ReadUInt8(buf); BufferIO::Read<uint8_t>(buf);
ClientCard* tcard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s); ClientCard* tcard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
if (tcard) { if (tcard) {
cardTarget.insert(tcard); cardTarget.insert(tcard);
...@@ -137,38 +137,38 @@ void ClientCard::UpdateInfo(unsigned char* buf) { ...@@ -137,38 +137,38 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
} }
} }
if(flag & QUERY_OVERLAY_CARD) { if(flag & QUERY_OVERLAY_CARD) {
int count = BufferIO::ReadInt32(buf); int count = BufferIO::Read<int32_t>(buf);
for(int i = 0; i < count; ++i) { for(int i = 0; i < count; ++i) {
overlayed[i]->SetCode(BufferIO::ReadInt32(buf)); overlayed[i]->SetCode(BufferIO::Read<int32_t>(buf));
} }
} }
if(flag & QUERY_COUNTERS) { if(flag & QUERY_COUNTERS) {
int count = BufferIO::ReadInt32(buf); int count = BufferIO::Read<int32_t>(buf);
for(int i = 0; i < count; ++i) { for(int i = 0; i < count; ++i) {
int ctype = BufferIO::ReadInt16(buf); int ctype = BufferIO::Read<uint16_t>(buf);
int ccount = BufferIO::ReadInt16(buf); int ccount = BufferIO::Read<uint16_t>(buf);
counters[ctype] = ccount; counters[ctype] = ccount;
} }
} }
if(flag & QUERY_OWNER) if(flag & QUERY_OWNER)
owner = BufferIO::ReadInt32(buf); owner = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_STATUS) if(flag & QUERY_STATUS)
status = BufferIO::ReadInt32(buf); status = BufferIO::Read<int32_t>(buf);
if(flag & QUERY_LSCALE) { if(flag & QUERY_LSCALE) {
lscale = BufferIO::ReadInt32(buf); lscale = BufferIO::Read<int32_t>(buf);
myswprintf(lscstring, L"%d", lscale); myswprintf(lscstring, L"%d", lscale);
} }
if(flag & QUERY_RSCALE) { if(flag & QUERY_RSCALE) {
rscale = BufferIO::ReadInt32(buf); rscale = BufferIO::Read<int32_t>(buf);
myswprintf(rscstring, L"%d", rscale); myswprintf(rscstring, L"%d", rscale);
} }
if(flag & QUERY_LINK) { if(flag & QUERY_LINK) {
int pdata = BufferIO::ReadInt32(buf); int pdata = BufferIO::Read<int32_t>(buf);
if (link != (unsigned int)pdata) { if (link != (unsigned int)pdata) {
link = pdata; link = pdata;
} }
myswprintf(linkstring, L"L\x2012%d", link); myswprintf(linkstring, L"L\x2012%d", link);
pdata = BufferIO::ReadInt32(buf); pdata = BufferIO::Read<int32_t>(buf);
if (link_marker != (unsigned int)pdata) { if (link_marker != (unsigned int)pdata) {
link_marker = pdata; link_marker = pdata;
} }
......
...@@ -325,7 +325,7 @@ ClientCard* ClientField::RemoveCard(int controler, int location, int sequence) { ...@@ -325,7 +325,7 @@ ClientCard* ClientField::RemoveCard(int controler, int location, int sequence) {
} }
void ClientField::UpdateCard(int controler, int location, int sequence, unsigned char* data) { void ClientField::UpdateCard(int controler, int location, int sequence, unsigned char* data) {
ClientCard* pcard = GetCard(controler, location, sequence); ClientCard* pcard = GetCard(controler, location, sequence);
int len = BufferIO::ReadInt32(data); int len = BufferIO::Read<int32_t>(data);
if (pcard && len > LEN_HEADER) if (pcard && len > LEN_HEADER)
pcard->UpdateInfo(data); pcard->UpdateInfo(data);
RefreshCardCountDisplay(); RefreshCardCountDisplay();
...@@ -359,7 +359,7 @@ void ClientField::UpdateFieldCard(int controler, int location, unsigned char* da ...@@ -359,7 +359,7 @@ void ClientField::UpdateFieldCard(int controler, int location, unsigned char* da
return; return;
int len; int len;
for(auto cit = lst->begin(); cit != lst->end(); ++cit) { for(auto cit = lst->begin(); cit != lst->end(); ++cit) {
len = BufferIO::ReadInt32(data); len = BufferIO::Read<int32_t>(data);
if(len > LEN_HEADER) if(len > LEN_HEADER)
(*cit)->UpdateInfo(data); (*cit)->UpdateInfo(data);
data += len - 4; data += len - 4;
...@@ -1424,7 +1424,8 @@ bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, st ...@@ -1424,7 +1424,8 @@ bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, st
|| check_sum_trib(index, end, acc + l2) || check_sum_trib(index, end, acc + l2)
|| check_sum_trib(index, end, acc); || check_sum_trib(index, end, acc);
} }
static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& opcode) { template <class T>
static bool is_declarable(const T& cd, const std::vector<unsigned int>& opcode) {
std::stack<int> stack; std::stack<int> stack;
for(auto it = opcode.begin(); it != opcode.end(); ++it) { for(auto it = opcode.begin(); it != opcode.end(); ++it) {
switch(*it) { switch(*it) {
...@@ -1514,9 +1515,15 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o ...@@ -1514,9 +1515,15 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o
} }
case OPCODE_ISSETCARD: { case OPCODE_ISSETCARD: {
if (stack.size() >= 1) { if (stack.size() >= 1) {
int set_code = stack.top(); uint32_t set_code = stack.top();
stack.pop(); stack.pop();
bool res = cd.is_setcode(set_code); bool res = false;
for (const auto& x : cd.setcode) {
if(check_setcode(x, set_code)) {
res = true;
break;
}
}
stack.push(res); stack.push(res);
} }
break; break;
...@@ -1560,12 +1567,12 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o ...@@ -1560,12 +1567,12 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o
void ClientField::UpdateDeclarableList() { void ClientField::UpdateDeclarableList() {
const wchar_t* pname = mainGame->ebANCard->getText(); const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname); int trycode = BufferIO::GetVal(pname);
CardString cstr;
CardData cd; CardData cd;
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) { if (dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
auto it = dataManager.GetStringPointer(trycode);
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str()); mainGame->lstANCard->addItem(it->second.name.c_str());
ancard.push_back(trycode); ancard.push_back(trycode);
return; return;
} }
...@@ -1574,8 +1581,9 @@ void ClientField::UpdateDeclarableList() { ...@@ -1574,8 +1581,9 @@ void ClientField::UpdateDeclarableList() {
if(pname[0] == 0 && mainGame->dInfo.announce_cache.size()) { if(pname[0] == 0 && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) { for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[i]; unsigned int cache_code = mainGame->dInfo.announce_cache[i];
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, declare_opcodes)) { if(dataManager.GetData(cache_code, &cd) && is_declarable(cd, declare_opcodes)) {
mainGame->lstANCard->addItem(cstr.name.c_str()); auto it = dataManager.GetStringPointer(cache_code);
mainGame->lstANCard->addItem(it->second.name.c_str());
ancard.push_back(cache_code); ancard.push_back(cache_code);
} }
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#define IRR_COMPILE_WITH_DX9_DEV_PACK #define IRR_COMPILE_WITH_DX9_DEV_PACK
#include <cerrno> #include <cerrno>
#include <vector>
#ifdef _WIN32 #ifdef _WIN32
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
#include <windows.h> #include <windows.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#if defined(_MSC_VER) or defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
#define mywcsncasecmp _wcsnicmp #define mywcsncasecmp _wcsnicmp
#define mystrncasecmp _strnicmp #define mystrncasecmp _strnicmp
#else #else
...@@ -72,8 +73,12 @@ extern char** environ; ...@@ -72,8 +73,12 @@ extern char** environ;
#include "../ocgcore/ocgapi.h" #include "../ocgcore/ocgapi.h"
template<size_t N, typename... TR> template<size_t N, typename... TR>
inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) { inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR&&... args) {
return std::swprintf(buf, N, fmt, args...); return std::swprintf(buf, N, fmt, std::forward<TR>(args)...);
}
template<size_t N, typename... TR>
inline int mysnprintf(char(&buf)[N], const char* fmt, TR&&... args) {
return std::snprintf(buf, N, fmt, std::forward<TR>(args)...);
} }
inline FILE* mywfopen(const wchar_t* filename, const char* mode) { inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
...@@ -90,20 +95,7 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) { ...@@ -90,20 +95,7 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
return fp; return fp;
} }
#if !defined(_WIN32)
#define myfopen std::fopen #define myfopen std::fopen
#elif defined(WDK_NTDDI_VERSION) && (WDK_NTDDI_VERSION >= 0x0A000005) // Redstone 4, Version 1803, Build 17134.
#define FOPEN_WINDOWS_SUPPORT_UTF8
#define myfopen std::fopen
#else
inline FILE* myfopen(const char* filename, const char* mode) {
wchar_t wfilename[256]{};
BufferIO::DecodeUTF8(filename, wfilename);
wchar_t wmode[20]{};
BufferIO::CopyCharArray(mode, wmode);
return _wfopen(wfilename, wmode);
}
#endif
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT) #if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
#include <irrlicht.h> #include <irrlicht.h>
......
...@@ -14,7 +14,10 @@ irr::io::IFileSystem* DataManager::FileSystem = nullptr; ...@@ -14,7 +14,10 @@ irr::io::IFileSystem* DataManager::FileSystem = nullptr;
DataManager dataManager; DataManager dataManager;
DataManager::DataManager() : _datas(32768), _strings(32768) { DataManager::DataManager() : _datas(32768), _strings(32768) {
extra_setcode = { {8512558u, {0x8f, 0x54, 0x59, 0x82, 0x13a}}, }; extra_setcode = {
{8512558u, {0x8f, 0x54, 0x59, 0x82, 0x13a}},
{55088578u, {0x8f, 0x54, 0x59, 0x82, 0x13a}},
};
} }
bool DataManager::ReadDB(sqlite3* pDB) { bool DataManager::ReadDB(sqlite3* pDB) {
sqlite3_stmt* pStmt = nullptr; sqlite3_stmt* pStmt = nullptr;
...@@ -23,73 +26,67 @@ bool DataManager::ReadDB(sqlite3* pDB) { ...@@ -23,73 +26,67 @@ bool DataManager::ReadDB(sqlite3* pDB) {
#else #else
const char* sql = "select * from datas,texts where datas.id=texts.id"; const char* sql = "select * from datas,texts where datas.id=texts.id";
#endif #endif
if (sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK) if (sqlite3_prepare_v2(pDB, sql, -1, &pStmt, nullptr) != SQLITE_OK)
return Error(pDB, pStmt); return Error(pDB, pStmt);
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
wchar_t strBuffer[4096]; wchar_t strBuffer[4096];
#endif #endif
int step = 0; for (int step = sqlite3_step(pStmt); step != SQLITE_DONE; step = sqlite3_step(pStmt)) {
do { if (step != SQLITE_ROW)
CardDataC cd; return Error(pDB, pStmt);
CardString cs; uint32_t code = static_cast<uint32_t>(sqlite3_column_int64(pStmt, 0));
step = sqlite3_step(pStmt); auto& cd = _datas[code];
if (step == SQLITE_ROW) { cd.code = code;
cd.code = sqlite3_column_int(pStmt, 0); cd.ot = sqlite3_column_int(pStmt, 1);
cd.ot = sqlite3_column_int(pStmt, 1); cd.alias = sqlite3_column_int(pStmt, 2);
cd.alias = sqlite3_column_int(pStmt, 2); uint64_t setcode = static_cast<uint64_t>(sqlite3_column_int64(pStmt, 3));
uint64_t setcode = static_cast<uint64_t>(sqlite3_column_int64(pStmt, 3)); write_setcode(cd.setcode, setcode);
if (setcode) { cd.type = static_cast<decltype(cd.type)>(sqlite3_column_int64(pStmt, 4));
auto it = extra_setcode.find(cd.code); cd.attack = sqlite3_column_int(pStmt, 5);
if (it != extra_setcode.end()) { cd.defense = sqlite3_column_int(pStmt, 6);
int len = it->second.size(); if (cd.type & TYPE_LINK) {
if (len > SIZE_SETCODE) cd.link_marker = cd.defense;
len = SIZE_SETCODE; cd.defense = 0;
if (len) }
std::memcpy(cd.setcode, it->second.data(), len * sizeof(uint16_t)); else
} cd.link_marker = 0;
else uint32_t level = static_cast<uint32_t>(sqlite3_column_int64(pStmt, 7));
cd.set_setcode(setcode); cd.level = level & 0xff;
} cd.lscale = (level >> 24) & 0xff;
cd.type = static_cast<decltype(cd.type)>(sqlite3_column_int64(pStmt, 4)); cd.rscale = (level >> 16) & 0xff;
cd.attack = sqlite3_column_int(pStmt, 5); cd.race = static_cast<decltype(cd.race)>(sqlite3_column_int64(pStmt, 8));
cd.defense = sqlite3_column_int(pStmt, 6); cd.attribute = static_cast<decltype(cd.attribute)>(sqlite3_column_int64(pStmt, 9));
if (cd.type & TYPE_LINK) { cd.category = static_cast<decltype(cd.category)>(sqlite3_column_int64(pStmt, 10));
cd.link_marker = cd.defense;
cd.defense = 0;
}
else
cd.link_marker = 0;
uint32_t level = static_cast<uint32_t>(sqlite3_column_int(pStmt, 7));
cd.level = level & 0xff;
cd.lscale = (level >> 24) & 0xff;
cd.rscale = (level >> 16) & 0xff;
cd.race = static_cast<decltype(cd.race)>(sqlite3_column_int64(pStmt, 8));
cd.attribute = static_cast<decltype(cd.attribute)>(sqlite3_column_int64(pStmt, 9));
cd.category = static_cast<decltype(cd.category)>(sqlite3_column_int64(pStmt, 10));
_datas[cd.code] = cd;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
if (const char* text = (const char*)sqlite3_column_text(pStmt, 12)) { auto& cs = _strings[code];
BufferIO::DecodeUTF8(text, strBuffer); if (const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
cs.name = strBuffer; BufferIO::DecodeUTF8(text, strBuffer);
} cs.name = strBuffer;
if (const char* text = (const char*)sqlite3_column_text(pStmt, 13)) { }
if (const char* text = (const char*)sqlite3_column_text(pStmt, 13)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.text = strBuffer;
}
constexpr int desc_count = sizeof cs.desc / sizeof cs.desc[0];
for (int i = 0; i < desc_count; ++i) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, i + 14)) {
BufferIO::DecodeUTF8(text, strBuffer); BufferIO::DecodeUTF8(text, strBuffer);
cs.text = strBuffer; cs.desc[i] = strBuffer;
} }
constexpr int desc_count = sizeof cs.desc / sizeof cs.desc[0];
for (int i = 0; i < desc_count; ++i) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, i + 14)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.desc[i] = strBuffer;
}
}
_strings[cd.code] = cs;
#endif //YGOPRO_SERVER_MODE
} }
else if (step != SQLITE_DONE) #endif //YGOPRO_SERVER_MODE
return Error(pDB, pStmt); }
} while (step == SQLITE_ROW);
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
for (const auto& entry : extra_setcode) {
const auto& code = entry.first;
const auto& list = entry.second;
if (list.size() > SIZE_SETCODE || list.empty())
continue;
auto it = _datas.find(code);
if (it == _datas.end())
continue;
std::memcpy(it->second.setcode, list.data(), list.size() * sizeof(uint16_t));
}
return true; return true;
} }
bool DataManager::LoadDB(const wchar_t* wfile) { bool DataManager::LoadDB(const wchar_t* wfile) {
...@@ -357,42 +354,32 @@ void DataManager::InsertServerList() { ...@@ -357,42 +354,32 @@ void DataManager::InsertServerList() {
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) { bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
std::snprintf(errmsg, sizeof errmsg, "%s", sqlite3_errmsg(pDB)); if (const char* msg = sqlite3_errmsg(pDB))
if(pStmt) mysnprintf(errmsg, "%s", msg);
sqlite3_finalize(pStmt); else
errmsg[0] = '\0';
sqlite3_finalize(pStmt);
return false; return false;
} }
code_pointer DataManager::GetCodePointer(unsigned int code) const { code_pointer DataManager::GetCodePointer(uint32_t code) const {
return _datas.find(code); return _datas.find(code);
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
string_pointer DataManager::GetStringPointer(unsigned int code) const { string_pointer DataManager::GetStringPointer(uint32_t code) const {
return _strings.find(code); return _strings.find(code);
} }
code_pointer DataManager::datas_begin() const {
return _datas.cbegin();
}
code_pointer DataManager::datas_end() const {
return _datas.cend();
}
string_pointer DataManager::strings_begin() const {
return _strings.cbegin();
}
string_pointer DataManager::strings_end() const {
return _strings.cend();
}
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
bool DataManager::GetData(unsigned int code, CardData* pData) const { bool DataManager::GetData(uint32_t code, CardData* pData) const {
auto cdit = _datas.find(code); auto cdit = _datas.find(code);
if(cdit == _datas.end()) if(cdit == _datas.end())
return false; return false;
if (pData) { if (pData) {
*pData = cdit->second; std::memcpy(pData, &cdit->second, sizeof(CardData));
} }
return true; return true;
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool DataManager::GetString(unsigned int code, CardString* pStr) const { bool DataManager::GetString(uint32_t code, CardString* pStr) const {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) { if(csit == _strings.end()) {
pStr->name = unknown_string; pStr->name = unknown_string;
...@@ -402,7 +389,7 @@ bool DataManager::GetString(unsigned int code, CardString* pStr) const { ...@@ -402,7 +389,7 @@ bool DataManager::GetString(unsigned int code, CardString* pStr) const {
*pStr = csit->second; *pStr = csit->second;
return true; return true;
} }
const wchar_t* DataManager::GetName(unsigned int code) const { const wchar_t* DataManager::GetName(uint32_t code) const {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) if(csit == _strings.end())
return unknown_string; return unknown_string;
...@@ -410,7 +397,7 @@ const wchar_t* DataManager::GetName(unsigned int code) const { ...@@ -410,7 +397,7 @@ const wchar_t* DataManager::GetName(unsigned int code) const {
return csit->second.name.c_str(); return csit->second.name.c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetText(unsigned int code) const { const wchar_t* DataManager::GetText(uint32_t code) const {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) if(csit == _strings.end())
return unknown_string; return unknown_string;
...@@ -418,7 +405,7 @@ const wchar_t* DataManager::GetText(unsigned int code) const { ...@@ -418,7 +405,7 @@ const wchar_t* DataManager::GetText(unsigned int code) const {
return csit->second.text.c_str(); return csit->second.text.c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetDesc(unsigned int strCode) const { const wchar_t* DataManager::GetDesc(uint32_t strCode) const {
if (strCode < (MIN_CARD_ID << 4)) if (strCode < (MIN_CARD_ID << 4))
return GetSysString(strCode); return GetSysString(strCode);
unsigned int code = (strCode >> 4) & 0x0fffffff; unsigned int code = (strCode >> 4) & 0x0fffffff;
...@@ -614,7 +601,7 @@ unsigned char* DataManager::ScriptReaderEx(const char* script_name, int* slen) { ...@@ -614,7 +601,7 @@ unsigned char* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
} }
unsigned char* DataManager::ScriptReaderExSingle(const char* path, const char* script_name, int* slen, int pre_len, unsigned int use_irr) { unsigned char* DataManager::ScriptReaderExSingle(const char* path, const char* script_name, int* slen, int pre_len, unsigned int use_irr) {
char sname[256]; char sname[256];
std::snprintf(sname, sizeof sname, "%s%s", path, script_name + pre_len); //default script name: ./script/c%d.lua mysnprintf(sname, "%s%s", path, script_name + pre_len); //default script name: ./script/c%d.lua
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT) #if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
if (use_irr) { if (use_irr) {
return ReadScriptFromIrrFS(sname, slen); return ReadScriptFromIrrFS(sname, slen);
......
...@@ -16,18 +16,34 @@ namespace irr { ...@@ -16,18 +16,34 @@ namespace irr {
namespace ygo { namespace ygo {
constexpr int MAX_STRING_ID = 0x7ff; constexpr int MAX_STRING_ID = 0x7ff;
constexpr unsigned int MIN_CARD_ID = (unsigned int)(MAX_STRING_ID + 1) >> 4; constexpr uint32_t MIN_CARD_ID = (uint32_t)(MAX_STRING_ID + 1) >> 4;
constexpr unsigned int MAX_CARD_ID = 0x0fffffffU; constexpr uint32_t MAX_CARD_ID = 0x0fffffffU;
using CardData = card_data; using CardData = card_data;
struct CardDataC : card_data { struct CardDataC {
uint32_t code{};
uint32_t alias{};
uint16_t setcode[SIZE_SETCODE]{};
uint32_t type{};
uint32_t level{};
uint32_t attribute{};
uint32_t race{};
int32_t attack{};
int32_t defense{};
uint32_t lscale{};
uint32_t rscale{};
uint32_t link_marker{};
uint32_t ot{}; uint32_t ot{};
uint32_t category{}; uint32_t category{};
bool is_setcodes(const std::vector<unsigned int>& values) const { bool is_setcodes(const std::vector<unsigned int>& values) const {
for (auto& value : values) { for (auto& value : values) {
if (is_setcode(value)) for (const auto& x : setcode) {
return true; if(!x)
break;
if(check_setcode(x, value))
return true;
}
} }
return false; return false;
} }
...@@ -37,8 +53,8 @@ struct CardString { ...@@ -37,8 +53,8 @@ struct CardString {
std::wstring text; std::wstring text;
std::wstring desc[16]; std::wstring desc[16];
}; };
using code_pointer = std::unordered_map<unsigned int, CardDataC>::const_iterator; using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator;
using string_pointer = std::unordered_map<unsigned int, CardString>::const_iterator; using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator;
class DataManager { class DataManager {
public: public:
...@@ -66,20 +82,28 @@ public: ...@@ -66,20 +82,28 @@ public:
#endif #endif
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = nullptr); bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = nullptr);
code_pointer GetCodePointer(unsigned int code) const; code_pointer GetCodePointer(uint32_t code) const;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
string_pointer GetStringPointer(unsigned int code) const; string_pointer GetStringPointer(uint32_t code) const;
code_pointer datas_begin() const; code_pointer datas_begin() const noexcept {
code_pointer datas_end() const; return _datas.cbegin();
string_pointer strings_begin() const; }
string_pointer strings_end() const; code_pointer datas_end() const noexcept {
#endif return _datas.cend();
bool GetData(unsigned int code, CardData* pData) const; }
string_pointer strings_begin() const noexcept {
return _strings.cbegin();
}
string_pointer strings_end() const noexcept {
return _strings.cend();
}
#endif //YGOPRO_SERVER_MODE
bool GetData(uint32_t code, CardData* pData) const;
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool GetString(unsigned int code, CardString* pStr) const; bool GetString(uint32_t code, CardString* pStr) const;
const wchar_t* GetName(unsigned int code) const; const wchar_t* GetName(uint32_t code) const;
const wchar_t* GetText(unsigned int code) const; const wchar_t* GetText(uint32_t code) const;
const wchar_t* GetDesc(unsigned int strCode) const; const wchar_t* GetDesc(uint32_t strCode) const;
const wchar_t* GetSysString(int code) const; const wchar_t* GetSysString(int code) const;
const wchar_t* GetVictoryString(int code) const; const wchar_t* GetVictoryString(int code) const;
const wchar_t* GetCounterName(int code) const; const wchar_t* GetCounterName(int code) const;
...@@ -131,9 +155,9 @@ public: ...@@ -131,9 +155,9 @@ public:
static bool deck_sort_name(code_pointer l1, code_pointer l2); static bool deck_sort_name(code_pointer l1, code_pointer l2);
private: private:
std::unordered_map<unsigned int, CardDataC> _datas; std::unordered_map<uint32_t, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings; std::unordered_map<uint32_t, CardString> _strings;
std::unordered_map<unsigned int, std::vector<uint16_t>> extra_setcode; std::unordered_map<uint32_t, std::vector<uint16_t>> extra_setcode;
std::wstring iniName; std::wstring iniName;
std::wstring iniHost; std::wstring iniHost;
std::wstring iniPort; std::wstring iniPort;
......
...@@ -215,6 +215,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -215,6 +215,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->cbDBDecks->addItem(dname); mainGame->cbDBDecks->addItem(dname);
mainGame->cbDBDecks->setSelected(mainGame->cbDBDecks->getItemCount() - 1); mainGame->cbDBDecks->setSelected(mainGame->cbDBDecks->getItemCount() - 1);
} }
prev_deck = mainGame->cbDBDecks->getSelected();
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());
...@@ -740,16 +741,16 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -740,16 +741,16 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
} }
mainGame->ClearCardInfo(); mainGame->ClearCardInfo();
unsigned char deckbuf[1024]; unsigned char deckbuf[1024]{};
auto pdeck = deckbuf; auto pdeck = deckbuf;
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main.size() + deckManager.current_deck.extra.size()); BufferIO::Write<int32_t>(pdeck, static_cast<int32_t>(deckManager.current_deck.main.size() + deckManager.current_deck.extra.size()));
BufferIO::WriteInt32(pdeck, deckManager.current_deck.side.size()); BufferIO::Write<int32_t>(pdeck, static_cast<int32_t>(deckManager.current_deck.side.size()));
for(size_t i = 0; i < deckManager.current_deck.main.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.main.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.main[i]->first);
for(size_t i = 0; i < deckManager.current_deck.extra.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.extra.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.extra[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.extra[i]->first);
for(size_t i = 0; i < deckManager.current_deck.side.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.side.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.side[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.side[i]->first);
DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf); DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf);
break; break;
} }
...@@ -1516,7 +1517,7 @@ void DeckBuilder::FilterCards() { ...@@ -1516,7 +1517,7 @@ void DeckBuilder::FilterCards() {
auto strpointer = dataManager.GetStringPointer(ptr->first); auto strpointer = dataManager.GetStringPointer(ptr->first);
if (strpointer == dataManager.strings_end()) if (strpointer == dataManager.strings_end())
continue; continue;
const CardString& text = strpointer->second; const CardString& strings = strpointer->second;
if(data.type & TYPE_TOKEN) if(data.type & TYPE_TOKEN)
continue; continue;
switch(filter_type) { switch(filter_type) {
...@@ -1592,15 +1593,15 @@ void DeckBuilder::FilterCards() { ...@@ -1592,15 +1593,15 @@ void DeckBuilder::FilterCards() {
for (auto elements_iterator = query_elements.begin(); elements_iterator != query_elements.end(); ++elements_iterator) { for (auto elements_iterator = query_elements.begin(); elements_iterator != query_elements.end(); ++elements_iterator) {
bool match = false; bool match = false;
if (elements_iterator->type == element_t::type_t::name) { if (elements_iterator->type == element_t::type_t::name) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str()); match = CardNameContains(strings.name.c_str(), elements_iterator->keyword.c_str());
} else if (elements_iterator->type == element_t::type_t::setcode) { } else if (elements_iterator->type == element_t::type_t::setcode) {
match = data.is_setcodes(elements_iterator->setcodes); match = data.is_setcodes(elements_iterator->setcodes);
} else if (trycode && (data.code == trycode || data.alias == trycode && data.is_alternative())){ } else if (trycode && (data.code == trycode || data.alias == trycode && is_alternative(data.code, data.alias))){
match = true; match = true;
} else { } else {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str()) match = CardNameContains(strings.name.c_str(), elements_iterator->keyword.c_str())
|| text.text.find(elements_iterator->keyword) != std::wstring::npos || strings.text.find(elements_iterator->keyword) != std::wstring::npos
|| mainGame->CheckRegEx(text.text, elements_iterator->keyword) || mainGame->CheckRegEx(strings.text, elements_iterator->keyword)
|| data.is_setcodes(elements_iterator->setcodes); || data.is_setcodes(elements_iterator->setcodes);
} }
if(elements_iterator->exclude) if(elements_iterator->exclude)
...@@ -1918,7 +1919,7 @@ void DeckBuilder::pop_side(int seq) { ...@@ -1918,7 +1919,7 @@ void DeckBuilder::pop_side(int seq) {
GetHoveredCard(); GetHoveredCard();
} }
bool DeckBuilder::check_limit(code_pointer pointer) { bool DeckBuilder::check_limit(code_pointer pointer) {
unsigned int limitcode = pointer->second.alias ? pointer->second.alias : pointer->first; auto limitcode = pointer->second.alias ? pointer->second.alias : pointer->first;
int limit = 3; int limit = 3;
auto flit = filterList->content.find(limitcode); auto flit = filterList->content.find(limitcode);
if(flit != filterList->content.end()) if(flit != filterList->content.end())
......
...@@ -50,8 +50,7 @@ void DeckManager::LoadLFListSingle(irr::io::IReadFile* reader, bool insert) { ...@@ -50,8 +50,7 @@ void DeckManager::LoadLFListSingle(irr::io::IReadFile* reader, bool insert) {
void DeckManager::LoadLFList() { void DeckManager::LoadLFList() {
#ifdef SERVER_PRO2_SUPPORT #ifdef SERVER_PRO2_SUPPORT
LoadLFListSingle("config/lflist.conf"); LoadLFListSingle("config/lflist.conf");
#endif #elif defined(SERVER_PRO3_SUPPORT)
#ifdef SERVER_PRO3_SUPPORT
LoadLFListSingle("Data/lflist.conf"); LoadLFListSingle("Data/lflist.conf");
#endif #endif
LoadLFListSingle("specials/lflist.conf"); LoadLFListSingle("specials/lflist.conf");
...@@ -208,8 +207,9 @@ uint32_t DeckManager::LoadDeckFromStream(Deck& deck, std::istringstream& deckStr ...@@ -208,8 +207,9 @@ uint32_t DeckManager::LoadDeckFromStream(Deck& deck, std::istringstream& deckStr
} }
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); auto code = std::strtoul(linebuf.c_str(), nullptr, 10);
if (code >= UINT32_MAX) if (errno || code > UINT32_MAX)
continue; continue;
cardlist[ct++] = code; cardlist[ct++] = code;
if (is_side) if (is_side)
...@@ -353,7 +353,7 @@ bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) { ...@@ -353,7 +353,7 @@ bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) {
return false; return false;
std::stringstream deckStream; std::stringstream deckStream;
SaveDeck(deck, deckStream); SaveDeck(deck, deckStream);
std::fwrite(deckStream.str().c_str(), 1, deckStream.str().length(), fp); std::fputs(deckStream.str().c_str(), fp);
std::fclose(fp); std::fclose(fp);
return true; return true;
} }
...@@ -374,21 +374,21 @@ bool DeckManager::LoadDeckFromCode(Deck& deck, const unsigned char *code, int le ...@@ -374,21 +374,21 @@ bool DeckManager::LoadDeckFromCode(Deck& deck, const unsigned char *code, int le
int decoded_len = Base64::DecodedLength(code, len); int decoded_len = Base64::DecodedLength(code, len);
if(decoded_len > 1024 || decoded_len < 8 || !Base64::Decode(code, len, data_, decoded_len)) if(decoded_len > 1024 || decoded_len < 8 || !Base64::Decode(code, len, data_, decoded_len))
return false; return false;
int mainc = BufferIO::ReadInt32(pdeck); int mainc = BufferIO::Read<int32_t>(pdeck);
int sidec = BufferIO::ReadInt32(pdeck); int sidec = BufferIO::Read<int32_t>(pdeck);
int errorcode = LoadDeck(deck, (uint32_t*)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) {
unsigned char deckbuf[1024], *pdeck = deckbuf; unsigned char deckbuf[1024], *pdeck = deckbuf;
BufferIO::WriteInt32(pdeck, deck.main.size() + deck.extra.size()); BufferIO::Write<int32_t>(pdeck, deck.main.size() + deck.extra.size());
BufferIO::WriteInt32(pdeck, deck.side.size()); BufferIO::Write<int32_t>(pdeck, deck.side.size());
for(size_t i = 0; i < deck.main.size(); ++i) for(size_t i = 0; i < deck.main.size(); ++i)
BufferIO::WriteInt32(pdeck, deck.main[i]->first); BufferIO::Write<int32_t>(pdeck, deck.main[i]->first);
for(size_t i = 0; i < deck.extra.size(); ++i) for(size_t i = 0; i < deck.extra.size(); ++i)
BufferIO::WriteInt32(pdeck, deck.extra[i]->first); BufferIO::Write<int32_t>(pdeck, deck.extra[i]->first);
for(size_t i = 0; i < deck.side.size(); ++i) for(size_t i = 0; i < deck.side.size(); ++i)
BufferIO::WriteInt32(pdeck, deck.side[i]->first); BufferIO::Write<int32_t>(pdeck, deck.side[i]->first);
int len = pdeck - deckbuf; int len = pdeck - deckbuf;
int encoded_len = Base64::EncodedLength(len); int encoded_len = Base64::EncodedLength(len);
Base64::Encode(deckbuf, len, code, encoded_len+1); Base64::Encode(deckbuf, len, code, encoded_len+1);
......
...@@ -30,10 +30,13 @@ namespace ygo { ...@@ -30,10 +30,13 @@ namespace ygo {
constexpr int SIDE_MAX_SIZE = YGOPRO_MAX_SIDE; constexpr int SIDE_MAX_SIZE = YGOPRO_MAX_SIDE;
constexpr int PACK_MAX_SIZE = 1000; constexpr int PACK_MAX_SIZE = 1000;
constexpr int MAINC_MAX = 250; // the limit of card_state
constexpr int SIDEC_MAX = MAINC_MAX;
struct LFList { struct LFList {
unsigned int hash{}; unsigned int hash{};
std::wstring listName; std::wstring listName;
std::unordered_map<unsigned int, int> content; std::unordered_map<uint32_t, int> content;
}; };
struct Deck { struct Deck {
std::vector<code_pointer> main; std::vector<code_pointer> main;
...@@ -130,17 +133,16 @@ private: ...@@ -130,17 +133,16 @@ private:
void _LoadLFListFromLineProvider(LineProvider getLine, bool insert = false) { void _LoadLFListFromLineProvider(LineProvider getLine, bool insert = false) {
std::vector<LFList> loadedLists; std::vector<LFList> loadedLists;
auto cur = loadedLists.rend(); // 注意:在临时 list 上操作 auto cur = loadedLists.rend(); // 注意:在临时 list 上操作
char line[256]{}; char linebuf[256]{};
wchar_t strBuffer[256]{}; wchar_t strBuffer[256]{};
char str1[16]{};
while (getLine(line, sizeof(line))) { while (getLine(linebuf, sizeof(linebuf))) {
if (line[0] == '#') if (linebuf[0] == '#')
continue; continue;
if (line[0] == '!') { if (linebuf[0] == '!') {
auto len = std::strcspn(line, "\r\n"); auto len = std::strcspn(linebuf, "\r\n");
line[len] = 0; linebuf[len] = 0;
BufferIO::DecodeUTF8(&line[1], strBuffer); BufferIO::DecodeUTF8(&linebuf[1], strBuffer);
LFList newlist; LFList newlist;
newlist.listName = strBuffer; newlist.listName = strBuffer;
newlist.hash = 0x7dfcee6a; newlist.hash = 0x7dfcee6a;
...@@ -150,13 +152,20 @@ private: ...@@ -150,13 +152,20 @@ private:
} }
if (cur == loadedLists.rend()) if (cur == loadedLists.rend())
continue; continue;
unsigned int code = 0; char* pos = linebuf;
int count = -1; errno = 0;
if (std::sscanf(line, "%10s%*[ ]%1d", str1, &count) != 2) auto result = std::strtoul(pos, &pos, 10);
if (errno || result > UINT32_MAX)
continue;
if (pos == linebuf || *pos != ' ')
continue;
uint32_t code = static_cast<uint32_t>(result);
errno = 0;
int count = std::strtol(pos, &pos, 10);
if (errno)
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)));
} }
......
...@@ -371,6 +371,7 @@ void Game::DrawCard(ClientCard* pcard) { ...@@ -371,6 +371,7 @@ void Game::DrawCard(ClientCard* pcard) {
if(pcard->aniFrame == 0) { if(pcard->aniFrame == 0) {
pcard->is_moving = false; pcard->is_moving = false;
pcard->is_fading = false; pcard->is_fading = false;
pcard->chain_code = 0;
} }
} }
matManager.mCard.AmbientColor = 0xffffffff; matManager.mCard.AmbientColor = 0xffffffff;
...@@ -378,7 +379,10 @@ void Game::DrawCard(ClientCard* pcard) { ...@@ -378,7 +379,10 @@ void Game::DrawCard(ClientCard* pcard) {
driver->setTransform(irr::video::ETS_WORLD, pcard->mTransform); driver->setTransform(irr::video::ETS_WORLD, pcard->mTransform);
auto m22 = pcard->mTransform(2, 2); auto m22 = pcard->mTransform(2, 2);
if(m22 > -0.99 || pcard->is_moving) { if(m22 > -0.99 || pcard->is_moving) {
matManager.mCard.setTexture(0, imageManager.GetTexture(pcard->code)); auto code = pcard->code;
if (code == 0 && pcard->is_moving)
code = pcard->chain_code;
matManager.mCard.setTexture(0, imageManager.GetTexture(code));
driver->setMaterial(matManager.mCard); driver->setMaterial(matManager.mCard);
driver->drawVertexPrimitiveList(matManager.vCardFront, 4, matManager.iRectangle, 2); driver->drawVertexPrimitiveList(matManager.vCardFront, 4, matManager.iRectangle, 2);
} }
...@@ -1197,7 +1201,7 @@ void Game::WaitFrameSignal(int frame) { ...@@ -1197,7 +1201,7 @@ void Game::WaitFrameSignal(int frame) {
frameSignal.Wait(); frameSignal.Wait();
} }
void Game::DrawThumb(code_pointer cp, irr::core::vector2di pos, const LFList* lflist, bool drag) { void Game::DrawThumb(code_pointer cp, irr::core::vector2di pos, const LFList* lflist, bool drag) {
int code = cp->first; auto code = cp->first;
auto lcode = cp->second.alias; auto lcode = cp->second.alias;
if(lcode == 0) if(lcode == 0)
lcode = code; lcode = code;
......
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <random> #include <random>
#include "config.h"
#include "network.h" #include "network.h"
namespace ygo { namespace ygo {
...@@ -96,8 +97,8 @@ public: ...@@ -96,8 +97,8 @@ public:
static HostResult ParseHost(char *hostname); static HostResult ParseHost(char *hostname);
static void SendPacketToServer(unsigned char proto) { static void SendPacketToServer(unsigned char proto) {
auto p = duel_client_write; auto p = duel_client_write;
buffer_write<uint16_t>(p, 1); BufferIO::Write<uint16_t>(p, 1);
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
#ifdef YGOPRO_MESSAGE_DEBUG #ifdef YGOPRO_MESSAGE_DEBUG
printf("CTOS: %d\n", proto); printf("CTOS: %d\n", proto);
#endif #endif
...@@ -107,8 +108,8 @@ public: ...@@ -107,8 +108,8 @@ public:
static void SendPacketToServer(unsigned char proto, const ST& st) { static void SendPacketToServer(unsigned char proto, const ST& st) {
auto p = duel_client_write; auto p = duel_client_write;
static_assert(sizeof(ST) <= MAX_DATA_SIZE, "Packet size is too large."); static_assert(sizeof(ST) <= MAX_DATA_SIZE, "Packet size is too large.");
buffer_write<uint16_t>(p, (uint16_t)(1 + sizeof(ST))); BufferIO::Write<uint16_t>(p, (uint16_t)(1 + sizeof(ST)));
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
std::memcpy(p, &st, sizeof(ST)); std::memcpy(p, &st, sizeof(ST));
#ifdef YGOPRO_MESSAGE_DEBUG #ifdef YGOPRO_MESSAGE_DEBUG
printf("CTOS: %d Length: %ld\n", proto, sizeof(ST)); printf("CTOS: %d Length: %ld\n", proto, sizeof(ST));
...@@ -119,8 +120,8 @@ public: ...@@ -119,8 +120,8 @@ public:
auto p = duel_client_write; auto p = duel_client_write;
if (len > MAX_DATA_SIZE) if (len > MAX_DATA_SIZE)
len = MAX_DATA_SIZE; len = MAX_DATA_SIZE;
buffer_write<uint16_t>(p, (uint16_t)(1 + len)); BufferIO::Write<uint16_t>(p, (uint16_t)(1 + len));
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
std::memcpy(p, buffer, len); std::memcpy(p, buffer, len);
#ifdef YGOPRO_MESSAGE_DEBUG #ifdef YGOPRO_MESSAGE_DEBUG
printf("CTOS: %d Length: %ld\n", proto, len); printf("CTOS: %d Length: %ld\n", proto, len);
......
...@@ -101,8 +101,7 @@ void Game::MainServerLoop() { ...@@ -101,8 +101,7 @@ void Game::MainServerLoop() {
LoadExpansionsAll(); LoadExpansionsAll();
#ifdef SERVER_PRO2_SUPPORT #ifdef SERVER_PRO2_SUPPORT
DataManager::FileSystem->addFileArchive("data/script.zip", true, false, irr::io::EFAT_ZIP); DataManager::FileSystem->addFileArchive("data/script.zip", true, false, irr::io::EFAT_ZIP);
#endif #elif defined(SERVER_PRO3_SUPPORT)
#ifdef SERVER_PRO3_SUPPORT
DataManager::FileSystem->addFileArchive("Data/script.zip", true, false, irr::io::EFAT_ZIP); DataManager::FileSystem->addFileArchive("Data/script.zip", true, false, irr::io::EFAT_ZIP);
#endif #endif
...@@ -274,7 +273,7 @@ bool Game::Initialize() { ...@@ -274,7 +273,7 @@ bool Game::Initialize() {
SetWindowsIcon(); SetWindowsIcon();
//main menu //main menu
wchar_t strbuf[256]; wchar_t strbuf[256];
myswprintf(strbuf, L"KoishiPro %X.0%X.%X Manjushage", (PRO_VERSION & 0xf000U) >> 12, (PRO_VERSION & 0x0ff0U) >> 4, PRO_VERSION & 0x000fU); myswprintf(strbuf, L"KoishiPro %X.0%X.%X Memes", (PRO_VERSION & 0xf000U) >> 12, (PRO_VERSION & 0x0ff0U) >> 4, PRO_VERSION & 0x000fU);
wMainMenu = env->addWindow(irr::core::rect<irr::s32>(370, 200, 650, 415), false, strbuf); wMainMenu = env->addWindow(irr::core::rect<irr::s32>(370, 200, 650, 415), false, strbuf);
wMainMenu->getCloseButton()->setVisible(false); wMainMenu->getCloseButton()->setVisible(false);
btnLanMode = env->addButton(irr::core::rect<irr::s32>(10, 30, 270, 60), wMainMenu, BUTTON_LAN_MODE, dataManager.GetSysString(1200)); btnLanMode = env->addButton(irr::core::rect<irr::s32>(10, 30, 270, 60), wMainMenu, BUTTON_LAN_MODE, dataManager.GetSysString(1200));
...@@ -1419,8 +1418,7 @@ void Game::LoadExpansionsAll() { ...@@ -1419,8 +1418,7 @@ void Game::LoadExpansionsAll() {
dataManager.LoadDB(fpath); dataManager.LoadDB(fpath);
} }
}); });
#endif // SERVER_PRO2_SUPPORT #elif defined(SERVER_PRO3_SUPPORT)
#ifdef SERVER_PRO3_SUPPORT
FileSystem::TraversalDir(L"./Data/locales/zh-CN", [](const wchar_t* name, bool isdir) { FileSystem::TraversalDir(L"./Data/locales/zh-CN", [](const wchar_t* name, bool isdir) {
wchar_t fpath[1024]; wchar_t fpath[1024];
myswprintf(fpath, L"./Data/locales/zh-CN/%ls", name); myswprintf(fpath, L"./Data/locales/zh-CN/%ls", name);
...@@ -1512,11 +1510,8 @@ void Game::RefreshDeck(const wchar_t* deckpath, const std::function<void(const w ...@@ -1512,11 +1510,8 @@ void Game::RefreshDeck(const wchar_t* deckpath, const std::function<void(const w
} }
FileSystem::TraversalDir(deckpath, [additem](const wchar_t* name, bool isdir) { FileSystem::TraversalDir(deckpath, [additem](const wchar_t* name, bool isdir) {
if (!isdir && IsExtension(name, L".ydk")) { if (!isdir && IsExtension(name, L".ydk")) {
size_t len = std::wcslen(name);
wchar_t deckname[256]{}; wchar_t deckname[256]{};
size_t count = std::min(len - 4, sizeof deckname / sizeof deckname[0] - 1); BufferIO::CopyWideString(name, deckname, std::wcslen(name) - 4);
std::wcsncpy(deckname, name, count);
deckname[count] = 0;
additem(deckname); additem(deckname);
} }
}); });
...@@ -2011,7 +2006,7 @@ void Game::ShowCardInfo(int code, bool resize) { ...@@ -2011,7 +2006,7 @@ void Game::ShowCardInfo(int code, bool resize) {
imgCard->setImage(imageManager.GetTexture(code, true)); imgCard->setImage(imageManager.GetTexture(code, true));
if (is_valid) { if (is_valid) {
auto& cd = cit->second; auto& cd = cit->second;
if (cd.is_alternative()) if (is_alternative(cd.code,cd.alias))
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias); myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else else
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code); myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
...@@ -2199,7 +2194,7 @@ void Game::AddDebugMsg(const char* msg) { ...@@ -2199,7 +2194,7 @@ void Game::AddDebugMsg(const char* msg) {
} }
if (enable_log & 0x2) { if (enable_log & 0x2) {
char msgbuf[1040]; char msgbuf[1040];
std::snprintf(msgbuf, sizeof msgbuf, "[Script Error]: %s", msg); mysnprintf(msgbuf, "[Script Error]: %s", msg);
ErrorLog(msgbuf); ErrorLog(msgbuf);
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
......
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
#include <sstream> #include <sstream>
#endif #endif
#if defined(_WIN32) && (!defined(WDK_NTDDI_VERSION) || (WDK_NTDDI_VERSION < 0x0A000005)) // Redstone 4, Version 1803, Build 17134.
#error "This program requires the Windows 10 SDK version 1803 or above to compile on Windows. Otherwise, non-ASCII characters will not be displayed or processed correctly."
#endif
unsigned int enable_log = 0x3; unsigned int enable_log = 0x3;
bool expansions_specified = false; bool expansions_specified = false;
std::vector<std::wstring> expansions_list; std::vector<std::wstring> expansions_list;
...@@ -36,11 +40,11 @@ void ClickButton(irr::gui::IGUIElement* btn) { ...@@ -36,11 +40,11 @@ void ClickButton(irr::gui::IGUIElement* btn) {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
#if defined(FOPEN_WINDOWS_SUPPORT_UTF8) #if defined(_WIN32)
std::setlocale(LC_CTYPE, ".UTF-8"); std::setlocale(LC_CTYPE, ".UTF-8");
#elif defined(__APPLE__) #elif defined(__APPLE__)
std::setlocale(LC_CTYPE, "UTF-8"); std::setlocale(LC_CTYPE, "UTF-8");
#elif !defined(_WIN32) #else
std::setlocale(LC_CTYPE, ""); std::setlocale(LC_CTYPE, "");
#endif #endif
#if defined __APPLE__ && !defined YGOPRO_SERVER_MODE #if defined __APPLE__ && !defined YGOPRO_SERVER_MODE
......
This diff is collapsed.
...@@ -17,14 +17,14 @@ void UpdateDeck() { ...@@ -17,14 +17,14 @@ void UpdateDeck() {
BufferIO::CopyWideString(mainGame->cbDeckSelect->getText(), mainGame->gameConf.lastdeck); BufferIO::CopyWideString(mainGame->cbDeckSelect->getText(), mainGame->gameConf.lastdeck);
unsigned char deckbuf[1024]{}; unsigned char deckbuf[1024]{};
auto pdeck = deckbuf; auto pdeck = deckbuf;
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main.size() + deckManager.current_deck.extra.size()); BufferIO::Write<int32_t>(pdeck, static_cast<int32_t>(deckManager.current_deck.main.size() + deckManager.current_deck.extra.size()));
BufferIO::WriteInt32(pdeck, deckManager.current_deck.side.size()); BufferIO::Write<int32_t>(pdeck, static_cast<int32_t>(deckManager.current_deck.side.size()));
for(size_t i = 0; i < deckManager.current_deck.main.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.main.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.main[i]->first);
for(size_t i = 0; i < deckManager.current_deck.extra.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.extra.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.extra[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.extra[i]->first);
for(size_t i = 0; i < deckManager.current_deck.side.size(); ++i) for(size_t i = 0; i < deckManager.current_deck.side.size(); ++i)
BufferIO::WriteInt32(pdeck, deckManager.current_deck.side[i]->first); BufferIO::Write<uint32_t>(pdeck, deckManager.current_deck.side[i]->first);
DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf); DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf);
} }
bool MenuHandler::OnEvent(const irr::SEvent& event) { bool MenuHandler::OnEvent(const irr::SEvent& event) {
...@@ -365,9 +365,9 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -365,9 +365,9 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
int flag = 0; int flag = 0;
flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0); flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0);
char arg2[8]; char arg2[8];
std::snprintf(arg2, sizeof arg2, "%d", flag); mysnprintf(arg2, "%d", flag);
char arg3[8]; char arg3[8];
std::snprintf(arg3, sizeof arg3, "%d", mainGame->gameConf.serverport); mysnprintf(arg3, "%d", mainGame->gameConf.serverport);
execl("./bot", "bot", arg1, arg2, arg3, nullptr); execl("./bot", "bot", arg1, arg2, arg3, nullptr);
std::exit(0); std::exit(0);
} else { } else {
...@@ -411,8 +411,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -411,8 +411,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t *dot = std::wcsrchr(open_file_name, L'.'); wchar_t *dot = std::wcsrchr(open_file_name, L'.');
if(dash && dot && !mywcsncasecmp(dot, L".ydk", 4)) { // full path if(dash && dot && !mywcsncasecmp(dot, L".ydk", 4)) { // full path
wchar_t deck_name[256]; wchar_t deck_name[256];
std::wcsncpy(deck_name, dash + 1, dot - dash - 1); BufferIO::CopyWideString(dash + 1, deck_name, dot - dash - 1);
deck_name[dot - dash - 1] = L'\0';
mainGame->ebDeckname->setText(deck_name); mainGame->ebDeckname->setText(deck_name);
mainGame->cbDBCategory->setSelected(-1); mainGame->cbDBCategory->setSelected(-1);
mainGame->cbDBDecks->setSelected(-1); mainGame->cbDBDecks->setSelected(-1);
...@@ -421,7 +420,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -421,7 +420,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->cbDBDecks->setEnabled(false); mainGame->cbDBDecks->setEnabled(false);
} else if(dash) { // has category } else if(dash) { // has category
wchar_t deck_name[256]; wchar_t deck_name[256];
std::wcsncpy(deck_name, dash + 1, 256); BufferIO::CopyWideString(dash + 1, deck_name);
for(size_t i = 0; i < mainGame->cbDBDecks->getItemCount(); ++i) { for(size_t i = 0; i < mainGame->cbDBDecks->getItemCount(); ++i) {
if(!std::wcscmp(mainGame->cbDBDecks->getItem(i), deck_name)) { if(!std::wcscmp(mainGame->cbDBDecks->getItem(i), deck_name)) {
BufferIO::CopyWideString(deck_name, mainGame->gameConf.lastdeck); BufferIO::CopyWideString(deck_name, mainGame->gameConf.lastdeck);
......
...@@ -182,7 +182,7 @@ public: ...@@ -182,7 +182,7 @@ public:
bool success = true; bool success = true;
TraversalDir(dir, [dir, &success](const char *name, bool isdir) { TraversalDir(dir, [dir, &success](const char *name, bool isdir) {
char full_path[1024]; char full_path[1024];
int len = std::snprintf(full_path, sizeof full_path, "%s/%s", dir, name); int len = mysnprintf(full_path, "%s/%s", dir, name);
if (len < 0 || len >= (int)(sizeof full_path)) { if (len < 0 || len >= (int)(sizeof full_path)) {
success = false; success = false;
return; return;
...@@ -234,7 +234,7 @@ public: ...@@ -234,7 +234,7 @@ public:
file_unit funit; file_unit funit;
#endif #endif
char fname[1024]; char fname[1024];
int len = std::snprintf(fname, sizeof fname, "%s/%s", path, dirp->d_name); int len = mysnprintf(fname, "%s/%s", path, dirp->d_name);
if (len < 0 || len >= (int)(sizeof fname)) if (len < 0 || len >= (int)(sizeof fname))
continue; continue;
stat(fname, &fileStat); stat(fname, &fileStat);
......
...@@ -95,7 +95,7 @@ bool NetServer::StartServer(unsigned short port) { ...@@ -95,7 +95,7 @@ bool NetServer::StartServer(unsigned short port) {
std::memset(&sin, 0, sizeof sin); std::memset(&sin, 0, sizeof sin);
server_port = port; server_port = port;
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
#ifdef SERVER_PRO2_SUPPORT #if defined(SERVER_PRO2_SUPPORT) && !defined(SERVER_PRO3_SUPPORT)
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#else #else
sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_addr.s_addr = htonl(INADDR_ANY);
...@@ -272,7 +272,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) { ...@@ -272,7 +272,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) {
} }
void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) { void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
auto pdata = data; auto pdata = data;
unsigned char pktType = BufferIO::ReadUInt8(pdata); unsigned char pktType = BufferIO::Read<uint8_t>(pdata);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if((pktType != CTOS_SURRENDER) && (pktType != CTOS_CHAT) && (pktType != CTOS_REQUEST_FIELD) && (dp->state == 0xff || (dp->state && dp->state != pktType))) if((pktType != CTOS_SURRENDER) && (pktType != CTOS_CHAT) && (pktType != CTOS_REQUEST_FIELD) && (dp->state == 0xff || (dp->state && dp->state != pktType)))
#else #else
...@@ -352,7 +352,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) { ...@@ -352,7 +352,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
// for other server & reverse proxy use only // for other server & reverse proxy use only
/* /*
wchar_t hostname[LEN_HOSTNAME]; wchar_t hostname[LEN_HOSTNAME];
uint32_t real_ip = ntohl(BufferIO::ReadInt32(pdata)); uint32_t real_ip = ntohl(BufferIO::Read<int32_t>(pdata));
BufferIO::CopyCharArray((uint16_t*)pdata, hostname); BufferIO::CopyCharArray((uint16_t*)pdata, hostname);
*/ */
break; break;
...@@ -488,8 +488,9 @@ size_t NetServer::CreateChatPacket(unsigned char* src, int src_size, unsigned ch ...@@ -488,8 +488,9 @@ size_t NetServer::CreateChatPacket(unsigned char* src, int src_size, unsigned ch
return 0; return 0;
// STOC_Chat packet // STOC_Chat packet
auto pdst = dst; auto pdst = dst;
buffer_write<uint16_t>(pdst, dst_player_type); BufferIO::Write<uint16_t>(pdst, dst_player_type);
buffer_write_block(pdst, src_msg, src_size); std::memcpy(pdst, src_msg, src_size);
pdst += src_size;
return sizeof(dst_player_type) + src_size; return sizeof(dst_player_type) + src_size;
} }
......
#ifndef NETSERVER_H #ifndef NETSERVER_H
#define NETSERVER_H #define NETSERVER_H
#include "network.h"
#include <unordered_map> #include <unordered_map>
#include "config.h"
#include "network.h"
namespace ygo { namespace ygo {
...@@ -49,8 +50,8 @@ public: ...@@ -49,8 +50,8 @@ public:
static size_t CreateChatPacket(unsigned char* src, int src_size, unsigned char* dst, uint16_t dst_player_type); static size_t CreateChatPacket(unsigned char* src, int src_size, unsigned char* dst, uint16_t dst_player_type);
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) { static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) {
auto p = net_server_write; auto p = net_server_write;
buffer_write<uint16_t>(p, 1); BufferIO::Write<uint16_t>(p, 1);
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
last_sent = 3; last_sent = 3;
if (dp) if (dp)
bufferevent_write(dp->bev, net_server_write, 3); bufferevent_write(dp->bev, net_server_write, 3);
...@@ -59,8 +60,8 @@ public: ...@@ -59,8 +60,8 @@ public:
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto, const ST& st) { static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto, const ST& st) {
auto p = net_server_write; auto p = net_server_write;
static_assert(sizeof(ST) <= MAX_DATA_SIZE, "Packet size is too large."); static_assert(sizeof(ST) <= MAX_DATA_SIZE, "Packet size is too large.");
buffer_write<uint16_t>(p, (uint16_t)(1 + sizeof(ST))); BufferIO::Write<uint16_t>(p, (uint16_t)(1 + sizeof(ST)));
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
std::memcpy(p, &st, sizeof(ST)); std::memcpy(p, &st, sizeof(ST));
last_sent = sizeof(ST) + 3; last_sent = sizeof(ST) + 3;
if (dp) if (dp)
...@@ -70,8 +71,8 @@ public: ...@@ -70,8 +71,8 @@ public:
auto p = net_server_write; auto p = net_server_write;
if (len > MAX_DATA_SIZE) if (len > MAX_DATA_SIZE)
len = MAX_DATA_SIZE; len = MAX_DATA_SIZE;
buffer_write<uint16_t>(p, (uint16_t)(1 + len)); BufferIO::Write<uint16_t>(p, (uint16_t)(1 + len));
buffer_write<uint8_t>(p, proto); BufferIO::Write<uint8_t>(p, proto);
std::memcpy(p, buffer, len); std::memcpy(p, buffer, len);
last_sent = len + 3; last_sent = len + 3;
if (dp) if (dp)
......
...@@ -9,14 +9,13 @@ ...@@ -9,14 +9,13 @@
#include <event2/buffer.h> #include <event2/buffer.h>
#include <event2/thread.h> #include <event2/thread.h>
#include <type_traits> #include <type_traits>
#include "deck_manager.h"
#define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true && std::is_standard_layout<T>::value == true, "not trivially copyable") #define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true && std::is_standard_layout<T>::value == true, "not trivially copyable")
namespace ygo { namespace ygo {
constexpr int SIZE_NETWORK_BUFFER = 0x20000; constexpr int SIZE_NETWORK_BUFFER = 0x20000;
constexpr int MAX_DATA_SIZE = UINT16_MAX - 1; constexpr int MAX_DATA_SIZE = UINT16_MAX - 1;
constexpr int MAINC_MAX = 250; // the limit of card_state
constexpr int SIDEC_MAX = MAINC_MAX;
struct HostInfo { struct HostInfo {
uint32_t lflist{}; uint32_t lflist{};
......
...@@ -73,7 +73,7 @@ end ...@@ -73,7 +73,7 @@ end
end end
if BUILD_FREETYPE then if BUILD_FREETYPE then
includedirs { "../freetype/include" } includedirs { "../freetype/custom", "../freetype/include" }
else else
includedirs { FREETYPE_INCLUDE_DIR } includedirs { FREETYPE_INCLUDE_DIR }
libdirs { FREETYPE_LIB_DIR } libdirs { FREETYPE_LIB_DIR }
...@@ -114,10 +114,12 @@ end ...@@ -114,10 +114,12 @@ end
end end
filter "system:windows" filter "system:windows"
if not SERVER_PRO3_SUPPORT then
entrypoint "mainCRTStartup" entrypoint "mainCRTStartup"
end
defines { "_IRR_WCHAR_FILESYSTEM" } defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc" files "ygopro.rc"
if SERVER_PRO2_SUPPORT then if SERVER_PRO2_SUPPORT and not SERVER_PRO3_SUPPORT then
targetname ("AI.Server") targetname ("AI.Server")
end end
if SERVER_MODE then if SERVER_MODE then
......
#include "config.h"
#include "replay.h" #include "replay.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
namespace ygo { namespace ygo {
...@@ -23,23 +23,6 @@ void Replay::BeginRecord() { ...@@ -23,23 +23,6 @@ void Replay::BeginRecord() {
#endif #endif
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay")) if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return; return;
#ifdef _WIN32
if(is_recording)
CloseHandle(recording_fp);
#ifdef YGOPRO_SERVER_MODE
time_t nowtime = time(nullptr);
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, nullptr, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, nullptr);
#else
recording_fp = CreateFileW(L"./replay/_LastReplay.yrp", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, nullptr);
#endif //YGOPRO_SERVER_MODE
if(recording_fp == INVALID_HANDLE_VALUE)
return;
#else
if(is_recording) if(is_recording)
std::fclose(fp); std::fclose(fp);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -55,7 +38,6 @@ void Replay::BeginRecord() { ...@@ -55,7 +38,6 @@ void Replay::BeginRecord() {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
if(!fp) if(!fp)
return; return;
#endif
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
...@@ -67,13 +49,8 @@ void Replay::WriteHeader(ExtendedReplayHeader& header) { ...@@ -67,13 +49,8 @@ void Replay::WriteHeader(ExtendedReplayHeader& header) {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return; if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif #endif
#ifdef _WIN32 std::fwrite(&header, sizeof header, 1, fp);
DWORD size;
WriteFile(recording_fp, &header, sizeof(header), &size, nullptr);
#else
std::fwrite(&header, sizeof(header), 1, fp);
std::fflush(fp); std::fflush(fp);
#endif
} }
void Replay::WriteData(const void* data, size_t length, bool flush) { void Replay::WriteData(const void* data, size_t length, bool flush) {
if(!is_recording) if(!is_recording)
...@@ -85,14 +62,9 @@ void Replay::WriteData(const void* data, size_t length, bool flush) { ...@@ -85,14 +62,9 @@ void Replay::WriteData(const void* data, size_t length, bool flush) {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return; if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif #endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, data, length, &size, nullptr);
#else
std::fwrite(data, length, 1, fp); std::fwrite(data, length, 1, fp);
if(flush) if(flush)
std::fflush(fp); std::fflush(fp);
#endif
} }
void Replay::WriteInt32(int32_t data, bool flush) { void Replay::WriteInt32(int32_t data, bool flush) {
Write<int32_t>(data, flush); Write<int32_t>(data, flush);
...@@ -103,10 +75,7 @@ void Replay::Flush() { ...@@ -103,10 +75,7 @@ void Replay::Flush() {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return; if(!(replay_mode & REPLAY_MODE_SAVE_IN_SERVER)) return;
#endif #endif
#ifdef _WIN32
#else
std::fflush(fp); std::fflush(fp);
#endif
} }
void Replay::EndRecord() { void Replay::EndRecord() {
if(!is_recording) if(!is_recording)
...@@ -114,11 +83,7 @@ void Replay::EndRecord() { ...@@ -114,11 +83,7 @@ void Replay::EndRecord() {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(replay_mode & REPLAY_MODE_SAVE_IN_SERVER) { if(replay_mode & REPLAY_MODE_SAVE_IN_SERVER) {
#endif #endif
#ifdef _WIN32
CloseHandle(recording_fp);
#else
std::fclose(fp); std::fclose(fp);
#endif
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
} }
#endif #endif
...@@ -211,17 +176,12 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) { ...@@ -211,17 +176,12 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t newfname[256]; wchar_t newfname[256];
myswprintf(oldfname, L"./replay/%ls", oldname); myswprintf(oldfname, L"./replay/%ls", oldname);
myswprintf(newfname, L"./replay/%ls", newname); myswprintf(newfname, L"./replay/%ls", newname);
#ifdef _WIN32 char oldfilefn[1024];
BOOL result = MoveFileW(oldfname, newfname); char newfilefn[1024];
return !!result;
#else
char oldfilefn[256];
char newfilefn[256];
BufferIO::EncodeUTF8(oldfname, oldfilefn); BufferIO::EncodeUTF8(oldfname, oldfilefn);
BufferIO::EncodeUTF8(newfname, newfilefn); BufferIO::EncodeUTF8(newfname, newfilefn);
int result = rename(oldfilefn, newfilefn); int result = std::rename(oldfilefn, newfilefn);
return result == 0; return result == 0;
#endif
} }
bool Replay::ReadNextResponse(unsigned char resp[]) { bool Replay::ReadNextResponse(unsigned char resp[]) {
unsigned char len{}; unsigned char len{};
......
#ifndef REPLAY_H #ifndef REPLAY_H
#define REPLAY_H #define REPLAY_H
#include "config.h" #include <cstdio>
#include <vector>
#include <string>
#include "../ocgcore/ocgapi.h"
#include "deck_manager.h" #include "deck_manager.h"
namespace ygo { namespace ygo {
...@@ -108,10 +111,6 @@ public: ...@@ -108,10 +111,6 @@ public:
#endif // YGOPRO_SERVER_MODE #endif // YGOPRO_SERVER_MODE
FILE* fp{ nullptr }; FILE* fp{ nullptr };
#ifdef _WIN32
HANDLE recording_fp{ nullptr };
#endif
ExtendedReplayHeader pheader; ExtendedReplayHeader pheader;
unsigned char* comp_data; unsigned char* comp_data;
size_t comp_size{}; size_t comp_size{};
......
This diff is collapsed.
#include "serverapi.h" #include "serverapi.h"
#include "game.h"
#include "netserver.h"
#include "network.h"
#include "config.h"
#include "data_manager.h"
#include "gframe.h"
#include <event2/thread.h>
#include <memory>
namespace ygo { namespace ygo {
extern "C" DECL_DLLEXPORT int start_server(const char* args) { YGOSERVER_API int start_server(const char* args) {
int argc = 1; int argc = 1;
char** argv = new char* [13]; char** argv = new char* [13];
const char* server_name = "ygoserver"; const char* server_name = "ygoserver";
...@@ -36,7 +44,7 @@ namespace ygo { ...@@ -36,7 +44,7 @@ namespace ygo {
return result; return result;
} }
extern "C" DECL_DLLEXPORT void stop_server() { YGOSERVER_API void stop_server() {
NetServer::StopServer(); NetServer::StopServer();
} }
} }
#ifndef SERVERAPI_H #ifndef SERVERAPI_H
#define SERVERAPI_H #define SERVERAPI_H
#include "game.h" #ifdef __cplusplus
#include "netserver.h" #define EXTERN_C extern "C"
#include "network.h" #else
#include "config.h" #define EXTERN_C
#include "data_manager.h" #endif
#include "gframe.h"
#include <event2/thread.h>
#include <memory>
#ifdef WIN32 #ifndef YGOSERVER_API
#define DECL_DLLEXPORT __declspec(dllexport) #if defined(__EMSCRIPTEN__)
#include <emscripten/emscripten.h>
#define YGOSERVER_API EXTERN_C EMSCRIPTEN_KEEPALIVE
#elif defined(_WIN32)
#define YGOSERVER_API EXTERN_C __declspec(dllexport)
#else #else
#define DECL_DLLEXPORT #define YGOSERVER_API EXTERN_C __attribute__ ((visibility ("default")))
#endif #endif
#endif
namespace ygo { namespace ygo {
extern "C" DECL_DLLEXPORT int start_server(const char* args); YGOSERVER_API int start_server(const char* args);
extern "C" DECL_DLLEXPORT void stop_server(); YGOSERVER_API void stop_server();
} }
#endif // !SERVERAPI_H #endif // !SERVERAPI_H
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Subproject commit 326c22e9bd5af2e0f295eb263c095584342db952 Subproject commit ce8c654094247120ee83ed7f753d19d20539220b
...@@ -10,9 +10,6 @@ project "event" ...@@ -10,9 +10,6 @@ project "event"
if EVENT_VERSION>=0x02020000 then if EVENT_VERSION>=0x02020000 then
print("Warning: Using libevent version 2.2.x is not supported, please use 2.1.x, otherwise you may encounter issues.") print("Warning: Using libevent version 2.2.x is not supported, please use 2.1.x, otherwise you may encounter issues.")
end end
if EVENT_VERSION>=0x02010000 and WINXP_SUPPORT then
print("Warning: libevent 2.1 uses some new APIs which require Windows Vista or later, so WinXP support will be invalid.")
end
includedirs { "include", "compat" } includedirs { "include", "compat" }
......
/****************************************************************************
*
* ft2build.h
*
* FreeType 2 build and setup macros.
*
* Use custom/ft2build.h instead of the default include/freetype/ft2build.h
* to customize the FreeType 2 build of YGOPro.
*
*/
#ifndef FT2_BUILD_MY_PLATFORM_H_
#define FT2_BUILD_MY_PLATFORM_H_
#define FT_CONFIG_OPTIONS_H <ygopro/ftoption.h>
#define FT_CONFIG_MODULES_H <ygopro/ftmodule.h>
#include <freetype/config/ftheader.h>
#endif /* FT2_BUILD_MY_PLATFORM_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -12,6 +12,7 @@ if not SERVER_PRO3_SUPPORT then ...@@ -12,6 +12,7 @@ if not SERVER_PRO3_SUPPORT then
"SQLITE_OMIT_DEPRECATED", "SQLITE_OMIT_DEPRECATED",
"SQLITE_OMIT_PROGRESS_CALLBACK", "SQLITE_OMIT_PROGRESS_CALLBACK",
"SQLITE_OMIT_SHARED_CACHE", "SQLITE_OMIT_SHARED_CACHE",
"SQLITE_TRUSTED_SCHEMA=0",
} }
end end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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