Commit 13e1fbf9 authored by nanahira's avatar nanahira

Merge branch 'server-develop' into server

parents 6a977bfc ad861a32
...@@ -83,7 +83,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) { ...@@ -83,7 +83,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
if (len > SIZE_SETCODE) if (len > SIZE_SETCODE)
len = SIZE_SETCODE; len = SIZE_SETCODE;
if (len) if (len)
memcpy(cd.setcode, it->second.data(), len * sizeof(uint16_t)); std::memcpy(cd.setcode, it->second.data(), len * sizeof(uint16_t));
} }
else else
cd.set_setcode(setcode); cd.set_setcode(setcode);
...@@ -225,7 +225,7 @@ bool DataManager::GetData(unsigned int code, CardData* pData) { ...@@ -225,7 +225,7 @@ bool DataManager::GetData(unsigned int code, CardData* pData) {
if (pData) { if (pData) {
pData->code = data.code; pData->code = data.code;
pData->alias = data.alias; pData->alias = data.alias;
memcpy(pData->setcode, data.setcode, SIZE_SETCODE); std::memcpy(pData->setcode, data.setcode, SIZE_SETCODE);
pData->type = data.type; pData->type = data.type;
pData->level = data.level; pData->level = data.level;
pData->attribute = data.attribute; pData->attribute = data.attribute;
......
...@@ -1249,7 +1249,7 @@ void DeckBuilder::GetHoveredCard() { ...@@ -1249,7 +1249,7 @@ void DeckBuilder::GetHoveredCard() {
} else if(y >= 164 && y <= 435) { } else if(y >= 164 && y <= 435) {
int lx = 10, px, py = (y - 164) / 68; int lx = 10, px, py = (y - 164) / 68;
hovered_pos = 1; hovered_pos = 1;
if(deckManager.current_deck.main.size() > 40) if(deckManager.current_deck.main.size() > DECK_MIN_SIZE)
lx = (deckManager.current_deck.main.size() - 41) / 4 + 11; lx = (deckManager.current_deck.main.size() - 41) / 4 + 11;
if(x >= 750) if(x >= 750)
px = lx - 1; px = lx - 1;
...@@ -1757,7 +1757,7 @@ bool DeckBuilder::push_main(code_pointer pointer, int seq) { ...@@ -1757,7 +1757,7 @@ bool DeckBuilder::push_main(code_pointer pointer, int seq) {
if(pointer->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) if(pointer->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK))
return false; return false;
auto& container = deckManager.current_deck.main; auto& container = deckManager.current_deck.main;
int maxc = mainGame->is_siding ? YGOPRO_MAX_DECK + 5 : YGOPRO_MAX_DECK; int maxc = mainGame->is_siding ? DECK_MAX_SIZE + 4 : DECK_MAX_SIZE;
if((int)container.size() >= maxc) if((int)container.size() >= maxc)
return false; return false;
if(seq >= 0 && seq < (int)container.size()) if(seq >= 0 && seq < (int)container.size())
...@@ -1772,7 +1772,7 @@ bool DeckBuilder::push_extra(code_pointer pointer, int seq) { ...@@ -1772,7 +1772,7 @@ bool DeckBuilder::push_extra(code_pointer pointer, int seq) {
if(!(pointer->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK))) if(!(pointer->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)))
return false; return false;
auto& container = deckManager.current_deck.extra; auto& container = deckManager.current_deck.extra;
int maxc = mainGame->is_siding ? YGOPRO_MAX_EXTRA + 5 : YGOPRO_MAX_EXTRA; int maxc = mainGame->is_siding ? EXTRA_MAX_SIZE + 5 : EXTRA_MAX_SIZE;
if((int)container.size() >= maxc) if((int)container.size() >= maxc)
return false; return false;
if(seq >= 0 && seq < (int)container.size()) if(seq >= 0 && seq < (int)container.size())
...@@ -1785,7 +1785,7 @@ bool DeckBuilder::push_extra(code_pointer pointer, int seq) { ...@@ -1785,7 +1785,7 @@ bool DeckBuilder::push_extra(code_pointer pointer, int seq) {
} }
bool DeckBuilder::push_side(code_pointer pointer, int seq) { bool DeckBuilder::push_side(code_pointer pointer, int seq) {
auto& container = deckManager.current_deck.side; auto& container = deckManager.current_deck.side;
int maxc = mainGame->is_siding ? YGOPRO_MAX_SIDE + 5 : YGOPRO_MAX_SIDE; int maxc = mainGame->is_siding ? SIDE_MAX_SIZE + 5 : SIDE_MAX_SIZE;
if((int)container.size() >= maxc) if((int)container.size() >= maxc)
return false; return false;
if(seq >= 0 && seq < (int)container.size()) if(seq >= 0 && seq < (int)container.size())
......
...@@ -91,11 +91,11 @@ int DeckManager::CheckDeck(Deck& deck, int lfhash, int rule) { ...@@ -91,11 +91,11 @@ int DeckManager::CheckDeck(Deck& deck, int lfhash, int rule) {
if(!list) if(!list)
return 0; return 0;
int dc = 0; int dc = 0;
if(deck.main.size() < YGOPRO_MIN_DECK || deck.main.size() > YGOPRO_MAX_DECK) if(deck.main.size() < DECK_MIN_SIZE || deck.main.size() > DECK_MAX_SIZE)
return (DECKERROR_MAINCOUNT << 28) + deck.main.size(); return (DECKERROR_MAINCOUNT << 28) + deck.main.size();
if(deck.extra.size() > YGOPRO_MAX_EXTRA) if(deck.extra.size() > EXTRA_MAX_SIZE)
return (DECKERROR_EXTRACOUNT << 28) + deck.extra.size(); return (DECKERROR_EXTRACOUNT << 28) + deck.extra.size();
if(deck.side.size() > YGOPRO_MAX_SIDE) if(deck.side.size() > SIDE_MAX_SIZE)
return (DECKERROR_SIDECOUNT << 28) + deck.side.size(); return (DECKERROR_SIDECOUNT << 28) + deck.side.size();
const int rule_map[6] = { AVAIL_OCG, AVAIL_TCG, AVAIL_SC, AVAIL_CUSTOM, AVAIL_OCGTCG, 0 }; const int rule_map[6] = { AVAIL_OCG, AVAIL_TCG, AVAIL_SC, AVAIL_CUSTOM, AVAIL_OCGTCG, 0 };
int avail = rule_map[rule]; int avail = rule_map[rule];
...@@ -163,10 +163,10 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p ...@@ -163,10 +163,10 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
continue; continue;
} }
else if(cd.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) { else if(cd.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) {
if(deck.extra.size() >= YGOPRO_MAX_EXTRA) if(deck.extra.size() >= EXTRA_MAX_SIZE)
continue; continue;
deck.extra.push_back(dataManager.GetCodePointer(code)); deck.extra.push_back(dataManager.GetCodePointer(code));
} else if(deck.main.size() < YGOPRO_MAX_DECK) { } else if(deck.main.size() < DECK_MAX_SIZE) {
deck.main.push_back(dataManager.GetCodePointer(code)); deck.main.push_back(dataManager.GetCodePointer(code));
} }
} }
...@@ -256,7 +256,9 @@ bool DeckManager::LoadDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUICom ...@@ -256,7 +256,9 @@ bool DeckManager::LoadDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUICom
} }
FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) { FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) {
#ifdef WIN32 #ifdef WIN32
FILE* fp = _wfopen(file, (wchar_t*)mode); wchar_t wmode[20]{};
BufferIO::CopyWStr(mode, wmode, sizeof(wmode) / sizeof(wchar_t));
FILE* fp = _wfopen(file, wmode);
#else #else
char file2[256]; char file2[256];
BufferIO::EncodeUTF8(file, file2); BufferIO::EncodeUTF8(file, file2);
......
...@@ -9,7 +9,27 @@ ...@@ -9,7 +9,27 @@
#include <sstream> #include <sstream>
#endif #endif
#ifndef YGOPRO_MAX_DECK
#define YGOPRO_MAX_DECK 60
#endif
#ifndef YGOPRO_MIN_DECK
#define YGOPRO_MIN_DECK 40
#endif
#ifndef YGOPRO_MAX_EXTRA
#define YGOPRO_MAX_EXTRA 15
#endif
#ifndef YGOPRO_MAX_SIDE
#define YGOPRO_MAX_SIDE 15
#endif
namespace ygo { namespace ygo {
constexpr int DECK_MAX_SIZE = YGOPRO_MAX_DECK;
constexpr int DECK_MIN_SIZE = YGOPRO_MIN_DECK;
constexpr int EXTRA_MAX_SIZE = YGOPRO_MAX_EXTRA;
constexpr int SIDE_MAX_SIZE = YGOPRO_MAX_SIDE;
struct LFList { struct LFList {
unsigned int hash{}; unsigned int hash{};
......
...@@ -18,10 +18,10 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, ...@@ -18,10 +18,10 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width,
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glMaterialfv(GL_FRONT, GL_AMBIENT, cv); glMaterialfv(GL_FRONT, GL_AMBIENT, cv);
glBegin(GL_LINE_LOOP); glBegin(GL_LINE_LOOP);
glVertex3fv((float*)&vec[0].Pos); glVertex3fv(&vec[0].Pos.X);
glVertex3fv((float*)&vec[1].Pos); glVertex3fv(&vec[1].Pos.X);
glVertex3fv((float*)&vec[3].Pos); glVertex3fv(&vec[3].Pos.X);
glVertex3fv((float*)&vec[2].Pos); glVertex3fv(&vec[2].Pos.X);
glEnd(); glEnd();
glMaterialfv(GL_FRONT, GL_AMBIENT, origin); glMaterialfv(GL_FRONT, GL_AMBIENT, origin);
glDisable(GL_LINE_STIPPLE); glDisable(GL_LINE_STIPPLE);
......
This diff is collapsed.
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <utility> #include <utility>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/thread.h>
#include "network.h" #include "network.h"
#include "data_manager.h" #include "data_manager.h"
#include "deck_manager.h" #include "deck_manager.h"
...@@ -27,6 +22,7 @@ private: ...@@ -27,6 +22,7 @@ private:
static event_base* client_base; static event_base* client_base;
static bufferevent* client_bev; static bufferevent* client_bev;
static unsigned char duel_client_read[SIZE_NETWORK_BUFFER]; static unsigned char duel_client_read[SIZE_NETWORK_BUFFER];
static int read_len;
static unsigned char duel_client_write[SIZE_NETWORK_BUFFER]; static unsigned char duel_client_write[SIZE_NETWORK_BUFFER];
static bool is_closing; static bool is_closing;
static bool is_swapping; static bool is_swapping;
...@@ -45,7 +41,7 @@ public: ...@@ -45,7 +41,7 @@ public:
static void ClientRead(bufferevent* bev, void* ctx); static void ClientRead(bufferevent* bev, void* ctx);
static void ClientEvent(bufferevent *bev, short events, void *ctx); static void ClientEvent(bufferevent *bev, short events, void *ctx);
static int ClientThread(); static int ClientThread();
static void HandleSTOCPacketLan(unsigned char* data, unsigned int len); static void HandleSTOCPacketLan(unsigned char* data, int len);
static int ClientAnalyze(unsigned char* msg, unsigned int len); static int ClientAnalyze(unsigned char* msg, unsigned int len);
static void SwapField(); static void SwapField();
static void SetResponseI(int respI); static void SetResponseI(int respI);
...@@ -62,10 +58,10 @@ public: ...@@ -62,10 +58,10 @@ public:
auto p = duel_client_write; auto p = duel_client_write;
int blen = sizeof(ST); int blen = sizeof(ST);
if (blen > MAX_DATA_SIZE) if (blen > MAX_DATA_SIZE)
blen = MAX_DATA_SIZE; return;
BufferIO::WriteInt16(p, (short)(1 + blen)); BufferIO::WriteInt16(p, (short)(1 + blen));
BufferIO::WriteInt8(p, proto); BufferIO::WriteInt8(p, proto);
memcpy(p, &st, blen); std::memcpy(p, &st, blen);
bufferevent_write(client_bev, duel_client_write, blen + 3); bufferevent_write(client_bev, duel_client_write, blen + 3);
} }
static void SendBufferToServer(unsigned char proto, void* buffer, size_t len) { static void SendBufferToServer(unsigned char proto, void* buffer, size_t len) {
...@@ -77,7 +73,7 @@ public: ...@@ -77,7 +73,7 @@ public:
blen = MAX_DATA_SIZE; blen = MAX_DATA_SIZE;
BufferIO::WriteInt16(p, (short)(1 + blen)); BufferIO::WriteInt16(p, (short)(1 + blen));
BufferIO::WriteInt8(p, proto); BufferIO::WriteInt8(p, proto);
memcpy(p, buffer, blen); std::memcpy(p, buffer, blen);
bufferevent_write(client_bev, duel_client_write, blen + 3); bufferevent_write(client_bev, duel_client_write, blen + 3);
} }
......
...@@ -2028,9 +2028,9 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) { ...@@ -2028,9 +2028,9 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
break; break;
const wchar_t* input = mainGame->ebChatInput->getText(); const wchar_t* input = mainGame->ebChatInput->getText();
if(input[0]) { if(input[0]) {
unsigned short msgbuf[256]; uint16_t msgbuf[LEN_CHAT_MSG];
int len = BufferIO::CopyWStr(input, msgbuf, 256); int len = BufferIO::CopyWStr(input, msgbuf, LEN_CHAT_MSG);
DuelClient::SendBufferToServer(CTOS_CHAT, msgbuf, (len + 1) * sizeof(short)); DuelClient::SendBufferToServer(CTOS_CHAT, msgbuf, (len + 1) * sizeof(uint16_t));
mainGame->ebChatInput->setText(L""); mainGame->ebChatInput->setText(L"");
return true; return true;
} }
......
...@@ -17,22 +17,6 @@ ...@@ -17,22 +17,6 @@
#define YGOPRO_DEFAULT_DUEL_RULE 5 #define YGOPRO_DEFAULT_DUEL_RULE 5
#endif #endif
#ifndef YGOPRO_MAX_DECK
#define YGOPRO_MAX_DECK 60
#endif
#ifndef YGOPRO_MIN_DECK
#define YGOPRO_MIN_DECK 40
#endif
#ifndef YGOPRO_MAX_EXTRA
#define YGOPRO_MAX_EXTRA 15
#endif
#ifndef YGOPRO_MAX_SIDE
#define YGOPRO_MAX_SIDE 15
#endif
#define DEFAULT_DUEL_RULE YGOPRO_DEFAULT_DUEL_RULE #define DEFAULT_DUEL_RULE YGOPRO_DEFAULT_DUEL_RULE
namespace ygo { namespace ygo {
......
...@@ -74,9 +74,15 @@ typedef unsigned long UInt64; ...@@ -74,9 +74,15 @@ typedef unsigned long UInt64;
#else #else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64; typedef long long int Int64;
typedef unsigned long long int UInt64; typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL #define UINT64_CONST(n) n ## ULL
#endif
#endif #endif
......
...@@ -10,6 +10,7 @@ event* NetServer::broadcast_ev = 0; ...@@ -10,6 +10,7 @@ event* NetServer::broadcast_ev = 0;
evconnlistener* NetServer::listener = 0; evconnlistener* NetServer::listener = 0;
DuelMode* NetServer::duel_mode = 0; DuelMode* NetServer::duel_mode = 0;
unsigned char NetServer::net_server_read[SIZE_NETWORK_BUFFER]; unsigned char NetServer::net_server_read[SIZE_NETWORK_BUFFER];
int NetServer::read_len = 0;
unsigned char NetServer::net_server_write[SIZE_NETWORK_BUFFER]; unsigned char NetServer::net_server_write[SIZE_NETWORK_BUFFER];
unsigned short NetServer::last_sent = 0; unsigned short NetServer::last_sent = 0;
...@@ -167,7 +168,9 @@ void NetServer::BroadcastEvent(evutil_socket_t fd, short events, void* arg) { ...@@ -167,7 +168,9 @@ void NetServer::BroadcastEvent(evutil_socket_t fd, short events, void* arg) {
int ret = recvfrom(fd, buf, 256, 0, (sockaddr*)&bc_addr, &sz); int ret = recvfrom(fd, buf, 256, 0, (sockaddr*)&bc_addr, &sz);
if(ret == -1) if(ret == -1)
return; return;
HostRequest* pHR = (HostRequest*)buf; HostRequest packet;
std::memcpy(&packet, buf, sizeof packet);
const HostRequest* pHR = &packet;
if(pHR->identifier == NETWORK_CLIENT_ID) { if(pHR->identifier == NETWORK_CLIENT_ID) {
SOCKADDR_IN sockTo; SOCKADDR_IN sockTo;
sockTo.sin_addr.s_addr = bc_addr.sin_addr.s_addr; sockTo.sin_addr.s_addr = bc_addr.sin_addr.s_addr;
...@@ -195,19 +198,30 @@ void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, socka ...@@ -195,19 +198,30 @@ void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, socka
void NetServer::ServerAcceptError(evconnlistener* listener, void* ctx) { void NetServer::ServerAcceptError(evconnlistener* listener, void* ctx) {
event_base_loopexit(net_evbase, 0); event_base_loopexit(net_evbase, 0);
} }
/*
* packet_len: 2 bytes
* proto: 1 byte
* [data]: (packet_len - 1) bytes
*/
void NetServer::ServerEchoRead(bufferevent *bev, void *ctx) { void NetServer::ServerEchoRead(bufferevent *bev, void *ctx) {
evbuffer* input = bufferevent_get_input(bev); evbuffer* input = bufferevent_get_input(bev);
size_t len = evbuffer_get_length(input); int len = evbuffer_get_length(input);
unsigned short packet_len = 0; unsigned short packet_len = 0;
while(true) { while(true) {
if(len < 2) if(len < 2)
return; return;
evbuffer_copyout(input, &packet_len, 2); evbuffer_copyout(input, &packet_len, 2);
if(len < (size_t)packet_len + 2) if (packet_len + 2 > SIZE_NETWORK_BUFFER) {
ServerEchoEvent(bev, BEV_EVENT_ERROR, 0);
return; return;
evbuffer_remove(input, net_server_read, packet_len + 2); }
if(packet_len) if (len < packet_len + 2)
HandleCTOSPacket(&users[bev], &net_server_read[2], packet_len); return;
if (packet_len < 1)
return;
read_len = evbuffer_remove(input, net_server_read, packet_len + 2);
if (read_len >= 3)
HandleCTOSPacket(&users[bev], &net_server_read[2], read_len - 2);
len -= packet_len + 2; len -= packet_len + 2;
} }
} }
...@@ -217,7 +231,8 @@ void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) { ...@@ -217,7 +231,8 @@ void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) {
DuelMode* dm = dp->game; DuelMode* dm = dp->game;
if(dm) if(dm)
dm->LeaveGame(dp); dm->LeaveGame(dp);
else DisconnectPlayer(dp); else
DisconnectPlayer(dp);
} }
} }
int NetServer::ServerThread() { int NetServer::ServerThread() {
...@@ -254,7 +269,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) { ...@@ -254,7 +269,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) {
users.erase(bit); users.erase(bit);
} }
} }
void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned int len) { void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
auto pdata = data; auto pdata = data;
unsigned char pktType = BufferIO::ReadUInt8(pdata); unsigned char pktType = BufferIO::ReadUInt8(pdata);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -267,6 +282,8 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i ...@@ -267,6 +282,8 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
case CTOS_RESPONSE: { case CTOS_RESPONSE: {
if(!dp->game || !duel_mode->pduel) if(!dp->game || !duel_mode->pduel)
return; return;
if (len < 1 + (int)sizeof(unsigned char))
return;
duel_mode->GetResponse(dp, pdata, len - 1); duel_mode->GetResponse(dp, pdata, len - 1);
break; break;
} }
...@@ -279,38 +296,58 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i ...@@ -279,38 +296,58 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
case CTOS_CHAT: { case CTOS_CHAT: {
if(!dp->game) if(!dp->game)
return; return;
if (len < 1 + (int)sizeof(unsigned char))
return;
duel_mode->Chat(dp, pdata, len - 1); duel_mode->Chat(dp, pdata, len - 1);
break; break;
} }
case CTOS_UPDATE_DECK: { case CTOS_UPDATE_DECK: {
if(!dp->game) if(!dp->game)
return; return;
if (len < 1 + (int)sizeof(unsigned char))
return;
duel_mode->UpdateDeck(dp, pdata, len - 1); duel_mode->UpdateDeck(dp, pdata, len - 1);
break; break;
} }
case CTOS_HAND_RESULT: { case CTOS_HAND_RESULT: {
if(!dp->game) if(!dp->game)
return; return;
CTOS_HandResult* pkt = (CTOS_HandResult*)pdata; if (len < 1 + (int)sizeof(CTOS_HandResult))
return;
CTOS_HandResult packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
dp->game->HandResult(dp, pkt->res); dp->game->HandResult(dp, pkt->res);
break; break;
} }
case CTOS_TP_RESULT: { case CTOS_TP_RESULT: {
if(!dp->game) if(!dp->game)
return; return;
CTOS_TPResult* pkt = (CTOS_TPResult*)pdata; if (len < 1 + (int)sizeof(CTOS_TPResult))
return;
CTOS_TPResult packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
dp->game->TPResult(dp, pkt->res); dp->game->TPResult(dp, pkt->res);
break; break;
} }
case CTOS_PLAYER_INFO: { case CTOS_PLAYER_INFO: {
CTOS_PlayerInfo* pkt = (CTOS_PlayerInfo*)pdata; if (len < 1 + (int)sizeof(CTOS_PlayerInfo))
return;
CTOS_PlayerInfo packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
BufferIO::CopyWStr(pkt->name, dp->name, 20); BufferIO::CopyWStr(pkt->name, dp->name, 20);
break; break;
} }
case CTOS_CREATE_GAME: { case CTOS_CREATE_GAME: {
if(dp->game || duel_mode) if(dp->game || duel_mode)
return; return;
CTOS_CreateGame* pkt = (CTOS_CreateGame*)pdata; if (len < 1 + (int)sizeof(CTOS_CreateGame))
return;
CTOS_CreateGame packet;
std::memcpy(&packet, pdata, sizeof packet);
auto pkt = &packet;
if(pkt->info.mode == MODE_SINGLE) { if(pkt->info.mode == MODE_SINGLE) {
duel_mode = new SingleDuel(false); duel_mode = new SingleDuel(false);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode); duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
...@@ -334,6 +371,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i ...@@ -334,6 +371,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
} }
if(hash == 1) if(hash == 1)
pkt->info.lflist = deckManager._lfList[0].hash; pkt->info.lflist = deckManager._lfList[0].hash;
std::memcpy(pdata, &packet, sizeof packet);
duel_mode->host_info = pkt->info; duel_mode->host_info = pkt->info;
BufferIO::CopyWStr(pkt->name, duel_mode->name, 20); BufferIO::CopyWStr(pkt->name, duel_mode->name, 20);
BufferIO::CopyWStr(pkt->pass, duel_mode->pass, 20); BufferIO::CopyWStr(pkt->pass, duel_mode->pass, 20);
...@@ -342,52 +380,58 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i ...@@ -342,52 +380,58 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
break; break;
} }
case CTOS_JOIN_GAME: { case CTOS_JOIN_GAME: {
if(!duel_mode) if (!duel_mode)
break; return;
if (len < 1 + (int)sizeof(CTOS_JoinGame))
return;
duel_mode->JoinGame(dp, pdata, false); duel_mode->JoinGame(dp, pdata, false);
break; break;
} }
case CTOS_LEAVE_GAME: { case CTOS_LEAVE_GAME: {
if(!duel_mode) if (!duel_mode)
break; return;
duel_mode->LeaveGame(dp); duel_mode->LeaveGame(dp);
break; break;
} }
case CTOS_SURRENDER: { case CTOS_SURRENDER: {
if(!duel_mode) if (!duel_mode)
break; return;
duel_mode->Surrender(dp); duel_mode->Surrender(dp);
break; break;
} }
case CTOS_HS_TODUELIST: { case CTOS_HS_TODUELIST: {
if(!duel_mode || duel_mode->pduel) if (!duel_mode || duel_mode->pduel)
break; return;
duel_mode->ToDuelist(dp); duel_mode->ToDuelist(dp);
break; break;
} }
case CTOS_HS_TOOBSERVER: { case CTOS_HS_TOOBSERVER: {
if(!duel_mode || duel_mode->pduel) if (!duel_mode || duel_mode->pduel)
break; return;
duel_mode->ToObserver(dp); duel_mode->ToObserver(dp);
break; break;
} }
case CTOS_HS_READY: case CTOS_HS_READY:
case CTOS_HS_NOTREADY: { case CTOS_HS_NOTREADY: {
if(!duel_mode || duel_mode->pduel) if (!duel_mode || duel_mode->pduel)
break; return;
duel_mode->PlayerReady(dp, (CTOS_HS_NOTREADY - pktType) != 0); duel_mode->PlayerReady(dp, (CTOS_HS_NOTREADY - pktType) != 0);
break; break;
} }
case CTOS_HS_KICK: { case CTOS_HS_KICK: {
if(!duel_mode || duel_mode->pduel) if (!duel_mode || duel_mode->pduel)
break; return;
CTOS_Kick* pkt = (CTOS_Kick*)pdata; if (len < 1 + (int)sizeof(CTOS_Kick))
return;
CTOS_Kick packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
duel_mode->PlayerKick(dp, pkt->pos); duel_mode->PlayerKick(dp, pkt->pos);
break; break;
} }
case CTOS_HS_START: { case CTOS_HS_START: {
if(!duel_mode || duel_mode->pduel) if (!duel_mode || duel_mode->pduel)
break; return;
duel_mode->StartDuel(dp); duel_mode->StartDuel(dp);
break; break;
} }
...@@ -401,5 +445,19 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i ...@@ -401,5 +445,19 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned i
#endif #endif
} }
} }
size_t NetServer::CreateChatPacket(unsigned char* src, int src_size, unsigned char* dst, uint16_t dst_player_type) {
if (!check_msg_size(src_size))
return 0;
uint16_t src_msg[LEN_CHAT_MSG];
std::memcpy(src_msg, src, src_size);
const int src_len = src_size / sizeof(uint16_t);
if (src_msg[src_len - 1] != 0)
return 0;
// STOC_Chat packet
auto pdst = dst;
buffer_write<uint16_t>(pdst, dst_player_type);
buffer_write_block(pdst, src_msg, src_size);
return sizeof(dst_player_type) + src_size;
}
} }
...@@ -21,6 +21,7 @@ private: ...@@ -21,6 +21,7 @@ private:
static evconnlistener* listener; static evconnlistener* listener;
static DuelMode* duel_mode; static DuelMode* duel_mode;
static unsigned char net_server_read[SIZE_NETWORK_BUFFER]; static unsigned char net_server_read[SIZE_NETWORK_BUFFER];
static int read_len;
static unsigned char net_server_write[SIZE_NETWORK_BUFFER]; static unsigned char net_server_write[SIZE_NETWORK_BUFFER];
static unsigned short last_sent; static unsigned short last_sent;
...@@ -44,7 +45,8 @@ public: ...@@ -44,7 +45,8 @@ public:
static void ServerEchoEvent(bufferevent* bev, short events, void* ctx); static void ServerEchoEvent(bufferevent* bev, short events, void* ctx);
static int ServerThread(); static int ServerThread();
static void DisconnectPlayer(DuelPlayer* dp); static void DisconnectPlayer(DuelPlayer* dp);
static void HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, unsigned int len); static void HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len);
static size_t CreateChatPacket(unsigned char* src, int src_size, unsigned char* dst, uint16_t dst_player_type);
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) { static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) {
auto p = net_server_write; auto p = net_server_write;
BufferIO::WriteInt16(p, 1); BufferIO::WriteInt16(p, 1);
...@@ -59,10 +61,10 @@ public: ...@@ -59,10 +61,10 @@ public:
auto p = net_server_write; auto p = net_server_write;
int blen = sizeof(ST); int blen = sizeof(ST);
if (blen > MAX_DATA_SIZE) if (blen > MAX_DATA_SIZE)
blen = MAX_DATA_SIZE; return;
BufferIO::WriteInt16(p, (short)(1 + blen)); BufferIO::WriteInt16(p, (short)(1 + blen));
BufferIO::WriteInt8(p, proto); BufferIO::WriteInt8(p, proto);
memcpy(p, &st, blen); std::memcpy(p, &st, blen);
last_sent = blen + 3; last_sent = blen + 3;
if (dp) if (dp)
bufferevent_write(dp->bev, net_server_write, blen + 3); bufferevent_write(dp->bev, net_server_write, blen + 3);
...@@ -76,7 +78,7 @@ public: ...@@ -76,7 +78,7 @@ public:
blen = MAX_DATA_SIZE; blen = MAX_DATA_SIZE;
BufferIO::WriteInt16(p, (short)(1 + blen)); BufferIO::WriteInt16(p, (short)(1 + blen));
BufferIO::WriteInt8(p, proto); BufferIO::WriteInt8(p, proto);
memcpy(p, buffer, blen); std::memcpy(p, buffer, blen);
last_sent = blen + 3; last_sent = blen + 3;
if (dp) if (dp)
bufferevent_write(dp->bev, net_server_write, blen + 3); bufferevent_write(dp->bev, net_server_write, blen + 3);
......
...@@ -8,95 +8,174 @@ ...@@ -8,95 +8,174 @@
#include <event2/bufferevent.h> #include <event2/bufferevent.h>
#include <event2/buffer.h> #include <event2/buffer.h>
#include <event2/thread.h> #include <event2/thread.h>
#include <type_traits>
#define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true, "not trivially copyable")
namespace ygo { namespace ygo {
constexpr int SIZE_NETWORK_BUFFER = 0x2000; constexpr int SIZE_NETWORK_BUFFER = 0x2000;
constexpr int MAX_DATA_SIZE = SIZE_NETWORK_BUFFER - 3; constexpr int MAX_DATA_SIZE = SIZE_NETWORK_BUFFER - 3;
constexpr int MAINC_MAX = 250; // the limit of card_state
constexpr int SIDEC_MAX = MAINC_MAX;
struct HostInfo { struct HostInfo {
unsigned int lflist{ 0 }; uint32_t lflist{};
unsigned char rule{ 0 }; unsigned char rule{};
unsigned char mode{ 0 }; unsigned char mode{};
unsigned char duel_rule{ 0 }; unsigned char duel_rule{};
bool no_check_deck{ false }; unsigned char no_check_deck{};
bool no_shuffle_deck{ false }; unsigned char no_shuffle_deck{};
unsigned int start_lp{ 0 }; // byte padding[3]
unsigned char start_hand{ 0 };
unsigned char draw_count{ 0 }; uint32_t start_lp{};
unsigned short time_limit{ 0 }; unsigned char start_hand{};
unsigned char draw_count{};
uint16_t time_limit{};
}; };
check_trivially_copyable(HostInfo);
static_assert(sizeof(HostInfo) == 20, "size mismatch: HostInfo");
struct HostPacket { struct HostPacket {
unsigned short identifier; uint16_t identifier;
unsigned short version; uint16_t version;
unsigned short port; uint16_t port;
unsigned int ipaddr; // byte padding[2]
unsigned short name[20];
uint32_t ipaddr;
uint16_t name[20];
HostInfo host; HostInfo host;
}; };
check_trivially_copyable(HostPacket);
static_assert(sizeof(HostPacket) == 72, "size mismatch: HostPacket");
struct HostRequest { struct HostRequest {
unsigned short identifier; uint16_t identifier;
}; };
check_trivially_copyable(HostRequest);
static_assert(sizeof(HostRequest) == 2, "size mismatch: HostRequest");
struct CTOS_HandResult { struct CTOS_HandResult {
unsigned char res; unsigned char res;
}; };
check_trivially_copyable(CTOS_HandResult);
static_assert(sizeof(CTOS_HandResult) == 1, "size mismatch: CTOS_HandResult");
struct CTOS_TPResult { struct CTOS_TPResult {
unsigned char res; unsigned char res;
}; };
check_trivially_copyable(CTOS_TPResult);
static_assert(sizeof(CTOS_TPResult) == 1, "size mismatch: CTOS_TPResult");
struct CTOS_PlayerInfo { struct CTOS_PlayerInfo {
unsigned short name[20]; uint16_t name[20];
}; };
check_trivially_copyable(CTOS_PlayerInfo);
static_assert(sizeof(CTOS_PlayerInfo) == 40, "size mismatch: CTOS_PlayerInfo");
struct CTOS_CreateGame { struct CTOS_CreateGame {
HostInfo info; HostInfo info;
unsigned short name[20]; uint16_t name[20];
unsigned short pass[20]; uint16_t pass[20];
}; };
check_trivially_copyable(CTOS_CreateGame);
static_assert(sizeof(CTOS_CreateGame) == 100, "size mismatch: CTOS_CreateGame");
struct CTOS_JoinGame { struct CTOS_JoinGame {
unsigned short version; uint16_t version;
unsigned int gameid; // byte padding[2]
unsigned short pass[20];
uint32_t gameid;
uint16_t pass[20];
}; };
check_trivially_copyable(CTOS_JoinGame);
static_assert(sizeof(CTOS_JoinGame) == 48, "size mismatch: CTOS_JoinGame");
struct CTOS_Kick { struct CTOS_Kick {
unsigned char pos; unsigned char pos;
}; };
check_trivially_copyable(CTOS_Kick);
static_assert(sizeof(CTOS_Kick) == 1, "size mismatch: CTOS_Kick");
// STOC
struct STOC_ErrorMsg { struct STOC_ErrorMsg {
unsigned char msg; unsigned char msg;
unsigned int code; // byte padding[3]
uint32_t code;
}; };
check_trivially_copyable(STOC_ErrorMsg);
static_assert(sizeof(STOC_ErrorMsg) == 8, "size mismatch: STOC_ErrorMsg");
struct STOC_HandResult { struct STOC_HandResult {
unsigned char res1; unsigned char res1;
unsigned char res2; unsigned char res2;
}; };
check_trivially_copyable(STOC_HandResult);
static_assert(sizeof(STOC_HandResult) == 2, "size mismatch: STOC_HandResult");
struct STOC_CreateGame { struct STOC_CreateGame {
unsigned int gameid; uint32_t gameid;
}; };
check_trivially_copyable(STOC_CreateGame);
static_assert(sizeof(STOC_CreateGame) == 4, "size mismatch: STOC_CreateGame");
struct STOC_JoinGame { struct STOC_JoinGame {
HostInfo info; HostInfo info;
}; };
check_trivially_copyable(STOC_JoinGame);
static_assert(sizeof(STOC_JoinGame) == 20, "size mismatch: STOC_JoinGame");
struct STOC_TypeChange { struct STOC_TypeChange {
unsigned char type; unsigned char type;
}; };
check_trivially_copyable(STOC_TypeChange);
static_assert(sizeof(STOC_TypeChange) == 1, "size mismatch: STOC_TypeChange");
struct STOC_ExitGame { struct STOC_ExitGame {
unsigned char pos; unsigned char pos;
}; };
check_trivially_copyable(STOC_ExitGame);
static_assert(sizeof(STOC_ExitGame) == 1, "size mismatch: STOC_ExitGame");
struct STOC_TimeLimit { struct STOC_TimeLimit {
unsigned char player; unsigned char player;
unsigned short left_time; // byte padding[1]
};
struct STOC_Chat { uint16_t left_time;
unsigned short player;
unsigned short msg[256];
}; };
check_trivially_copyable(STOC_TimeLimit);
static_assert(sizeof(STOC_TimeLimit) == 4, "size mismatch: STOC_TimeLimit");
/*
* STOC_Chat
* uint16_t player_type;
* uint16_t msg[256]; (UTF-16 string)
*/
constexpr int LEN_CHAT_PLAYER = 1;
constexpr int LEN_CHAT_MSG = 256;
constexpr int SIZE_STOC_CHAT = (LEN_CHAT_PLAYER + LEN_CHAT_MSG) * sizeof(uint16_t);
struct STOC_HS_PlayerEnter { struct STOC_HS_PlayerEnter {
unsigned short name[20]; uint16_t name[20];
unsigned char pos; unsigned char pos;
// byte padding[1]
}; };
check_trivially_copyable(STOC_HS_PlayerEnter);
//static_assert(sizeof(STOC_HS_PlayerEnter) == 42, "size mismatch: STOC_HS_PlayerEnter");
constexpr int STOC_HS_PlayerEnter_size = 41; //workwround
struct STOC_HS_PlayerChange { struct STOC_HS_PlayerChange {
//pos<<4 | state //pos<<4 | state
unsigned char status; unsigned char status;
}; };
check_trivially_copyable(STOC_HS_PlayerChange);
static_assert(sizeof(STOC_HS_PlayerChange) == 1, "size mismatch: STOC_HS_PlayerChange");
struct STOC_HS_WatchChange { struct STOC_HS_WatchChange {
unsigned short watch_count; uint16_t watch_count;
}; };
check_trivially_copyable(STOC_HS_WatchChange);
static_assert(sizeof(STOC_HS_WatchChange) == 2, "size mismatch: STOC_HS_WatchChange");
class DuelMode; class DuelMode;
...@@ -108,18 +187,34 @@ struct DuelPlayer { ...@@ -108,18 +187,34 @@ struct DuelPlayer {
bufferevent* bev{ 0 }; bufferevent* bev{ 0 };
}; };
inline bool check_msg_size(int size) {
// empty string is not allowed
if (size < 2* sizeof(uint16_t))
return false;
if (size > LEN_CHAT_MSG * sizeof(uint16_t))
return false;
if (size % sizeof(uint16_t) != 0)
return false;
return true;
}
inline unsigned int GetPosition(unsigned char* qbuf, int offset) {
unsigned int info = 0;
std::memcpy(&info, qbuf + offset, sizeof info);
return info >> 24;
}
class DuelMode { class DuelMode {
public: public:
DuelMode(): host_player(nullptr), pduel(0), duel_stage(0) {}
virtual ~DuelMode() {} virtual ~DuelMode() {}
virtual void Chat(DuelPlayer* dp, void* pdata, int len) {} virtual void Chat(DuelPlayer* dp, unsigned char* pdata, int len) {}
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {} virtual void JoinGame(DuelPlayer* dp, unsigned char* pdata, bool is_creater) {}
virtual void LeaveGame(DuelPlayer* dp) {} virtual void LeaveGame(DuelPlayer* dp) {}
virtual void ToDuelist(DuelPlayer* dp) {} virtual void ToDuelist(DuelPlayer* dp) {}
virtual void ToObserver(DuelPlayer* dp) {} virtual void ToObserver(DuelPlayer* dp) {}
virtual void PlayerReady(DuelPlayer* dp, bool is_ready) {} virtual void PlayerReady(DuelPlayer* dp, bool is_ready) {}
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos) {} virtual void PlayerKick(DuelPlayer* dp, unsigned char pos) {}
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {} virtual void UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {}
virtual void StartDuel(DuelPlayer* dp) {} virtual void StartDuel(DuelPlayer* dp) {}
virtual void HandResult(DuelPlayer* dp, unsigned char res) {} virtual void HandResult(DuelPlayer* dp, unsigned char res) {}
virtual void TPResult(DuelPlayer* dp, unsigned char tp) {} virtual void TPResult(DuelPlayer* dp, unsigned char tp) {}
...@@ -128,21 +223,21 @@ public: ...@@ -128,21 +223,21 @@ public:
return 0; return 0;
} }
virtual void Surrender(DuelPlayer* dp) {} virtual void Surrender(DuelPlayer* dp) {}
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {} virtual void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) {}
virtual void TimeConfirm(DuelPlayer* dp) {} virtual void TimeConfirm(DuelPlayer* dp) {}
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp) {} virtual void RequestField(DuelPlayer* dp) {}
#endif #endif
virtual void EndDuel() {}; virtual void EndDuel() {}
public: public:
event* etimer; event* etimer { nullptr };
DuelPlayer* host_player; DuelPlayer* host_player{ nullptr };
HostInfo host_info; HostInfo host_info;
int duel_stage; int duel_stage{};
intptr_t pduel; intptr_t pduel{};
wchar_t name[20]; wchar_t name[20]{};
wchar_t pass[20]; wchar_t pass[20]{};
}; };
} }
......
...@@ -29,6 +29,9 @@ if SERVER_MODE then ...@@ -29,6 +29,9 @@ if SERVER_MODE then
if SERVER_PRO2_SUPPORT then if SERVER_PRO2_SUPPORT then
defines { "SERVER_PRO2_SUPPORT" } defines { "SERVER_PRO2_SUPPORT" }
end end
if SERVER_TAG_SURRENDER_CONFIRM then
defines { "SERVER_TAG_SURRENDER_CONFIRM" }
end
else else
kind "WindowedApp" kind "WindowedApp"
......
...@@ -273,6 +273,7 @@ void ReplayMode::EndDuel() { ...@@ -273,6 +273,7 @@ void ReplayMode::EndDuel() {
} }
void ReplayMode::Restart(bool refresh) { void ReplayMode::Restart(bool refresh) {
end_duel(pduel); end_duel(pduel);
mainGame->dInfo.isInDuel = false;
mainGame->dInfo.isStarted = false; mainGame->dInfo.isStarted = false;
mainGame->dInfo.isInDuel = false; mainGame->dInfo.isInDuel = false;
mainGame->dInfo.isFinished = true; mainGame->dInfo.isFinished = true;
...@@ -940,7 +941,7 @@ uint32 ReplayMode::MessageHandler(intptr_t fduel, uint32 type) { ...@@ -940,7 +941,7 @@ uint32 ReplayMode::MessageHandler(intptr_t fduel, uint32 type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
char msgbuf[1024]; char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf); get_log_message(fduel, msgbuf);
mainGame->AddDebugMsg(msgbuf); mainGame->AddDebugMsg(msgbuf);
return 0; return 0;
} }
......
...@@ -19,12 +19,12 @@ SingleDuel::SingleDuel(bool is_match) { ...@@ -19,12 +19,12 @@ SingleDuel::SingleDuel(bool is_match) {
} }
SingleDuel::~SingleDuel() { SingleDuel::~SingleDuel() {
} }
void SingleDuel::Chat(DuelPlayer* dp, void* pdata, int len) { void SingleDuel::Chat(DuelPlayer* dp, unsigned char* pdata, int len) {
STOC_Chat scc; unsigned char scc[SIZE_STOC_CHAT];
scc.player = dp->type; const auto scc_size = NetServer::CreateChatPacket(pdata, len, scc, dp->type);
unsigned short* msg = (unsigned short*)pdata; if (!scc_size)
int msglen = BufferIO::CopyWStr(msg, scc.msg, 256); return;
NetServer::SendBufferToPlayer(players[0], STOC_CHAT, &scc, 4 + msglen * 2); NetServer::SendBufferToPlayer(players[0], STOC_CHAT, scc, scc_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
...@@ -35,7 +35,7 @@ void SingleDuel::Chat(DuelPlayer* dp, void* pdata, int len) { ...@@ -35,7 +35,7 @@ void SingleDuel::Chat(DuelPlayer* dp, void* pdata, int len) {
NetServer::ReSendToPlayer(replay_recorder); NetServer::ReSendToPlayer(replay_recorder);
#endif #endif
} }
void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { void SingleDuel::JoinGame(DuelPlayer* dp, unsigned char* pdata, bool is_creater) {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
bool is_recorder = false; bool is_recorder = false;
#endif #endif
...@@ -48,7 +48,9 @@ void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { ...@@ -48,7 +48,9 @@ void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
return; return;
} }
CTOS_JoinGame* pkt = (CTOS_JoinGame*)pdata; CTOS_JoinGame packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
if(pkt->version != PRO_VERSION) { if(pkt->version != PRO_VERSION) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_VERERROR; scem.msg = ERRMSG_VERERROR;
...@@ -386,25 +388,35 @@ void SingleDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) { ...@@ -386,25 +388,35 @@ void SingleDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
return; return;
LeaveGame(players[pos]); LeaveGame(players[pos]);
} }
void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) { void SingleDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
if(dp->type > 1 || ready[dp->type]) if(dp->type > 1 || ready[dp->type])
return; return;
unsigned char* deckbuf = (unsigned char*)pdata; if (len < 8)
return;
bool valid = true;
auto deckbuf = pdata;
int mainc = BufferIO::ReadInt32(deckbuf); int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf); int sidec = BufferIO::ReadInt32(deckbuf);
// verify data const int deck_size = len - 2 * sizeof(int32_t);
const unsigned int possibleMaxLength = (len - 8) / 4; if (mainc < 0 || mainc > MAINC_MAX)
if((unsigned)mainc > possibleMaxLength || (unsigned)sidec > possibleMaxLength || (unsigned)mainc + (unsigned)sidec > possibleMaxLength) { valid = false;
else if (sidec < 0 || sidec > SIDEC_MAX)
valid = false;
else if (deck_size != (mainc + sidec) * (int)sizeof(int32_t))
valid = false;
if (!valid) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR; scem.msg = ERRMSG_DECKERROR;
scem.code = 0; scem.code = 0;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
int deck_list[SIZE_NETWORK_BUFFER / sizeof(int32_t)];
std::memcpy(deck_list, deckbuf, deck_size);
if(duel_count == 0) { if(duel_count == 0) {
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec); deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], deck_list, mainc, sidec);
} else { } else {
if(deckManager.LoadSide(pdeck[dp->type], (int*)deckbuf, mainc, sidec)) { if(deckManager.LoadSide(pdeck[dp->type], deck_list, mainc, sidec)) {
ready[dp->type] = true; ready[dp->type] = true;
NetServer::SendPacketToPlayer(dp, STOC_DUEL_START); NetServer::SendPacketToPlayer(dp, STOC_DUEL_START);
if(ready[0] && ready[1]) { if(ready[0] && ready[1]) {
...@@ -451,9 +463,9 @@ void SingleDuel::StartDuel(DuelPlayer* dp) { ...@@ -451,9 +463,9 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
BufferIO::WriteInt16(pbuf, (short)pdeck[1].side.size()); BufferIO::WriteInt16(pbuf, (short)pdeck[1].side.size());
NetServer::SendBufferToPlayer(players[0], STOC_DECK_COUNT, deckbuff, 12); NetServer::SendBufferToPlayer(players[0], STOC_DECK_COUNT, deckbuff, 12);
char tempbuff[6]; char tempbuff[6];
memcpy(tempbuff, deckbuff, 6); std::memcpy(tempbuff, deckbuff, 6);
memcpy(deckbuff, deckbuff + 6, 6); std::memcpy(deckbuff, deckbuff + 6, 6);
memcpy(deckbuff + 6, tempbuff, 6); std::memcpy(deckbuff + 6, tempbuff, 6);
NetServer::SendBufferToPlayer(players[1], STOC_DECK_COUNT, deckbuff, 12); NetServer::SendBufferToPlayer(players[1], STOC_DECK_COUNT, deckbuff, 12);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND); NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
...@@ -554,11 +566,11 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -554,11 +566,11 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
set_card_reader(DataManager::CardReader); set_card_reader(DataManager::CardReader);
set_message_handler(SingleDuel::MessageHandler); set_message_handler(SingleDuel::MessageHandler);
pduel = create_duel(duel_seed); pduel = create_duel(duel_seed);
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0); preload_script(pduel, "./script/special.lua", 0);
#endif #endif
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16; int opt = (int)host_info.duel_rule << 16;
if(host_info.no_shuffle_deck) if(host_info.no_shuffle_deck)
opt |= DUEL_PSEUDO_SHUFFLE; opt |= DUEL_PSEUDO_SHUFFLE;
...@@ -1767,11 +1779,11 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) { ...@@ -1767,11 +1779,11 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
} }
return 0; return 0;
} }
void SingleDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { void SingleDuel::GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) {
byte resb[SIZE_RETURN_VALUE]; byte resb[SIZE_RETURN_VALUE];
if (len > SIZE_RETURN_VALUE) if (len > SIZE_RETURN_VALUE)
len = SIZE_RETURN_VALUE; len = SIZE_RETURN_VALUE;
memcpy(resb, pdata, len); std::memcpy(resb, pdata, len);
last_replay.WriteInt8(len); last_replay.WriteInt8(len);
last_replay.WriteData(resb, len); last_replay.WriteData(resb, len);
set_responseb(pduel, resb); set_responseb(pduel, resb);
...@@ -1796,9 +1808,9 @@ void SingleDuel::EndDuel() { ...@@ -1796,9 +1808,9 @@ void SingleDuel::EndDuel() {
return; return;
last_replay.EndRecord(); last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); std::memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader));
pbuf += sizeof(ReplayHeader); pbuf += sizeof(ReplayHeader);
memcpy(pbuf, last_replay.comp_data, last_replay.comp_size); std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size); NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -1921,10 +1933,6 @@ inline int SingleDuel::WriteUpdateData(int& player, int location, int& flag, uns ...@@ -1921,10 +1933,6 @@ inline int SingleDuel::WriteUpdateData(int& player, int location, int& flag, uns
int len = query_field_card(pduel, player, location, flag, qbuf, use_cache); int len = query_field_card(pduel, player, location, flag, qbuf, use_cache);
return len; return len;
} }
inline unsigned int GetPosition(unsigned char*& qbuf, int offset) {
unsigned int info = *(unsigned int*)(qbuf + offset);
return info >> 24;
}
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
void SingleDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp) void SingleDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp)
#else #else
...@@ -2179,7 +2187,7 @@ uint32 SingleDuel::MessageHandler(intptr_t fduel, uint32 type) { ...@@ -2179,7 +2187,7 @@ uint32 SingleDuel::MessageHandler(intptr_t fduel, uint32 type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
char msgbuf[1024]; char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf); get_log_message(fduel, msgbuf);
mainGame->AddDebugMsg(msgbuf); mainGame->AddDebugMsg(msgbuf);
return 0; return 0;
} }
......
...@@ -11,21 +11,21 @@ class SingleDuel: public DuelMode { ...@@ -11,21 +11,21 @@ class SingleDuel: public DuelMode {
public: public:
SingleDuel(bool is_match); SingleDuel(bool is_match);
virtual ~SingleDuel(); virtual ~SingleDuel();
virtual void Chat(DuelPlayer* dp, void* pdata, int len); virtual void Chat(DuelPlayer* dp, unsigned char* pdata, int len);
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater); virtual void JoinGame(DuelPlayer* dp, unsigned char* pdata, bool is_creater);
virtual void LeaveGame(DuelPlayer* dp); virtual void LeaveGame(DuelPlayer* dp);
virtual void ToDuelist(DuelPlayer* dp); virtual void ToDuelist(DuelPlayer* dp);
virtual void ToObserver(DuelPlayer* dp); virtual void ToObserver(DuelPlayer* dp);
virtual void PlayerReady(DuelPlayer* dp, bool ready); virtual void PlayerReady(DuelPlayer* dp, bool ready);
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos); virtual void PlayerKick(DuelPlayer* dp, unsigned char pos);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len); virtual void UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len);
virtual void StartDuel(DuelPlayer* dp); virtual void StartDuel(DuelPlayer* dp);
virtual void HandResult(DuelPlayer* dp, unsigned char res); virtual void HandResult(DuelPlayer* dp, unsigned char res);
virtual void TPResult(DuelPlayer* dp, unsigned char tp); virtual void TPResult(DuelPlayer* dp, unsigned char tp);
virtual void Process(); virtual void Process();
virtual void Surrender(DuelPlayer* dp); virtual void Surrender(DuelPlayer* dp);
virtual int Analyze(unsigned char* msgbuffer, unsigned int len); virtual int Analyze(unsigned char* msgbuffer, unsigned int len);
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len); virtual void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len);
virtual void TimeConfirm(DuelPlayer* dp); virtual void TimeConfirm(DuelPlayer* dp);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp); virtual void RequestField(DuelPlayer* dp);
......
...@@ -751,7 +751,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) { ...@@ -751,7 +751,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) {
int len = BufferIO::ReadInt16(pbuf); int len = BufferIO::ReadInt16(pbuf);
auto begin = pbuf; auto begin = pbuf;
pbuf += len + 1; pbuf += len + 1;
memcpy(namebuf, begin, len + 1); std::memcpy(namebuf, begin, len + 1);
BufferIO::DecodeUTF8(namebuf, wname); BufferIO::DecodeUTF8(namebuf, wname);
BufferIO::CopyWStr(wname, mainGame->dInfo.clientname, 20); BufferIO::CopyWStr(wname, mainGame->dInfo.clientname, 20);
break; break;
...@@ -762,7 +762,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) { ...@@ -762,7 +762,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) {
int len = BufferIO::ReadInt16(pbuf); int len = BufferIO::ReadInt16(pbuf);
auto begin = pbuf; auto begin = pbuf;
pbuf += len + 1; pbuf += len + 1;
memcpy(msgbuf, begin, len + 1); std::memcpy(msgbuf, begin, len + 1);
BufferIO::DecodeUTF8(msgbuf, msg); BufferIO::DecodeUTF8(msgbuf, msg);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->guiFont, msg); mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->guiFont, msg);
...@@ -836,7 +836,7 @@ uint32 SingleMode::MessageHandler(intptr_t fduel, uint32 type) { ...@@ -836,7 +836,7 @@ uint32 SingleMode::MessageHandler(intptr_t fduel, uint32 type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
char msgbuf[1024]; char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf); get_log_message(fduel, msgbuf);
mainGame->AddDebugMsg(msgbuf); mainGame->AddDebugMsg(msgbuf);
return 0; return 0;
} }
......
...@@ -23,13 +23,13 @@ TagDuel::TagDuel() { ...@@ -23,13 +23,13 @@ TagDuel::TagDuel() {
} }
TagDuel::~TagDuel() { TagDuel::~TagDuel() {
} }
void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) { void TagDuel::Chat(DuelPlayer* dp, unsigned char* pdata, int len) {
STOC_Chat scc; unsigned char scc[SIZE_STOC_CHAT];
scc.player = dp->type; const auto scc_size = NetServer::CreateChatPacket(pdata, len, scc, dp->type);
unsigned short* msg = (unsigned short*)pdata; if (!scc_size)
int msglen = BufferIO::CopyWStr(msg, scc.msg, 256); return;
for(int i = 0; i < 4; ++i) for(int i = 0; i < 4; ++i)
NetServer::SendBufferToPlayer(players[i], STOC_CHAT, &scc, 4 + msglen * 2); NetServer::SendBufferToPlayer(players[i], STOC_CHAT, scc, scc_size);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -39,7 +39,7 @@ void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) { ...@@ -39,7 +39,7 @@ void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) {
NetServer::ReSendToPlayer(replay_recorder); NetServer::ReSendToPlayer(replay_recorder);
#endif #endif
} }
void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { void TagDuel::JoinGame(DuelPlayer* dp, unsigned char* pdata, bool is_creater) {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
bool is_recorder = false; bool is_recorder = false;
#endif #endif
...@@ -52,7 +52,9 @@ void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { ...@@ -52,7 +52,9 @@ void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
return; return;
} }
CTOS_JoinGame* pkt = (CTOS_JoinGame*)pdata; CTOS_JoinGame packet;
std::memcpy(&packet, pdata, sizeof packet);
const auto* pkt = &packet;
if(pkt->version != PRO_VERSION) { if(pkt->version != PRO_VERSION) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_VERERROR; scem.msg = ERRMSG_VERERROR;
...@@ -372,22 +374,32 @@ void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) { ...@@ -372,22 +374,32 @@ void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
return; return;
LeaveGame(players[pos]); LeaveGame(players[pos]);
} }
void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) { void TagDuel::UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len) {
if(dp->type > 3 || ready[dp->type]) if(dp->type > 3 || ready[dp->type])
return; return;
unsigned char* deckbuf = (unsigned char*)pdata; if (len < 8)
return;
bool valid = true;
auto deckbuf = pdata;
int mainc = BufferIO::ReadInt32(deckbuf); int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf); int sidec = BufferIO::ReadInt32(deckbuf);
// verify data const int deck_size = len - 2 * sizeof(int32_t);
const unsigned int possibleMaxLength = (len - 8) / 4; if (mainc < 0 || mainc > MAINC_MAX)
if((unsigned)mainc > possibleMaxLength || (unsigned)sidec > possibleMaxLength || (unsigned)mainc + (unsigned)sidec > possibleMaxLength) { valid = false;
else if (sidec < 0 || sidec > SIDEC_MAX)
valid = false;
else if (deck_size != (mainc + sidec) * (int)sizeof(int32_t))
valid = false;
if (!valid) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR; scem.msg = ERRMSG_DECKERROR;
scem.code = 0; scem.code = 0;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec); 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);
} }
void TagDuel::StartDuel(DuelPlayer* dp) { void TagDuel::StartDuel(DuelPlayer* dp) {
if(dp != host_player) if(dp != host_player)
...@@ -420,9 +432,9 @@ void TagDuel::StartDuel(DuelPlayer* dp) { ...@@ -420,9 +432,9 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
NetServer::SendBufferToPlayer(players[0], STOC_DECK_COUNT, deckbuff, 12); NetServer::SendBufferToPlayer(players[0], STOC_DECK_COUNT, deckbuff, 12);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
char tempbuff[6]; char tempbuff[6];
memcpy(tempbuff, deckbuff, 6); std::memcpy(tempbuff, deckbuff, 6);
memcpy(deckbuff, deckbuff + 6, 6); std::memcpy(deckbuff, deckbuff + 6, 6);
memcpy(deckbuff + 6, tempbuff, 6); std::memcpy(deckbuff + 6, tempbuff, 6);
NetServer::SendBufferToPlayer(players[2], STOC_DECK_COUNT, deckbuff, 12); NetServer::SendBufferToPlayer(players[2], STOC_DECK_COUNT, deckbuff, 12);
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND); NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND);
...@@ -679,7 +691,7 @@ void TagDuel::Surrender(DuelPlayer* dp) { ...@@ -679,7 +691,7 @@ void TagDuel::Surrender(DuelPlayer* dp) {
if(dp->type > 3 || !pduel) if(dp->type > 3 || !pduel)
return; return;
uint32 player = dp->type; uint32 player = dp->type;
#if !defined(YGOPRO_SERVER_MODE) || defined(YGOPRO_TAG_SURRENDER_CONFIRM) #if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_TAG_SURRENDER_CONFIRM)
if(surrender[player]) if(surrender[player])
return; return;
static const uint32 teammatemap[] = { 1, 0, 3, 2 }; static const uint32 teammatemap[] = { 1, 0, 3, 2 };
...@@ -1870,11 +1882,11 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) { ...@@ -1870,11 +1882,11 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
} }
return 0; return 0;
} }
void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { void TagDuel::GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) {
byte resb[SIZE_RETURN_VALUE]; byte resb[SIZE_RETURN_VALUE];
if (len > SIZE_RETURN_VALUE) if (len > SIZE_RETURN_VALUE)
len = SIZE_RETURN_VALUE; len = SIZE_RETURN_VALUE;
memcpy(resb, pdata, len); std::memcpy(resb, pdata, len);
last_replay.WriteInt8(len); last_replay.WriteInt8(len);
last_replay.WriteData(resb, len); last_replay.WriteData(resb, len);
set_responseb(pduel, resb); set_responseb(pduel, resb);
...@@ -1900,9 +1912,9 @@ void TagDuel::EndDuel() { ...@@ -1900,9 +1912,9 @@ void TagDuel::EndDuel() {
return; return;
last_replay.EndRecord(); last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); std::memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader));
pbuf += sizeof(ReplayHeader); pbuf += sizeof(ReplayHeader);
memcpy(pbuf, last_replay.comp_data, last_replay.comp_size); std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size); NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]); NetServer::ReSendToPlayer(players[2]);
...@@ -2031,10 +2043,6 @@ inline int TagDuel::WriteUpdateData(int& player, int location, int& flag, unsign ...@@ -2031,10 +2043,6 @@ inline int TagDuel::WriteUpdateData(int& player, int location, int& flag, unsign
int len = query_field_card(pduel, player, location, flag, qbuf, use_cache); int len = query_field_card(pduel, player, location, flag, qbuf, use_cache);
return len; return len;
} }
inline unsigned int GetPosition(unsigned char*& qbuf, int offset) {
unsigned int info = *(unsigned int*)(qbuf + offset);
return info >> 24;
}
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
void TagDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp) void TagDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp)
#else #else
...@@ -2341,7 +2349,7 @@ uint32 TagDuel::MessageHandler(intptr_t fduel, uint32 type) { ...@@ -2341,7 +2349,7 @@ uint32 TagDuel::MessageHandler(intptr_t fduel, uint32 type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
char msgbuf[1024]; char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf); get_log_message(fduel, msgbuf);
mainGame->AddDebugMsg(msgbuf); mainGame->AddDebugMsg(msgbuf);
return 0; return 0;
} }
......
...@@ -11,21 +11,21 @@ class TagDuel: public DuelMode { ...@@ -11,21 +11,21 @@ class TagDuel: public DuelMode {
public: public:
TagDuel(); TagDuel();
virtual ~TagDuel(); virtual ~TagDuel();
virtual void Chat(DuelPlayer* dp, void* pdata, int len); virtual void Chat(DuelPlayer* dp, unsigned char* pdata, int len);
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater); virtual void JoinGame(DuelPlayer* dp, unsigned char* pdata, bool is_creater);
virtual void LeaveGame(DuelPlayer* dp); virtual void LeaveGame(DuelPlayer* dp);
virtual void ToDuelist(DuelPlayer* dp); virtual void ToDuelist(DuelPlayer* dp);
virtual void ToObserver(DuelPlayer* dp); virtual void ToObserver(DuelPlayer* dp);
virtual void PlayerReady(DuelPlayer* dp, bool ready); virtual void PlayerReady(DuelPlayer* dp, bool ready);
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos); virtual void PlayerKick(DuelPlayer* dp, unsigned char pos);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len); virtual void UpdateDeck(DuelPlayer* dp, unsigned char* pdata, int len);
virtual void StartDuel(DuelPlayer* dp); virtual void StartDuel(DuelPlayer* dp);
virtual void HandResult(DuelPlayer* dp, unsigned char res); virtual void HandResult(DuelPlayer* dp, unsigned char res);
virtual void TPResult(DuelPlayer* dp, unsigned char tp); virtual void TPResult(DuelPlayer* dp, unsigned char tp);
virtual void Process(); virtual void Process();
virtual void Surrender(DuelPlayer* dp); virtual void Surrender(DuelPlayer* dp);
virtual int Analyze(unsigned char* msgbuffer, unsigned int len); virtual int Analyze(unsigned char* msgbuffer, unsigned int len);
virtual void GetResponse(DuelPlayer* dp, void* pdata, unsigned int len); virtual void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len);
virtual void TimeConfirm(DuelPlayer* dp); virtual void TimeConfirm(DuelPlayer* dp);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
virtual void RequestField(DuelPlayer* dp); virtual void RequestField(DuelPlayer* dp);
......
Subproject commit 4367d7a0f8ef432a1564f9c804926f9fc6af997b Subproject commit 74520eb0c3980f3eb3b49147d11c402af4b28ae7
...@@ -12,6 +12,7 @@ LUA_LIB_NAME = "lua" ...@@ -12,6 +12,7 @@ LUA_LIB_NAME = "lua"
SERVER_MODE = true SERVER_MODE = true
SERVER_ZIP_SUPPORT = false SERVER_ZIP_SUPPORT = false
SERVER_PRO2_SUPPORT = false SERVER_PRO2_SUPPORT = false
SERVER_TAG_SURRENDER_CONFIRM = false
USE_IRRKLANG = false USE_IRRKLANG = false
-- read settings from command line or environment variables -- read settings from command line or environment variables
...@@ -60,11 +61,11 @@ newoption { trigger = "mac-arm", category = "YGOPro", description = "M1" } ...@@ -60,11 +61,11 @@ newoption { trigger = "mac-arm", category = "YGOPro", description = "M1" }
newoption { trigger = "server-mode", category = "YGOPro - server", description = "" } newoption { trigger = "server-mode", category = "YGOPro - server", description = "" }
newoption { trigger = "server-zip-support", category = "YGOPro - server", description = "" } newoption { trigger = "server-zip-support", category = "YGOPro - server", description = "" }
newoption { trigger = "server-pro2-support", category = "YGOPro - server", description = "" } newoption { trigger = "server-pro2-support", category = "YGOPro - server", description = "" }
newoption { trigger = "server-tag-surrender-confirm", category = "YGOPro - server", description = "" }
boolOptions = { boolOptions = {
"no-lua-safe", "no-lua-safe",
"no-side-check", "no-side-check"
"tag-surrender-confirm"
} }
for _, boolOption in ipairs(boolOptions) do for _, boolOption in ipairs(boolOptions) do
...@@ -205,7 +206,6 @@ if GetParam("mac-arm") and os.istarget("macosx") then ...@@ -205,7 +206,6 @@ if GetParam("mac-arm") and os.istarget("macosx") then
end end
if GetParam("server-mode") then if GetParam("server-mode") then
SERVER_MODE = true SERVER_MODE = true
SERVER_ZIP_SUPPORT = false
end end
if GetParam("server-zip-support") then if GetParam("server-zip-support") then
SERVER_ZIP_SUPPORT = true SERVER_ZIP_SUPPORT = true
...@@ -214,6 +214,9 @@ if GetParam("server-pro2-support") then ...@@ -214,6 +214,9 @@ if GetParam("server-pro2-support") then
SERVER_PRO2_SUPPORT = true SERVER_PRO2_SUPPORT = true
SERVER_ZIP_SUPPORT = true SERVER_ZIP_SUPPORT = true
end end
if GetParam("server-tag-surrender-confirm") then
SERVER_TAG_SURRENDER_CONFIRM = true
end
workspace "YGOPro" workspace "YGOPro"
location "build" location "build"
......
Subproject commit 1c6ce6ed259e832a860d5333fb79075ee7a8132e Subproject commit c5271c21b3bdd1789e29fc09e83af44c8ff537bb
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