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