Commit db7c06e6 authored by Nanahira's avatar Nanahira Committed by GitHub

Do with MSG_REVERSE_DECK in reconnect (#31)

parent 74f96822
...@@ -12,10 +12,6 @@ extern unsigned short replay_mode; ...@@ -12,10 +12,6 @@ extern unsigned short replay_mode;
#endif #endif
SingleDuel::SingleDuel(bool is_match) { SingleDuel::SingleDuel(bool is_match) {
match_mode = is_match; match_mode = is_match;
#ifdef YGOPRO_SERVER_MODE
cache_recorder = 0;
replay_recorder = 0;
#endif
} }
SingleDuel::~SingleDuel() { SingleDuel::~SingleDuel() {
} }
...@@ -609,6 +605,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -609,6 +605,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19); NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19);
turn_player = 0; turn_player = 0;
phase = 1; phase = 1;
deck_reversed = false;
#endif #endif
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
...@@ -1093,6 +1090,7 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) { ...@@ -1093,6 +1090,7 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
deck_reversed = !deck_reversed;
#endif #endif
break; break;
} }
...@@ -1827,10 +1825,18 @@ void SingleDuel::WaitforResponse(int playerid) { ...@@ -1827,10 +1825,18 @@ void SingleDuel::WaitforResponse(int playerid) {
void SingleDuel::RequestField(DuelPlayer* dp) { void SingleDuel::RequestField(DuelPlayer* dp) {
if(dp->type > 1) if(dp->type > 1)
return; return;
int player = dp->type; uint8_t player = dp->type;
NetServer::SendPacketToPlayer(dp, STOC_DUEL_START); NetServer::SendPacketToPlayer(dp, STOC_DUEL_START);
unsigned char startbuf[32], *pbuf = startbuf; uint8_t buf[1024];
uint8_t* temp_buf = buf;
auto WriteMsg = [&](const std::function<void(uint8_t*&)> &writer) {
temp_buf = buf;
writer(temp_buf);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, buf, temp_buf - buf);
};
WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf, MSG_START); BufferIO::WriteInt8(pbuf, MSG_START);
BufferIO::WriteInt8(pbuf, player); BufferIO::WriteInt8(pbuf, player);
BufferIO::WriteInt8(pbuf, host_info.duel_rule); BufferIO::WriteInt8(pbuf, host_info.duel_rule);
...@@ -1840,26 +1846,26 @@ void SingleDuel::RequestField(DuelPlayer* dp) { ...@@ -1840,26 +1846,26 @@ void SingleDuel::RequestField(DuelPlayer* dp) {
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, startbuf, 19); });
int newturn_count = 1; uint8_t newturn_count = (turn_player == 1) ? 2 : 1;
if(turn_player == 1) for (uint8_t i = 0; i < newturn_count; ++i) {
newturn_count = 2; WriteMsg([&](uint8_t*& pbuf) {
for(int i = 0; i < newturn_count; i++) { BufferIO::WriteInt8(pbuf, MSG_NEW_TURN);
unsigned char turnbuf[2], *pbuf_t = turnbuf; BufferIO::WriteInt8(pbuf, i);
BufferIO::WriteInt8(pbuf_t, MSG_NEW_TURN); });
BufferIO::WriteInt8(pbuf_t, i);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, turnbuf, 2);
} }
unsigned char phasebuf[4], *pbuf_p = phasebuf; WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf_p, MSG_NEW_PHASE); BufferIO::WriteInt8(pbuf, MSG_NEW_PHASE);
BufferIO::WriteInt16(pbuf_p, phase); BufferIO::WriteInt16(pbuf, phase);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, phasebuf, 3); });
WriteMsg([&](uint8_t*& pbuf) {
auto length = query_field_info(pduel, pbuf);
pbuf += length;
});
unsigned char query_buffer[1024];
int length = query_field_info(pduel, (unsigned char*)query_buffer);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, query_buffer, length);
RefreshMzone(1 - player, 0xefffff, 0, dp); RefreshMzone(1 - player, 0xefffff, 0, dp);
RefreshMzone(player, 0xefffff, 0, dp); RefreshMzone(player, 0xefffff, 0, dp);
RefreshSzone(1 - player, 0xefffff, 0, dp); RefreshSzone(1 - player, 0xefffff, 0, dp);
...@@ -1872,6 +1878,42 @@ void SingleDuel::RequestField(DuelPlayer* dp) { ...@@ -1872,6 +1878,42 @@ void SingleDuel::RequestField(DuelPlayer* dp) {
RefreshExtra(player, 0xefffff, 0, dp); RefreshExtra(player, 0xefffff, 0, dp);
RefreshRemoved(1 - player, 0xefffff, 0, dp); RefreshRemoved(1 - player, 0xefffff, 0, dp);
RefreshRemoved(player, 0xefffff, 0, dp); RefreshRemoved(player, 0xefffff, 0, dp);
// send MSG_REVERSE_DECK if deck is reversed
if(deck_reversed)
WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf, MSG_REVERSE_DECK);
});
uint8_t query_buffer[SIZE_QUERY_BUFFER];
for(uint8_t i = 0; i < 2; ++i) {
// get decktop card
auto qlen = query_field_card(pduel, i, LOCATION_DECK, QUERY_CODE | QUERY_POSITION, query_buffer, 0);
if(!qlen)
continue; // no cards in deck
uint8_t *qbuf = query_buffer;
uint32_t code = 0;
uint32_t position = 0;
while(qbuf < query_buffer + qlen) {
auto clen = BufferIO::ReadInt32(qbuf);
if(qbuf + clen - 4 == query_buffer + qlen) {
// last card
code = *(uint32_t*)(qbuf + 4);
position = GetPosition(qbuf, 8);
}
qbuf += clen - 4;
}
if(position & POS_FACEUP)
code |= 0x80000000; // mark as reversed
if(deck_reversed || position & POS_FACEUP)
WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf, MSG_DECK_TOP);
BufferIO::WriteInt8(pbuf, i);
BufferIO::WriteInt8(pbuf, 0);
BufferIO::WriteInt32(pbuf, code);
});
}
/* /*
if(dp == players[last_response]) if(dp == players[last_response])
WaitforResponse(last_response); WaitforResponse(last_response);
......
...@@ -67,10 +67,11 @@ protected: ...@@ -67,10 +67,11 @@ protected:
unsigned char last_response{ 0 }; unsigned char last_response{ 0 };
std::set<DuelPlayer*> observers; std::set<DuelPlayer*> observers;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder; DuelPlayer* cache_recorder{};
DuelPlayer* replay_recorder; DuelPlayer* replay_recorder{};
unsigned char turn_player; unsigned char turn_player{ 0 };
unsigned short phase; unsigned short phase{ 0 };
bool deck_reversed{ false };
#endif #endif
Replay last_replay; Replay last_replay;
bool match_mode{ false }; bool match_mode{ false };
...@@ -81,13 +82,12 @@ protected: ...@@ -81,13 +82,12 @@ protected:
short time_limit[2]{}; short time_limit[2]{};
short time_elapsed{ 0 }; short time_elapsed{ 0 };
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
short time_compensator[2]; short time_compensator[2]{};
short time_backed[2]; short time_backed[2]{};
unsigned char last_game_msg; unsigned char last_game_msg{ 0 };
#endif #endif
}; };
} }
#endif //SINGLE_DUEL_H #endif //SINGLE_DUEL_H
...@@ -16,10 +16,6 @@ TagDuel::TagDuel() { ...@@ -16,10 +16,6 @@ TagDuel::TagDuel() {
ready[i] = false; ready[i] = false;
surrender[i] = false; surrender[i] = false;
} }
#ifdef YGOPRO_SERVER_MODE
cache_recorder = 0;
replay_recorder = 0;
#endif
} }
TagDuel::~TagDuel() { TagDuel::~TagDuel() {
} }
...@@ -602,6 +598,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -602,6 +598,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19); NetServer::SendBufferToPlayer(replay_recorder, STOC_GAME_MSG, startbuf, 19);
turn_player = 0; turn_player = 0;
phase = 1; phase = 1;
deck_reversed = false;
#endif #endif
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
...@@ -1055,6 +1052,7 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) { ...@@ -1055,6 +1052,7 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
deck_reversed = !deck_reversed;
#endif #endif
break; break;
} }
...@@ -1924,10 +1922,18 @@ void TagDuel::WaitforResponse(int playerid) { ...@@ -1924,10 +1922,18 @@ void TagDuel::WaitforResponse(int playerid) {
void TagDuel::RequestField(DuelPlayer* dp) { void TagDuel::RequestField(DuelPlayer* dp) {
if(dp->type > 3) if(dp->type > 3)
return; return;
int player = (dp->type > 1) ? 1 : 0; uint8_t player = (dp->type > 1) ? 1 : 0;
NetServer::SendPacketToPlayer(dp, STOC_DUEL_START); NetServer::SendPacketToPlayer(dp, STOC_DUEL_START);
unsigned char startbuf[32], *pbuf = startbuf; uint8_t buf[1024];
uint8_t* temp_buf = buf;
auto WriteMsg = [&](const std::function<void(uint8_t*&)> &writer) {
temp_buf = buf;
writer(temp_buf);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, buf, temp_buf - buf);
};
WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf, MSG_START); BufferIO::WriteInt8(pbuf, MSG_START);
BufferIO::WriteInt8(pbuf, player); BufferIO::WriteInt8(pbuf, player);
BufferIO::WriteInt8(pbuf, host_info.duel_rule); BufferIO::WriteInt8(pbuf, host_info.duel_rule);
...@@ -1937,26 +1943,28 @@ void TagDuel::RequestField(DuelPlayer* dp) { ...@@ -1937,26 +1943,28 @@ void TagDuel::RequestField(DuelPlayer* dp) {
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
BufferIO::WriteInt16(pbuf, 0); BufferIO::WriteInt16(pbuf, 0);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, startbuf, 19); });
int newturn_count = turn_count % 4; uint8_t newturn_count = turn_count % 4;
if(newturn_count == 0) if(newturn_count == 0)
newturn_count = 4; newturn_count = 4;
for(int i = 0; i < newturn_count; i++) { for (uint8_t i = 0; i < newturn_count; ++i) {
unsigned char turnbuf[2], *pbuf_t = turnbuf; WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf_t, MSG_NEW_TURN); BufferIO::WriteInt8(pbuf, MSG_NEW_TURN);
BufferIO::WriteInt8(pbuf_t, i % 2); BufferIO::WriteInt8(pbuf, i % 2);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, turnbuf, 2); });
} }
unsigned char phasebuf[4], *pbuf_p = phasebuf; WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf_p, MSG_NEW_PHASE); BufferIO::WriteInt8(pbuf, MSG_NEW_PHASE);
BufferIO::WriteInt16(pbuf_p, phase); BufferIO::WriteInt16(pbuf, phase);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, phasebuf, 3); });
WriteMsg([&](uint8_t*& pbuf) {
auto length = query_field_info(pduel, pbuf);
pbuf += length;
});
unsigned char query_buffer[1024];
int length = query_field_info(pduel, (unsigned char*)query_buffer);
NetServer::SendBufferToPlayer(dp, STOC_GAME_MSG, query_buffer, length);
RefreshMzone(1 - player, 0xefffff, 0, dp); RefreshMzone(1 - player, 0xefffff, 0, dp);
RefreshMzone(player, 0xefffff, 0, dp); RefreshMzone(player, 0xefffff, 0, dp);
RefreshSzone(1 - player, 0xefffff, 0, dp); RefreshSzone(1 - player, 0xefffff, 0, dp);
...@@ -1969,6 +1977,36 @@ void TagDuel::RequestField(DuelPlayer* dp) { ...@@ -1969,6 +1977,36 @@ void TagDuel::RequestField(DuelPlayer* dp) {
RefreshExtra(player, 0xefffff, 0, dp); RefreshExtra(player, 0xefffff, 0, dp);
RefreshRemoved(1 - player, 0xefffff, 0, dp); RefreshRemoved(1 - player, 0xefffff, 0, dp);
RefreshRemoved(player, 0xefffff, 0, dp); RefreshRemoved(player, 0xefffff, 0, dp);
uint8_t query_buffer[SIZE_QUERY_BUFFER];
for(uint8_t i = 0; i < 2; ++i) {
// get decktop card
auto qlen = query_field_card(pduel, i, LOCATION_DECK, QUERY_CODE | QUERY_POSITION, query_buffer, 0);
if(!qlen)
continue; // no cards in deck
uint8_t *qbuf = query_buffer;
uint32_t code = 0;
uint32_t position = 0;
while(qbuf < query_buffer + qlen) {
auto clen = BufferIO::ReadInt32(qbuf);
if(qbuf + clen - 4 == query_buffer + qlen) {
// last card
code = *(uint32_t*)(qbuf + 4);
position = GetPosition(qbuf, 8);
}
qbuf += clen - 4;
}
if(position & POS_FACEUP)
code |= 0x80000000; // mark as reversed
if(deck_reversed || position & POS_FACEUP)
WriteMsg([&](uint8_t*& pbuf) {
BufferIO::WriteInt8(pbuf, MSG_DECK_TOP);
BufferIO::WriteInt8(pbuf, i);
BufferIO::WriteInt8(pbuf, 0);
BufferIO::WriteInt32(pbuf, code);
});
}
/* /*
if(dp == cur_player[last_response]) if(dp == cur_player[last_response])
WaitforResponse(last_response); WaitforResponse(last_response);
......
...@@ -63,10 +63,11 @@ protected: ...@@ -63,10 +63,11 @@ protected:
DuelPlayer* cur_player[2]; DuelPlayer* cur_player[2];
std::set<DuelPlayer*> observers; std::set<DuelPlayer*> observers;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder; DuelPlayer* cache_recorder{};
DuelPlayer* replay_recorder; DuelPlayer* replay_recorder{};
int turn_player; unsigned char turn_player{ 0 };
int phase; unsigned short phase{ 0 };
bool deck_reversed{ false };
#endif #endif
bool ready[4]; bool ready[4];
bool surrender[4]; bool surrender[4];
...@@ -79,13 +80,12 @@ protected: ...@@ -79,13 +80,12 @@ protected:
short time_limit[2]; short time_limit[2];
short time_elapsed; short time_elapsed;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
short time_compensator[2]; short time_compensator[2]{};
short time_backed[2]; short time_backed[2]{};
unsigned char last_game_msg; unsigned char last_game_msg{ 0 };
#endif #endif
}; };
} }
#endif //TAG_DUEL_H #endif //TAG_DUEL_H
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