Commit ad9a7069 authored by Chen Bill's avatar Chen Bill Committed by GitHub

fix DeckManager::CheckDeck (#2656)

* fix DeckManager::CheckDeck

* use MAX_CARD_ID
parent 53d951c7
...@@ -17,6 +17,7 @@ namespace irr { ...@@ -17,6 +17,7 @@ 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 unsigned int MIN_CARD_ID = (unsigned int)(MAX_STRING_ID + 1) >> 4;
constexpr unsigned int MAX_CARD_ID = 0x0fffffffU;
using CardData = card_data; using CardData = card_data;
struct CardDataC : card_data { struct CardDataC : card_data {
......
...@@ -35,7 +35,7 @@ void DeckManager::LoadLFListSingle(const char* path) { ...@@ -35,7 +35,7 @@ void DeckManager::LoadLFListSingle(const char* path) {
int count = -1; int count = -1;
if (sscanf(linebuf, "%d %d", &code, &count) != 2) if (sscanf(linebuf, "%d %d", &code, &count) != 2)
continue; continue;
if (code <= 0 || code > 0xfffffff) if (code <= 0 || code > MAX_CARD_ID)
continue; continue;
if (count < 0 || count > 2) if (count < 0 || count > 2)
continue; continue;
...@@ -72,71 +72,75 @@ const std::unordered_map<int, int>* DeckManager::GetLFListContent(int lfhash) { ...@@ -72,71 +72,75 @@ const std::unordered_map<int, int>* DeckManager::GetLFListContent(int lfhash) {
return &lit->content; return &lit->content;
return nullptr; return nullptr;
} }
static int checkAvail(unsigned int ot, unsigned int avail) { static unsigned int checkAvail(unsigned int ot, unsigned int avail) {
if((ot & avail) == avail) if((ot & avail) == avail)
return 0; return 0;
if((ot & AVAIL_OCG) && !(avail == AVAIL_OCG)) if((ot & AVAIL_OCG) && (avail != AVAIL_OCG))
return DECKERROR_OCGONLY; return DECKERROR_OCGONLY;
if((ot & AVAIL_TCG) && !(avail == AVAIL_TCG)) if((ot & AVAIL_TCG) && (avail != AVAIL_TCG))
return DECKERROR_TCGONLY; return DECKERROR_TCGONLY;
return DECKERROR_NOTAVAIL; return DECKERROR_NOTAVAIL;
} }
int DeckManager::CheckDeck(Deck& deck, int lfhash, int rule) { unsigned int DeckManager::CheckDeck(Deck& deck, int lfhash, int rule) {
std::unordered_map<int, int> ccount; std::unordered_map<int, int> ccount;
auto list = GetLFListContent(lfhash); // rule
if(!list)
return 0;
int dc = 0;
if(deck.main.size() < DECK_MIN_SIZE || deck.main.size() > DECK_MAX_SIZE) if(deck.main.size() < DECK_MIN_SIZE || deck.main.size() > DECK_MAX_SIZE)
return ((unsigned)DECKERROR_MAINCOUNT << 28) + deck.main.size(); return (DECKERROR_MAINCOUNT << 28) | (unsigned)deck.main.size();
if(deck.extra.size() > EXTRA_MAX_SIZE) if(deck.extra.size() > EXTRA_MAX_SIZE)
return ((unsigned)DECKERROR_EXTRACOUNT << 28) + deck.extra.size(); return (DECKERROR_EXTRACOUNT << 28) | (unsigned)deck.extra.size();
if(deck.side.size() > SIDE_MAX_SIZE) if(deck.side.size() > SIDE_MAX_SIZE)
return ((unsigned)DECKERROR_SIDECOUNT << 28) + deck.side.size(); return (DECKERROR_SIDECOUNT << 28) | (unsigned)deck.side.size();
if (rule < 0 || rule >= 6) auto list = GetLFListContent(lfhash);
if (!list)
return 0; return 0;
const unsigned int rule_map[6] = { AVAIL_OCG, AVAIL_TCG, AVAIL_SC, AVAIL_CUSTOM, AVAIL_OCGTCG, 0 }; const unsigned int rule_map[6] = { AVAIL_OCG, AVAIL_TCG, AVAIL_SC, AVAIL_CUSTOM, AVAIL_OCGTCG, 0 };
auto avail = rule_map[rule]; unsigned int avail = 0;
if (rule >= 0 && rule < (int)(sizeof rule_map / sizeof rule_map[0]))
avail = rule_map[rule];
for (auto& cit : deck.main) { for (auto& cit : deck.main) {
int gameruleDeckError = checkAvail(cit->second.ot, avail); auto gameruleDeckError = checkAvail(cit->second.ot, avail);
if(gameruleDeckError) if(gameruleDeckError)
return (gameruleDeckError << 28) + cit->first; return (gameruleDeckError << 28) | cit->first;
if (cit->second.type & (TYPES_EXTRA_DECK | TYPE_TOKEN)) if (cit->second.type & (TYPES_EXTRA_DECK | TYPE_TOKEN))
return (DECKERROR_EXTRACOUNT << 28); return (DECKERROR_MAINCOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; int dc = ccount[code];
if(dc > 3) if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first; return (DECKERROR_CARDCOUNT << 28) | cit->first;
auto it = list->find(code); auto it = list->find(code);
if(it != list->end() && dc > it->second) if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first; return (DECKERROR_LFLIST << 28) | cit->first;
} }
for (auto& cit : deck.extra) { for (auto& cit : deck.extra) {
int gameruleDeckError = checkAvail(cit->second.ot, avail); auto gameruleDeckError = checkAvail(cit->second.ot, avail);
if(gameruleDeckError) if(gameruleDeckError)
return (gameruleDeckError << 28) + cit->first; return (gameruleDeckError << 28) | cit->first;
if (!(cit->second.type & TYPES_EXTRA_DECK) || cit->second.type & TYPE_TOKEN)
return (DECKERROR_EXTRACOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; int dc = ccount[code];
if(dc > 3) if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first; return (DECKERROR_CARDCOUNT << 28) | cit->first;
auto it = list->find(code); auto it = list->find(code);
if(it != list->end() && dc > it->second) if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first; return (DECKERROR_LFLIST << 28) | cit->first;
} }
for (auto& cit : deck.side) { for (auto& cit : deck.side) {
int gameruleDeckError = checkAvail(cit->second.ot, avail); auto gameruleDeckError = checkAvail(cit->second.ot, avail);
if(gameruleDeckError) if(gameruleDeckError)
return (gameruleDeckError << 28) + cit->first; return (gameruleDeckError << 28) | cit->first;
if (cit->second.type & TYPE_TOKEN)
return (DECKERROR_SIDECOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; int dc = ccount[code];
if(dc > 3) if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first; return (DECKERROR_CARDCOUNT << 28) | cit->first;
auto it = list->find(code); auto it = list->find(code);
if(it != list->end() && dc > it->second) if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first; return (DECKERROR_LFLIST << 28) | cit->first;
} }
return 0; return 0;
} }
...@@ -160,11 +164,11 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -160,11 +164,11 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
continue; continue;
} }
if (cd.type & TYPES_EXTRA_DECK) { if (cd.type & TYPES_EXTRA_DECK) {
if ((int)deck.extra.size() < EXTRA_MAX_SIZE) if (deck.extra.size() < EXTRA_MAX_SIZE)
deck.extra.push_back(dataManager.GetCodePointer(code)); deck.extra.push_back(dataManager.GetCodePointer(code));
} }
else { else {
if ((int)deck.main.size() < DECK_MAX_SIZE) if (deck.main.size() < DECK_MAX_SIZE)
deck.main.push_back(dataManager.GetCodePointer(code)); deck.main.push_back(dataManager.GetCodePointer(code));
} }
} }
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
void LoadLFList(); void LoadLFList();
const wchar_t* GetLFListName(int lfhash); const wchar_t* GetLFListName(int lfhash);
const std::unordered_map<int, int>* GetLFListContent(int lfhash); const std::unordered_map<int, int>* GetLFListContent(int lfhash);
int CheckDeck(Deck& deck, int lfhash, int rule); unsigned int CheckDeck(Deck& deck, int lfhash, int rule);
int LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_packlist = false); int LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_packlist = false);
int LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_packlist = false); int LoadDeck(Deck& deck, std::istringstream& deckStream, bool is_packlist = false);
bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec); bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec);
......
...@@ -274,8 +274,8 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -274,8 +274,8 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
} }
case ERRMSG_DECKERROR: { case ERRMSG_DECKERROR: {
mainGame->gMutex.lock(); mainGame->gMutex.lock();
unsigned int code = pkt->code & 0xFFFFFFF; unsigned int code = pkt->code & MAX_CARD_ID;
int flag = pkt->code >> 28; unsigned int flag = pkt->code >> 28;
wchar_t msgbuf[256]; wchar_t msgbuf[256];
switch(flag) switch(flag)
{ {
......
...@@ -324,15 +324,15 @@ public: ...@@ -324,15 +324,15 @@ public:
#define ERRMSG_SIDEERROR 0x3 #define ERRMSG_SIDEERROR 0x3
#define ERRMSG_VERERROR 0x4 #define ERRMSG_VERERROR 0x4
#define DECKERROR_LFLIST 0x1 #define DECKERROR_LFLIST 0x1U
#define DECKERROR_OCGONLY 0x2 #define DECKERROR_OCGONLY 0x2U
#define DECKERROR_TCGONLY 0x3 #define DECKERROR_TCGONLY 0x3U
#define DECKERROR_UNKNOWNCARD 0x4 #define DECKERROR_UNKNOWNCARD 0x4U
#define DECKERROR_CARDCOUNT 0x5 #define DECKERROR_CARDCOUNT 0x5U
#define DECKERROR_MAINCOUNT 0x6 #define DECKERROR_MAINCOUNT 0x6U
#define DECKERROR_EXTRACOUNT 0x7 #define DECKERROR_EXTRACOUNT 0x7U
#define DECKERROR_SIDECOUNT 0x8 #define DECKERROR_SIDECOUNT 0x8U
#define DECKERROR_NOTAVAIL 0x9 #define DECKERROR_NOTAVAIL 0x9U
#define MODE_SINGLE 0x0 #define MODE_SINGLE 0x0
#define MODE_MATCH 0x1 #define MODE_MATCH 0x1
......
...@@ -245,7 +245,7 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) { ...@@ -245,7 +245,7 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
unsigned int deckerror = 0; unsigned int deckerror = 0;
if(!host_info.no_check_deck) { if(!host_info.no_check_deck) {
if(deck_error[dp->type]) { if(deck_error[dp->type]) {
deckerror = (DECKERROR_UNKNOWNCARD << 28) + deck_error[dp->type]; deckerror = (DECKERROR_UNKNOWNCARD << 28) | deck_error[dp->type];
} else { } else {
deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, host_info.rule); deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, host_info.rule);
} }
......
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