Commit 3a597afc authored by edo9300's avatar edo9300

New replay system

parent 6880af21
...@@ -121,6 +121,27 @@ public: ...@@ -121,6 +121,27 @@ public:
return ret; return ret;
return 0; return 0;
} }
struct ReplayPacket {
int message;
int length;
unsigned char data[0x2000];
ReplayPacket() {}
ReplayPacket(char * buf, int len) {
message = ReadInt8(buf);
length = len;
memcpy(data, buf, length);
}
ReplayPacket(int msg, char * buf, int len) {
message = msg;
length = len;
memcpy(data, buf, length);
}
void Set(int msg, char * buf, int len) {
message = msg;
length = len;
memcpy(data, buf, length);
}
};
}; };
#endif //BUFFERIO_H #endif //BUFFERIO_H
...@@ -53,7 +53,8 @@ ClientCard::ClientCard() { ...@@ -53,7 +53,8 @@ ClientCard::ClientCard() {
void ClientCard::SetCode(int code) { void ClientCard::SetCode(int code) {
if((location == LOCATION_HAND) && (this->code != (unsigned int)code)) { if((location == LOCATION_HAND) && (this->code != (unsigned int)code)) {
this->code = code; this->code = code;
mainGame->dField.MoveCard(this, 5); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->dField.MoveCard(this, 5);
} else } else
this->code = code; this->code = code;
} }
...@@ -66,7 +67,8 @@ void ClientCard::UpdateInfo(char* buf) { ...@@ -66,7 +67,8 @@ void ClientCard::UpdateInfo(char* buf) {
pdata = BufferIO::ReadInt32(buf); pdata = BufferIO::ReadInt32(buf);
if((location == LOCATION_HAND) && ((unsigned int)pdata != code)) { if((location == LOCATION_HAND) && ((unsigned int)pdata != code)) {
code = pdata; code = pdata;
mainGame->dField.MoveCard(this, 5); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->dField.MoveCard(this, 5);
} else } else
code = pdata; code = pdata;
} }
......
...@@ -26,6 +26,10 @@ u64 DuelClient::select_hint = 0; ...@@ -26,6 +26,10 @@ u64 DuelClient::select_hint = 0;
wchar_t DuelClient::event_string[256]; wchar_t DuelClient::event_string[256];
mtrandom DuelClient::rnd; mtrandom DuelClient::rnd;
std::vector<BufferIO::ReplayPacket> DuelClient::replay_stream;
Replay DuelClient::last_replay;
bool DuelClient::old_replay = true;
bool DuelClient::is_refreshing = false; bool DuelClient::is_refreshing = false;
int DuelClient::match_kill = 0; int DuelClient::match_kill = 0;
std::vector<HostPacket> DuelClient::hosts; std::vector<HostPacket> DuelClient::hosts;
...@@ -693,43 +697,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -693,43 +697,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->btnSideReload->setVisible(false); mainGame->btnSideReload->setVisible(false);
mainGame->wChat->setVisible(true); mainGame->wChat->setVisible(true);
mainGame->device->setEventReceiver(&mainGame->dField); mainGame->device->setEventReceiver(&mainGame->dField);
// reset master rule 4 phase button position mainGame->SetPhaseButtons();
mainGame->wPhase->setRelativePosition(mainGame->Resize(480, 310, 855, 330));
if(mainGame->dInfo.extraval & 0x1) {
if(mainGame->dInfo.duel_field >= 4) {
mainGame->wPhase->setRelativePosition(mainGame->Resize(480, 290, 855, 350));
mainGame->btnShuffle->setRelativePosition(mainGame->Resize(0, 40, 50, 60));
mainGame->btnDP->setRelativePosition(mainGame->Resize(0, 40, 50, 60));
mainGame->btnSP->setRelativePosition(mainGame->Resize(0, 40, 50, 60));
mainGame->btnM1->setRelativePosition(mainGame->Resize(160, 20, 210, 40));
mainGame->btnBP->setRelativePosition(mainGame->Resize(160, 20, 210, 40));
mainGame->btnM2->setRelativePosition(mainGame->Resize(160, 20, 210, 40));
mainGame->btnEP->setRelativePosition(mainGame->Resize(310, 0, 360, 20));
} else {
mainGame->btnShuffle->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnDP->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnSP->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(130, 0, 180, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(195, 0, 245, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(260, 0, 310, 20));
mainGame->btnEP->setRelativePosition(mainGame->Resize(260, 0, 310, 20));
}
} else {
mainGame->btnDP->setRelativePosition(mainGame->Resize(0, 0, 50, 20));
if(mainGame->dInfo.duel_field >= 4) {
mainGame->btnSP->setRelativePosition(mainGame->Resize(0, 0, 50, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
} else {
mainGame->btnSP->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(130, 0, 180, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(195, 0, 245, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(260, 0, 310, 20));
}
mainGame->btnEP->setRelativePosition(mainGame->Resize(320, 0, 370, 20));
mainGame->btnShuffle->setRelativePosition(mainGame->Resize(0, 0, 50, 20));
}
if(!mainGame->dInfo.isTag) { if(!mainGame->dInfo.isTag) {
if(selftype > 1) { if(selftype > 1) {
mainGame->dInfo.player_type = 7; mainGame->dInfo.player_type = 7;
...@@ -767,6 +735,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -767,6 +735,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
} }
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
match_kill = 0; match_kill = 0;
replay_stream.clear();
break; break;
} }
case STOC_DUEL_END: { case STOC_DUEL_END: {
...@@ -823,16 +792,28 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -823,16 +792,28 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
mainGame->replaySignal.Reset(); mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait(); mainGame->replaySignal.Wait();
if(mainGame->actionParam || !is_host) { if(mainGame->saveReplay || !is_host) {
char* prep = pdata; char* prep = pdata;
Replay new_replay; ReplayHeader pheader;
memcpy(&new_replay.pheader, prep, sizeof(ReplayHeader)); memcpy(&pheader, prep, sizeof(ReplayHeader));
prep += sizeof(ReplayHeader); replay_stream.push_back(BufferIO::ReplayPacket(OLD_REPLAY_SYSTEM, prep, len - 1));
memcpy(new_replay.comp_data, prep, len - sizeof(ReplayHeader) - 1); if(old_replay && mainGame->saveReplay) {
new_replay.comp_size = len - sizeof(ReplayHeader) - 1; last_replay.BeginRecord();
if(mainGame->actionParam) last_replay.WriteHeader(pheader);
new_replay.SaveReplay(mainGame->ebRSName->getText()); last_replay.pheader.id = 0x58707279;
else new_replay.SaveReplay(L"_LastReplay"); last_replay.WriteData(mainGame->dInfo.hostname, 40, false);
last_replay.WriteData(mainGame->dInfo.clientname, 40, false);
if (last_replay.pheader.flag & REPLAY_TAG) {
last_replay.WriteData(mainGame->dInfo.hostname_tag, 40, false);
last_replay.WriteData(mainGame->dInfo.clientname_tag, 40, false);
}
last_replay.WriteInt32(mainGame->dInfo.duel_field | mainGame->dInfo.extraval);
last_replay.WriteStream(replay_stream);
last_replay.EndRecord();
}
if (mainGame->saveReplay)
last_replay.SaveReplay(mainGame->ebRSName->getText());
else last_replay.SaveReplay(L"_LastReplay");
} }
break; break;
} }
...@@ -975,12 +956,30 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -975,12 +956,30 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
break; break;
} }
case STOC_NEW_REPLAY: {
char* prep = pdata;
memcpy(&last_replay.pheader, prep, sizeof(ReplayHeader));
prep += sizeof(ReplayHeader);
memcpy(last_replay.comp_data, prep, len - sizeof(ReplayHeader) - 1);
last_replay.comp_size = len - sizeof(ReplayHeader) - 1;
old_replay = false;
break;
}
} }
} }
int DuelClient::ClientAnalyze(char * msg, unsigned int len) { 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); if(!mainGame->dInfo.isReplay) {
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
if(mainGame->dInfo.curMsg != MSG_WAITING) {
BufferIO::ReplayPacket p;
p.message = mainGame->dInfo.curMsg;
p.length = len - 1;
memcpy(p.data, pbuf, p.length);
replay_stream.push_back(p);
}
}
mainGame->wCmdMenu->setVisible(false); mainGame->wCmdMenu->setVisible(false);
if(!mainGame->dInfo.isReplay && mainGame->dInfo.curMsg != MSG_WAITING && mainGame->dInfo.curMsg != MSG_CARD_SELECTED) { if(!mainGame->dInfo.isReplay && mainGame->dInfo.curMsg != MSG_WAITING && mainGame->dInfo.curMsg != MSG_CARD_SELECTED) {
mainGame->waitFrame = -1; mainGame->waitFrame = -1;
...@@ -1164,15 +1163,17 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1164,15 +1163,17 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
return true; return true;
} }
case MSG_START: { case MSG_START: {
mainGame->showcardcode = 11;
mainGame->showcarddif = 30;
mainGame->showcardp = 0;
mainGame->showcard = 101;
mainGame->WaitFrameSignal(40);
mainGame->showcard = 0;
mainGame->gMutex.Lock();
int playertype = BufferIO::ReadInt8(pbuf); int playertype = BufferIO::ReadInt8(pbuf);
mainGame->dInfo.isFirst = (playertype & 0xf) ? false : true; if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->showcardcode = 11;
mainGame->showcarddif = 30;
mainGame->showcardp = 0;
mainGame->showcard = 101;
mainGame->WaitFrameSignal(40);
mainGame->showcard = 0;
mainGame->gMutex.Lock();
mainGame->dInfo.isFirst = (playertype & 0xf) ? false : true;
}
if(playertype & 0xf0) if(playertype & 0xf0)
mainGame->dInfo.player_type = 7; mainGame->dInfo.player_type = 7;
if(mainGame->dInfo.isTag) { if(mainGame->dInfo.isTag) {
...@@ -1197,24 +1198,29 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1197,24 +1198,29 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dField.Initial(mainGame->LocalPlayer(1), deckc, extrac); mainGame->dField.Initial(mainGame->LocalPlayer(1), deckc, extrac);
mainGame->dInfo.turn = 0; mainGame->dInfo.turn = 0;
mainGame->dInfo.is_shuffling = false; mainGame->dInfo.is_shuffling = false;
mainGame->gMutex.Unlock(); if (!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Unlock();
return true; return true;
} }
case MSG_UPDATE_DATA: { case MSG_UPDATE_DATA: {
int player = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf)); int player = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int location = BufferIO::ReadInt8(pbuf); int location = BufferIO::ReadInt8(pbuf);
mainGame->gMutex.Lock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Lock();
mainGame->dField.UpdateFieldCard(player, location, pbuf); mainGame->dField.UpdateFieldCard(player, location, pbuf);
mainGame->gMutex.Unlock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Unlock();
return true; return true;
} }
case MSG_UPDATE_CARD: { case MSG_UPDATE_CARD: {
int player = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf)); int player = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int loc = BufferIO::ReadInt8(pbuf); int loc = BufferIO::ReadInt8(pbuf);
int seq = BufferIO::ReadInt8(pbuf); int seq = BufferIO::ReadInt8(pbuf);
mainGame->gMutex.Lock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Lock();
mainGame->dField.UpdateCard(player, loc, seq, pbuf); mainGame->dField.UpdateCard(player, loc, seq, pbuf);
mainGame->gMutex.Unlock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Unlock();
break; break;
} }
case MSG_SELECT_BATTLECMD: { case MSG_SELECT_BATTLECMD: {
...@@ -3728,11 +3734,13 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -3728,11 +3734,13 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
break; break;
} }
case MSG_RELOAD_FIELD: { case MSG_RELOAD_FIELD: {
mainGame->gMutex.Lock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Lock();
mainGame->dField.Clear(); mainGame->dField.Clear();
int field = BufferIO::ReadInt8(pbuf); int field = BufferIO::ReadInt8(pbuf);
mainGame->dInfo.duel_field = field & 0xf; mainGame->dInfo.duel_field = field & 0xf;
mainGame->dInfo.extraval = field >> 4; mainGame->dInfo.extraval = field >> 4;
mainGame->SetPhaseButtons();
int val = 0; int val = 0;
for(int i = 0; i < 2; ++i) { for(int i = 0; i < 2; ++i) {
int p = mainGame->LocalPlayer(i); int p = mainGame->LocalPlayer(i);
...@@ -3847,7 +3855,8 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -3847,7 +3855,8 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code)); myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code));
mainGame->dField.last_chain = true; mainGame->dField.last_chain = true;
} }
mainGame->gMutex.Unlock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping)
mainGame->gMutex.Unlock();
break; break;
} }
} }
...@@ -3913,10 +3922,11 @@ void DuelClient::SendResponse() { ...@@ -3913,10 +3922,11 @@ void DuelClient::SendResponse() {
break; break;
} }
} }
replay_stream.pop_back();
if(mainGame->dInfo.isSingleMode) { if(mainGame->dInfo.isSingleMode) {
SingleMode::SetResponse(response_buf, response_len); SingleMode::SetResponse(response_buf, response_len);
mainGame->singleSignal.Set(); mainGame->singleSignal.Set();
} else { } else if (!mainGame->dInfo.isReplay) {
mainGame->dInfo.time_player = 2; mainGame->dInfo.time_player = 2;
SendBufferToServer(CTOS_RESPONSE, response_buf, response_len); SendBufferToServer(CTOS_RESPONSE, response_buf, response_len);
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "data_manager.h" #include "data_manager.h"
#include "deck_manager.h" #include "deck_manager.h"
#include "../ocgcore/mtrandom.h" #include "../ocgcore/mtrandom.h"
#include "replay.h"
namespace ygo { namespace ygo {
...@@ -45,6 +46,9 @@ public: ...@@ -45,6 +46,9 @@ 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 std::vector<BufferIO::ReplayPacket> replay_stream;
static Replay last_replay;
static bool old_replay;
static int ClientAnalyze(char* msg, unsigned int len); static int ClientAnalyze(char* msg, unsigned int len);
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);
......
...@@ -95,13 +95,13 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -95,13 +95,13 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case BUTTON_REPLAY_SAVE: { case BUTTON_REPLAY_SAVE: {
if(mainGame->ebRSName->getText()[0] == 0) if(mainGame->ebRSName->getText()[0] == 0)
break; break;
mainGame->actionParam = 1; mainGame->saveReplay = 1;
mainGame->HideElement(mainGame->wReplaySave); mainGame->HideElement(mainGame->wReplaySave);
mainGame->replaySignal.Set(); mainGame->replaySignal.Set();
break; break;
} }
case BUTTON_REPLAY_CANCEL: { case BUTTON_REPLAY_CANCEL: {
mainGame->actionParam = 0; mainGame->saveReplay = 0;
mainGame->HideElement(mainGame->wReplaySave); mainGame->HideElement(mainGame->wReplaySave);
mainGame->replaySignal.Set(); mainGame->replaySignal.Set();
break; break;
......
...@@ -1228,7 +1228,7 @@ bool Game::PlayChant(unsigned int code) { ...@@ -1228,7 +1228,7 @@ bool Game::PlayChant(unsigned int code) {
return false; return false;
} }
void Game::PlaySoundEffect(char* sound) { void Game::PlaySoundEffect(char* sound) {
if(chkEnableSound->isChecked()) { if(chkEnableSound->isChecked() && (!dInfo.isReplay || !dInfo.isReplaySkiping)) {
engineSound->play2D(sound); engineSound->play2D(sound);
engineSound->setSoundVolume(gameConf.volume); engineSound->setSoundVolume(gameConf.volume);
} }
...@@ -1563,8 +1563,46 @@ int Game::GetMasterRule(uint32 param, uint32 forbiddentypes, int* truerule) { ...@@ -1563,8 +1563,46 @@ int Game::GetMasterRule(uint32 param, uint32 forbiddentypes, int* truerule) {
} }
} }
} }
void Game::OnResize() void Game::SetPhaseButtons() {
{ // reset master rule 4 phase button position
wPhase->setRelativePosition(Resize(480, 310, 855, 330));
if (dInfo.extraval & 0x1) {
if (dInfo.duel_field >= 4) {
wPhase->setRelativePosition(Resize(480, 290, 855, 350));
btnShuffle->setRelativePosition(Resize(0, 40, 50, 60));
btnDP->setRelativePosition(Resize(0, 40, 50, 60));
btnSP->setRelativePosition(Resize(0, 40, 50, 60));
btnM1->setRelativePosition(Resize(160, 20, 210, 40));
btnBP->setRelativePosition(Resize(160, 20, 210, 40));
btnM2->setRelativePosition(Resize(160, 20, 210, 40));
btnEP->setRelativePosition(Resize(310, 0, 360, 20));
} else {
btnShuffle->setRelativePosition(Resize(65, 0, 115, 20));
btnDP->setRelativePosition(Resize(65, 0, 115, 20));
btnSP->setRelativePosition(Resize(65, 0, 115, 20));
btnM1->setRelativePosition(Resize(130, 0, 180, 20));
btnBP->setRelativePosition(Resize(195, 0, 245, 20));
btnM2->setRelativePosition(Resize(260, 0, 310, 20));
btnEP->setRelativePosition(Resize(260, 0, 310, 20));
}
} else {
btnDP->setRelativePosition(Resize(0, 0, 50, 20));
if (dInfo.duel_field >= 4) {
btnSP->setRelativePosition(Resize(0, 0, 50, 20));
btnM1->setRelativePosition(Resize(160, 0, 210, 20));
btnBP->setRelativePosition(Resize(160, 0, 210, 20));
btnM2->setRelativePosition(Resize(160, 0, 210, 20));
} else {
btnSP->setRelativePosition(Resize(65, 0, 115, 20));
btnM1->setRelativePosition(Resize(130, 0, 180, 20));
btnBP->setRelativePosition(Resize(195, 0, 245, 20));
btnM2->setRelativePosition(Resize(260, 0, 310, 20));
}
btnEP->setRelativePosition(Resize(320, 0, 370, 20));
btnShuffle->setRelativePosition(Resize(0, 0, 50, 20));
}
}
void Game::OnResize() {
wMainMenu->setRelativePosition(ResizeWin(370, 200, 650, 415)); wMainMenu->setRelativePosition(ResizeWin(370, 200, 650, 415));
wDeckEdit->setRelativePosition(Resize(309, 8, 605, 130)); wDeckEdit->setRelativePosition(Resize(309, 8, 605, 130));
cbDBLFList->setRelativePosition(Resize(80, 5, 220, 30)); cbDBLFList->setRelativePosition(Resize(80, 5, 220, 30));
...@@ -1662,42 +1700,7 @@ void Game::OnResize() ...@@ -1662,42 +1700,7 @@ void Game::OnResize()
btnReplaySwap->setRelativePosition(Resize(5, 30, 85, 50)); btnReplaySwap->setRelativePosition(Resize(5, 30, 85, 50));
btnReplayExit->setRelativePosition(Resize(5, 105, 85, 125)); btnReplayExit->setRelativePosition(Resize(5, 105, 85, 125));
wPhase->setRelativePosition(Resize(480, 310, 855, 330)); SetPhaseButtons();
if(dInfo.extraval & 0x1) {
if(dInfo.duel_field >= 4) {
wPhase->setRelativePosition(Resize(480, 290, 855, 350));
btnShuffle->setRelativePosition(Resize(0, 40, 50, 60));
btnDP->setRelativePosition(Resize(0, 40, 50, 60));
btnSP->setRelativePosition(Resize(0, 40, 50, 60));
btnM1->setRelativePosition(Resize(160, 20, 210, 40));
btnBP->setRelativePosition(Resize(160, 20, 210, 40));
btnM2->setRelativePosition(Resize(160, 20, 210, 40));
btnEP->setRelativePosition(Resize(310, 0, 360, 20));
} else {
btnShuffle->setRelativePosition(Resize(65, 0, 115, 20));
btnDP->setRelativePosition(Resize(65, 0, 115, 20));
btnSP->setRelativePosition(Resize(65, 0, 115, 20));
btnM1->setRelativePosition(Resize(130, 0, 180, 20));
btnBP->setRelativePosition(Resize(195, 0, 245, 20));
btnM2->setRelativePosition(Resize(260, 0, 310, 20));
btnEP->setRelativePosition(Resize(260, 0, 310, 20));
}
} else {
btnDP->setRelativePosition(Resize(0, 0, 50, 20));
if(dInfo.duel_field >= 4) {
btnSP->setRelativePosition(Resize(0, 0, 50, 20));
btnM1->setRelativePosition(Resize(160, 0, 210, 20));
btnBP->setRelativePosition(Resize(160, 0, 210, 20));
btnM2->setRelativePosition(Resize(160, 0, 210, 20));
} else {
btnSP->setRelativePosition(Resize(65, 0, 115, 20));
btnM1->setRelativePosition(Resize(130, 0, 180, 20));
btnBP->setRelativePosition(Resize(195, 0, 245, 20));
btnM2->setRelativePosition(Resize(260, 0, 310, 20));
}
btnEP->setRelativePosition(Resize(320, 0, 370, 20));
btnShuffle->setRelativePosition(Resize(0, 0, 50, 20));
}
btnSpectatorSwap->setRelativePosition(Resize(205, 100, 295, 135)); btnSpectatorSwap->setRelativePosition(Resize(205, 100, 295, 135));
btnChainAlways->setRelativePosition(Resize(205, 140, 295, 175)); btnChainAlways->setRelativePosition(Resize(205, 140, 295, 175));
btnChainIgnore->setRelativePosition(Resize(205, 100, 295, 135)); btnChainIgnore->setRelativePosition(Resize(205, 100, 295, 135));
......
...@@ -134,6 +134,7 @@ public: ...@@ -134,6 +134,7 @@ public:
const wchar_t* LocalName(int local_player); const wchar_t* LocalName(int local_player);
void UpdateDuelParam(); void UpdateDuelParam();
int GetMasterRule(uint32 param, uint32 forbidden, int* truerule = 0); int GetMasterRule(uint32 param, uint32 forbidden, int* truerule = 0);
void SetPhaseButtons();
bool HasFocus(EGUI_ELEMENT_TYPE type) const { bool HasFocus(EGUI_ELEMENT_TYPE type) const {
irr::gui::IGUIElement* focus = env->getFocus(); irr::gui::IGUIElement* focus = env->getFocus();
...@@ -170,7 +171,7 @@ public: ...@@ -170,7 +171,7 @@ public:
unsigned short linePattern; unsigned short linePattern;
int waitFrame; int waitFrame;
int signalFrame; int signalFrame;
int actionParam; int saveReplay;
const wchar_t* showingtext; const wchar_t* showingtext;
int showcard; int showcard;
int showcardcode; int showcardcode;
......
...@@ -215,6 +215,9 @@ public: ...@@ -215,6 +215,9 @@ public:
#define STOC_HS_PLAYER_CHANGE 0x21 #define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22 #define STOC_HS_WATCH_CHANGE 0x22
#define STOC_NEW_REPLAY 0x30
#define PLAYERCHANGE_OBSERVE 0x8 #define PLAYERCHANGE_OBSERVE 0x8
#define PLAYERCHANGE_READY 0x9 #define PLAYERCHANGE_READY 0x9
#define PLAYERCHANGE_NOTREADY 0xa #define PLAYERCHANGE_NOTREADY 0xa
......
...@@ -33,6 +33,33 @@ void Replay::BeginRecord() { ...@@ -33,6 +33,33 @@ void Replay::BeginRecord() {
pdata = replay_data; pdata = replay_data;
is_recording = true; is_recording = true;
} }
void Replay::BeginRecord2() {
#ifdef _WIN32
if(is_recording)
CloseHandle(recording_fp);
recording_fp = CreateFileW(L"./replay/_LastReplay2.yrp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
if(recording_fp == INVALID_HANDLE_VALUE)
return;
#else
if(is_recording)
fclose(fp);
fp = fopen("./replay/_LastReplay2.yrp", "wb");
if(!fp)
return;
#endif
pdata = replay_data;
is_recording = true;
}
void Replay::WritePacket(BufferIO::ReplayPacket p) {
WriteInt8(p.message, false);
WriteInt32(p.length, false);
WriteData((char*)p.data, p.length);
}
void Replay::WriteStream(std::vector<BufferIO::ReplayPacket> stream) {
if(stream.size())
for(auto it = stream.begin(); it != stream.end(); it++)
WritePacket((*it));
}
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ReplayHeader& header) {
pheader = header; pheader = header;
#ifdef _WIN32 #ifdef _WIN32
...@@ -118,7 +145,7 @@ void Replay::EndRecord() { ...@@ -118,7 +145,7 @@ void Replay::EndRecord() {
pheader.datasize = pdata - replay_data; pheader.datasize = pdata - replay_data;
pheader.flag |= REPLAY_COMPRESSED; pheader.flag |= REPLAY_COMPRESSED;
size_t propsize = 5; size_t propsize = 5;
comp_size = 0x1000; comp_size = 0x20000;
LzmaCompress(comp_data, &comp_size, replay_data, pdata - replay_data, pheader.props, &propsize, 5, 1 << 24, 3, 0, 2, 32, 1); LzmaCompress(comp_data, &comp_size, replay_data, pdata - replay_data, pheader.props, &propsize, 5, 1 << 24, 3, 0, 2, 32, 1);
is_recording = false; is_recording = false;
} }
...@@ -161,7 +188,7 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -161,7 +188,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
return false; return false;
fread(&pheader, sizeof(pheader), 1, fp); fread(&pheader, sizeof(pheader), 1, fp);
if(pheader.flag & REPLAY_COMPRESSED) { if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = fread(comp_data, 1, 0x1000, fp); comp_size = fread(comp_data, 1, 0x20000, fp);
fclose(fp); fclose(fp);
replay_size = pheader.datasize; replay_size = pheader.datasize;
if(LzmaUncompress(replay_data, &replay_size, comp_data, &comp_size, pheader.props, 5) != SZ_OK) if(LzmaUncompress(replay_data, &replay_size, comp_data, &comp_size, pheader.props, 5) != SZ_OK)
...@@ -190,7 +217,15 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -190,7 +217,15 @@ bool Replay::CheckReplay(const wchar_t* name) {
ReplayHeader rheader; ReplayHeader rheader;
fread(&rheader, sizeof(ReplayHeader), 1, rfp); fread(&rheader, sizeof(ReplayHeader), 1, rfp);
fclose(rfp); fclose(rfp);
return rheader.id == 0x31707279 && rheader.version >= 0x12d0; return (rheader.id == 0x31707279 || rheader.id == 0x58707279) && rheader.version >= 0x12d0;
}
bool Replay::ReadNextPacket(BufferIO::ReplayPacket* packet) {
if (pdata - replay_data >= (int)replay_size)
return false;
packet->message = *pdata++;
packet->length = ReadInt32();
ReadData((char*)&packet->data, packet->length);
return true;
} }
bool Replay::ReadNextResponse(unsigned char resp[64]) { bool Replay::ReadNextResponse(unsigned char resp[64]) {
if(pdata - replay_data >= (int)replay_size) if(pdata - replay_data >= (int)replay_size)
......
...@@ -27,6 +27,9 @@ public: ...@@ -27,6 +27,9 @@ public:
Replay(); Replay();
~Replay(); ~Replay();
void BeginRecord(); void BeginRecord();
void BeginRecord2();
void WriteStream(std::vector<BufferIO::ReplayPacket> stream);
void WritePacket(BufferIO::ReplayPacket p);
void WriteHeader(ReplayHeader& header); void WriteHeader(ReplayHeader& header);
void WriteData(const void* data, unsigned int length, bool flush = true); void WriteData(const void* data, unsigned int length, bool flush = true);
void WriteInt32(int data, bool flush = true); void WriteInt32(int data, bool flush = true);
...@@ -37,6 +40,7 @@ public: ...@@ -37,6 +40,7 @@ public:
void SaveReplay(const wchar_t* name); void SaveReplay(const wchar_t* name);
bool OpenReplay(const wchar_t* name); bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name); static bool CheckReplay(const wchar_t* name);
bool ReadNextPacket(BufferIO::ReplayPacket* packet);
bool ReadNextResponse(unsigned char resp[64]); bool ReadNextResponse(unsigned char resp[64]);
void ReadName(wchar_t* data); void ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header); void ReadHeader(ReplayHeader& header);
......
This diff is collapsed.
...@@ -16,8 +16,9 @@ private: ...@@ -16,8 +16,9 @@ private:
static bool is_closing; static bool is_closing;
static bool is_pausing; static bool is_pausing;
static bool is_paused; static bool is_paused;
static bool is_swaping; static bool is_swapping;
static bool is_restarting; static bool is_restarting;
static bool undo;
static bool exit_pending; static bool exit_pending;
static int skip_turn; static int skip_turn;
static int current_step; static int current_step;
...@@ -25,6 +26,7 @@ private: ...@@ -25,6 +26,7 @@ private:
public: public:
static Replay cur_replay; static Replay cur_replay;
static std::vector<BufferIO::ReplayPacket> ReplayMode::current_stream;
public: public:
static bool StartReplay(int skipturn); static bool StartReplay(int skipturn);
...@@ -37,17 +39,7 @@ public: ...@@ -37,17 +39,7 @@ public:
static void EndDuel(); static void EndDuel();
static void Restart(bool refresh); static void Restart(bool refresh);
static void Undo(); static void Undo();
static bool ReplayAnalyze(char* msg, unsigned int len); static bool ReplayAnalyze(BufferIO::ReplayPacket p);
static void ReplayRefresh(int flag = 0xf81fff);
static void ReplayRefreshHand(int player, int flag = 0x781fff);
static void ReplayRefreshGrave(int player, int flag = 0x181fff);
static void ReplayRefreshDeck(int player, int flag = 0x181fff);
static void ReplayRefreshExtra(int player, int flag = 0x181fff);
static void ReplayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void ReplayReload();
static int MessageHandler(long fduel, int type);
}; };
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
namespace ygo { namespace ygo {
std::vector<BufferIO::ReplayPacket> SingleDuel::replay_stream;
SingleDuel::SingleDuel(bool is_match) { SingleDuel::SingleDuel(bool is_match) {
game_started = false; game_started = false;
match_mode = is_match; match_mode = is_match;
...@@ -185,6 +187,8 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) { ...@@ -185,6 +187,8 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
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);
BufferIO::ReplayPacket p((char*)wbuf, 3);
replay_stream.push_back(p);
EndDuel(); EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END); NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
...@@ -401,6 +405,13 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -401,6 +405,13 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rnd.reset(seed); rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false); last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false); last_replay.WriteData(players[1]->name, 40, false);
//records the replay with the new system
new_replay.BeginRecord2();
rh.id = 0x58707279;
new_replay.WriteHeader(rh);
new_replay.WriteData(players[0]->name, 40, false);
new_replay.WriteData(players[1]->name, 40);
replay_stream.clear();
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1); int swap = rnd.real() * (i + 1);
...@@ -425,6 +436,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -425,6 +436,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
opt |= DUEL_PSEUDO_SHUFFLE; opt |= DUEL_PSEUDO_SHUFFLE;
if(host_info.speed) if(host_info.speed)
opt |= SPEED_DUEL; opt |= SPEED_DUEL;
new_replay.WriteInt32((mainGame->GetMasterRule(opt, 0)) | (opt & SPEED_DUEL) << 8);
last_replay.WriteInt32(host_info.start_lp, false); last_replay.WriteInt32(host_info.start_lp, false);
last_replay.WriteInt32(host_info.start_hand, false); last_replay.WriteInt32(host_info.start_hand, false);
last_replay.WriteInt32(host_info.draw_count, false); last_replay.WriteInt32(host_info.draw_count, false);
...@@ -516,8 +528,14 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -516,8 +528,14 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
else startbuf[1] = 0x11; else startbuf[1] = 0x11;
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18); NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18);
startbuf[1] = 0;
BufferIO::ReplayPacket p((char*)startbuf, 17);
replay_stream.push_back(p);
PseudoRefreshDeck(0);
PseudoRefreshDeck(1);
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
new_replay.WriteStream(replay_stream);
start_duel(pduel, opt); start_duel(pduel, opt);
Process(); Process();
} }
...@@ -592,6 +610,8 @@ void SingleDuel::Surrender(DuelPlayer* dp) { ...@@ -592,6 +610,8 @@ void SingleDuel::Surrender(DuelPlayer* dp) {
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);
BufferIO::ReplayPacket p((char*)wbuf, 3);
replay_stream.push_back(p);
if(players[player] == pplayer[player]) { if(players[player] == pplayer[player]) {
match_result[duel_count++] = 1 - player; match_result[duel_count++] = 1 - player;
tp_player = player; tp_player = player;
...@@ -607,12 +627,19 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -607,12 +627,19 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
char* offset, *pbufw, *pbuf = msgbuffer; char* offset, *pbufw, *pbuf = msgbuffer;
int player, count, type; int player, count, type;
while (pbuf - msgbuffer < (int)len) { while (pbuf - msgbuffer < (int)len) {
replay_stream.clear();
bool record = true;
BufferIO::ReplayPacket p;
offset = pbuf; offset = pbuf;
unsigned char engType = BufferIO::ReadUInt8(pbuf); unsigned char engType = BufferIO::ReadUInt8(pbuf);
p.message = engType;
p.length = len - 1;
memcpy(p.data, pbuf, p.length);
switch (engType) { switch (engType) {
case MSG_RETRY: { case MSG_RETRY: {
WaitforResponse(last_response); WaitforResponse(last_response);
NetServer::SendBufferToPlayer(players[last_response], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[last_response], STOC_GAME_MSG, offset, pbuf - offset);
replay_stream.push_back(p);
return 1; return 1;
} }
case MSG_HINT: { case MSG_HINT: {
...@@ -625,6 +652,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -625,6 +652,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
case 3: case 3:
case 5: { case 5: {
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
record = false;
break; break;
} }
case 4: case 4:
...@@ -664,6 +692,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -664,6 +692,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
match_result[duel_count++] = 1 - player; match_result[duel_count++] = 1 - player;
tp_player = player; tp_player = player;
} }
replay_stream.push_back(p);
EndDuel(); EndDuel();
return 2; return 2;
} }
...@@ -870,6 +899,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -870,6 +899,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
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);
PseudoRefreshDeck(player);
break; break;
} }
case MSG_SHUFFLE_HAND: { case MSG_SHUFFLE_HAND: {
...@@ -918,6 +948,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -918,6 +948,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
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);
PseudoRefreshDeck(0);
PseudoRefreshDeck(1);
break; break;
} }
case MSG_DECK_TOP: { case MSG_DECK_TOP: {
...@@ -1430,6 +1462,12 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1430,6 +1462,12 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
break; break;
} }
} }
//setting the length again in case of multiple messages in a row,
//when the packet will be written in the replay, the extra data registered previously will be discarded
p.length = (pbuf - offset) - 1;
if (record)
replay_stream.insert(replay_stream.begin(), p);
new_replay.WriteStream(replay_stream);
} }
return 0; return 0;
} }
...@@ -1456,6 +1494,23 @@ void SingleDuel::EndDuel() { ...@@ -1456,6 +1494,23 @@ void SingleDuel::EndDuel() {
memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader));
pbuf += sizeof(ReplayHeader); pbuf += sizeof(ReplayHeader);
memcpy(pbuf, last_replay.comp_data, last_replay.comp_size); memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
replay_stream.push_back(BufferIO::ReplayPacket(OLD_REPLAY_SYSTEM, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size));
//in case of remaining packets, e.g. MSG_WIN
new_replay.WriteStream(replay_stream);
new_replay.EndRecord();
char nreplaybuf[0x2000], *npbuf = nreplaybuf;
memcpy(npbuf, &new_replay.pheader, sizeof(ReplayHeader));
npbuf += sizeof(ReplayHeader);
memcpy(npbuf, new_replay.comp_data, new_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_NEW_REPLAY, nreplaybuf, sizeof(ReplayHeader) + new_replay.comp_size);
NetServer::ReSendToPlayer(players[1]);
for (auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size); NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
...@@ -1495,8 +1550,10 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) { ...@@ -1495,8 +1550,10 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_MZONE); BufferIO::WriteInt8(qbuf, LOCATION_MZONE);
int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
int qlen = 0; int qlen = 0;
while(qlen < len) { while (qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen; qlen += clen;
if (clen == 4) if (clen == 4)
...@@ -1517,8 +1574,10 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) { ...@@ -1517,8 +1574,10 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_SZONE); BufferIO::WriteInt8(qbuf, LOCATION_SZONE);
int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
int qlen = 0; int qlen = 0;
while(qlen < len) { while (qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen; qlen += clen;
if (clen == 4) if (clen == 4)
...@@ -1556,6 +1615,8 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) { ...@@ -1556,6 +1615,8 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) {
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer, len + 3);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
} }
void SingleDuel::RefreshGrave(int player, int flag, int use_cache) { void SingleDuel::RefreshGrave(int player, int flag, int use_cache) {
char query_buffer[0x2000]; char query_buffer[0x2000];
...@@ -1568,6 +1629,8 @@ void SingleDuel::RefreshGrave(int player, int flag, int use_cache) { ...@@ -1568,6 +1629,8 @@ void SingleDuel::RefreshGrave(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
} }
void SingleDuel::RefreshExtra(int player, int flag, int use_cache) { void SingleDuel::RefreshExtra(int player, int flag, int use_cache) {
char query_buffer[0x2000]; char query_buffer[0x2000];
...@@ -1577,6 +1640,8 @@ void SingleDuel::RefreshExtra(int player, int flag, int use_cache) { ...@@ -1577,6 +1640,8 @@ void SingleDuel::RefreshExtra(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_EXTRA); BufferIO::WriteInt8(qbuf, LOCATION_EXTRA);
int len = query_field_card(pduel, player, LOCATION_EXTRA, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_EXTRA, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
} }
void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag) { void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag) {
char query_buffer[0x2000]; char query_buffer[0x2000];
...@@ -1587,6 +1652,8 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag) ...@@ -1587,6 +1652,8 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
BufferIO::WriteInt8(qbuf, sequence); BufferIO::WriteInt8(qbuf, sequence);
int len = query_card(pduel, player, location, sequence, flag, (unsigned char*)qbuf, 0); int len = query_card(pduel, player, location, sequence, flag, (unsigned char*)qbuf, 0);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4);
BufferIO::ReplayPacket p((char*)query_buffer, len + 3);
replay_stream.push_back(p);
if(location == LOCATION_REMOVED && (qbuf[15] & POS_FACEDOWN)) if(location == LOCATION_REMOVED && (qbuf[15] & POS_FACEDOWN))
return; return;
if ((location & 0x90) || ((location & 0x2c) && (qbuf[15] & POS_FACEUP))) { if ((location & 0x90) || ((location & 0x2c) && (qbuf[15] & POS_FACEUP))) {
...@@ -1595,6 +1662,16 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag) ...@@ -1595,6 +1662,16 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
} }
} }
void SingleDuel::PseudoRefreshDeck(int player, int flag) {
char query_buffer[0x2000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_DECK);
int len = query_field_card(pduel, player, LOCATION_DECK, flag, (unsigned char*)qbuf, 0);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
}
int SingleDuel::MessageHandler(long fduel, int type) { int SingleDuel::MessageHandler(long fduel, int type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
...@@ -1616,6 +1693,8 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) { ...@@ -1616,6 +1693,8 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) {
NetServer::ReSendToPlayer(sd->players[1]); NetServer::ReSendToPlayer(sd->players[1]);
for(auto oit = sd->observers.begin(); oit != sd->observers.end(); ++oit) for(auto oit = sd->observers.begin(); oit != sd->observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
BufferIO::ReplayPacket p((char*)wbuf, 3);
sd->replay_stream.push_back(p);
if(sd->players[player] == sd->pplayer[player]) { if(sd->players[player] == sd->pplayer[player]) {
sd->match_result[sd->duel_count++] = 1 - player; sd->match_result[sd->duel_count++] = 1 - player;
sd->tp_player = player; sd->tp_player = player;
......
...@@ -40,6 +40,9 @@ public: ...@@ -40,6 +40,9 @@ public:
static int MessageHandler(long fduel, int type); static int MessageHandler(long fduel, int type);
static void SingleTimer(evutil_socket_t fd, short events, void* arg); static void SingleTimer(evutil_socket_t fd, short events, void* arg);
void PseudoRefreshDeck(int player, int flag = 0x181fff);
static std::vector<BufferIO::ReplayPacket> replay_stream;
protected: protected:
DuelPlayer* players[2]; DuelPlayer* players[2];
...@@ -51,6 +54,7 @@ protected: ...@@ -51,6 +54,7 @@ protected:
unsigned char last_response; unsigned char last_response;
std::set<DuelPlayer*> observers; std::set<DuelPlayer*> observers;
Replay last_replay; Replay last_replay;
Replay new_replay;
bool match_mode; bool match_mode;
int match_kill; int match_kill;
bool game_started; bool game_started;
......
This diff is collapsed.
...@@ -31,6 +31,8 @@ public: ...@@ -31,6 +31,8 @@ public:
protected: protected:
static Replay last_replay; static Replay last_replay;
static Replay new_replay;
static std::vector<BufferIO::ReplayPacket> replay_stream;
}; };
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
namespace ygo { namespace ygo {
std::vector<BufferIO::ReplayPacket> TagDuel::replay_stream;
TagDuel::TagDuel() { TagDuel::TagDuel() {
game_started = false; game_started = false;
for(int i = 0; i < 4; ++i) { for(int i = 0; i < 4; ++i) {
...@@ -362,6 +364,15 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -362,6 +364,15 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
last_replay.WriteData(players[1]->name, 40, false); last_replay.WriteData(players[1]->name, 40, false);
last_replay.WriteData(players[2]->name, 40, false); last_replay.WriteData(players[2]->name, 40, false);
last_replay.WriteData(players[3]->name, 40, false); last_replay.WriteData(players[3]->name, 40, false);
//records the replay with the new system
new_replay.BeginRecord2();
rh.id = 0x58707279;
new_replay.WriteHeader(rh);
new_replay.WriteData(players[0]->name, 40, false);
new_replay.WriteData(players[1]->name, 40, false);
new_replay.WriteData(players[2]->name, 40, false);
new_replay.WriteData(players[3]->name, 40);
replay_stream.clear();
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1); int swap = rnd.real() * (i + 1);
...@@ -395,6 +406,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -395,6 +406,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(host_info.speed) if(host_info.speed)
opt |= SPEED_DUEL; opt |= SPEED_DUEL;
opt |= DUEL_TAG_MODE; opt |= DUEL_TAG_MODE;
new_replay.WriteInt32((mainGame->GetMasterRule(opt, 0)) | (opt & SPEED_DUEL) << 8);
last_replay.WriteInt32(host_info.start_lp, false); last_replay.WriteInt32(host_info.start_lp, false);
last_replay.WriteInt32(host_info.start_hand, false); last_replay.WriteInt32(host_info.start_hand, false);
last_replay.WriteInt32(host_info.draw_count, false); last_replay.WriteInt32(host_info.draw_count, false);
...@@ -519,8 +531,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -519,8 +531,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
else startbuf[1] = 0x11; else startbuf[1] = 0x11;
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18); NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18);
startbuf[1] = 0;
BufferIO::ReplayPacket p((char*)startbuf, 17);
replay_stream.push_back(p);
PseudoRefreshDeck(0);
PseudoRefreshDeck(1);
RefreshExtra(0); RefreshExtra(0);
RefreshExtra(1); RefreshExtra(1);
new_replay.WriteStream(replay_stream);
start_duel(pduel, opt); start_duel(pduel, opt);
Process(); Process();
} }
...@@ -558,12 +576,19 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -558,12 +576,19 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
char* offset, *pbufw, *pbuf = msgbuffer; char* offset, *pbufw, *pbuf = msgbuffer;
int player, count, type; int player, count, type;
while (pbuf - msgbuffer < (int)len) { while (pbuf - msgbuffer < (int)len) {
replay_stream.clear();
bool record = true;
BufferIO::ReplayPacket p;
offset = pbuf; offset = pbuf;
unsigned char engType = BufferIO::ReadUInt8(pbuf); unsigned char engType = BufferIO::ReadUInt8(pbuf);
p.message = engType;
p.length = len - 1;
memcpy(p.data, pbuf, p.length);
switch (engType) { switch (engType) {
case MSG_RETRY: { case MSG_RETRY: {
WaitforResponse(last_response); WaitforResponse(last_response);
NetServer::SendBufferToPlayer(cur_player[last_response], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(cur_player[last_response], STOC_GAME_MSG, offset, pbuf - offset);
replay_stream.push_back(p);
return 1; return 1;
} }
case MSG_HINT: { case MSG_HINT: {
...@@ -577,6 +602,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -577,6 +602,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
case 5: case 5:
case 10: { case 10: {
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
record = false;
break; break;
} }
case 4: case 4:
...@@ -603,6 +629,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -603,6 +629,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
replay_stream.push_back(p);
EndDuel(); EndDuel();
return 2; return 2;
} }
...@@ -817,6 +844,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -817,6 +844,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
PseudoRefreshDeck(player);
break; break;
} }
case MSG_SHUFFLE_HAND: { case MSG_SHUFFLE_HAND: {
...@@ -875,6 +903,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -875,6 +903,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
PseudoRefreshDeck(0);
PseudoRefreshDeck(1);
break; break;
} }
case MSG_DECK_TOP: { case MSG_DECK_TOP: {
...@@ -1499,6 +1529,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1499,6 +1529,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(players[p], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[p], STOC_GAME_MSG, offset, pbuf - offset);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
PseudoRefreshDeck(player);
RefreshExtra(player); RefreshExtra(player);
RefreshMzone(0, 0x81fff, 0); RefreshMzone(0, 0x81fff, 0);
RefreshMzone(1, 0x81fff, 0); RefreshMzone(1, 0x81fff, 0);
...@@ -1513,6 +1544,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1513,6 +1544,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
break; break;
} }
} }
//setting the length again in case of multiple messages in a row,
//when the packet will be written in the replay, the extra data registered previously will be discarded
p.length = (pbuf - offset) - 1;
if (record)
replay_stream.insert(replay_stream.begin(), p);
new_replay.WriteStream(replay_stream);
} }
return 0; return 0;
} }
...@@ -1535,6 +1572,21 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -1535,6 +1572,21 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
void TagDuel::EndDuel() { void TagDuel::EndDuel() {
if(!pduel) if(!pduel)
return; return;
//in case of remaining packets, e.g. MSG_WIN
new_replay.WriteStream(replay_stream);
new_replay.EndRecord();
char nreplaybuf[0x2000], *npbuf = nreplaybuf;
memcpy(npbuf, &new_replay.pheader, sizeof(ReplayHeader));
npbuf += sizeof(ReplayHeader);
memcpy(npbuf, new_replay.comp_data, new_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_NEW_REPLAY, nreplaybuf, sizeof(ReplayHeader) + new_replay.comp_size);
NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]);
NetServer::ReSendToPlayer(players[3]);
for (auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
last_replay.EndRecord(); last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader));
...@@ -1586,6 +1638,8 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) { ...@@ -1586,6 +1638,8 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache);
int pid = (player == 0) ? 0 : 2; int pid = (player == 0) ? 0 : 2;
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
NetServer::ReSendToPlayer(players[pid + 1]); NetServer::ReSendToPlayer(players[pid + 1]);
int qlen = 0; int qlen = 0;
while(qlen < len) { while(qlen < len) {
...@@ -1612,6 +1666,8 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) { ...@@ -1612,6 +1666,8 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache);
int pid = (player == 0) ? 0 : 2; int pid = (player == 0) ? 0 : 2;
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
NetServer::ReSendToPlayer(players[pid + 1]); NetServer::ReSendToPlayer(players[pid + 1]);
int qlen = 0; int qlen = 0;
while(qlen < len) { while(qlen < len) {
...@@ -1637,6 +1693,8 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) { ...@@ -1637,6 +1693,8 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_HAND); BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
int qlen = 0; int qlen = 0;
while(qlen < len) { while(qlen < len) {
int slen = BufferIO::ReadInt32(qbuf); int slen = BufferIO::ReadInt32(qbuf);
...@@ -1670,6 +1728,8 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) { ...@@ -1670,6 +1728,8 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
} }
void TagDuel::RefreshExtra(int player, int flag, int use_cache) { void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
char query_buffer[0x2000]; char query_buffer[0x2000];
...@@ -1679,6 +1739,8 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) { ...@@ -1679,6 +1739,8 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_EXTRA); BufferIO::WriteInt8(qbuf, LOCATION_EXTRA);
int len = query_field_card(pduel, player, LOCATION_EXTRA, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_EXTRA, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
} }
void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) { void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
char query_buffer[0x2000]; char query_buffer[0x2000];
...@@ -1688,6 +1750,8 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) { ...@@ -1688,6 +1750,8 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
BufferIO::WriteInt8(qbuf, location); BufferIO::WriteInt8(qbuf, location);
BufferIO::WriteInt8(qbuf, sequence); BufferIO::WriteInt8(qbuf, sequence);
int len = query_card(pduel, player, location, sequence, flag, (unsigned char*)qbuf, 0); int len = query_card(pduel, player, location, sequence, flag, (unsigned char*)qbuf, 0);
BufferIO::ReplayPacket p((char*)query_buffer, len + 3);
replay_stream.push_back(p);
if(location & LOCATION_ONFIELD) { if(location & LOCATION_ONFIELD) {
int pid = (player == 0) ? 0 : 2; int pid = (player == 0) ? 0 : 2;
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 4); NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 4);
...@@ -1714,6 +1778,16 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) { ...@@ -1714,6 +1778,16 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
} }
} }
} }
void TagDuel::PseudoRefreshDeck(int player, int flag) {
char query_buffer[0x2000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_DECK);
int len = query_field_card(pduel, player, LOCATION_DECK, flag, (unsigned char*)qbuf, 0);
BufferIO::ReplayPacket p((char*)query_buffer, len + 2);
replay_stream.push_back(p);
}
int TagDuel::MessageHandler(long fduel, int type) { int TagDuel::MessageHandler(long fduel, int type) {
if(!enable_log) if(!enable_log)
return 0; return 0;
...@@ -1735,6 +1809,8 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) { ...@@ -1735,6 +1809,8 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) {
NetServer::ReSendToPlayer(sd->players[1]); NetServer::ReSendToPlayer(sd->players[1]);
NetServer::ReSendToPlayer(sd->players[2]); NetServer::ReSendToPlayer(sd->players[2]);
NetServer::ReSendToPlayer(sd->players[3]); NetServer::ReSendToPlayer(sd->players[3]);
BufferIO::ReplayPacket p((char*)wbuf, 3);
sd->replay_stream.push_back(p);
sd->EndDuel(); sd->EndDuel();
sd->DuelEndProc(); sd->DuelEndProc();
event_del(sd->etimer); event_del(sd->etimer);
......
...@@ -40,6 +40,9 @@ public: ...@@ -40,6 +40,9 @@ public:
static int MessageHandler(long fduel, int type); static int MessageHandler(long fduel, int type);
static void TagTimer(evutil_socket_t fd, short events, void* arg); static void TagTimer(evutil_socket_t fd, short events, void* arg);
void PseudoRefreshDeck(int player, int flag = 0x181fff);
static std::vector<BufferIO::ReplayPacket> replay_stream;
protected: protected:
DuelPlayer* players[4]; DuelPlayer* players[4];
...@@ -52,6 +55,7 @@ protected: ...@@ -52,6 +55,7 @@ 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;
Replay new_replay;
bool game_started; bool game_started;
unsigned char turn_count; unsigned char turn_count;
unsigned short time_limit[2]; unsigned short time_limit[2];
......
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