Commit 268c67af authored by mercury233's avatar mercury233

Merge branch 'fh' into patch-deck-category

parents 87a5e4a2 b1c43a18
......@@ -595,7 +595,7 @@ void ClientField::ShowSelectOption(int select_hint) {
wchar_t textBuffer[256];
int count = select_options.size();
bool quickmode = true;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
for(auto option : select_options) {
if(mainGame->guiFont->getDimension(dataManager.GetDesc(option)).Width > 310) {
quickmode = false;
......@@ -643,7 +643,7 @@ void ClientField::ShowSelectOption(int select_hint) {
myswprintf(textBuffer, dataManager.GetSysString(555));
mainGame->wOptions->setText(textBuffer);
mainGame->PopupElement(mainGame->wOptions);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
void ClientField::ReplaySwap() {
std::swap(deck[0], deck[1]);
......@@ -1271,13 +1271,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) {
......@@ -1418,59 +1411,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;
}
if(pname[0] == 0) {
std::vector<int> cache;
cache.swap(ancard);
int sel = mainGame->lstANCard->getSelected();
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
mainGame->lstANCard->setSelected(cstr.name.c_str());
}
}
if(!ancard.empty())
return;
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
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) { //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());
......@@ -1484,7 +1430,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
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)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
......@@ -1500,7 +1446,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(cit->second.name.find(pname) != std::wstring::npos) {
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) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
......@@ -1512,10 +1458,4 @@ void ClientField::UpdateDeclarableCodeOpcode() {
}
}
}
void ClientField::UpdateDeclarableCode() {
if(opcode.size() == 0)
UpdateDeclarableCodeType();
else
UpdateDeclarableCodeOpcode();
}
}
......@@ -60,14 +60,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];
......@@ -112,9 +111,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();
irr::gui::IGUIElement* panel;
std::vector<int> ancard;
......
......@@ -65,11 +65,11 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <thread>
#include <mutex>
#include "bufferio.h"
#include "myfilesystem.h"
#include "mymutex.h"
#include "mysignal.h"
#include "mythread.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/common.h"
......
......@@ -212,10 +212,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
soundManager.PlaySoundEffect(SOUND_BUTTON);
switch(id) {
case BUTTON_CLEAR_DECK: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, dataManager.GetSysString(1339));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......@@ -274,22 +274,22 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int sel = mainGame->cbDBDecks->getSelected();
if(sel == -1)
break;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->cbDBDecks->getItem(sel), dataManager.GetSysString(1337));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
prev_sel = sel;
break;
}
case BUTTON_LEAVE_GAME: {
if(is_modified && !readonly && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......@@ -323,10 +323,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
case BUTTON_MANAGE_DECK: {
if(is_modified && !readonly && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......@@ -334,69 +334,69 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
case BUTTON_NEW_CATEGORY: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1469));
mainGame->ebDMName->setVisible(true);
mainGame->ebDMName->setText(L"");
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_RENAME_CATEGORY: {
if(mainGame->lstCategories->getSelected() < 4)
break;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1469));
mainGame->ebDMName->setVisible(true);
mainGame->ebDMName->setText(L"");
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_DELETE_CATEGORY: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1470));
mainGame->stDMMessage2->setVisible(true);
mainGame->stDMMessage2->setText(mainGame->lstCategories->getListItem(mainGame->lstCategories->getSelected()));
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_NEW_DECK: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1471));
mainGame->ebDMName->setVisible(true);
mainGame->ebDMName->setText(L"");
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_RENAME_DECK: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1471));
mainGame->ebDMName->setVisible(true);
mainGame->ebDMName->setText(L"");
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_DELETE_DECK_DM: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1337));
mainGame->stDMMessage2->setVisible(true);
mainGame->stDMMessage2->setText(mainGame->lstDecks->getListItem(mainGame->lstDecks->getSelected()));
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_MOVE_DECK: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1472));
mainGame->cbDMCategory->setVisible(true);
mainGame->cbDMCategory->clear();
......@@ -408,12 +408,12 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
}
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
case BUTTON_COPY_DECK: {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stDMMessage->setText(dataManager.GetSysString(1473));
mainGame->cbDMCategory->setVisible(true);
mainGame->cbDMCategory->clear();
......@@ -425,7 +425,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
}
mainGame->PopupElement(mainGame->wDMQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......@@ -849,10 +849,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
if(is_modified && !readonly && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......@@ -865,10 +865,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
if(is_modified && !readonly && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
break;
}
......
......@@ -1142,8 +1142,8 @@ void Game::DrawDeckBd() {
driver->draw2DRectangleOutline(Resize(313 + i * dx, 563, 359 + i * dx, 629));
}
//search result
driver->draw2DRectangle(Resize(805, 137, 915, 157), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 136, 915, 157));
driver->draw2DRectangle(Resize(805, 137, 923, 157), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 136, 923, 157));
DrawShadowText(textFont, dataManager.GetSysString(1333), Resize(810, 137, 915, 157), Resize(1, 1, 1, 1), 0xffffffff, 0xff000000, false, true);
DrawShadowText(numFont, deckBuilder.result_string, Resize(875, 137, 935, 157), Resize(1, 1, 1, 1), 0xffffffff, 0xff000000, false, true);
driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
......
This diff is collapsed.
......@@ -29,10 +29,11 @@ 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;
static char last_successful_msg[2048];
static char last_successful_msg[0x2000];
static unsigned int last_successful_msg_length;
static wchar_t event_string[256];
static mtrandom rnd;
......@@ -42,9 +43,10 @@ public:
static void StopClient(bool is_exiting = false);
static void ClientRead(bufferevent* bev, void* ctx);
static void ClientEvent(bufferevent *bev, short events, void *ctx);
static int ClientThread(void* param);
static int ClientThread();
static void HandleSTOCPacketLan(char* data, unsigned int len);
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();
......@@ -78,7 +80,7 @@ protected:
public:
static std::vector<HostPacket> hosts;
static void BeginRefreshHost();
static int RefreshThread(void* arg);
static int RefreshThread(event_base* broadev);
static void BroadcastReply(evutil_socket_t fd, short events, void* arg);
};
......
......@@ -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: {
......@@ -963,7 +963,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......@@ -972,7 +972,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_ENTER: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......@@ -1537,8 +1537,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"%ls", dataManager.GetName(mcard->code));
str.append(formatBuffer);
if(mcard->type & TYPE_MONSTER) {
if(mcard->alias && (mcard->alias < mcard->code - 10 || mcard->alias > mcard->code + 10)
&& wcscmp(dataManager.GetName(mcard->code), dataManager.GetName(mcard->alias))) {
if(mcard->alias && wcscmp(dataManager.GetName(mcard->code), dataManager.GetName(mcard->alias))) {
myswprintf(formatBuffer, L"\n(%ls)", dataManager.GetName(mcard->alias));
str.append(formatBuffer);
}
......@@ -1560,7 +1559,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
str.append(formatBuffer);
}
} else {
if(mcard->alias && (mcard->alias < mcard->code - 10 || mcard->alias > mcard->code + 10)) {
if(mcard->alias && wcscmp(dataManager.GetName(mcard->code), dataManager.GetName(mcard->alias))) {
myswprintf(formatBuffer, L"\n(%ls)", dataManager.GetName(mcard->alias));
str.append(formatBuffer);
}
......
......@@ -10,7 +10,7 @@
#include "netserver.h"
#include "single_mode.h"
const unsigned short PRO_VERSION = 0x134A;
const unsigned short PRO_VERSION = 0x134B;
namespace ygo {
......@@ -835,7 +835,7 @@ void Game::MainLoop() {
atkframe += 0.1f;
atkdy = (float)sin(atkframe);
driver->beginScene(true, true, SColor(0, 0, 0, 0));
gMutex.Lock();
gMutex.lock();
if(dInfo.isStarted) {
if(dInfo.isFinished && showcardcode == 1)
soundManager.PlayBGM(BGM_WIN);
......@@ -864,7 +864,7 @@ void Game::MainLoop() {
}
DrawGUI();
DrawSpec();
gMutex.Unlock();
gMutex.unlock();
if(signalFrame > 0) {
signalFrame--;
if(!signalFrame)
......@@ -881,16 +881,12 @@ void Game::MainLoop() {
}
}
driver->endScene();
if(closeSignal.Wait(0))
if(closeSignal.Wait(1))
CloseDuelWindow();
fps++;
cur_time = timer->getTime();
if(cur_time < fps * 17 - 20)
#ifdef _WIN32
Sleep(20);
#else
usleep(20000);
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(20));
if(cur_time >= 1000) {
myswprintf(cap, L"YGOPro FPS: %d", fps);
device->setWindowCaption(cap);
......@@ -905,11 +901,7 @@ void Game::MainLoop() {
DuelClient::StopClient(true);
if(dInfo.isSingleMode)
SingleMode::StopPlay(true);
#ifdef _WIN32
Sleep(500);
#else
usleep(500000);
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(500));
SaveConfig();
// device->drop();
}
......
......@@ -179,8 +179,7 @@ public:
void FlashWindow();
void SetCursor(ECURSOR_ICON icon);
Mutex gMutex;
Mutex gBuffer;
std::mutex gMutex;
Signal frameSignal;
Signal actionSignal;
Signal replaySignal;
......
......@@ -82,10 +82,10 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
hints.ai_flags = EVUTIL_AI_ADDRCONFIG;
int status = evutil_getaddrinfo(hostname, port, &hints, &answer);
if(status != 0) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
soundManager.PlaySoundEffect(SOUND_INFO);
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1412));
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
break;
} else {
sockaddr_in * sin = ((struct sockaddr_in *)answer->ai_addr);
......@@ -250,12 +250,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
int sel = mainGame->lstReplayList->getSelected();
if(sel == -1)
break;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->lstReplayList->getListItem(sel), dataManager.GetSysString(1363));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->guiFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
prev_sel = sel;
break;
......@@ -264,11 +264,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
int sel = mainGame->lstReplayList->getSelected();
if(sel == -1)
break;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->wReplaySave->setText(dataManager.GetSysString(1364));
mainGame->ebRSName->setText(mainGame->lstReplayList->getListItem(sel));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
prev_operation = id;
prev_sel = sel;
break;
......
#ifndef MUTEX_H
#define MUTEX_H
#ifdef _WIN32
#include <windows.h>
class Mutex {
public:
Mutex() {
InitializeCriticalSection(&_mutex);
}
~Mutex() {
DeleteCriticalSection(&_mutex);
}
void Lock() {
EnterCriticalSection(&_mutex);
}
void Unlock() {
LeaveCriticalSection(&_mutex);
}
bool TryLock() {
return TryEnterCriticalSection(&_mutex) == TRUE;
}
private:
CRITICAL_SECTION _mutex;
};
#else // _WIN32
#include <pthread.h>
class Mutex {
public:
Mutex() {
pthread_mutex_init(&mutex_t, NULL);
}
~Mutex() {
pthread_mutex_destroy(&mutex_t);
}
void Lock() {
pthread_mutex_lock(&mutex_t);
}
void Unlock() {
pthread_mutex_unlock(&mutex_t);
}
bool TryLock() {
return !pthread_mutex_trylock(&mutex_t);
}
private:
pthread_mutex_t mutex_t;
};
#endif // _WIN32
#endif // MUTEX_H
#ifndef SIGNAL_H
#define SIGNAL_H
#ifdef _WIN32
#include <windows.h>
class Signal {
public:
Signal() {
_event = CreateEvent(0, FALSE, FALSE, 0);
_nowait = false;
}
~Signal() {
CloseHandle(_event);
}
void Set() {
SetEvent(_event);
}
void Reset() {
ResetEvent(_event);
}
void Wait() {
if(_nowait)
return;
WaitForSingleObject(_event, INFINITE);
}
bool Wait(long milli) {
if(_nowait)
return false;
return WaitForSingleObject(_event, milli + 1) != WAIT_TIMEOUT;
}
void SetNoWait(bool nowait) {
_nowait = nowait;
}
private:
HANDLE _event;
bool _nowait;
};
#else // _WIN32
#include <sys/time.h>
#include <pthread.h>
#include <mutex>
#include <condition_variable>
class Signal {
public:
Signal() {
_state = false;
_nowait = false;
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_cond, NULL);
}
~Signal() {
pthread_cond_destroy(&_cond);
pthread_mutex_destroy(&_mutex);
}
void Set() {
if(pthread_mutex_lock(&_mutex))
return;
std::unique_lock<std::mutex> lock(_mutex);
_state = true;
if(pthread_cond_broadcast(&_cond))
{
pthread_mutex_unlock(&_mutex);
// ERROR Broadcasting event status!
return;
}
pthread_mutex_unlock(&_mutex);
_cond.notify_all();
}
void Reset() {
if(pthread_mutex_lock(&_mutex))
return;
std::unique_lock<std::mutex> lock(_mutex);
_state = false;
pthread_mutex_unlock(&_mutex);
}
void Wait() {
if(_nowait || pthread_mutex_lock(&_mutex))
if(_nowait)
return;
while(!_state)
{
if(pthread_cond_wait(&_cond, &_mutex))
{
pthread_mutex_unlock(&_mutex);
// ERROR Waiting events;
return;
}
}
std::unique_lock<std::mutex> lock(_mutex);
_cond.wait(lock, [this]() { return _state; });
_state = false;
pthread_mutex_unlock(&_mutex);
}
bool Wait(long milliseconds)
{
if (_nowait || pthread_mutex_lock(&_mutex) != 0)
bool Wait(long milliseconds) {
if(_nowait)
return false;
int rc = 0;
struct timespec abstime;
struct timeval tv;
gettimeofday(&tv, NULL);
abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
if (abstime.tv_nsec >= 1000000000)
{
abstime.tv_nsec -= 1000000000;
abstime.tv_sec++;
}
while (!_state)
{
if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime)))
{
if (rc == ETIMEDOUT) break;
pthread_mutex_unlock(&_mutex);
return false;
}
}
std::unique_lock<std::mutex> lock(_mutex);
bool res = _cond.wait_for(lock, std::chrono::milliseconds(milliseconds), [this]() { return _state; });
_state = false;
pthread_mutex_unlock(&_mutex);
return rc == 0;
return res;
}
void SetNoWait(bool nowait) {
_nowait = nowait;
}
private:
pthread_mutex_t _mutex;
pthread_cond_t _cond;
std::mutex _mutex;
std::condition_variable _cond;
bool _state;
bool _nowait;
};
#endif // _WIN32
#endif // SIGNAL_H
#ifndef THREAD_H
#define THREAD_H
#ifdef _WIN32
#include <windows.h>
class Thread {
public:
static void NewThread(int (*thread_func)(void*), void* param) {
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_func, param, 0, 0);
}
};
#else // _WIN32
#include <pthread.h>
class Thread {
public:
static void NewThread(int (*thread_func)(void*), void* param) {
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&thread, &attr, (void * (*)(void *))thread_func, param);
}
};
#endif // _WIN32
#endif // THREAD_H
......@@ -33,18 +33,20 @@ bool NetServer::StartServer(unsigned short port) {
return false;
}
evconnlistener_set_error_cb(listener, ServerAcceptError);
Thread::NewThread(ServerThread, net_evbase);
std::thread(ServerThread).detach();
return true;
}
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) {
......@@ -130,7 +136,7 @@ void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) {
else DisconnectPlayer(dp);
}
}
int NetServer::ServerThread(void* param) {
int NetServer::ServerThread() {
event_base_dispatch(net_evbase);
for(auto bit = users.begin(); bit != users.end(); ++bit) {
bufferevent_disable(bit->first, EV_READ);
......
......@@ -33,7 +33,7 @@ public:
static void ServerAcceptError(evconnlistener *listener, void* ctx);
static void ServerEchoRead(bufferevent* bev, void* ctx);
static void ServerEchoEvent(bufferevent* bev, short events, void* ctx);
static int ServerThread(void* param);
static int ServerThread();
static void DisconnectPlayer(DuelPlayer* dp);
static void HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len);
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) {
......
......@@ -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];
......@@ -219,4 +220,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
......@@ -24,7 +24,7 @@ bool ReplayMode::StartReplay(int skipturn) {
skip_turn = skipturn;
if(skip_turn < 0)
skip_turn = 0;
Thread::NewThread(ReplayThread, 0);
std::thread(ReplayThread).detach();
return true;
}
void ReplayMode::StopReplay(bool is_exiting) {
......@@ -56,7 +56,7 @@ bool ReplayMode::ReadReplayResponse() {
set_responseb(pduel, resp);
return result;
}
int ReplayMode::ReplayThread(void* param) {
int ReplayMode::ReplayThread() {
const ReplayHeader& rh = cur_replay.pheader;
mainGame->dInfo.isFirst = true;
mainGame->dInfo.isTag = !!(rh.flag & REPLAY_TAG);
......@@ -90,7 +90,7 @@ int ReplayMode::ReplayThread(void* param) {
exit_pending = false;
current_step = 0;
if(mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
while (is_continuing && !exit_pending) {
int result = process(pduel);
int len = result & 0xffff;
......@@ -99,7 +99,7 @@ int ReplayMode::ReplayThread(void* param) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = ReplayAnalyze(engineBuffer, len);
if(is_restarting) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
is_restarting = false;
mainGame->dInfo.isReplaySkiping = true;
Restart(false);
......@@ -125,7 +125,7 @@ int ReplayMode::ReplayThread(void* param) {
mainGame->dInfo.isFinished = false;
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
skip_step = step;
current_step = 0;
......@@ -135,7 +135,7 @@ int ReplayMode::ReplayThread(void* param) {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
EndDuel();
return 0;
......@@ -228,26 +228,26 @@ void ReplayMode::EndDuel() {
end_duel(pduel);
if(!is_closing) {
mainGame->actionSignal.Reset();
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stMessage->setText(dataManager.GetSysString(1501));
if(mainGame->wCardSelect->isVisible())
mainGame->HideElement(mainGame->wCardSelect);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->actionSignal.Wait();
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = true;
mainGame->dInfo.isReplay = false;
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->ShowElement(mainGame->wReplay);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
......@@ -291,9 +291,9 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
return true;
}
if(is_swaping) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
is_swaping = false;
}
char* offset = pbuf;
......@@ -304,12 +304,12 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
......@@ -323,7 +323,7 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
......@@ -505,7 +505,7 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
if(skip_turn == 0) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
}
player = BufferIO::ReadInt8(pbuf);
......@@ -770,13 +770,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;
......@@ -847,7 +842,7 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
mainGame->dInfo.isFinished = false;
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
}
}
if(is_pausing) {
......
......@@ -32,7 +32,7 @@ public:
static void SwapField();
static void Pause(bool is_pause, bool is_step);
static bool ReadReplayResponse();
static int ReplayThread(void* param);
static int ReplayThread();
static bool StartDuel();
static void EndDuel();
static void Restart(bool refresh);
......
......@@ -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) {
......@@ -139,7 +138,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])
......@@ -151,7 +150,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;
......@@ -164,26 +163,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);
}
}
}
......@@ -304,6 +305,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;
......@@ -320,7 +322,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) {
......@@ -333,6 +334,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)
......@@ -360,21 +362,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];
......@@ -497,7 +502,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)
......@@ -510,7 +515,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];
......@@ -529,6 +534,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;
}
}
}
......@@ -1345,15 +1351,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];
......
......@@ -12,7 +12,7 @@ bool SingleMode::is_continuing = false;
Replay SingleMode::last_replay;
bool SingleMode::StartPlay() {
Thread::NewThread(SinglePlayThread, 0);
std::thread(SinglePlayThread).detach();
return true;
}
void SingleMode::StopPlay(bool is_exiting) {
......@@ -28,7 +28,7 @@ void SingleMode::SetResponse(unsigned char* resp, unsigned int len) {
last_replay.WriteData(resp, len);
set_responseb(pduel, resp);
}
int SingleMode::SinglePlayThread(void* param) {
int SingleMode::SinglePlayThread() {
const int start_lp = 8000;
const int start_hand = 5;
const int draw_count = 1;
......@@ -79,7 +79,7 @@ int SingleMode::SinglePlayThread(void* param) {
rh.version = PRO_VERSION;
rh.flag = REPLAY_SINGLE_MODE;
rh.seed = seed;
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo();
mainGame->wCardImg->setVisible(true);
......@@ -93,7 +93,7 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame->dInfo.isFinished = false;
mainGame->dInfo.isSingleMode = true;
mainGame->device->setEventReceiver(&mainGame->dField);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
char engineBuffer[0x1000];
is_closing = false;
is_continuing = true;
......@@ -125,6 +125,7 @@ int SingleMode::SinglePlayThread(void* param) {
}
}
last_replay.EndRecord();
mainGame->gMutex.lock();
time_t nowtime = time(NULL);
tm* localedtime = localtime(&nowtime);
wchar_t timetext[40];
......@@ -133,7 +134,7 @@ int SingleMode::SinglePlayThread(void* param) {
if(!mainGame->chkAutoSaveReplay->isChecked()) {
mainGame->wReplaySave->setText(dataManager.GetSysString(1340));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait();
} else {
......@@ -142,26 +143,26 @@ int SingleMode::SinglePlayThread(void* param) {
myswprintf(msgbuf, dataManager.GetSysString(1367), timetext);
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, msgbuf);
mainGame->PopupElement(mainGame->wACMessage, 20);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->WaitFrameSignal(30);
}
if(mainGame->actionParam)
last_replay.SaveReplay(mainGame->ebRSName->getText());
end_duel(pduel);
if(!is_closing) {
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = true;
mainGame->dInfo.isSingleMode = false;
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->ShowElement(mainGame->wSinglePlay);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
......@@ -679,17 +680,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;
......@@ -740,9 +732,9 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayReload();
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
break;
}
case MSG_AI_NAME: {
......@@ -764,10 +756,10 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
pbuf += len + 1;
memcpy(msgbuf, begin, len + 1);
BufferIO::DecodeUTF8(msgbuf, msg);
mainGame->gMutex.Lock();
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->guiFont, msg);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->gMutex.unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
break;
......
......@@ -15,7 +15,7 @@ public:
static bool StartPlay();
static void StopPlay(bool is_exiting = false);
static void SetResponse(unsigned char* resp, unsigned int len);
static int SinglePlayThread(void* param);
static int SinglePlayThread();
static bool SinglePlayAnalyze(char* msg, unsigned int len);
static void SinglePlayRefresh(int flag = 0xf81fff);
......
......@@ -8,7 +8,6 @@
namespace ygo {
TagDuel::TagDuel() {
game_started = false;
for(int i = 0; i < 4; ++i) {
players[i] = 0;
ready[i] = false;
......@@ -119,7 +118,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)
......@@ -130,7 +129,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;
......@@ -141,10 +140,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) {
......@@ -278,7 +278,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);
......@@ -292,6 +291,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)
......@@ -322,19 +322,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];
......@@ -500,7 +503,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) {
return;
......@@ -1394,15 +1397,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;
......
This diff is collapsed.
Subproject commit f95d908449a428691301ff6ae29ab9920eb492c0
Subproject commit 511f2f9f74d31878cb5e6fce62f7f969f6b0cec2
Subproject commit 9ec1a4429cf9e3a3fd5002b6286061f9a83db917
Subproject commit 573645ee990be70d8e7c7ae2fa8a8fad33e9d62e
......@@ -9,9 +9,9 @@
!system 5 特殊召唤成功
!system 6 反转召唤成功
!system 7 发动
!system 10 除指示物
!system 10 除指示物
!system 11 支付基本分
!system 12 除本身的素材
!system 12 除本身的素材
!system 20 抽卡阶段中
!system 21 准备阶段中
!system 22 主要阶段中
......@@ -36,6 +36,7 @@
!system 64 二重状态
!system 65 使用效果
!system 66 持续公开
!system 67 原本持有者为对方
!system 70 怪兽卡
!system 71 魔法卡
!system 72 陷阱卡
......@@ -56,7 +57,7 @@
!system 201 此时没有可以发动的效果
!system 202 是否要确认场上的情况?
!system 203 是否要进行连锁?
!system 204除%d个[%ls]
!system 204除%d个[%ls]
!system 205 请选择排列顺序
!system 206 请选择连锁顺序
!system 207 翻开卡组上方%d张卡:
......@@ -334,7 +335,7 @@
!system 1294 可用时点
!system 1295 取消操作
!system 1296 完成选择
!system 1297 切洗手卡
!system 1297 洗切手卡
!system 1298 辅助功能
!system 1299 加快动画效果
!system 1300 卡组分类:
......@@ -495,7 +496,7 @@
!system 1615 我方回复%d基本分
!system 1616 对方回复%d基本分
!system 1617 [%ls]放置了%d个[%ls]
!system 1618 [%ls]除了%d个[%ls]
!system 1618 [%ls]除了%d个[%ls]
!system 1619 [%ls]攻击[%ls]
!system 1620 [%ls]直接攻击
!system 1621 攻击被无效
......@@ -603,6 +604,10 @@
!counter 0x104f 蛊指示物
!counter 0x50 指示物(娱乐伙伴 掉头跑骑兵)
!counter 0x51 指示物(蜂军巢)
!counter 0x52 指示物(防火龙·暗流体)
!counter 0x53 指示物(炽天蝶)
!counter 0x54 指示物(星遗物引导的前路)
!counter 0x55 指示物(隐居者的大釜)
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......@@ -991,3 +996,5 @@
!setname 0x12d 斯摩夫 シムルグ
!setname 0x12e 占卜魔女 占い魔女
!setname 0x12f 蜂军 BF(ビー・フォース)
!setname 0x130 破械
!setname 0x1130 破械神
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