Commit b4feb49a authored by wind2009's avatar wind2009

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

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