Skip to content

Commit 147e269

Browse files
authored
add support for POS_REVEAL (#3121)
1 parent 2321b35 commit 147e269

3 files changed

Lines changed: 89 additions & 29 deletions

File tree

gframe/netserver.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ class NetServer {
2626
static void DisconnectPlayer(DuelPlayer* dp);
2727
static void HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, size_t len);
2828
static size_t CreateChatPacket(unsigned char* src, int src_size, unsigned char* dst, uint16_t dst_player_type);
29+
static inline bool ShouldHideFacedownCode(uint8_t position) {
30+
return (position & POS_FACEDOWN) != 0 && (position & POS_REVEAL) == 0;
31+
}
32+
// TODO: remove this function in the next protocol version, let the client handle the POS_REVEAL flag instead.
33+
static inline uint8_t StripRevealFlag(unsigned char* qbuf, size_t offset) {
34+
uint32_t info = 0;
35+
std::memcpy(&info, qbuf + offset, sizeof info);
36+
info &= ~(static_cast<uint32_t>(POS_REVEAL) << 24);
37+
std::memcpy(qbuf + offset, &info, sizeof info);
38+
return static_cast<uint8_t>(info >> 24);
39+
}
2940
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) {
3041
auto p = net_server_write;
3142
BufferIO::Write<uint16_t>(p, 1);

gframe/single_duel.cpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <array>
2+
#include <utility>
23
#include "config.h"
34
#include "single_duel.h"
45
#include "netserver.h"
@@ -960,10 +961,14 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
960961
int cc = pbuf[8];
961962
int cl = pbuf[9];
962963
int cs = pbuf[10];
963-
int cp = pbuf[11];
964+
uint8_t cp = pbuf[11];
965+
const bool hide_code = NetServer::ShouldHideFacedownCode(cp);
966+
if (cl & LOCATION_ONFIELD)
967+
cp = NetServer::StripRevealFlag(pbufw, 8);
964968
pbuf += 16;
965969
NetServer::SendBufferToPlayer(players[cc], STOC_GAME_MSG, offset, pbuf - offset);
966-
if (!(cl & (LOCATION_GRAVE + LOCATION_OVERLAY)) && ((cl & (LOCATION_DECK + LOCATION_HAND)) || (cp & POS_FACEDOWN)))
970+
if (!(cl & (LOCATION_GRAVE | LOCATION_OVERLAY))
971+
&& ((cl & (LOCATION_DECK | LOCATION_HAND)) || hide_code))
967972
BufferIO::Write<int32_t>(pbufw, 0);
968973
NetServer::SendBufferToPlayer(players[1 - cc], STOC_GAME_MSG, offset, pbuf - offset);
969974
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
@@ -1044,10 +1049,12 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
10441049
int cc = pbuf[4];
10451050
/*int cl = pbuf[5];*/
10461051
/*int cs = pbuf[6];*/
1047-
int cp = pbuf[7];
1052+
uint8_t cp = pbuf[7];
1053+
const bool hide_code = NetServer::ShouldHideFacedownCode(cp);
1054+
cp = NetServer::StripRevealFlag(pbufw, 4);
10481055
pbuf += 8;
10491056
NetServer::SendBufferToPlayer(players[cc], STOC_GAME_MSG, offset, pbuf - offset);
1050-
if (cp & POS_FACEDOWN)
1057+
if (hide_code)
10511058
BufferIO::Write<int32_t>(pbufw, 0);
10521059
NetServer::SendBufferToPlayer(players[1 - cc], STOC_GAME_MSG, offset, pbuf - offset);
10531060
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
@@ -1483,18 +1490,23 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) {
14831490
std::array<unsigned char, SIZE_QUERY_BUFFER> query_buffer;
14841491
auto qbuf = query_buffer.data();
14851492
auto len = WriteUpdateData(player, LOCATION_MZONE, flag, qbuf, use_cache);
1486-
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer.data(), len + 3);
1493+
std::vector<std::pair<unsigned char*, int>> hidden_segments;
14871494
int qlen = 0;
14881495
while(qlen < len) {
14891496
const int clen = BufferIO::Read<int32_t>(qbuf);
14901497
qlen += clen;
14911498
if (clen <= LEN_HEADER)
14921499
continue;
14931500
auto position = GetPosition(qbuf, 8);
1494-
if (position & POS_FACEDOWN)
1495-
std::memset(qbuf, 0, clen - 4);
1501+
const bool hide_code = NetServer::ShouldHideFacedownCode(position);
1502+
position = NetServer::StripRevealFlag(qbuf, 8);
1503+
if (hide_code)
1504+
hidden_segments.emplace_back(qbuf, clen);
14961505
qbuf += clen - 4;
14971506
}
1507+
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer.data(), len + 3);
1508+
for(const auto& segment : hidden_segments)
1509+
std::memset(segment.first, 0, segment.second - 4);
14981510
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer.data(), len + 3);
14991511
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
15001512
NetServer::ReSendToPlayer(*pit);
@@ -1503,18 +1515,23 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) {
15031515
std::array<unsigned char, SIZE_QUERY_BUFFER> query_buffer;
15041516
auto qbuf = query_buffer.data();
15051517
auto len = WriteUpdateData(player, LOCATION_SZONE, flag, qbuf, use_cache);
1506-
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer.data(), len + 3);
1518+
std::vector<std::pair<unsigned char*, int>> hidden_segments;
15071519
int qlen = 0;
15081520
while(qlen < len) {
15091521
const int clen = BufferIO::Read<int32_t>(qbuf);
15101522
qlen += clen;
15111523
if (clen <= LEN_HEADER)
15121524
continue;
15131525
auto position = GetPosition(qbuf, 8);
1514-
if (position & POS_FACEDOWN)
1515-
std::memset(qbuf, 0, clen - 4);
1526+
const bool hide_code = NetServer::ShouldHideFacedownCode(position);
1527+
position = NetServer::StripRevealFlag(qbuf, 8);
1528+
if (hide_code)
1529+
hidden_segments.emplace_back(qbuf, clen);
15161530
qbuf += clen - 4;
15171531
}
1532+
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer.data(), len + 3);
1533+
for(const auto& segment : hidden_segments)
1534+
std::memset(segment.first, 0, segment.second - 4);
15181535
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer.data(), len + 3);
15191536
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
15201537
NetServer::ReSendToPlayer(*pit);
@@ -1563,11 +1580,18 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
15631580
BufferIO::Write<uint8_t>(qbuf, location);
15641581
BufferIO::Write<uint8_t>(qbuf, sequence);
15651582
int len = query_card(pduel, player, location, sequence, flag, qbuf, 0);
1566-
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4);
1567-
if (len <= LEN_HEADER)
1583+
if (len <= LEN_HEADER) {
1584+
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4);
15681585
return;
1586+
}
15691587
auto position = GetPosition(qbuf, 12);
1570-
if (position & POS_FACEDOWN) {
1588+
bool hide_code = position & POS_FACEDOWN;
1589+
if (location & LOCATION_ONFIELD) {
1590+
hide_code = NetServer::ShouldHideFacedownCode(position);
1591+
position = NetServer::StripRevealFlag(qbuf, 12);
1592+
}
1593+
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4);
1594+
if (hide_code) {
15711595
BufferIO::Write<int32_t>(qbuf, 16);
15721596
BufferIO::Write<uint32_t>(qbuf, QUERY_CODE | QUERY_POSITION);
15731597
BufferIO::Write<uint32_t>(qbuf, 0);

gframe/tag_duel.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <array>
2+
#include <utility>
23
#include "config.h"
34
#include "tag_duel.h"
45
#include "netserver.h"
@@ -954,10 +955,14 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
954955
int cc = pbuf[8];
955956
int cl = pbuf[9];
956957
int cs = pbuf[10];
957-
int cp = pbuf[11];
958+
uint8_t cp = pbuf[11];
959+
const bool hide_code = NetServer::ShouldHideFacedownCode(cp);
960+
if (cl & LOCATION_ONFIELD)
961+
cp = NetServer::StripRevealFlag(pbufw, 8);
958962
pbuf += 16;
959963
NetServer::SendBufferToPlayer(cur_player[cc], STOC_GAME_MSG, offset, pbuf - offset);
960-
if (!(cl & (LOCATION_GRAVE + LOCATION_OVERLAY)) && ((cl & (LOCATION_DECK + LOCATION_HAND)) || (cp & POS_FACEDOWN)))
964+
if (!(cl & (LOCATION_GRAVE | LOCATION_OVERLAY))
965+
&& ((cl & (LOCATION_DECK | LOCATION_HAND)) || hide_code))
961966
BufferIO::Write<int32_t>(pbufw, 0);
962967
for(int i = 0; i < 4; ++i)
963968
if(players[i] != cur_player[cc])
@@ -1052,12 +1057,14 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
10521057
int cc = pbuf[4];
10531058
/*int cl = pbuf[5];*/
10541059
/*int cs = pbuf[6];*/
1055-
int cp = pbuf[7];
1060+
uint8_t cp = pbuf[7];
1061+
const bool hide_code = NetServer::ShouldHideFacedownCode(cp);
1062+
cp = NetServer::StripRevealFlag(pbufw, 4);
10561063
pbuf += 8;
10571064
auto pid = (cc == 0) ? 0 : 2;
10581065
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, offset, pbuf - offset);
10591066
NetServer::ReSendToPlayer(players[pid + 1]);
1060-
if (cp & POS_FACEDOWN)
1067+
if (hide_code)
10611068
BufferIO::Write<int32_t>(pbufw, 0);
10621069
pid = 2 - pid;
10631070
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, offset, pbuf - offset);
@@ -1596,20 +1603,25 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
15961603
std::array<unsigned char, SIZE_QUERY_BUFFER> query_buffer;
15971604
auto qbuf = query_buffer.data();
15981605
auto len = WriteUpdateData(player, LOCATION_MZONE, flag, qbuf, use_cache);
1606+
std::vector<std::pair<unsigned char*, int>> hidden_segments;
15991607
int pid = (player == 0) ? 0 : 2;
1600-
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
1601-
NetServer::ReSendToPlayer(players[pid + 1]);
16021608
int qlen = 0;
16031609
while(qlen < len) {
16041610
int clen = BufferIO::Read<int32_t>(qbuf);
16051611
qlen += clen;
16061612
if (clen <= LEN_HEADER)
16071613
continue;
16081614
auto position = GetPosition(qbuf, 8);
1609-
if (position & POS_FACEDOWN)
1610-
std::memset(qbuf, 0, clen - 4);
1615+
const bool hide_code = NetServer::ShouldHideFacedownCode(position);
1616+
position = NetServer::StripRevealFlag(qbuf, 8);
1617+
if (hide_code)
1618+
hidden_segments.emplace_back(qbuf, clen);
16111619
qbuf += clen - 4;
16121620
}
1621+
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
1622+
NetServer::ReSendToPlayer(players[pid + 1]);
1623+
for(const auto& segment : hidden_segments)
1624+
std::memset(segment.first, 0, segment.second - 4);
16131625
pid = 2 - pid;
16141626
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
16151627
NetServer::ReSendToPlayer(players[pid + 1]);
@@ -1620,20 +1632,25 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
16201632
std::array<unsigned char, SIZE_QUERY_BUFFER> query_buffer;
16211633
auto qbuf = query_buffer.data();
16221634
auto len = WriteUpdateData(player, LOCATION_SZONE, flag, qbuf, use_cache);
1635+
std::vector<std::pair<unsigned char*, int>> hidden_segments;
16231636
int pid = (player == 0) ? 0 : 2;
1624-
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
1625-
NetServer::ReSendToPlayer(players[pid + 1]);
16261637
int qlen = 0;
16271638
while(qlen < len) {
16281639
int clen = BufferIO::Read<int32_t>(qbuf);
16291640
qlen += clen;
16301641
if (clen <= LEN_HEADER)
16311642
continue;
16321643
auto position = GetPosition(qbuf, 8);
1633-
if (position & POS_FACEDOWN)
1634-
std::memset(qbuf, 0, clen - 4);
1644+
const bool hide_code = NetServer::ShouldHideFacedownCode(position);
1645+
position = NetServer::StripRevealFlag(qbuf, 8);
1646+
if (hide_code)
1647+
hidden_segments.emplace_back(qbuf, clen);
16351648
qbuf += clen - 4;
16361649
}
1650+
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
1651+
NetServer::ReSendToPlayer(players[pid + 1]);
1652+
for(const auto& segment : hidden_segments)
1653+
std::memset(segment.first, 0, segment.second - 4);
16371654
pid = 2 - pid;
16381655
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer.data(), len + 3);
16391656
NetServer::ReSendToPlayer(players[pid + 1]);
@@ -1689,12 +1706,20 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
16891706
BufferIO::Write<uint8_t>(qbuf, sequence);
16901707
int len = query_card(pduel, player, location, sequence, flag, qbuf, 0);
16911708
int pid = (player == 0) ? 0 : 2;
1692-
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 4);
1693-
NetServer::ReSendToPlayer(players[pid + 1]);
1694-
if (len <= LEN_HEADER)
1709+
if (len <= LEN_HEADER) {
1710+
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 4);
1711+
NetServer::ReSendToPlayer(players[pid + 1]);
16951712
return;
1713+
}
16961714
auto position = GetPosition(qbuf, 12);
1697-
if (position & POS_FACEDOWN) {
1715+
bool hide_code = position & POS_FACEDOWN;
1716+
if (location & LOCATION_ONFIELD) {
1717+
hide_code = NetServer::ShouldHideFacedownCode(position);
1718+
position = NetServer::StripRevealFlag(qbuf, 12);
1719+
}
1720+
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 4);
1721+
NetServer::ReSendToPlayer(players[pid + 1]);
1722+
if (hide_code) {
16981723
BufferIO::Write<int32_t>(qbuf, 16);
16991724
BufferIO::Write<uint32_t>(qbuf, QUERY_CODE | QUERY_POSITION);
17001725
BufferIO::Write<uint32_t>(qbuf, 0);

0 commit comments

Comments
 (0)