Commit 0a59d7f0 authored by mycard's avatar mycard

Merge branch 'server' of https://github.com/purerosefallen/ygopro

parents dc2e5561 c39fc021
No preview for this file type
...@@ -1304,13 +1304,6 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se ...@@ -1304,13 +1304,6 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se
|| check_sum(index, end, acc, count); || check_sum(index, end, acc, count);
} }
template <class T> 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) { static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
std::stack<int> stack; std::stack<int> stack;
for(auto it = opcode.begin(); it != opcode.end(); ++it) { 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) { ...@@ -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 return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN)); || (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN));
} }
void ClientField::UpdateDeclarableCodeType() { 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, 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() {
const wchar_t* pname = mainGame->ebANCard->getText(); const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname); int trycode = BufferIO::GetVal(pname);
CardString cstr; CardString cstr;
CardData cd; 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(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str()); mainGame->lstANCard->addItem(cstr.name.c_str());
...@@ -1517,7 +1465,7 @@ void ClientField::UpdateDeclarableCodeOpcode() { ...@@ -1517,7 +1465,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(try_cache && mainGame->dInfo.announce_cache.size()) { if(try_cache && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) { for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[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()); mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(cache_code); ancard.push_back(cache_code);
} }
...@@ -1529,7 +1477,7 @@ void ClientField::UpdateDeclarableCodeOpcode() { ...@@ -1529,7 +1477,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(cit->second.name.find(pname) != std::wstring::npos || mainGame->CheckRegEx(cit->second.name, pname)) { if(cit->second.name.find(pname) != std::wstring::npos || mainGame->CheckRegEx(cit->second.name, pname)) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias //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 if(pname == cit->second.name || mainGame->CheckRegEx(cit->second.name, pname, true)) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1); mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first); ancard.insert(ancard.begin(), cit->first);
...@@ -1541,12 +1489,6 @@ void ClientField::UpdateDeclarableCodeOpcode() { ...@@ -1541,12 +1489,6 @@ void ClientField::UpdateDeclarableCodeOpcode() {
} }
} }
} }
void ClientField::UpdateDeclarableCode() {
if(opcode.size() == 0)
UpdateDeclarableCodeType();
else
UpdateDeclarableCodeOpcode();
}
void ClientField::RefreshCardCountDisplay() { void ClientField::RefreshCardCountDisplay() {
ClientCard* pcard; ClientCard* pcard;
for(int p = 0; p < 2; ++p) { for(int p = 0; p < 2; ++p) {
......
...@@ -61,14 +61,13 @@ public: ...@@ -61,14 +61,13 @@ public:
bool select_panalmode; bool select_panalmode;
bool select_ready; bool select_ready;
int announce_count; int announce_count;
int declarable_type;
int select_counter_count; int select_counter_count;
int select_counter_type; int select_counter_type;
std::vector<ClientCard*> selectable_cards; std::vector<ClientCard*> selectable_cards;
std::vector<ClientCard*> selected_cards; std::vector<ClientCard*> selected_cards;
std::set<ClientCard*> selectsum_cards; std::set<ClientCard*> selectsum_cards;
std::vector<ClientCard*> selectsum_all; std::vector<ClientCard*> selectsum_all;
std::vector<int> opcode; std::vector<int> declare_opcodes;
std::vector<ClientCard*> display_cards; std::vector<ClientCard*> display_cards;
std::vector<int> sort_list; std::vector<int> sort_list;
std::map<int, int> player_desc_hints[2]; std::map<int, int> player_desc_hints[2];
...@@ -113,9 +112,7 @@ public: ...@@ -113,9 +112,7 @@ public:
void check_sel_sum_t(const std::set<ClientCard*>& left, int acc); 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); bool check_sum(std::set<ClientCard*>::const_iterator index, std::set<ClientCard*>::const_iterator end, int acc, int count);
void UpdateDeclarableCodeType(); void UpdateDeclarableList();
void UpdateDeclarableCodeOpcode();
void UpdateDeclarableCode();
void RefreshCardCountDisplay(); void RefreshCardCountDisplay();
......
...@@ -23,6 +23,7 @@ bufferevent* DuelClient::client_bev = 0; ...@@ -23,6 +23,7 @@ bufferevent* DuelClient::client_bev = 0;
char DuelClient::duel_client_read[0x2000]; char DuelClient::duel_client_read[0x2000];
char DuelClient::duel_client_write[0x2000]; char DuelClient::duel_client_write[0x2000];
bool DuelClient::is_closing = false; bool DuelClient::is_closing = false;
bool DuelClient::is_swapping = false;
int DuelClient::select_hint = 0; int DuelClient::select_hint = 0;
int DuelClient::select_unselect_hint = 0; int DuelClient::select_unselect_hint = 0;
int DuelClient::last_select_hint = 0; int DuelClient::last_select_hint = 0;
...@@ -958,7 +959,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -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; char* pbuf = msg;
wchar_t textBuffer[256]; wchar_t textBuffer[256];
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf); mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
...@@ -985,17 +986,56 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -985,17 +986,56 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
} }
if(mainGame->dInfo.time_player == 1) if(mainGame->dInfo.time_player == 1)
mainGame->dInfo.time_player = 2; mainGame->dInfo.time_player = 2;
if(is_swapping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swapping = false;
}
switch(mainGame->dInfo.curMsg) { switch(mainGame->dInfo.curMsg) {
case MSG_RETRY: { case MSG_RETRY: {
if(last_successful_msg_length) { if(last_successful_msg_length) {
char* p = last_successful_msg; char* p = last_successful_msg;
auto last_msg = BufferIO::ReadUInt8(p); auto last_msg = BufferIO::ReadUInt8(p);
int err_desc = 1422; int err_desc = 1421;
switch(last_msg) { switch(last_msg) {
case MSG_ANNOUNCE_CARD: case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_CARD_FILTER: err_desc = 1422;
err_desc = 1421; break;
//TODO: other cases case MSG_ANNOUNCE_ATTRIB:
err_desc = 1423;
break;
case MSG_ANNOUNCE_RACE:
err_desc = 1424;
break;
case MSG_ANNOUNCE_NUMBER:
err_desc = 1425;
break;
case MSG_SELECT_EFFECTYN:
case MSG_SELECT_YESNO:
case MSG_SELECT_OPTION:
err_desc = 1426;
break;
case MSG_SELECT_CARD:
case MSG_SELECT_UNSELECT_CARD:
case MSG_SELECT_TRIBUTE:
case MSG_SELECT_SUM:
case MSG_SORT_CARD:
err_desc = 1427;
break;
case MSG_SELECT_CHAIN:
err_desc = 1428;
break;
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD:
err_desc = 1429;
break;
case MSG_SELECT_POSITION:
err_desc = 1430;
break;
case MSG_SELECT_COUNTER:
err_desc = 1431;
break;
default: default:
break; break;
} }
...@@ -2286,8 +2326,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -2286,8 +2326,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
} }
mainGame->WaitFrameSignal(11); 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)->SetCode(BufferIO::ReadInt32(pbuf));
(*cit)->desc_hints.clear();
}
if(!mainGame->dInfo.isReplaySkiping) { if(!mainGame->dInfo.isReplaySkiping) {
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)->is_hovered = false; (*cit)->is_hovered = false;
...@@ -3608,8 +3650,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -3608,8 +3650,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
} }
case MSG_ANNOUNCE_CARD: { case MSG_ANNOUNCE_CARD: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf)); /*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
mainGame->dField.declarable_type = BufferIO::ReadInt32(pbuf); int count = BufferIO::ReadUInt8(pbuf);
mainGame->dField.opcode.clear(); mainGame->dField.declare_opcodes.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.declare_opcodes.push_back(BufferIO::ReadInt32(pbuf));
if(select_hint) if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint)); myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(564)); else myswprintf(textBuffer, dataManager.GetSysString(564));
...@@ -3617,7 +3661,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -3617,7 +3661,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L""); mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer); mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode(); mainGame->dField.UpdateDeclarableList();
mainGame->PopupElement(mainGame->wANCard); mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
return false; return false;
...@@ -3642,25 +3686,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -3642,25 +3686,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
return false; 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: { case MSG_CARD_HINT: {
int c = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf)); int c = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int l = BufferIO::ReadInt8(pbuf); int l = BufferIO::ReadInt8(pbuf);
...@@ -3945,6 +3970,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) { ...@@ -3945,6 +3970,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len, bool retry) {
} }
return true; return true;
} }
void DuelClient::SwapField() {
is_swapping = true;
}
void DuelClient::SetResponseI(int respI) { void DuelClient::SetResponseI(int respI) {
*((int*)response_buf) = respI; *((int*)response_buf) = respI;
response_len = 4; response_len = 4;
......
...@@ -29,6 +29,7 @@ private: ...@@ -29,6 +29,7 @@ private:
static char duel_client_read[0x2000]; static char duel_client_read[0x2000];
static char duel_client_write[0x2000]; static char duel_client_write[0x2000];
static bool is_closing; static bool is_closing;
static bool is_swapping;
static int select_hint; static int select_hint;
static int select_unselect_hint; static int select_unselect_hint;
static int last_select_hint; static int last_select_hint;
...@@ -49,7 +50,8 @@ public: ...@@ -49,7 +50,8 @@ public:
static void ClientEvent(bufferevent *bev, short events, void *ctx); static void ClientEvent(bufferevent *bev, short events, void *ctx);
static int ClientThread(void* param); static int ClientThread(void* param);
static void HandleSTOCPacketLan(char* data, unsigned int len); 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 SetResponseI(int respI);
static void SetResponseB(void* respB, unsigned char len); static void SetResponseB(void* respB, unsigned char len);
static void SendResponse(); static void SendResponse();
......
...@@ -91,8 +91,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -91,8 +91,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
soundManager.PlaySoundEffect(SOUND_BUTTON); soundManager.PlaySoundEffect(SOUND_BUTTON);
if(mainGame->dInfo.isReplay) if(mainGame->dInfo.isReplay)
ReplayMode::SwapField(); ReplayMode::SwapField();
else if (mainGame->dInfo.player_type == 7) else if(mainGame->dInfo.player_type == 7)
mainGame->dField.ReplaySwap(); DuelClient::SwapField();
break; break;
} }
case BUTTON_REPLAY_UNDO: { case BUTTON_REPLAY_UNDO: {
...@@ -965,7 +965,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -965,7 +965,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: { case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) { switch(id) {
case EDITBOX_ANCARD: { case EDITBOX_ANCARD: {
UpdateDeclarableCode(); UpdateDeclarableList();
break; break;
} }
} }
...@@ -974,7 +974,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -974,7 +974,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_ENTER: { case irr::gui::EGET_EDITBOX_ENTER: {
switch(id) { switch(id) {
case EDITBOX_ANCARD: { case EDITBOX_ANCARD: {
UpdateDeclarableCode(); UpdateDeclarableList();
break; break;
} }
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <regex> #include <regex>
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
unsigned short PRO_VERSION = 0x134A; unsigned short PRO_VERSION = 0x134B;
namespace ygo { namespace ygo {
...@@ -153,7 +153,7 @@ bool Game::Initialize() { ...@@ -153,7 +153,7 @@ bool Game::Initialize() {
SetWindowsIcon(); SetWindowsIcon();
//main menu //main menu
wchar_t strbuf[256]; wchar_t strbuf[256];
myswprintf(strbuf, L"KoishiPro %X.0%X.%X Saigetsu", PRO_VERSION >> 12, (PRO_VERSION >> 4) & 0xff, PRO_VERSION & 0xf); myswprintf(strbuf, L"KoishiPro %X.0%X.%X Ayakashi", PRO_VERSION >> 12, (PRO_VERSION >> 4) & 0xff, PRO_VERSION & 0xf);
wMainMenu = env->addWindow(rect<s32>(370, 200, 650, 415), false, strbuf); wMainMenu = env->addWindow(rect<s32>(370, 200, 650, 415), false, strbuf);
wMainMenu->getCloseButton()->setVisible(false); wMainMenu->getCloseButton()->setVisible(false);
btnLanMode = env->addButton(rect<s32>(10, 30, 270, 60), wMainMenu, BUTTON_LAN_MODE, dataManager.GetSysString(1200)); btnLanMode = env->addButton(rect<s32>(10, 30, 270, 60), wMainMenu, BUTTON_LAN_MODE, dataManager.GetSysString(1200));
......
...@@ -117,7 +117,12 @@ void NetServer::StopServer() { ...@@ -117,7 +117,12 @@ void NetServer::StopServer() {
return; return;
if(duel_mode) if(duel_mode)
duel_mode->EndDuel(); duel_mode->EndDuel();
#ifdef YGOPRO_SERVER_MODE // For solving the problem of connection lost after duel. See https://github.com/Fluorohydride/ygopro/issues/2067 for details.
timeval etv = { 0, 1 };
event_base_loopexit(net_evbase, &etv);
#else
event_base_loopexit(net_evbase, 0); event_base_loopexit(net_evbase, 0);
#endif
} }
void NetServer::StopBroadcast() { void NetServer::StopBroadcast() {
if(!net_evbase || !broadcast_ev) if(!net_evbase || !broadcast_ev)
......
...@@ -114,7 +114,7 @@ struct DuelPlayer { ...@@ -114,7 +114,7 @@ struct DuelPlayer {
class DuelMode { class DuelMode {
public: public:
DuelMode(): host_player(0), pduel(0) {} DuelMode(): host_player(0), pduel(0), duel_stage(0) {}
virtual ~DuelMode() {} virtual ~DuelMode() {}
virtual void Chat(DuelPlayer* dp, void* pdata, int len) {} virtual void Chat(DuelPlayer* dp, void* pdata, int len) {}
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {} virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {}
...@@ -146,6 +146,7 @@ public: ...@@ -146,6 +146,7 @@ public:
event* etimer; event* etimer;
DuelPlayer* host_player; DuelPlayer* host_player;
HostInfo host_info; HostInfo host_info;
int duel_stage;
unsigned long pduel; unsigned long pduel;
wchar_t name[20]; wchar_t name[20];
wchar_t pass[20]; wchar_t pass[20];
...@@ -232,4 +233,11 @@ public: ...@@ -232,4 +233,11 @@ public:
#define MODE_SINGLE 0x0 #define MODE_SINGLE 0x0
#define MODE_MATCH 0x1 #define MODE_MATCH 0x1
#define MODE_TAG 0x2 #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 #endif //NETWORK_H
...@@ -101,6 +101,8 @@ int ReplayMode::ReplayThread(void* param) { ...@@ -101,6 +101,8 @@ int ReplayMode::ReplayThread(void* param) {
if(is_restarting) { if(is_restarting) {
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
is_restarting = false; is_restarting = false;
mainGame->dInfo.isReplaySkiping = true;
Restart(false);
int step = current_step - 1; int step = current_step - 1;
if(step < 0) if(step < 0)
step = 0; step = 0;
...@@ -109,10 +111,13 @@ int ReplayMode::ReplayThread(void* param) { ...@@ -109,10 +111,13 @@ int ReplayMode::ReplayThread(void* param) {
skip_step = 0; skip_step = 0;
int len = get_message(pduel, (byte*)engineBuffer); int len = get_message(pduel, (byte*)engineBuffer);
if (len > 0) { if (len > 0) {
mainGame->gMutex.Unlock();
is_continuing = ReplayAnalyze(engineBuffer, len); is_continuing = ReplayAnalyze(engineBuffer, len);
mainGame->gMutex.Lock();
} }
} else {
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
ReplayRefreshExtra(0);
ReplayRefreshExtra(1);
} }
if(step == 0) { if(step == 0) {
Pause(true, false); Pause(true, false);
...@@ -175,14 +180,14 @@ bool ReplayMode::StartDuel() { ...@@ -175,14 +180,14 @@ bool ReplayMode::StartDuel() {
int extra = cur_replay.ReadInt32(); int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i) for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(0, main, extra); mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32(); main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i) for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
extra = cur_replay.ReadInt32(); extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i) for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(1, main, extra); mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
} else { } else {
int main = cur_replay.ReadInt32(); int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i) for(int i = 0; i < main; ++i)
...@@ -190,7 +195,7 @@ bool ReplayMode::StartDuel() { ...@@ -190,7 +195,7 @@ bool ReplayMode::StartDuel() {
int extra = cur_replay.ReadInt32(); int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i) for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(0, main, extra); mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32(); main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i) for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK); new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK);
...@@ -203,7 +208,7 @@ bool ReplayMode::StartDuel() { ...@@ -203,7 +208,7 @@ bool ReplayMode::StartDuel() {
extra = cur_replay.ReadInt32(); extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i) for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(1, main, extra); mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
main = cur_replay.ReadInt32(); main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i) for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK); new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK);
...@@ -271,13 +276,11 @@ void ReplayMode::Restart(bool refresh) { ...@@ -271,13 +276,11 @@ void ReplayMode::Restart(bool refresh) {
//mainGame->dInfo.isReplay = true; //mainGame->dInfo.isReplay = true;
} }
skip_turn = 0; skip_turn = 0;
is_restarting = true;
} }
void ReplayMode::Undo() { void ReplayMode::Undo() {
if(skip_step > 0 || current_step == 0) if(skip_step > 0 || current_step == 0)
return; return;
mainGame->dInfo.isReplaySkiping = true; is_restarting = true;
Restart(false);
Pause(false, false); Pause(false, false);
} }
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) { bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
...@@ -771,13 +774,8 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) { ...@@ -771,13 +774,8 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
pbuf += 5; pbuf += 5;
return ReadReplayResponse(); return ReadReplayResponse();
} }
case MSG_ANNOUNCE_CARD: { case MSG_ANNOUNCE_CARD:
player = BufferIO::ReadInt8(pbuf); case MSG_ANNOUNCE_NUMBER: {
pbuf += 4;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf); count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count; pbuf += 4 * count;
......
...@@ -11,7 +11,6 @@ namespace ygo { ...@@ -11,7 +11,6 @@ namespace ygo {
extern unsigned short replay_mode; extern unsigned short replay_mode;
#endif #endif
SingleDuel::SingleDuel(bool is_match) { SingleDuel::SingleDuel(bool is_match) {
game_started = false;
match_mode = is_match; match_mode = is_match;
match_kill = 0; match_kill = 0;
for(int i = 0; i < 2; ++i) { for(int i = 0; i < 2; ++i) {
...@@ -199,7 +198,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) { ...@@ -199,7 +198,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer(); NetServer::StopServer();
return; return;
} }
if(!game_started) { if(duel_stage == DUEL_STAGE_BEGIN) {
ready[host_pos] = false; ready[host_pos] = false;
STOC_TypeChange sctc; STOC_TypeChange sctc;
sctc.type = 0x10 | host_pos; sctc.type = 0x10 | host_pos;
...@@ -213,7 +212,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) { ...@@ -213,7 +212,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) { } else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
observers.erase(dp); observers.erase(dp);
if(!game_started) { if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc; STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size(); scwc.watch_count = observers.size();
if(players[0]) if(players[0])
...@@ -231,7 +230,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) { ...@@ -231,7 +230,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
} }
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
} else { } else {
if(!game_started && duel_count == 0) { if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc; STOC_HS_PlayerChange scpc;
players[dp->type] = 0; players[dp->type] = 0;
ready[dp->type] = false; ready[dp->type] = false;
...@@ -250,32 +249,34 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) { ...@@ -250,32 +249,34 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
#endif #endif
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
} else { } else {
if(!game_started) { if(duel_stage == DUEL_STAGE_SIDING) {
if(!ready[0]) if(!ready[0])
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START); NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
if(!ready[1]) if(!ready[1])
NetServer::SendPacketToPlayer(players[1], STOC_DUEL_START); NetServer::SendPacketToPlayer(players[1], STOC_DUEL_START);
} }
unsigned char wbuf[3]; if(duel_stage != DUEL_STAGE_END) {
wbuf[0] = MSG_WIN; unsigned char wbuf[3];
wbuf[1] = 1 - dp->type; wbuf[0] = MSG_WIN;
wbuf[2] = 0x4; wbuf[1] = 1 - dp->type;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3); wbuf[2] = 0x4;
NetServer::ReSendToPlayer(players[1]); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(*oit); for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif #endif
EndDuel(); EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END); NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif #endif
NetServer::StopServer(); }
NetServer::DisconnectPlayer(dp);
} }
} }
} }
...@@ -418,6 +419,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -418,6 +419,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP); NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP);
players[1 - tp_player]->state = 0xff; players[1 - tp_player]->state = 0xff;
players[tp_player]->state = CTOS_TP_RESULT; players[tp_player]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} }
} else { } else {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
...@@ -434,7 +436,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) { ...@@ -434,7 +436,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
return; return;
NetServer::StopListen(); NetServer::StopListen();
//NetServer::StopBroadcast(); //NetServer::StopBroadcast();
game_started = true;
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START); NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) { for(auto oit = observers.begin(); oit != observers.end(); ++oit) {
...@@ -457,6 +458,7 @@ void SingleDuel::StartDuel(DuelPlayer* dp) { ...@@ -457,6 +458,7 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
//reset 2pick deck //reset 2pick deck
pick_deck_saved[0] = false; pick_deck_saved[0] = false;
pick_deck_saved[1] = false; pick_deck_saved[1] = false;
duel_stage = DUEL_STAGE_FINGER;
} }
void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) { void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3) if(res > 3)
...@@ -487,21 +489,24 @@ void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) { ...@@ -487,21 +489,24 @@ void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2) } else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3) || (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) { || (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; tp_player = 1;
players[0]->state = 0xff; players[0]->state = 0xff;
players[1]->state = CTOS_TP_RESULT; players[1]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else { } else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT); NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[1]->state = 0xff; players[1]->state = 0xff;
players[0]->state = CTOS_TP_RESULT; players[0]->state = CTOS_TP_RESULT;
tp_player = 0; tp_player = 0;
duel_stage = DUEL_STAGE_FIRSTGO;
} }
} }
} }
void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT) if(dp->state != CTOS_TP_RESULT)
return; return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd; mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
...@@ -644,8 +649,10 @@ void SingleDuel::DuelEndProc() { ...@@ -644,8 +649,10 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer(); NetServer::StopServer();
#else
duel_stage = DUEL_STAGE_END;
#endif
} else { } else {
int winc[3] = {0, 0, 0}; int winc[3] = {0, 0, 0};
for(int i = 0; i < duel_count; ++i) for(int i = 0; i < duel_count; ++i)
...@@ -660,8 +667,10 @@ void SingleDuel::DuelEndProc() { ...@@ -660,8 +667,10 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer(); NetServer::StopServer();
#else
duel_stage = DUEL_STAGE_END;
#endif
} else { } else {
if(players[0] != pplayer[0]) { if(players[0] != pplayer[0]) {
players[0] = pplayer[0]; players[0] = pplayer[0];
...@@ -704,6 +713,7 @@ void SingleDuel::DuelEndProc() { ...@@ -704,6 +713,7 @@ void SingleDuel::DuelEndProc() {
NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP); NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP);
players[1 - tp_player]->state = 0xff; players[1 - tp_player]->state = 0xff;
players[tp_player]->state = CTOS_TP_RESULT; players[tp_player]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} }
} }
} }
...@@ -1732,15 +1742,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1732,15 +1742,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1; return 1;
} }
case MSG_ANNOUNCE_CARD: { case MSG_ANNOUNCE_CARD:
player = BufferIO::ReadInt8(pbuf); case MSG_ANNOUNCE_NUMBER: {
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: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf); count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count; pbuf += 4 * count;
......
...@@ -82,7 +82,6 @@ protected: ...@@ -82,7 +82,6 @@ protected:
Replay last_replay; Replay last_replay;
bool match_mode; bool match_mode;
int match_kill; int match_kill;
bool game_started;
unsigned char duel_count; unsigned char duel_count;
unsigned char tp_player; unsigned char tp_player;
unsigned char match_result[3]; unsigned char match_result[3];
......
...@@ -683,17 +683,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) { ...@@ -683,17 +683,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
} }
break; break;
} }
case MSG_ANNOUNCE_CARD: { case MSG_ANNOUNCE_CARD:
player = BufferIO::ReadInt8(pbuf); case MSG_ANNOUNCE_NUMBER: {
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf); count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count; pbuf += 4 * count;
......
...@@ -11,7 +11,6 @@ namespace ygo { ...@@ -11,7 +11,6 @@ namespace ygo {
extern unsigned short replay_mode; extern unsigned short replay_mode;
#endif #endif
TagDuel::TagDuel() { TagDuel::TagDuel() {
game_started = false;
for(int i = 0; i < 4; ++i) { for(int i = 0; i < 4; ++i) {
players[i] = 0; players[i] = 0;
ready[i] = false; ready[i] = false;
...@@ -180,7 +179,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) { ...@@ -180,7 +179,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer(); NetServer::StopServer();
return; return;
} }
if(!game_started) { if(duel_stage == DUEL_STAGE_BEGIN) {
ready[host_pos] = false; ready[host_pos] = false;
STOC_TypeChange sctc; STOC_TypeChange sctc;
sctc.type = 0x10 | host_pos; sctc.type = 0x10 | host_pos;
...@@ -194,7 +193,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) { ...@@ -194,7 +193,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) { } else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
observers.erase(dp); observers.erase(dp);
if(!game_started) { if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc; STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size(); scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i) for(int i = 0; i < 4; ++i)
...@@ -211,7 +210,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) { ...@@ -211,7 +210,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
} }
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
} else { } else {
if(!game_started) { if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc; STOC_HS_PlayerChange scpc;
players[dp->type] = 0; players[dp->type] = 0;
ready[dp->type] = false; ready[dp->type] = false;
...@@ -228,10 +227,11 @@ void TagDuel::LeaveGame(DuelPlayer* dp) { ...@@ -228,10 +227,11 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
NetServer::SendPacketToPlayer(replay_recorder, STOC_HS_PLAYER_CHANGE, scpc); NetServer::SendPacketToPlayer(replay_recorder, STOC_HS_PLAYER_CHANGE, scpc);
#endif #endif
NetServer::DisconnectPlayer(dp); NetServer::DisconnectPlayer(dp);
} else { } else if(duel_stage != DUEL_STAGE_END) {
EndDuel(); EndDuel();
DuelEndProc(); DuelEndProc();
} }
NetServer::DisconnectPlayer(dp);
} }
} }
void TagDuel::ToDuelist(DuelPlayer* dp) { void TagDuel::ToDuelist(DuelPlayer* dp) {
...@@ -393,7 +393,6 @@ void TagDuel::StartDuel(DuelPlayer* dp) { ...@@ -393,7 +393,6 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
if(!ready[0] || !ready[1] || !ready[2] || !ready[3]) if(!ready[0] || !ready[1] || !ready[2] || !ready[3])
return; return;
NetServer::StopListen(); NetServer::StopListen();
game_started = true;
//NetServer::StopBroadcast(); //NetServer::StopBroadcast();
for(int i = 0; i < 4; ++i) for(int i = 0; i < 4; ++i)
NetServer::SendPacketToPlayer(players[i], STOC_DUEL_START); NetServer::SendPacketToPlayer(players[i], STOC_DUEL_START);
...@@ -414,6 +413,7 @@ void TagDuel::StartDuel(DuelPlayer* dp) { ...@@ -414,6 +413,7 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0; hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT; players[0]->state = CTOS_HAND_RESULT;
players[2]->state = CTOS_HAND_RESULT; players[2]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
} }
void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) { void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3 || dp->state != CTOS_HAND_RESULT) if(res > 3 || dp->state != CTOS_HAND_RESULT)
...@@ -447,19 +447,22 @@ void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) { ...@@ -447,19 +447,22 @@ void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2) } else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3) || (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) { || (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[0]->state = 0xff;
players[2]->state = CTOS_TP_RESULT; players[2]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else { } else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT); NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[2]->state = 0xff; players[2]->state = 0xff;
players[0]->state = CTOS_TP_RESULT; players[0]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} }
} }
} }
void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT) if(dp->state != CTOS_TP_RESULT)
return; return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd; mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
...@@ -637,8 +640,10 @@ void TagDuel::DuelEndProc() { ...@@ -637,8 +640,10 @@ void TagDuel::DuelEndProc() {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder); NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer(); NetServer::StopServer();
#else
duel_stage = DUEL_STAGE_END;
#endif
} }
void TagDuel::Surrender(DuelPlayer* dp) { void TagDuel::Surrender(DuelPlayer* dp) {
if(dp->type > 3 || !pduel) if(dp->type > 3 || !pduel)
...@@ -1739,15 +1744,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1739,15 +1744,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1; return 1;
} }
case MSG_ANNOUNCE_CARD: { case MSG_ANNOUNCE_CARD:
player = BufferIO::ReadInt8(pbuf); case MSG_ANNOUNCE_NUMBER: {
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: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf); count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count; pbuf += 4 * count;
......
...@@ -70,7 +70,6 @@ protected: ...@@ -70,7 +70,6 @@ protected:
unsigned char hand_result[2]; unsigned char hand_result[2];
unsigned char last_response; unsigned char last_response;
Replay last_replay; Replay last_replay;
bool game_started;
unsigned char turn_count; unsigned char turn_count;
unsigned short time_limit[2]; unsigned short time_limit[2];
unsigned short time_elapsed; unsigned short time_elapsed;
......
1 ICON "ygopro.ico" 1 ICON "ygopro.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 1, 0, 34, 10 FILEVERSION 1, 0, 34, 11
PRODUCTVERSION 1, 0, 34, 10 PRODUCTVERSION 1, 0, 34, 11
FILEOS 0x4 FILEOS 0x4
FILETYPE 0x1 FILETYPE 0x1
...@@ -16,8 +16,8 @@ VALUE "InternalName", "YGOPRO Server Mode" ...@@ -16,8 +16,8 @@ VALUE "InternalName", "YGOPRO Server Mode"
VALUE "LegalCopyright", "Copyright (C) 2018 Nanahira" VALUE "LegalCopyright", "Copyright (C) 2018 Nanahira"
VALUE "OriginalFilename", "ygopro.exe" VALUE "OriginalFilename", "ygopro.exe"
VALUE "ProductName", "YGOPRO Server Mode" VALUE "ProductName", "YGOPRO Server Mode"
VALUE "FileVersion", "1.034.A.Koishi" VALUE "FileVersion", "Ayakashi"
VALUE "ProductVersion", "1.034.A.Koishi" VALUE "ProductVersion", "Ayakashi"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
!system 64 二重状态 !system 64 二重状态
!system 65 使用效果 !system 65 使用效果
!system 66 持续公开 !system 66 持续公开
!system 67 原本持有者为对方
!system 70 怪兽卡 !system 70 怪兽卡
!system 71 魔法卡 !system 71 魔法卡
!system 72 陷阱卡 !system 72 陷阱卡
...@@ -447,8 +448,17 @@ ...@@ -447,8 +448,17 @@
!system 1418 额外卡组数量应不超过15张,当前卡组数量为%d张。 !system 1418 额外卡组数量应不超过15张,当前卡组数量为%d张。
!system 1419 副卡组数量应不超过15张,当前卡组数量为%d张。 !system 1419 副卡组数量应不超过15张,当前卡组数量为%d张。
!system 1420 有额外卡组卡片存在于主卡组,可能是额外卡组数量超过15张。 !system 1420 有额外卡组卡片存在于主卡组,可能是额外卡组数量超过15张。
!system 1421 宣言的卡不符合条件,或无法被主机识别。 !system 1421 操作无效,请重试。
!system 1422 操作无效,请重试。 !system 1422 宣言的卡不符合条件,或无法被主机识别。
!system 1423 宣言的属性不符合条件。
!system 1424 宣言的种族不符合条件
!system 1425 宣言的数字不符合条件。
!system 1426 选择的选项不符合条件
!system 1427 选择的卡片不符合条件。
!system 1428 选择的连锁不符合条件。
!system 1429 选择的位置不符合条件。
!system 1430 选择的表示形式不符合条件。
!system 1431 选择的指示物不符合条件。
!system 1450 卡包展示 !system 1450 卡包展示
!system 1451 人机卡组 !system 1451 人机卡组
!system 1452 未分类卡组 !system 1452 未分类卡组
......
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