Commit 39a85650 authored by nanahira's avatar nanahira

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

parents d22feaff 6a3a3dc0
No preview for this file type
...@@ -28,7 +28,7 @@ endif () ...@@ -28,7 +28,7 @@ endif ()
target_link_libraries (ygopro ocgcore clzma) target_link_libraries (ygopro ocgcore clzma)
if (MSVC) if (MSVC)
target_link_libraries (ygopro irrlicht freetype sqlite3 event lua) target_link_libraries (ygopro irrlicht freetype sqlite3 event)
include_directories ( "../irrlicht/include" "../freetype/include" "../event/include" "../sqlite3" ) include_directories ( "../irrlicht/include" "../freetype/include" "../event/include" "../sqlite3" )
else () else ()
target_link_libraries (ygopro target_link_libraries (ygopro
...@@ -36,7 +36,6 @@ else () ...@@ -36,7 +36,6 @@ else ()
${FREETYPE_LIBRARIES} ${FREETYPE_LIBRARIES}
${SQLITE_LIBRARIES} ${SQLITE_LIBRARIES}
${LIBEVENT_LIBRARIES} ${LIBEVENT_LIBRARIES}
${LUA_LIBRARIES}
${OPENGL_gl_LIBRARY} ${OPENGL_gl_LIBRARY}
) )
include_directories ( include_directories (
......
...@@ -12,6 +12,9 @@ namespace ygo { ...@@ -12,6 +12,9 @@ namespace ygo {
ClientField::ClientField() { ClientField::ClientField() {
panel = 0; panel = 0;
is_dragging_cardtext = false;
dragging_cardtext_start_pos = 0;
dragging_cardtext_start_y = 0;
hovered_card = 0; hovered_card = 0;
clicked_card = 0; clicked_card = 0;
highlighting_card = 0; highlighting_card = 0;
......
...@@ -117,6 +117,9 @@ public: ...@@ -117,6 +117,9 @@ public:
void RefreshCardCountDisplay(); void RefreshCardCountDisplay();
irr::gui::IGUIElement* panel; irr::gui::IGUIElement* panel;
bool is_dragging_cardtext;
int dragging_cardtext_start_pos;
int dragging_cardtext_start_y;
std::vector<int> ancard; std::vector<int> ancard;
int hovered_controler; int hovered_controler;
int hovered_location; int hovered_location;
......
...@@ -205,17 +205,21 @@ bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) { ...@@ -205,17 +205,21 @@ bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) {
pcount[deck.side[i]->first]++; pcount[deck.side[i]->first]++;
Deck ndeck; Deck ndeck;
LoadDeck(ndeck, dbuf, mainc, sidec); LoadDeck(ndeck, dbuf, mainc, sidec);
#ifndef NO_SIDE_CHECK
if(ndeck.main.size() != deck.main.size() || ndeck.extra.size() != deck.extra.size()) if(ndeck.main.size() != deck.main.size() || ndeck.extra.size() != deck.extra.size())
return false; return false;
#endif
for(size_t i = 0; i < ndeck.main.size(); ++i) for(size_t i = 0; i < ndeck.main.size(); ++i)
ncount[ndeck.main[i]->first]++; ncount[ndeck.main[i]->first]++;
for(size_t i = 0; i < ndeck.extra.size(); ++i) for(size_t i = 0; i < ndeck.extra.size(); ++i)
ncount[ndeck.extra[i]->first]++; ncount[ndeck.extra[i]->first]++;
for(size_t i = 0; i < ndeck.side.size(); ++i) for(size_t i = 0; i < ndeck.side.size(); ++i)
ncount[ndeck.side[i]->first]++; ncount[ndeck.side[i]->first]++;
#ifndef NO_SIDE_CHECK
for(auto cdit = ncount.begin(); cdit != ncount.end(); ++cdit) for(auto cdit = ncount.begin(); cdit != ncount.end(); ++cdit)
if(cdit->second != pcount[cdit->first]) if(cdit->second != pcount[cdit->first])
return false; return false;
#endif
deck = ndeck; deck = ndeck;
*/ */
return true; return true;
......
...@@ -496,7 +496,7 @@ void Game::DrawMisc() { ...@@ -496,7 +496,7 @@ void Game::DrawMisc() {
driver->setTransform(irr::video::ETS_WORLD, im); driver->setTransform(irr::video::ETS_WORLD, im);
driver->drawVertexPrimitiveList(matManager.vActivate, 4, matManager.iRectangle, 2); driver->drawVertexPrimitiveList(matManager.vActivate, 4, matManager.iRectangle, 2);
} }
if(dField.chains.size() > 1) { if(dField.chains.size() > 1 || mainGame->gameConf.draw_single_chain) {
for(size_t i = 0; i < dField.chains.size(); ++i) { for(size_t i = 0; i < dField.chains.size(); ++i) {
if(dField.chains[i].solved) if(dField.chains[i].solved)
break; break;
...@@ -1072,6 +1072,8 @@ void Game::ShowElement(irr::gui::IGUIElement * win, int autoframe) { ...@@ -1072,6 +1072,8 @@ void Game::ShowElement(irr::gui::IGUIElement * win, int autoframe) {
fadingList.push_back(fu); fadingList.push_back(fu);
} }
void Game::HideElement(irr::gui::IGUIElement * win, bool set_action) { void Game::HideElement(irr::gui::IGUIElement * win, bool set_action) {
if(!win->isVisible() && !set_action)
return;
FadingUnit fu; FadingUnit fu;
fu.fadingSize = win->getRelativePosition(); fu.fadingSize = win->getRelativePosition();
for(auto fit = fadingList.begin(); fit != fadingList.end(); ++fit) for(auto fit = fadingList.begin(); fit != fadingList.end(); ++fit)
...@@ -1287,8 +1289,13 @@ void Game::DrawDeckBd() { ...@@ -1287,8 +1289,13 @@ void Game::DrawDeckBd() {
DrawShadowText(numFont, deckBuilder.result_string, Resize(875, 137, 935, 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); driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630)); driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630));
for(size_t i = 0; i < 7 && i + scrFilter->getPos() < deckBuilder.results.size(); ++i) { for(size_t i = 0; i < 9 && i + scrFilter->getPos() < deckBuilder.results.size(); ++i) {
code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()]; code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()];
if(i >= 7)
{
imageManager.GetTextureThumb(ptr->second.code);
break;
}
if(deckBuilder.hovered_pos == 4 && deckBuilder.hovered_seq == (int)i) if(deckBuilder.hovered_pos == 4 && deckBuilder.hovered_seq == (int)i)
driver->draw2DRectangle(0x80000000, Resize(806, 164 + i * 66, 1019, 230 + i * 66)); driver->draw2DRectangle(0x80000000, Resize(806, 164 + i * 66, 1019, 230 + i * 66));
DrawThumb(ptr, position2di(810, 165 + i * 66), deckBuilder.filterList); DrawThumb(ptr, position2di(810, 165 + i * 66), deckBuilder.filterList);
......
...@@ -267,6 +267,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -267,6 +267,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
#endif #endif
switch(pktType) { switch(pktType) {
case STOC_GAME_MSG: { case STOC_GAME_MSG: {
if(!mainGame->dInfo.isStarted)
break;
ClientAnalyze(pdata, len - 1); ClientAnalyze(pdata, len - 1);
break; break;
} }
...@@ -466,24 +468,17 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -466,24 +468,17 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->dField.Clear(); mainGame->dField.Clear();
mainGame->is_building = true; mainGame->is_building = true;
mainGame->is_siding = true; mainGame->is_siding = true;
mainGame->CloseGameWindow();
mainGame->wChat->setVisible(false); mainGame->wChat->setVisible(false);
mainGame->wPhase->setVisible(false);
mainGame->wDeckEdit->setVisible(false); mainGame->wDeckEdit->setVisible(false);
mainGame->wFilter->setVisible(false); mainGame->wFilter->setVisible(false);
mainGame->wSort->setVisible(false); mainGame->wSort->setVisible(false);
mainGame->stTip->setVisible(false); if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSideOK->setVisible(true); mainGame->btnSideOK->setVisible(true);
mainGame->btnSideShuffle->setVisible(true); mainGame->btnSideShuffle->setVisible(true);
mainGame->btnSideSort->setVisible(true); mainGame->btnSideSort->setVisible(true);
mainGame->btnSideReload->setVisible(true); mainGame->btnSideReload->setVisible(true);
if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSpectatorSwap->setVisible(false);
mainGame->btnChainIgnore->setVisible(false);
mainGame->btnChainAlways->setVisible(false);
mainGame->btnChainWhenAvail->setVisible(false);
mainGame->btnCancelOrFinish->setVisible(false);
mainGame->btnShuffle->setVisible(false);
mainGame->deckBuilder.result_string[0] = L'0'; mainGame->deckBuilder.result_string[0] = L'0';
mainGame->deckBuilder.result_string[1] = 0; mainGame->deckBuilder.result_string[1] = 0;
mainGame->deckBuilder.results.clear(); mainGame->deckBuilder.results.clear();
...@@ -586,12 +581,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -586,12 +581,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->RefreshCategoryDeck(mainGame->cbCategorySelect, mainGame->cbDeckSelect); mainGame->RefreshCategoryDeck(mainGame->cbCategorySelect, mainGame->cbDeckSelect);
mainGame->cbCategorySelect->setEnabled(true); mainGame->cbCategorySelect->setEnabled(true);
mainGame->cbDeckSelect->setEnabled(true); mainGame->cbDeckSelect->setEnabled(true);
if(mainGame->wCreateHost->isVisible()) mainGame->HideElement(mainGame->wCreateHost);
mainGame->HideElement(mainGame->wCreateHost); mainGame->HideElement(mainGame->wLanWindow);
else if(mainGame->wLanWindow->isVisible()) mainGame->HideElement(mainGame->wSinglePlay);
mainGame->HideElement(mainGame->wLanWindow);
else if(mainGame->wSinglePlay->isVisible())
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ShowElement(mainGame->wHostPrepare); mainGame->ShowElement(mainGame->wHostPrepare);
//if(!mainGame->chkIgnore1->isChecked()) //if(!mainGame->chkIgnore1->isChecked())
mainGame->wChat->setVisible(true); mainGame->wChat->setVisible(true);
...@@ -753,14 +745,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -753,14 +745,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->gMutex.lock(); mainGame->gMutex.lock();
if(mainGame->dInfo.player_type < 7) if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false); mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSpectatorSwap->setVisible(false);
mainGame->btnChainIgnore->setVisible(false);
mainGame->btnChainAlways->setVisible(false);
mainGame->btnChainWhenAvail->setVisible(false);
mainGame->btnCancelOrFinish->setVisible(false);
if(!mainGame->dInfo.isReplay && mainGame->dInfo.isReplaySkiping) if(!mainGame->dInfo.isReplay && mainGame->dInfo.isReplaySkiping)
mainGame->dInfo.isReplaySkiping = false; mainGame->dInfo.isReplaySkiping = false;
mainGame->wSurrender->setVisible(false); mainGame->CloseGameButtons();
mainGame->stMessage->setText(dataManager.GetSysString(1500)); mainGame->stMessage->setText(dataManager.GetSysString(1500));
mainGame->PopupElement(mainGame->wMessage); mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.unlock(); mainGame->gMutex.unlock();
...@@ -801,14 +788,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -801,14 +788,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
case STOC_REPLAY: { case STOC_REPLAY: {
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->wPhase->setVisible(false); mainGame->wPhase->setVisible(false);
mainGame->wSurrender->setVisible(false);
if(mainGame->dInfo.player_type < 7) if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false); mainGame->btnLeaveGame->setVisible(false);
mainGame->btnChainIgnore->setVisible(false); mainGame->CloseGameButtons();
mainGame->btnChainAlways->setVisible(false);
mainGame->btnChainWhenAvail->setVisible(false);
mainGame->btnCancelOrFinish->setVisible(false);
mainGame->btnShuffle->setVisible(false);
char* prep = pdata; char* prep = pdata;
Replay new_replay; Replay new_replay;
memcpy(&new_replay.pheader, prep, sizeof(ReplayHeader)); memcpy(&new_replay.pheader, prep, sizeof(ReplayHeader));
...@@ -2610,8 +2592,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -2610,8 +2592,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dInfo.is_swapped = !mainGame->dInfo.is_swapped; mainGame->dInfo.is_swapped = !mainGame->dInfo.is_swapped;
return true; return true;
} }
if(mainGame->wSurrender->isVisible()) mainGame->HideElement(mainGame->wSurrender);
mainGame->HideElement(mainGame->wSurrender);
if(!mainGame->dInfo.isReplay && mainGame->dInfo.player_type < 7) { if(!mainGame->dInfo.isReplay && mainGame->dInfo.player_type < 7) {
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1351)); mainGame->btnLeaveGame->setText(dataManager.GetSysString(1351));
mainGame->btnLeaveGame->setVisible(true); mainGame->btnLeaveGame->setVisible(true);
...@@ -3143,7 +3124,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -3143,7 +3124,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->WaitFrameSignal(11); mainGame->WaitFrameSignal(11);
} }
} }
if (mainGame->dField.chains.size() > 1) { if(mainGame->dField.chains.size() > 1 || mainGame->gameConf.draw_single_chain) {
if (mainGame->dField.last_chain) if (mainGame->dField.last_chain)
mainGame->WaitFrameSignal(11); mainGame->WaitFrameSignal(11);
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
......
...@@ -129,13 +129,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -129,13 +129,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->dInfo.isStarted = false; mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = false; mainGame->dInfo.isFinished = false;
mainGame->device->setEventReceiver(&mainGame->menuHandler); mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->stTip->setVisible(false); mainGame->CloseDuelWindow();
mainGame->wCardImg->setVisible(false);
mainGame->wInfos->setVisible(false);
mainGame->wPhase->setVisible(false);
mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSpectatorSwap->setVisible(false);
mainGame->wChat->setVisible(false);
mainGame->btnCreateHost->setEnabled(true); mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true); mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true); mainGame->btnJoinCancel->setEnabled(true);
...@@ -1461,8 +1455,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -1461,8 +1455,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->chain_when_avail = false; mainGame->chain_when_avail = false;
UpdateChainButtons(); UpdateChainButtons();
} }
if(mainGame->wSurrender->isVisible()) mainGame->HideElement(mainGame->wSurrender);
mainGame->HideElement(mainGame->wSurrender);
mainGame->wCmdMenu->setVisible(false); mainGame->wCmdMenu->setVisible(false);
if(mainGame->fadingList.size()) if(mainGame->fadingList.size())
break; break;
...@@ -1907,6 +1900,11 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) { ...@@ -1907,6 +1900,11 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
return true; return true;
break; break;
} }
case CHECKBOX_DRAW_SINGLE_CHAIN: {
mainGame->gameConf.draw_single_chain = mainGame->chkDrawSingleChain->isChecked() ? 1 : 0;
return true;
break;
}
case CHECKBOX_PREFER_EXPANSION: { case CHECKBOX_PREFER_EXPANSION: {
mainGame->gameConf.prefer_expansion_script = mainGame->chkPreferExpansionScript->isChecked() ? 1 : 0; mainGame->gameConf.prefer_expansion_script = mainGame->chkPreferExpansionScript->isChecked() ? 1 : 0;
return true; return true;
...@@ -2047,6 +2045,46 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) { ...@@ -2047,6 +2045,46 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
} }
break; break;
} }
case irr::EET_MOUSE_INPUT_EVENT: {
switch(event.MouseInput.Event) {
case irr::EMIE_LMOUSE_PRESSED_DOWN: {
IGUIElement* root = mainGame->env->getRootGUIElement();
position2di mousepos = position2di(event.MouseInput.X, event.MouseInput.Y);
if(root->getElementFromPoint(mousepos) == mainGame->stText) {
if(!mainGame->scrCardText->isVisible()) {
break;
}
is_dragging_cardtext = true;
dragging_cardtext_start_pos = mainGame->scrCardText->getPos();
dragging_cardtext_start_y = event.MouseInput.Y;
return true;
}
break;
}
case irr::EMIE_LMOUSE_LEFT_UP: {
is_dragging_cardtext = false;
break;
}
case irr::EMIE_MOUSE_MOVED: {
if(is_dragging_cardtext) {
if(!mainGame->scrCardText->isVisible()) {
is_dragging_cardtext = false;
break;
}
int step = mainGame->guiFont->getDimension(L"A").Height + mainGame->guiFont->getKerningHeight();
int pos = dragging_cardtext_start_pos + (dragging_cardtext_start_y - event.MouseInput.Y) / step;
int max = mainGame->scrCardText->getMax();
if(pos < 0) pos = 0;
if(pos > max) pos = max;
mainGame->scrCardText->setPos(pos);
mainGame->SetStaticText(mainGame->stText, mainGame->stText->getRelativePosition().getWidth() - 25, mainGame->guiFont, mainGame->showingtext, pos);
}
break;
}
default: break;
}
break;
}
default: break; default: break;
} }
return false; return false;
......
This diff is collapsed.
...@@ -60,6 +60,7 @@ struct Config { ...@@ -60,6 +60,7 @@ struct Config {
int window_height; int window_height;
bool resize_popup_menu; bool resize_popup_menu;
int auto_save_replay; int auto_save_replay;
int draw_single_chain;
int prefer_expansion_script; int prefer_expansion_script;
bool enable_sound; bool enable_sound;
bool enable_music; bool enable_music;
...@@ -173,6 +174,7 @@ public: ...@@ -173,6 +174,7 @@ public:
void WaitFrameSignal(int frame); void WaitFrameSignal(int frame);
void DrawThumb(code_pointer cp, position2di pos, const std::unordered_map<int,int>* lflist, bool drag = false); void DrawThumb(code_pointer cp, position2di pos, const std::unordered_map<int,int>* lflist, bool drag = false);
void DrawDeckBd(); void DrawDeckBd();
bool LoadConfigFromFile(const char* file);
void LoadConfig(); void LoadConfig();
void SaveConfig(); void SaveConfig();
void ShowCardInfo(int code, bool resize = false); void ShowCardInfo(int code, bool resize = false);
...@@ -184,6 +186,8 @@ public: ...@@ -184,6 +186,8 @@ public:
void ErrorLog(const char* msgbuf); void ErrorLog(const char* msgbuf);
void initUtils(); void initUtils();
void ClearTextures(); void ClearTextures();
void CloseGameButtons();
void CloseGameWindow();
void CloseDuelWindow(); void CloseDuelWindow();
int LocalPlayer(int player); int LocalPlayer(int player);
...@@ -327,6 +331,7 @@ public: ...@@ -327,6 +331,7 @@ public:
irr::gui::IGUICheckBox* chkWaitChain; irr::gui::IGUICheckBox* chkWaitChain;
irr::gui::IGUICheckBox* chkQuickAnimation; irr::gui::IGUICheckBox* chkQuickAnimation;
irr::gui::IGUICheckBox* chkAutoSaveReplay; irr::gui::IGUICheckBox* chkAutoSaveReplay;
irr::gui::IGUICheckBox* chkDrawSingleChain;
irr::gui::IGUIWindow* tabSystem; irr::gui::IGUIWindow* tabSystem;
irr::gui::IGUIElement* elmTabSystemLast; irr::gui::IGUIElement* elmTabSystemLast;
irr::gui::IGUIScrollBar* scrTabSystem; irr::gui::IGUIScrollBar* scrTabSystem;
...@@ -627,8 +632,8 @@ extern Game* mainGame; ...@@ -627,8 +632,8 @@ extern Game* mainGame;
extern unsigned short aServerPort; extern unsigned short aServerPort;
extern unsigned short replay_mode; extern unsigned short replay_mode;
extern HostInfo game_info; extern HostInfo game_info;
extern time_t pre_seed[3];
#endif #endif
} }
#define CARD_IMG_WIDTH 177 #define CARD_IMG_WIDTH 177
...@@ -831,8 +836,9 @@ extern HostInfo game_info; ...@@ -831,8 +836,9 @@ extern HostInfo game_info;
#define SCROLL_TAB_SYSTEM 371 #define SCROLL_TAB_SYSTEM 371
#define CHECKBOX_MULTI_KEYWORDS 372 #define CHECKBOX_MULTI_KEYWORDS 372
#define CHECKBOX_PREFER_EXPANSION 373 #define CHECKBOX_PREFER_EXPANSION 373
#define CHECKBOX_REGEX 374 #define CHECKBOX_DRAW_SINGLE_CHAIN 374
#define COMBOBOX_LOCALE 375 #define CHECKBOX_REGEX 375
#define COMBOBOX_LOCALE 376
#define BUTTON_DECK_CODE 389 #define BUTTON_DECK_CODE 389
#define BUTTON_DECK_CODE_SAVE 390 #define BUTTON_DECK_CODE_SAVE 390
......
...@@ -74,6 +74,8 @@ int main(int argc, char* argv[]) { ...@@ -74,6 +74,8 @@ int main(int argc, char* argv[]) {
ygo::game_info.no_shuffle_deck = false; ygo::game_info.no_shuffle_deck = false;
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE; ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180; ygo::game_info.time_limit = 180;
for (int i = 0; i < 3; ++i)
ygo::pre_seed[i] = (time_t)0;
if (argc == 2) { if (argc == 2) {
int code = atoi(argv[1]); int code = atoi(argv[1]);
ygo::mainGame = &_game; ygo::mainGame = &_game;
...@@ -115,6 +117,10 @@ int main(int argc, char* argv[]) { ...@@ -115,6 +117,10 @@ int main(int argc, char* argv[]) {
ygo::game_info.draw_count = atoi(argv[10]); ygo::game_info.draw_count = atoi(argv[10]);
ygo::game_info.time_limit = atoi(argv[11]); ygo::game_info.time_limit = atoi(argv[11]);
ygo::replay_mode = atoi(argv[12]); ygo::replay_mode = atoi(argv[12]);
for (int i = 13; (i < argc && i <= 15) ; ++i)
{
ygo::pre_seed[i - 13] = (time_t)atoi(argv[i]);
}
} }
ygo::mainGame = &_game; ygo::mainGame = &_game;
ygo::mainGame->MainServerLoop(); ygo::mainGame->MainServerLoop();
......
...@@ -21,6 +21,8 @@ bool ImageManager::Initial() { ...@@ -21,6 +21,8 @@ bool ImageManager::Initial() {
tUnknown = NULL; tUnknown = NULL;
tUnknownFit = NULL; tUnknownFit = NULL;
tUnknownThumb = NULL; tUnknownThumb = NULL;
tLoading = NULL;
tThumbLoadingThreadRunning = false;
tAct = GetRandomImage(TEXTURE_ACTIVATE); tAct = GetRandomImage(TEXTURE_ACTIVATE);
tAttack = GetRandomImage(TEXTURE_ATTACK); tAttack = GetRandomImage(TEXTURE_ATTACK);
if(!tAct) if(!tAct)
...@@ -127,12 +129,18 @@ void ImageManager::ClearTexture() { ...@@ -127,12 +129,18 @@ void ImageManager::ClearTexture() {
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) { for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) {
if(tit->second) if(tit->second && tit->second != tLoading)
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
tMap[0].clear(); tMap[0].clear();
tMap[1].clear(); tMap[1].clear();
tThumb.clear(); tThumb.clear();
tThumbLoadingMutex.lock();
tThumbLoading.clear();
while(!tThumbLoadingCodes.empty())
tThumbLoadingCodes.pop();
tThumbLoadingThreadRunning = false;
tThumbLoadingMutex.unlock();
tFields.clear(); tFields.clear();
} }
void ImageManager::RemoveTexture(int code) { void ImageManager::RemoveTexture(int code) {
...@@ -174,9 +182,11 @@ void ImageManager::ResizeTexture() { ...@@ -174,9 +182,11 @@ void ImageManager::ResizeTexture() {
driver->removeTexture(tUnknown); driver->removeTexture(tUnknown);
driver->removeTexture(tUnknownFit); driver->removeTexture(tUnknownFit);
driver->removeTexture(tUnknownThumb); driver->removeTexture(tUnknownThumb);
driver->removeTexture(tLoading);
tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT); tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit); tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit);
tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb); tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
driver->removeTexture(tBackGround); driver->removeTexture(tBackGround);
tBackGround = GetRandomImage(TEXTURE_DUEL, bgWidth, bgHeight); tBackGround = GetRandomImage(TEXTURE_DUEL, bgWidth, bgHeight);
if(!tBackGround) if(!tBackGround)
...@@ -342,62 +352,122 @@ irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) { ...@@ -342,62 +352,122 @@ irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) {
else else
return mainGame->gameConf.use_image_scale ? (fit ? tUnknownFit : tUnknown) : GetTextureThumb(code); return mainGame->gameConf.use_image_scale ? (fit ? tUnknownFit : tUnknown) : GetTextureThumb(code);
} }
irr::video::ITexture* ImageManager::GetTextureThumb(int code) { int ImageManager::LoadThumbThread() {
if(code == 0) while(true) {
return tUnknownThumb; imageManager.tThumbLoadingMutex.lock();
auto tit = tThumb.find(code); int code = imageManager.tThumbLoadingCodes.front();
int width = CARD_THUMB_WIDTH * mainGame->xScale; imageManager.tThumbLoadingCodes.pop();
int height = CARD_THUMB_HEIGHT * mainGame->yScale; imageManager.tThumbLoadingMutex.unlock();
if(tit == tThumb.end()) {
char file[256]; char file[256];
sprintf(file, "expansions/pics/thumbnail/%d.png", code); sprintf(file, "expansions/pics/thumbnail/%d.png", code);
irr::video::ITexture* img = GetTextureFromFile(file, width, height); irr::video::IImage* img = imageManager.driver->createImageFromFile(file);
if(img == NULL) { if(img == NULL) {
sprintf(file, "expansions/pics/thumbnail/%d.jpg", code); sprintf(file, "expansions/pics/thumbnail/%d.jpg", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/thumbnail/%d.png"), code); sprintf(file, mainGame->GetLocaleDir("pics/thumbnail/%d.png"), code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/thumbnail/%d.jpg"), code); sprintf(file, mainGame->GetLocaleDir("pics/thumbnail/%d.jpg"), code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, "pics/thumbnail/%d.png", code); sprintf(file, "pics/thumbnail/%d.png", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, "pics/thumbnail/%d.jpg", code); sprintf(file, "pics/thumbnail/%d.jpg", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL && mainGame->gameConf.use_image_scale) { if(img == NULL && mainGame->gameConf.use_image_scale) {
sprintf(file, "expansions/pics/%d.png", code); sprintf(file, "expansions/pics/%d.png", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
if(img == NULL) { if(img == NULL) {
sprintf(file, "expansions/pics/%d.jpg", code); sprintf(file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/%d.png"), code); sprintf(file, mainGame->GetLocaleDir("pics/%d.png"), code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, mainGame->GetLocaleDir("pics/%d.jpg"), code); sprintf(file, mainGame->GetLocaleDir("pics/%d.jpg"), code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, "pics/%d.png", code); sprintf(file, "pics/%d.png", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
if(img == NULL) { if(img == NULL) {
sprintf(file, "pics/%d.jpg", code); sprintf(file, "pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height); img = imageManager.driver->createImageFromFile(file);
} }
} }
tThumb[code] = img; if(img != NULL) {
return (img == NULL) ? tUnknownThumb : img; int width = CARD_THUMB_WIDTH * mainGame->xScale;
int height = CARD_THUMB_HEIGHT * mainGame->yScale;
if(img->getDimension() == irr::core::dimension2d<u32>(width, height)) {
img->grab();
imageManager.tThumbLoadingMutex.lock();
if(imageManager.tThumbLoadingThreadRunning)
imageManager.tThumbLoading[code] = img;
imageManager.tThumbLoadingMutex.unlock();
} else {
irr::video::IImage *destimg = imageManager.driver->createImage(img->getColorFormat(), irr::core::dimension2d<u32>(width, height));
imageScaleNNAA(img, destimg);
img->drop();
destimg->grab();
imageManager.tThumbLoadingMutex.lock();
if(imageManager.tThumbLoadingThreadRunning)
imageManager.tThumbLoading[code] = destimg;
imageManager.tThumbLoadingMutex.unlock();
}
} else {
imageManager.tThumbLoadingMutex.lock();
if(imageManager.tThumbLoadingThreadRunning)
imageManager.tThumbLoading[code] = NULL;
imageManager.tThumbLoadingMutex.unlock();
}
imageManager.tThumbLoadingMutex.lock();
imageManager.tThumbLoadingThreadRunning = !imageManager.tThumbLoadingCodes.empty();
if(!imageManager.tThumbLoadingThreadRunning)
break;
imageManager.tThumbLoadingMutex.unlock();
}
imageManager.tThumbLoadingMutex.unlock();
return 0;
}
irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0)
return tUnknownThumb;
imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) {
if(lit->second != NULL) {
char file[256];
sprintf(file, "pics/thumbnail/%d.jpg", code);
irr::video::ITexture* texture = driver->addTexture(file, lit->second); // textures must be added in the main thread due to OpenGL
lit->second->drop();
tThumb[code] = texture;
} else {
tThumb[code] = NULL;
}
tThumbLoading.erase(lit);
}
imageManager.tThumbLoadingMutex.unlock();
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
tThumb[code] = tLoading;
imageManager.tThumbLoadingMutex.lock();
tThumbLoadingCodes.push(code);
if(!tThumbLoadingThreadRunning) {
tThumbLoadingThreadRunning = true;
std::thread(LoadThumbThread).detach();
}
imageManager.tThumbLoadingMutex.unlock();
return tLoading;
} }
if(tit->second) if(tit->second)
return tit->second; return tit->second;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#include "data_manager.h" #include "data_manager.h"
#include <unordered_map> #include <unordered_map>
#include <queue>
namespace ygo { namespace ygo {
...@@ -25,16 +26,22 @@ public: ...@@ -25,16 +26,22 @@ public:
irr::video::ITexture* GetTexture(int code, bool fit = false); irr::video::ITexture* GetTexture(int code, bool fit = false);
irr::video::ITexture* GetTextureThumb(int code); irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code); irr::video::ITexture* GetTextureField(int code);
static int LoadThumbThread();
std::unordered_map<int, irr::video::ITexture*> tMap[2]; std::unordered_map<int, irr::video::ITexture*> tMap[2];
std::unordered_map<int, irr::video::ITexture*> tThumb; std::unordered_map<int, irr::video::ITexture*> tThumb;
std::unordered_map<int, irr::video::ITexture*> tFields; std::unordered_map<int, irr::video::ITexture*> tFields;
std::unordered_map<int, irr::video::IImage*> tThumbLoading;
std::queue<int> tThumbLoadingCodes;
std::mutex tThumbLoadingMutex;
bool tThumbLoadingThreadRunning;
irr::IrrlichtDevice* device; irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver; irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[4]; irr::video::ITexture* tCover[4];
irr::video::ITexture* tUnknown; irr::video::ITexture* tUnknown;
irr::video::ITexture* tUnknownFit; irr::video::ITexture* tUnknownFit;
irr::video::ITexture* tUnknownThumb; irr::video::ITexture* tUnknownThumb;
irr::video::ITexture* tLoading;
irr::video::ITexture* tAct; irr::video::ITexture* tAct;
irr::video::ITexture* tAttack; irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated; irr::video::ITexture* tNegated;
......
...@@ -9,6 +9,7 @@ project "ygopro" ...@@ -9,6 +9,7 @@ project "ygopro"
"DECKCOUNT_MAIN_MAX", "DECKCOUNT_MAIN_MAX",
"DECKCOUNT_SIDE", "DECKCOUNT_SIDE",
"DECKCOUNT_EXTRA", "DECKCOUNT_EXTRA",
"NO_SIDE_CHECK"
} }
for _,param in ipairs(params) do for _,param in ipairs(params) do
......
...@@ -234,8 +234,7 @@ void ReplayMode::EndDuel() { ...@@ -234,8 +234,7 @@ void ReplayMode::EndDuel() {
mainGame->actionSignal.Reset(); mainGame->actionSignal.Reset();
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->stMessage->setText(dataManager.GetSysString(1501)); mainGame->stMessage->setText(dataManager.GetSysString(1501));
if(mainGame->wCardSelect->isVisible()) mainGame->HideElement(mainGame->wCardSelect);
mainGame->HideElement(mainGame->wCardSelect);
mainGame->PopupElement(mainGame->wMessage); mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.unlock(); mainGame->gMutex.unlock();
if(auto_watch_mode) { if(auto_watch_mode) {
......
...@@ -553,6 +553,11 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -553,6 +553,11 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = 0; rh.flag = 0;
time_t seed = time(0); time_t seed = time(0);
#ifdef YGOPRO_SERVER_MODE
if(pre_seed[duel_count] > 0) {
seed = pre_seed[duel_count];
}
#endif
rh.seed = seed; rh.seed = seed;
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
...@@ -638,6 +643,15 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -638,6 +643,15 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
start_duel(pduel, opt); start_duel(pduel, opt);
if(host_info.time_limit) {
time_elapsed = 0;
#ifdef YGOPRO_SERVER_MODE
time_compensator[0] = host_info.time_limit;
time_compensator[1] = host_info.time_limit;
#endif
timeval timeout = { 1, 0 };
event_add(etimer, &timeout);
}
Process(); Process();
} }
void SingleDuel::Process() { void SingleDuel::Process() {
...@@ -1195,6 +1209,10 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1195,6 +1209,10 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
#endif #endif
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
#ifdef YGOPRO_SERVER_MODE
time_compensator[0] = host_info.time_limit;
time_compensator[1] = host_info.time_limit;
#endif
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
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)
...@@ -1819,7 +1837,7 @@ void SingleDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -1819,7 +1837,7 @@ void SingleDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
if(time_limit[dp->type] >= time_elapsed) if(time_limit[dp->type] >= time_elapsed)
time_limit[dp->type] -= time_elapsed; time_limit[dp->type] -= time_elapsed;
else time_limit[dp->type] = 0; else time_limit[dp->type] = 0;
event_del(etimer); time_elapsed = 0;
} }
Process(); Process();
} }
...@@ -1846,6 +1864,7 @@ void SingleDuel::EndDuel() { ...@@ -1846,6 +1864,7 @@ void SingleDuel::EndDuel() {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
*/ */
end_duel(pduel); end_duel(pduel);
event_del(etimer);
pduel = 0; pduel = 0;
} }
void SingleDuel::WaitforResponse(int playerid) { void SingleDuel::WaitforResponse(int playerid) {
...@@ -1932,9 +1951,19 @@ void SingleDuel::TimeConfirm(DuelPlayer* dp) { ...@@ -1932,9 +1951,19 @@ void SingleDuel::TimeConfirm(DuelPlayer* dp) {
if(dp->type != last_response) if(dp->type != last_response)
return; return;
players[last_response]->state = CTOS_RESPONSE; players[last_response]->state = CTOS_RESPONSE;
time_elapsed = 0; #ifdef YGOPRO_SERVER_MODE
timeval timeout = {1, 0}; if(time_elapsed < 10 && time_elapsed <= time_compensator[dp->type]){
event_add(etimer, &timeout); time_compensator[dp->type] -= time_elapsed;
time_elapsed = 0;
}
else {
time_limit[dp->type] -= time_elapsed;
time_elapsed = 0;
}
#else
if(time_elapsed < 10)
time_elapsed = 0;
#endif //YGOPRO_SERVER_MODE
} }
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
void SingleDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp) void SingleDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp)
...@@ -2244,7 +2273,10 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) { ...@@ -2244,7 +2273,10 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) {
sd->EndDuel(); sd->EndDuel();
sd->DuelEndProc(); sd->DuelEndProc();
event_del(sd->etimer); event_del(sd->etimer);
return;
} }
timeval timeout = { 1, 0 };
event_add(sd->etimer, &timeout);
} }
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
void SingleDuel::TestCard(int code) { void SingleDuel::TestCard(int code) {
......
...@@ -87,6 +87,9 @@ protected: ...@@ -87,6 +87,9 @@ protected:
unsigned char match_result[3]; unsigned char match_result[3];
unsigned short time_limit[2]; unsigned short time_limit[2];
unsigned short time_elapsed; unsigned short time_elapsed;
#ifdef YGOPRO_SERVER_MODE
unsigned short time_compensator[2];
#endif
}; };
} }
......
...@@ -506,6 +506,11 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -506,6 +506,11 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh.flag = REPLAY_TAG; rh.flag = REPLAY_TAG;
time_t seed = time(0); time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
#ifdef YGOPRO_SERVER_MODE
if(pre_seed[0] > 0) {
seed = pre_seed[0];
}
#endif
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
rnd.reset(seed); rnd.reset(seed);
...@@ -627,6 +632,15 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -627,6 +632,15 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
start_duel(pduel, opt); start_duel(pduel, opt);
if(host_info.time_limit) {
time_elapsed = 0;
#ifdef YGOPRO_SERVER_MODE
time_compensator[0] = host_info.time_limit;
time_compensator[1] = host_info.time_limit;
#endif
timeval timeout = { 1, 0 };
event_add(etimer, &timeout);
}
Process(); Process();
} }
void TagDuel::Process() { void TagDuel::Process() {
...@@ -1098,6 +1112,10 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1098,6 +1112,10 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
#endif #endif
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
#ifdef YGOPRO_SERVER_MODE
time_compensator[0] = host_info.time_limit;
time_compensator[1] = host_info.time_limit;
#endif
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]); NetServer::ReSendToPlayer(players[2]);
...@@ -1853,7 +1871,7 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -1853,7 +1871,7 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
if(time_limit[resp_type] >= time_elapsed) if(time_limit[resp_type] >= time_elapsed)
time_limit[resp_type] -= time_elapsed; time_limit[resp_type] -= time_elapsed;
else time_limit[resp_type] = 0; else time_limit[resp_type] = 0;
event_del(etimer); time_elapsed = 0;
} }
Process(); Process();
} }
...@@ -1880,6 +1898,7 @@ void TagDuel::EndDuel() { ...@@ -1880,6 +1898,7 @@ void TagDuel::EndDuel() {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
#endif #endif
end_duel(pduel); end_duel(pduel);
event_del(etimer);
pduel = 0; pduel = 0;
} }
void TagDuel::WaitforResponse(int playerid) { void TagDuel::WaitforResponse(int playerid) {
...@@ -1970,9 +1989,19 @@ void TagDuel::TimeConfirm(DuelPlayer* dp) { ...@@ -1970,9 +1989,19 @@ void TagDuel::TimeConfirm(DuelPlayer* dp) {
if(dp != cur_player[last_response]) if(dp != cur_player[last_response])
return; return;
cur_player[last_response]->state = CTOS_RESPONSE; cur_player[last_response]->state = CTOS_RESPONSE;
time_elapsed = 0; #ifdef YGOPRO_SERVER_MODE
timeval timeout = {1, 0}; if(time_elapsed < 10 && time_elapsed <= time_compensator[dp->type]){
event_add(etimer, &timeout); time_compensator[dp->type] -= time_elapsed;
time_elapsed = 0;
}
else {
time_limit[dp->type] -= time_elapsed;
time_elapsed = 0;
}
#else
if(time_elapsed < 10)
time_elapsed = 0;
#endif //YGOPRO_SERVER_MODE
} }
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
void TagDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp) void TagDuel::RefreshMzone(int player, int flag, int use_cache, DuelPlayer* dp)
...@@ -2328,7 +2357,10 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) { ...@@ -2328,7 +2357,10 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) {
sd->EndDuel(); sd->EndDuel();
sd->DuelEndProc(); sd->DuelEndProc();
event_del(sd->etimer); event_del(sd->etimer);
return;
} }
timeval timeout = { 1, 0 };
event_add(sd->etimer, &timeout);
} }
} }
...@@ -73,6 +73,9 @@ protected: ...@@ -73,6 +73,9 @@ protected:
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;
#ifdef YGOPRO_SERVER_MODE
unsigned short time_compensator[2];
#endif
}; };
} }
......
...@@ -317,6 +317,7 @@ ...@@ -317,6 +317,7 @@
!system 1262 大师规则3 !system 1262 大师规则3
!system 1263 新大师规则 !system 1263 新大师规则
!system 1264 大师规则2020 !system 1264 大师规则2020
!system 1269 数字灵摆图片
!system 1270 卡片信息 !system 1270 卡片信息
!system 1271 消息记录 !system 1271 消息记录
!system 1272 清除记录 !system 1272 清除记录
...@@ -334,7 +335,7 @@ ...@@ -334,7 +335,7 @@
!system 1284 !system 1284
!system 1285 !system 1285
!system 1286 特大 !system 1286 特大
!system 1287 数字灵摆图片 !system 1287 只有连锁1也显示连锁动画
!system 1288 语言(重启后生效) !system 1288 语言(重启后生效)
!system 1289 默认 !system 1289 默认
!system 1290 忽略对方发言 !system 1290 忽略对方发言
......
...@@ -38,6 +38,7 @@ enable_bot_mode = 1 ...@@ -38,6 +38,7 @@ enable_bot_mode = 1
bot_deck_path = ./windbot/Decks bot_deck_path = ./windbot/Decks
quick_animation = 1 quick_animation = 1
auto_save_replay = 1 auto_save_replay = 1
draw_single_chain = 0
window_maximized = 0 window_maximized = 0
window_width = 1024 window_width = 1024
window_height = 640 window_height = 640
......
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