Commit b4feb49a authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master' into develop

parents 34743d0f 8b622643
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
namespace ygo { namespace ygo {
const wchar_t* DataManager::unknown_string = L"???"; const wchar_t* DataManager::unknown_string = L"???";
unsigned char DataManager::scriptBuffer[0x100000]; unsigned char DataManager::scriptBuffer[0x100000] = {};
IFileSystem* DataManager::FileSystem; IFileSystem* DataManager::FileSystem = nullptr;
DataManager dataManager; DataManager dataManager;
DataManager::DataManager() : _datas(32768), _strings(32768) { DataManager::DataManager() : _datas(32768), _strings(32768) {
......
...@@ -268,11 +268,11 @@ FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) { ...@@ -268,11 +268,11 @@ FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) {
} }
IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) { IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) {
#ifdef _WIN32 #ifdef _WIN32
IReadFile* reader = dataManager.FileSystem->createAndOpenFile(file); IReadFile* reader = DataManager::FileSystem->createAndOpenFile(file);
#else #else
char file2[256]; char file2[256];
BufferIO::EncodeUTF8(file, file2); BufferIO::EncodeUTF8(file, file2);
IReadFile* reader = dataManager.FileSystem->createAndOpenFile(file2); IReadFile* reader = DataManager::FileSystem->createAndOpenFile(file2);
#endif #endif
return reader; return reader;
} }
......
...@@ -26,7 +26,7 @@ bool DuelClient::is_swapping = false; ...@@ -26,7 +26,7 @@ bool DuelClient::is_swapping = false;
int DuelClient::select_hint = 0; int DuelClient::select_hint = 0;
int DuelClient::select_unselect_hint = 0; int DuelClient::select_unselect_hint = 0;
int DuelClient::last_select_hint = 0; int DuelClient::last_select_hint = 0;
unsigned char DuelClient::last_successful_msg[0x2000]; unsigned char DuelClient::last_successful_msg[SIZE_NETWORK_BUFFER];
size_t DuelClient::last_successful_msg_length = 0; size_t DuelClient::last_successful_msg_length = 0;
wchar_t DuelClient::event_string[256]; wchar_t DuelClient::event_string[256];
mt19937 DuelClient::rnd; mt19937 DuelClient::rnd;
...@@ -936,7 +936,7 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -936,7 +936,7 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
} }
} }
// Analyze STOC_GAME_MSG packet // Analyze STOC_GAME_MSG packet
int DuelClient::ClientAnalyze(unsigned char* msg, unsigned int len) { bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
unsigned char* pbuf = msg; unsigned char* pbuf = msg;
wchar_t textBuffer[256]; wchar_t textBuffer[256];
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf); mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
......
...@@ -23,7 +23,7 @@ private: ...@@ -23,7 +23,7 @@ private:
static int select_hint; static int select_hint;
static int select_unselect_hint; static int select_unselect_hint;
static int last_select_hint; static int last_select_hint;
static unsigned char last_successful_msg[0x2000]; static unsigned char last_successful_msg[SIZE_NETWORK_BUFFER];
static size_t last_successful_msg_length; static size_t last_successful_msg_length;
static wchar_t event_string[256]; static wchar_t event_string[256];
static mt19937 rnd; static mt19937 rnd;
...@@ -41,7 +41,7 @@ public: ...@@ -41,7 +41,7 @@ public:
static void ClientEvent(bufferevent* bev, short events, void* ctx); static void ClientEvent(bufferevent* bev, short events, void* ctx);
static int ClientThread(); static int ClientThread();
static void HandleSTOCPacketLan(unsigned char* data, int len); static void HandleSTOCPacketLan(unsigned char* data, int len);
static int ClientAnalyze(unsigned char* msg, unsigned int len); static bool ClientAnalyze(unsigned char* msg, int len);
static void SwapField(); static void SwapField();
static void SetResponseI(int32_t respI); static void SetResponseI(int32_t respI);
static void SetResponseB(void* respB, size_t len); static void SetResponseB(void* respB, size_t len);
......
...@@ -99,7 +99,7 @@ bool Game::Initialize() { ...@@ -99,7 +99,7 @@ bool Game::Initialize() {
ErrorLog("Failed to load textures!"); ErrorLog("Failed to load textures!");
return false; return false;
} }
dataManager.FileSystem = device->getFileSystem(); DataManager::FileSystem = device->getFileSystem();
if(!dataManager.LoadDB(L"cards.cdb")) { if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!"); ErrorLog("Failed to load card database (cards.cdb)!");
return false; return false;
...@@ -1182,11 +1182,11 @@ void Game::LoadExpansions() { ...@@ -1182,11 +1182,11 @@ void Game::LoadExpansions() {
} }
if (!isdir && (IsExtension(name, L".zip") || IsExtension(name, L".ypk"))) { if (!isdir && (IsExtension(name, L".zip") || IsExtension(name, L".ypk"))) {
#ifdef _WIN32 #ifdef _WIN32
dataManager.FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP); DataManager::FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP);
#else #else
char upath[1024]; char upath[1024];
BufferIO::EncodeUTF8(fpath, upath); BufferIO::EncodeUTF8(fpath, upath);
dataManager.FileSystem->addFileArchive(upath, true, false, EFAT_ZIP); DataManager::FileSystem->addFileArchive(upath, true, false, EFAT_ZIP);
#endif #endif
return; return;
} }
......
...@@ -832,19 +832,6 @@ extern Game* mainGame; ...@@ -832,19 +832,6 @@ extern Game* mainGame;
#define BUTTON_BIG_CARD_ZOOM_OUT 382 #define BUTTON_BIG_CARD_ZOOM_OUT 382
#define BUTTON_BIG_CARD_ORIG_SIZE 383 #define BUTTON_BIG_CARD_ORIG_SIZE 383
//STOC_GAME_MSG messages
#define MSG_WAITING 3
#define MSG_START 4
#define MSG_UPDATE_DATA 6 // flag=0: clear
#define MSG_UPDATE_CARD 7 // flag=QUERY_CODE, code=0: clear
#define MSG_REQUEST_DECK 8
#define MSG_REFRESH_DECK 34
#define MSG_CARD_SELECTED 80
#define MSG_UNEQUIP 95
#define MSG_BE_CHAIN_TARGET 121
#define MSG_CREATE_RELATION 122
#define MSG_RELEASE_RELATION 123
#define AVAIL_OCG 0x1 #define AVAIL_OCG 0x1
#define AVAIL_TCG 0x2 #define AVAIL_TCG 0x2
#define AVAIL_CUSTOM 0x4 #define AVAIL_CUSTOM 0x4
......
...@@ -214,7 +214,9 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) { ...@@ -214,7 +214,9 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
case CTOS_UPDATE_DECK: { case CTOS_UPDATE_DECK: {
if(!dp->game) if(!dp->game)
return; return;
if (len < 1 + (int)sizeof(unsigned char)) if (len < 1 + (int)sizeof(int32_t) + (int)sizeof(int32_t))
return;
if (len > 1 + (int)sizeof(CTOS_DeckData))
return; return;
duel_mode->UpdateDeck(dp, pdata, len - 1); duel_mode->UpdateDeck(dp, pdata, len - 1);
break; break;
......
...@@ -20,16 +20,16 @@ namespace ygo { ...@@ -20,16 +20,16 @@ namespace ygo {
struct HostInfo { struct HostInfo {
uint32_t lflist{}; uint32_t lflist{};
unsigned char rule{}; uint8_t rule{};
unsigned char mode{}; uint8_t mode{};
unsigned char duel_rule{}; uint8_t duel_rule{};
unsigned char no_check_deck{}; uint8_t no_check_deck{};
unsigned char no_shuffle_deck{}; uint8_t no_shuffle_deck{};
// byte padding[3] // byte padding[3]
uint32_t start_lp{}; uint32_t start_lp{};
unsigned char start_hand{}; uint8_t start_hand{};
unsigned char draw_count{}; uint8_t draw_count{};
uint16_t time_limit{}; uint16_t time_limit{};
}; };
check_trivially_copyable(HostInfo); check_trivially_copyable(HostInfo);
...@@ -54,14 +54,21 @@ struct HostRequest { ...@@ -54,14 +54,21 @@ struct HostRequest {
check_trivially_copyable(HostRequest); check_trivially_copyable(HostRequest);
static_assert(sizeof(HostRequest) == 2, "size mismatch: HostRequest"); static_assert(sizeof(HostRequest) == 2, "size mismatch: HostRequest");
struct CTOS_DeckData {
int32_t mainc{};
int32_t sidec{};
int32_t list[MAINC_MAX + SIDEC_MAX]{};
};
check_trivially_copyable(CTOS_DeckData);
struct CTOS_HandResult { struct CTOS_HandResult {
unsigned char res{}; uint8_t res{};
}; };
check_trivially_copyable(CTOS_HandResult); check_trivially_copyable(CTOS_HandResult);
static_assert(sizeof(CTOS_HandResult) == 1, "size mismatch: CTOS_HandResult"); static_assert(sizeof(CTOS_HandResult) == 1, "size mismatch: CTOS_HandResult");
struct CTOS_TPResult { struct CTOS_TPResult {
unsigned char res{}; uint8_t res{};
}; };
check_trivially_copyable(CTOS_TPResult); check_trivially_copyable(CTOS_TPResult);
static_assert(sizeof(CTOS_TPResult) == 1, "size mismatch: CTOS_TPResult"); static_assert(sizeof(CTOS_TPResult) == 1, "size mismatch: CTOS_TPResult");
...@@ -91,14 +98,14 @@ check_trivially_copyable(CTOS_JoinGame); ...@@ -91,14 +98,14 @@ check_trivially_copyable(CTOS_JoinGame);
static_assert(sizeof(CTOS_JoinGame) == 48, "size mismatch: CTOS_JoinGame"); static_assert(sizeof(CTOS_JoinGame) == 48, "size mismatch: CTOS_JoinGame");
struct CTOS_Kick { struct CTOS_Kick {
unsigned char pos{}; uint8_t pos{};
}; };
check_trivially_copyable(CTOS_Kick); check_trivially_copyable(CTOS_Kick);
static_assert(sizeof(CTOS_Kick) == 1, "size mismatch: CTOS_Kick"); static_assert(sizeof(CTOS_Kick) == 1, "size mismatch: CTOS_Kick");
// STOC // STOC
struct STOC_ErrorMsg { struct STOC_ErrorMsg {
unsigned char msg{}; uint8_t msg{};
// byte padding[3] // byte padding[3]
uint32_t code{}; uint32_t code{};
...@@ -107,8 +114,8 @@ check_trivially_copyable(STOC_ErrorMsg); ...@@ -107,8 +114,8 @@ check_trivially_copyable(STOC_ErrorMsg);
static_assert(sizeof(STOC_ErrorMsg) == 8, "size mismatch: STOC_ErrorMsg"); static_assert(sizeof(STOC_ErrorMsg) == 8, "size mismatch: STOC_ErrorMsg");
struct STOC_HandResult { struct STOC_HandResult {
unsigned char res1{}; uint8_t res1{};
unsigned char res2{}; uint8_t res2{};
}; };
check_trivially_copyable(STOC_HandResult); check_trivially_copyable(STOC_HandResult);
static_assert(sizeof(STOC_HandResult) == 2, "size mismatch: STOC_HandResult"); static_assert(sizeof(STOC_HandResult) == 2, "size mismatch: STOC_HandResult");
...@@ -127,20 +134,20 @@ check_trivially_copyable(STOC_JoinGame); ...@@ -127,20 +134,20 @@ check_trivially_copyable(STOC_JoinGame);
static_assert(sizeof(STOC_JoinGame) == 20, "size mismatch: STOC_JoinGame"); static_assert(sizeof(STOC_JoinGame) == 20, "size mismatch: STOC_JoinGame");
struct STOC_TypeChange { struct STOC_TypeChange {
unsigned char type{}; uint8_t type{};
}; };
check_trivially_copyable(STOC_TypeChange); check_trivially_copyable(STOC_TypeChange);
static_assert(sizeof(STOC_TypeChange) == 1, "size mismatch: STOC_TypeChange"); static_assert(sizeof(STOC_TypeChange) == 1, "size mismatch: STOC_TypeChange");
// reserved for STOC_LEAVE_GAME // reserved for STOC_LEAVE_GAME
struct STOC_ExitGame { struct STOC_ExitGame {
unsigned char pos{}; uint8_t pos{};
}; };
check_trivially_copyable(STOC_ExitGame); check_trivially_copyable(STOC_ExitGame);
static_assert(sizeof(STOC_ExitGame) == 1, "size mismatch: STOC_ExitGame"); static_assert(sizeof(STOC_ExitGame) == 1, "size mismatch: STOC_ExitGame");
struct STOC_TimeLimit { struct STOC_TimeLimit {
unsigned char player{}; uint8_t player{};
// byte padding[1] // byte padding[1]
uint16_t left_time{}; uint16_t left_time{};
...@@ -159,7 +166,7 @@ constexpr int SIZE_STOC_CHAT = (LEN_CHAT_PLAYER + LEN_CHAT_MSG) * sizeof(uint16_ ...@@ -159,7 +166,7 @@ constexpr int SIZE_STOC_CHAT = (LEN_CHAT_PLAYER + LEN_CHAT_MSG) * sizeof(uint16_
struct STOC_HS_PlayerEnter { struct STOC_HS_PlayerEnter {
uint16_t name[20]{}; uint16_t name[20]{};
unsigned char pos{}; uint8_t pos{};
// byte padding[1] // byte padding[1]
}; };
check_trivially_copyable(STOC_HS_PlayerEnter); check_trivially_copyable(STOC_HS_PlayerEnter);
...@@ -168,7 +175,7 @@ constexpr int STOC_HS_PlayerEnter_size = 41; //workwround ...@@ -168,7 +175,7 @@ constexpr int STOC_HS_PlayerEnter_size = 41; //workwround
struct STOC_HS_PlayerChange { struct STOC_HS_PlayerChange {
//pos<<4 | state //pos<<4 | state
unsigned char status{}; uint8_t status{};
}; };
check_trivially_copyable(STOC_HS_PlayerChange); check_trivially_copyable(STOC_HS_PlayerChange);
static_assert(sizeof(STOC_HS_PlayerChange) == 1, "size mismatch: STOC_HS_PlayerChange"); static_assert(sizeof(STOC_HS_PlayerChange) == 1, "size mismatch: STOC_HS_PlayerChange");
...@@ -182,10 +189,10 @@ static_assert(sizeof(STOC_HS_WatchChange) == 2, "size mismatch: STOC_HS_WatchCha ...@@ -182,10 +189,10 @@ static_assert(sizeof(STOC_HS_WatchChange) == 2, "size mismatch: STOC_HS_WatchCha
class DuelMode; class DuelMode;
struct DuelPlayer { struct DuelPlayer {
unsigned short name[20]{}; uint16_t name[20]{};
DuelMode* game{}; DuelMode* game{};
unsigned char type{}; uint8_t type{};
unsigned char state{}; uint8_t state{};
bufferevent* bev{}; bufferevent* bev{};
}; };
...@@ -252,7 +259,7 @@ public: ...@@ -252,7 +259,7 @@ public:
#define NETPLAYER_TYPE_OBSERVER 7 #define NETPLAYER_TYPE_OBSERVER 7
#define CTOS_RESPONSE 0x1 // byte array #define CTOS_RESPONSE 0x1 // byte array
#define CTOS_UPDATE_DECK 0x2 // mainc, sidec, int32_t[mainc + sidec] #define CTOS_UPDATE_DECK 0x2 // CTOS_DeckData
#define CTOS_HAND_RESULT 0x3 // CTOS_HandResult #define CTOS_HAND_RESULT 0x3 // CTOS_HandResult
#define CTOS_TP_RESULT 0x4 // CTOS_TPResult #define CTOS_TP_RESULT 0x4 // CTOS_TPResult
#define CTOS_PLAYER_INFO 0x10 // CTOS_PlayerInfo #define CTOS_PLAYER_INFO 0x10 // CTOS_PlayerInfo
...@@ -294,6 +301,19 @@ public: ...@@ -294,6 +301,19 @@ public:
#define STOC_TEAMMATE_SURRENDER 0x23 // no data #define STOC_TEAMMATE_SURRENDER 0x23 // no data
#define STOC_FIELD_FINISH 0x30 #define STOC_FIELD_FINISH 0x30
// STOC_GAME_MSG header
#define MSG_WAITING 3
#define MSG_START 4
#define MSG_UPDATE_DATA 6 // flag=0: clear
#define MSG_UPDATE_CARD 7 // flag=QUERY_CODE, code=0: clear
#define MSG_REQUEST_DECK 8
#define MSG_REFRESH_DECK 34
#define MSG_CARD_SELECTED 80
#define MSG_UNEQUIP 95
#define MSG_BE_CHAIN_TARGET 121
#define MSG_CREATE_RELATION 122
#define MSG_RELEASE_RELATION 123
#define PLAYERCHANGE_OBSERVE 0x8 #define PLAYERCHANGE_OBSERVE 0x8
#define PLAYERCHANGE_READY 0x9 #define PLAYERCHANGE_READY 0x9
#define PLAYERCHANGE_NOTREADY 0xa #define PLAYERCHANGE_NOTREADY 0xa
......
...@@ -278,18 +278,14 @@ void SingleDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) { ...@@ -278,18 +278,14 @@ void SingleDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
if(dp->type > 1 || ready[dp->type]) if(dp->type > 1 || ready[dp->type])
return; return;
if (len < 8)
return;
bool valid = true; bool valid = true;
auto deckbuf = pdata; CTOS_DeckData deckbuf;
int mainc = BufferIO::ReadInt32(deckbuf); std::memcpy(&deckbuf, pdata, len);
int sidec = BufferIO::ReadInt32(deckbuf); if (deckbuf.mainc < 0 || deckbuf.mainc > MAINC_MAX)
const int deck_size = len - 2 * sizeof(int32_t);
if (mainc < 0 || mainc > MAINC_MAX)
valid = false; valid = false;
else if (sidec < 0 || sidec > SIDEC_MAX) else if (deckbuf.sidec < 0 || deckbuf.sidec > SIDEC_MAX)
valid = false; valid = false;
else if (deck_size != (mainc + sidec) * (int)sizeof(int32_t)) else if (len < (2 + deckbuf.mainc + deckbuf.sidec) * (int)sizeof(int32_t))
valid = false; valid = false;
if (!valid) { if (!valid) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
...@@ -298,12 +294,10 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -298,12 +294,10 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
int deck_list[SIZE_NETWORK_BUFFER / sizeof(int32_t)];
std::memcpy(deck_list, deckbuf, deck_size);
if(duel_count == 0) { if(duel_count == 0) {
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deck_list, mainc, sidec); deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec);
} else { } else {
if(deckManager.LoadSide(pdeck[dp->type], deck_list, mainc, sidec)) { if(deckManager.LoadSide(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec)) {
ready[dp->type] = true; ready[dp->type] = true;
NetServer::SendPacketToPlayer(dp, STOC_DUEL_START); NetServer::SendPacketToPlayer(dp, STOC_DUEL_START);
if(ready[0] && ready[1]) { if(ready[0] && ready[1]) {
......
...@@ -261,18 +261,14 @@ void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) { ...@@ -261,18 +261,14 @@ void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
if(dp->type > 3 || ready[dp->type]) if(dp->type > 3 || ready[dp->type])
return; return;
if (len < 8)
return;
bool valid = true; bool valid = true;
auto deckbuf = pdata; CTOS_DeckData deckbuf;
int mainc = BufferIO::ReadInt32(deckbuf); std::memcpy(&deckbuf, pdata, len);
int sidec = BufferIO::ReadInt32(deckbuf); if (deckbuf.mainc < 0 || deckbuf.mainc > MAINC_MAX)
const int deck_size = len - 2 * sizeof(int32_t);
if (mainc < 0 || mainc > MAINC_MAX)
valid = false; valid = false;
else if (sidec < 0 || sidec > SIDEC_MAX) else if (deckbuf.sidec < 0 || deckbuf.sidec > SIDEC_MAX)
valid = false; valid = false;
else if (deck_size != (mainc + sidec) * (int)sizeof(int32_t)) else if (len < (2 + deckbuf.mainc + deckbuf.sidec) * (int)sizeof(int32_t))
valid = false; valid = false;
if (!valid) { if (!valid) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
...@@ -281,9 +277,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) { ...@@ -281,9 +277,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
int deck_list[SIZE_NETWORK_BUFFER / sizeof(int32_t)]; deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deckbuf.list, deckbuf.mainc, deckbuf.sidec);
std::memcpy(deck_list, deckbuf, deck_size);
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deck_list, mainc, sidec);
} }
void TagDuel::StartDuel(DuelPlayer* dp) { void TagDuel::StartDuel(DuelPlayer* dp) {
if(dp != host_player) if(dp != host_player)
......
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