Commit a33a7706 authored by nanahira's avatar nanahira

Merge branch 'master' of github.com:Fluorohydride/ygopro

parents ff5212d2 6641bb30
......@@ -1304,13 +1304,6 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se
|| check_sum(index, end, acc, count);
}
template <class T>
static bool is_declarable(T const& cd, int declarable_type) {
if(!(cd.type & declarable_type))
return false;
return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN));
}
template <class T>
static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
std::stack<int> stack;
for(auto it = opcode.begin(); it != opcode.end(); ++it) {
......@@ -1451,57 +1444,12 @@ static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN));
}
void ClientField::UpdateDeclarableCodeType() {
const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname);
CardString cstr;
CardData cd;
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
mainGame->lstANCard->clear();
ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(trycode);
return;
}
bool try_cache = false;
if(pname[0] == 0) {
try_cache = true;
}
mainGame->lstANCard->clear();
ancard.clear();
if(try_cache && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[i];
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, declarable_type)) {
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(cache_code);
}
}
if(ancard.size())
return;
}
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos || mainGame->CheckRegEx(cit->second.name, pname)) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias
if(is_declarable(cp->second, declarable_type)) {
if(pname == cit->second.name || mainGame->CheckRegEx(cit->second.name, pname, true)) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
} else {
mainGame->lstANCard->addItem(cit->second.name.c_str());
ancard.push_back(cit->first);
}
}
}
}
}
void ClientField::UpdateDeclarableCodeOpcode() {
void ClientField::UpdateDeclarableList() {
const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname);
CardString cstr;
CardData cd;
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
mainGame->lstANCard->clear();
ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str());
......@@ -1517,7 +1465,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(try_cache && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[i];
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, opcode)) {
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, declare_opcodes)) {
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(cache_code);
}
......@@ -1529,7 +1477,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(cit->second.name.find(pname) != std::wstring::npos || mainGame->CheckRegEx(cit->second.name, pname)) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias
if(is_declarable(cp->second, opcode)) {
if(is_declarable(cp->second, declare_opcodes)) {
if(pname == cit->second.name || mainGame->CheckRegEx(cit->second.name, pname, true)) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
......@@ -1541,12 +1489,6 @@ void ClientField::UpdateDeclarableCodeOpcode() {
}
}
}
void ClientField::UpdateDeclarableCode() {
if(opcode.size() == 0)
UpdateDeclarableCodeType();
else
UpdateDeclarableCodeOpcode();
}
void ClientField::RefreshCardCountDisplay() {
ClientCard* pcard;
for(int p = 0; p < 2; ++p) {
......
......@@ -61,14 +61,13 @@ public:
bool select_panalmode;
bool select_ready;
int announce_count;
int declarable_type;
int select_counter_count;
int select_counter_type;
std::vector<ClientCard*> selectable_cards;
std::vector<ClientCard*> selected_cards;
std::set<ClientCard*> selectsum_cards;
std::vector<ClientCard*> selectsum_all;
std::vector<int> opcode;
std::vector<int> declare_opcodes;
std::vector<ClientCard*> display_cards;
std::vector<int> sort_list;
std::map<int, int> player_desc_hints[2];
......@@ -113,9 +112,7 @@ public:
void check_sel_sum_t(const std::set<ClientCard*>& left, int acc);
bool check_sum(std::set<ClientCard*>::const_iterator index, std::set<ClientCard*>::const_iterator end, int acc, int count);
void UpdateDeclarableCodeType();
void UpdateDeclarableCodeOpcode();
void UpdateDeclarableCode();
void UpdateDeclarableList();
void RefreshCardCountDisplay();
......
......@@ -23,6 +23,7 @@ bufferevent* DuelClient::client_bev = 0;
char DuelClient::duel_client_read[0x2000];
char DuelClient::duel_client_write[0x2000];
bool DuelClient::is_closing = false;
bool DuelClient::is_swapping = false;
int DuelClient::select_hint = 0;
int DuelClient::select_unselect_hint = 0;
int DuelClient::last_select_hint = 0;
......@@ -958,7 +959,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
}
}
}
int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
char* pbuf = msg;
wchar_t textBuffer[256];
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
......@@ -985,6 +986,12 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
}
if(mainGame->dInfo.time_player == 1)
mainGame->dInfo.time_player = 2;
if(is_swapping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swapping = false;
}
switch(mainGame->dInfo.curMsg) {
case MSG_RETRY: {
if(last_successful_msg_length) {
......@@ -993,7 +1000,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
int err_desc = 1421;
switch(last_msg) {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_CARD_FILTER:
err_desc = 1422;
break;
case MSG_ANNOUNCE_ATTRIB:
......@@ -2320,8 +2326,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
}
mainGame->WaitFrameSignal(11);
}
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit)
for(auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->SetCode(BufferIO::ReadInt32(pbuf));
(*cit)->desc_hints.clear();
}
if(!mainGame->dInfo.isReplaySkiping) {
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->is_hovered = false;
......@@ -3642,8 +3650,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
}
case MSG_ANNOUNCE_CARD: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
mainGame->dField.declarable_type = BufferIO::ReadInt32(pbuf);
mainGame->dField.opcode.clear();
int count = BufferIO::ReadUInt8(pbuf);
mainGame->dField.declare_opcodes.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.declare_opcodes.push_back(BufferIO::ReadInt32(pbuf));
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(564));
......@@ -3651,7 +3661,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode();
mainGame->dField.UpdateDeclarableList();
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
......@@ -3676,25 +3686,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
mainGame->gMutex.Unlock();
return false;
}
case MSG_ANNOUNCE_CARD_FILTER: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int count = BufferIO::ReadUInt8(pbuf);
mainGame->dField.declarable_type = 0;
mainGame->dField.opcode.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.opcode.push_back(BufferIO::ReadInt32(pbuf));
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(564));
select_hint = 0;
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode();
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
}
case MSG_CARD_HINT: {
int c = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int l = BufferIO::ReadInt8(pbuf);
......@@ -3979,6 +3970,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
}
return true;
}
void DuelClient::SwapField() {
is_swapping = true;
}
void DuelClient::SetResponseI(int respI) {
*((int*)response_buf) = respI;
response_len = 4;
......@@ -4063,24 +4057,45 @@ void DuelClient::BeginRefreshHost() {
if(!host)
return;
SOCKET reply = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
BOOL opt = TRUE;
setsockopt(reply, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
sockaddr_in reply_addr;
memset(&reply_addr, 0, sizeof(reply_addr));
reply_addr.sin_family = AF_INET;
reply_addr.sin_port = htons(7921);
reply_addr.sin_addr.s_addr = 0;
if(bind(reply, (sockaddr*)&reply_addr, sizeof(reply_addr)) == SOCKET_ERROR) {
closesocket(reply);
return;
}
timeval timeout = {3, 0};
resp_event = event_new(broadev, reply, EV_TIMEOUT | EV_READ | EV_PERSIST, BroadcastReply, broadev);
event_add(resp_event, &timeout);
Thread::NewThread(RefreshThread, broadev);
//send request
SOCKADDR_IN sockTo = {};
SOCKADDR_IN local;
local.sin_family = AF_INET;
local.sin_port = htons(7922);
SOCKADDR_IN sockTo;
sockTo.sin_addr.s_addr = htonl(INADDR_BROADCAST);
sockTo.sin_family = AF_INET;
sockTo.sin_port = htons(7911);
sockTo.sin_port = htons(7920);
HostRequest hReq;
hReq.identifier = NETWORK_CLIENT_ID;
for(int i = 0; i < 8; ++i) {
if(host->h_addr_list[i] == 0)
break;
unsigned int local_addr = *(unsigned int*)host->h_addr_list[i];
sockTo.sin_addr.s_addr = local_addr;
sendto(reply, (const char*)&hReq, sizeof(HostRequest), 0, (sockaddr*)&sockTo, sizeof(sockaddr));
local.sin_addr.s_addr = local_addr;
SOCKET sSend = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sSend == INVALID_SOCKET)
break;
BOOL opt = TRUE;
setsockopt(sSend, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
if(bind(sSend, (sockaddr*)&local, sizeof(sockaddr)) == SOCKET_ERROR) {
closesocket(sSend);
break;
}
sendto(sSend, (const char*)&hReq, sizeof(HostRequest), 0, (sockaddr*)&sockTo, sizeof(sockaddr));
closesocket(sSend);
}
}
int DuelClient::RefreshThread(void * arg) {
......
......@@ -29,6 +29,7 @@ private:
static char duel_client_read[0x2000];
static char duel_client_write[0x2000];
static bool is_closing;
static bool is_swapping;
static int select_hint;
static int select_unselect_hint;
static int last_select_hint;
......@@ -49,7 +50,8 @@ public:
static void ClientEvent(bufferevent *bev, short events, void *ctx);
static int ClientThread(void* param);
static void HandleSTOCPacketLan(char* data, unsigned int len);
static int ClientAnalyze(char* msg, unsigned int len, bool retry = false);
static int ClientAnalyze(char* msg, unsigned int len);
static void SwapField();
static void SetResponseI(int respI);
static void SetResponseB(void* respB, unsigned char len);
static void SendResponse();
......
......@@ -91,8 +91,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
soundManager.PlaySoundEffect(SOUND_BUTTON);
if(mainGame->dInfo.isReplay)
ReplayMode::SwapField();
else if (mainGame->dInfo.player_type == 7)
mainGame->dField.ReplaySwap();
else if(mainGame->dInfo.player_type == 7)
DuelClient::SwapField();
break;
}
case BUTTON_REPLAY_UNDO: {
......@@ -966,7 +966,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......@@ -975,7 +975,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_ENTER: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......
......@@ -12,7 +12,7 @@
#include <sstream>
#include <regex>
unsigned short PRO_VERSION = 0x134A;
unsigned short PRO_VERSION = 0x134B;
namespace ygo {
......
......@@ -40,11 +40,13 @@ bool NetServer::StartBroadcast() {
if(!net_evbase)
return false;
SOCKET udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
BOOL opt = TRUE;
setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(7911);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(7920);
addr.sin_addr.s_addr = 0;
if(bind(udp, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
closesocket(udp);
return false;
......@@ -83,13 +85,17 @@ void NetServer::BroadcastEvent(evutil_socket_t fd, short events, void* arg) {
return;
HostRequest* pHR = (HostRequest*)buf;
if(pHR->identifier == NETWORK_CLIENT_ID) {
SOCKADDR_IN sockTo;
sockTo.sin_addr.s_addr = bc_addr.sin_addr.s_addr;
sockTo.sin_family = AF_INET;
sockTo.sin_port = htons(7921);
HostPacket hp;
hp.identifier = NETWORK_SERVER_ID;
hp.port = server_port;
hp.version = PRO_VERSION;
hp.host = duel_mode->host_info;
BufferIO::CopyWStr(duel_mode->name, hp.name, 20);
sendto(fd, (const char*)&hp, sizeof(HostPacket), 0, (sockaddr*)&bc_addr, sz);
sendto(fd, (const char*)&hp, sizeof(HostPacket), 0, (sockaddr*)&sockTo, sizeof(sockTo));
}
}
void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx) {
......
......@@ -114,7 +114,7 @@ struct DuelPlayer {
class DuelMode {
public:
DuelMode(): host_player(0), pduel(0) {}
DuelMode(): host_player(0), pduel(0), duel_stage(0) {}
virtual ~DuelMode() {}
virtual void Chat(DuelPlayer* dp, void* pdata, int len) {}
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {}
......@@ -140,6 +140,7 @@ public:
event* etimer;
DuelPlayer* host_player;
HostInfo host_info;
int duel_stage;
unsigned long pduel;
wchar_t name[20];
wchar_t pass[20];
......@@ -220,4 +221,11 @@ public:
#define MODE_SINGLE 0x0
#define MODE_MATCH 0x1
#define MODE_TAG 0x2
#define DUEL_STAGE_BEGIN 0
#define DUEL_STAGE_FINGER 1
#define DUEL_STAGE_FIRSTGO 2
#define DUEL_STAGE_DUELING 3
#define DUEL_STAGE_SIDING 4
#define DUEL_STAGE_END 5
#endif //NETWORK_H
......@@ -774,13 +774,8 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -8,7 +8,6 @@
namespace ygo {
SingleDuel::SingleDuel(bool is_match) {
game_started = false;
match_mode = is_match;
match_kill = 0;
for(int i = 0; i < 2; ++i) {
......@@ -141,7 +140,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer();
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
if(players[0])
......@@ -153,7 +152,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started && duel_count == 0) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -166,26 +165,28 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_SIDING) {
if(!ready[0])
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
if(!ready[1])
NetServer::SendPacketToPlayer(players[1], STOC_DUEL_START);
}
unsigned char wbuf[3];
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - dp->type;
wbuf[2] = 0x4;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
if(duel_stage != DUEL_STAGE_END) {
unsigned char wbuf[3];
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - dp->type;
wbuf[2] = 0x4;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
}
NetServer::DisconnectPlayer(dp);
}
}
}
......@@ -306,6 +307,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP);
players[1 - tp_player]->state = 0xff;
players[tp_player]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
} else {
STOC_ErrorMsg scem;
......@@ -322,7 +324,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
return;
NetServer::StopListen();
//NetServer::StopBroadcast();
game_started = true;
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) {
......@@ -335,6 +336,7 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3)
......@@ -362,21 +364,24 @@ void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) {
NetServer::SendPacketToPlayer(players[1], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[1], STOC_SELECT_TP);
tp_player = 1;
players[0]->state = 0xff;
players[1]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[1]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
tp_player = 0;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -501,7 +506,7 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
int winc[3] = {0, 0, 0};
for(int i = 0; i < duel_count; ++i)
......@@ -514,7 +519,7 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
if(players[0] != pplayer[0]) {
players[0] = pplayer[0];
......@@ -533,6 +538,7 @@ void SingleDuel::DuelEndProc() {
NetServer::SendPacketToPlayer(players[1], STOC_CHANGE_SIDE);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendPacketToPlayer(*oit, STOC_WAITING_SIDE);
duel_stage = DUEL_STAGE_SIDING;
}
}
}
......@@ -1352,15 +1358,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
WaitforResponse(player);
pbuf += 4;
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -53,7 +53,6 @@ protected:
Replay last_replay;
bool match_mode;
int match_kill;
bool game_started;
unsigned char duel_count;
unsigned char tp_player;
unsigned char match_result[3];
......
......@@ -684,17 +684,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
}
break;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -8,7 +8,6 @@
namespace ygo {
TagDuel::TagDuel() {
game_started = false;
for(int i = 0; i < 4; ++i) {
players[i] = 0;
ready[i] = false;
......@@ -121,7 +120,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer();
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i)
......@@ -132,7 +131,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -143,10 +142,11 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
NetServer::DisconnectPlayer(dp);
} else {
} else if(duel_stage != DUEL_STAGE_END) {
EndDuel();
DuelEndProc();
}
NetServer::DisconnectPlayer(dp);
}
}
void TagDuel::ToDuelist(DuelPlayer* dp) {
......@@ -280,7 +280,6 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
if(!ready[0] || !ready[1] || !ready[2] || !ready[3])
return;
NetServer::StopListen();
game_started = true;
//NetServer::StopBroadcast();
for(int i = 0; i < 4; ++i)
NetServer::SendPacketToPlayer(players[i], STOC_DUEL_START);
......@@ -294,6 +293,7 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[2]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3 || dp->state != CTOS_HAND_RESULT)
......@@ -324,19 +324,22 @@ void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) {
NetServer::SendPacketToPlayer(players[2], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[2], STOC_SELECT_TP);
players[0]->state = 0xff;
players[2]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[2]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -504,7 +507,7 @@ void TagDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
}
void TagDuel::Surrender(DuelPlayer* dp) {
if(dp->type > 3 || !pduel)
......@@ -1424,15 +1427,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
WaitforResponse(player);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -52,7 +52,6 @@ protected:
unsigned char hand_result[2];
unsigned char last_response;
Replay last_replay;
bool game_started;
unsigned char turn_count;
unsigned short time_limit[2];
unsigned short time_elapsed;
......
......@@ -36,6 +36,7 @@
!system 64 二重状态
!system 65 使用效果
!system 66 持续公开
!system 67 原本持有者为对方
!system 70 怪兽卡
!system 71 魔法卡
!system 72 陷阱卡
......
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