Commit 3516ba98 authored by edo9300's avatar edo9300

Merge remote-tracking branch 'refs/remotes/origin/new-replay-system'

parents 80ffa24b 38ff205e
...@@ -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;
} }
......
This diff is collapsed.
...@@ -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<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;
......
...@@ -617,6 +617,7 @@ bool Game::Initialize() { ...@@ -617,6 +617,7 @@ bool Game::Initialize() {
btnReplayCancel = env->addButton(rect<s32>(460, 385, 570, 410), wReplay, BUTTON_CANCEL_REPLAY, dataManager.GetSysString(1347)); btnReplayCancel = env->addButton(rect<s32>(460, 385, 570, 410), wReplay, BUTTON_CANCEL_REPLAY, dataManager.GetSysString(1347));
env->addStaticText(dataManager.GetSysString(1349), rect<s32>(360, 30, 570, 50), false, true, wReplay); env->addStaticText(dataManager.GetSysString(1349), rect<s32>(360, 30, 570, 50), false, true, wReplay);
stReplayInfo = env->addStaticText(L"", rect<s32>(360, 60, 570, 350), false, true, wReplay); stReplayInfo = env->addStaticText(L"", rect<s32>(360, 60, 570, 350), false, true, wReplay);
chkYrp = env->addCheckBox(false, recti(360, 250, 560, 270), wReplay, -1, dataManager.GetSysString(1999));
env->addStaticText(dataManager.GetSysString(1353), rect<s32>(360, 275, 570, 295), false, true, wReplay); env->addStaticText(dataManager.GetSysString(1353), rect<s32>(360, 275, 570, 295), false, true, wReplay);
ebRepStartTurn = env->addEditBox(L"", rect<s32>(360, 300, 460, 320), true, wReplay, -1); ebRepStartTurn = env->addEditBox(L"", rect<s32>(360, 300, 460, 320), true, wReplay, -1);
ebRepStartTurn->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER); ebRepStartTurn->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
...@@ -1228,7 +1229,7 @@ bool Game::PlayChant(unsigned int code) { ...@@ -1228,7 +1229,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 +1564,46 @@ int Game::GetMasterRule(uint32 param, uint32 forbiddentypes, int* truerule) { ...@@ -1563,8 +1564,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 +1701,7 @@ void Game::OnResize() ...@@ -1662,42 +1701,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));
......
...@@ -48,6 +48,7 @@ struct Config { ...@@ -48,6 +48,7 @@ struct Config {
struct DuelInfo { struct DuelInfo {
bool isStarted; bool isStarted;
bool isReplay; bool isReplay;
bool isOldReplay;
bool isReplaySkiping; bool isReplaySkiping;
bool isFirst; bool isFirst;
bool isTag; bool isTag;
...@@ -134,6 +135,7 @@ public: ...@@ -134,6 +135,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 +172,7 @@ public: ...@@ -170,7 +172,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;
...@@ -309,6 +311,7 @@ public: ...@@ -309,6 +311,7 @@ public:
irr::gui::IGUIWindow* wReplay; irr::gui::IGUIWindow* wReplay;
irr::gui::IGUIListBox* lstReplayList; irr::gui::IGUIListBox* lstReplayList;
irr::gui::IGUIStaticText* stReplayInfo; irr::gui::IGUIStaticText* stReplayInfo;
irr::gui::IGUICheckBox* chkYrp;
irr::gui::IGUIButton* btnLoadReplay; irr::gui::IGUIButton* btnLoadReplay;
irr::gui::IGUIButton* btnReplayCancel; irr::gui::IGUIButton* btnReplayCancel;
irr::gui::IGUIEditBox* ebRepStartTurn; irr::gui::IGUIEditBox* ebRepStartTurn;
......
...@@ -274,6 +274,8 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -274,6 +274,8 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(!ReplayMode::cur_replay.OpenReplay(mainGame->lstReplayList->getListItem(mainGame->lstReplayList->getSelected()))) if(!ReplayMode::cur_replay.OpenReplay(mainGame->lstReplayList->getListItem(mainGame->lstReplayList->getSelected())))
break; break;
} }
if(mainGame->chkYrp->isChecked() && !ReplayMode::cur_replay.LoadYrp())
break;
mainGame->imgCard->setImage(imageManager.tCover[0]); mainGame->imgCard->setImage(imageManager.tCover[0]);
mainGame->wCardImg->setVisible(true); mainGame->wCardImg->setVisible(true);
mainGame->wInfos->setVisible(true); mainGame->wInfos->setVisible(true);
...@@ -393,6 +395,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -393,6 +395,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
repinfo.append(infobuf); repinfo.append(infobuf);
mainGame->ebRepStartTurn->setText(L"1"); mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, (wchar_t*)repinfo.c_str()); mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, (wchar_t*)repinfo.c_str());
if(ReplayMode::cur_replay.pheader.id == 0x31707279) {
mainGame->chkYrp->setChecked(false);
mainGame->chkYrp->setEnabled(false);
} else
mainGame->chkYrp->setEnabled(true);
break; break;
} }
} }
......
...@@ -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
......
This diff is collapsed.
#include "replay.h" #include "replay.h"
#include "../ocgcore/ocgapi.h" #include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h" #include "../ocgcore/card.h"
#include "../ocgcore/field.h"
#include <algorithm> #include <algorithm>
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
namespace ygo { namespace ygo {
ReplayPacket::ReplayPacket(char * buf, int len) {
message = BufferIO::ReadInt8(buf);
length = len;
memcpy(data, buf, length);
}
ReplayPacket::ReplayPacket(int msg, char * buf, int len) {
message = msg;
length = len;
memcpy(data, buf, length);
}
void ReplayPacket::Set(int msg, char * buf, int len) {
message = msg;
length = len;
memcpy(data, buf, length);
}
Replay::Replay() { Replay::Replay() {
is_recording = false; is_recording = false;
is_replaying = false; is_replaying = false;
...@@ -16,25 +33,42 @@ Replay::~Replay() { ...@@ -16,25 +33,42 @@ Replay::~Replay() {
delete[] replay_data; delete[] replay_data;
delete[] comp_data; delete[] comp_data;
} }
void Replay::BeginRecord() { void Replay::BeginRecord(bool write) {
#ifdef _WIN32 #ifdef _WIN32
if(is_recording) if(is_recording && is_writing)
CloseHandle(recording_fp); CloseHandle(recording_fp);
recording_fp = CreateFileW(L"./replay/_LastReplay.yrp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL); is_writing = write;
if(recording_fp == INVALID_HANDLE_VALUE) if(is_writing) {
return; recording_fp = CreateFileW(L"./replay/_LastReplay.yrpX", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
if(recording_fp == INVALID_HANDLE_VALUE)
return;
}
#else #else
if(is_recording) if(is_recording && is_writing)
fclose(fp); fclose(fp);
fp = fopen("./replay/_LastReplay.yrp", "wb"); is_writing = write;
if(!fp) if(is_writing) {
return; fp = fopen("./replay/_LastReplay.yrpX", "wb");
if(!fp)
return;
}
#endif #endif
pdata = replay_data; pdata = replay_data;
is_recording = true; is_recording = true;
} }
void Replay::WritePacket(ReplayPacket p) {
WriteInt8(p.message, false);
WriteInt32(p.length, false);
WriteData((char*)p.data, p.length);
}
void Replay::WriteStream(std::vector<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;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, &header, sizeof(header), &size, NULL); WriteFile(recording_fp, &header, sizeof(header), &size, NULL);
...@@ -48,6 +82,7 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) { ...@@ -48,6 +82,7 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) {
return; return;
memcpy(pdata, data, length); memcpy(pdata, data, length);
pdata += length; pdata += length;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, data, length, &size, NULL); WriteFile(recording_fp, data, length, &size, NULL);
...@@ -62,6 +97,7 @@ void Replay::WriteInt32(int data, bool flush) { ...@@ -62,6 +97,7 @@ void Replay::WriteInt32(int data, bool flush) {
return; return;
*((int*)(pdata)) = data; *((int*)(pdata)) = data;
pdata += 4; pdata += 4;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL); WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
...@@ -76,6 +112,7 @@ void Replay::WriteInt16(short data, bool flush) { ...@@ -76,6 +112,7 @@ void Replay::WriteInt16(short data, bool flush) {
return; return;
*((short*)(pdata)) = data; *((short*)(pdata)) = data;
pdata += 2; pdata += 2;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL); WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
...@@ -90,6 +127,7 @@ void Replay::WriteInt8(char data, bool flush) { ...@@ -90,6 +127,7 @@ void Replay::WriteInt8(char data, bool flush) {
return; return;
*pdata = data; *pdata = data;
pdata++; pdata++;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL); WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
...@@ -102,14 +140,16 @@ void Replay::WriteInt8(char data, bool flush) { ...@@ -102,14 +140,16 @@ void Replay::WriteInt8(char data, bool flush) {
void Replay::Flush() { void Replay::Flush() {
if(!is_recording) if(!is_recording)
return; return;
if(!is_writing) return;
#ifdef _WIN32 #ifdef _WIN32
#else #else
fflush(fp); fflush(fp);
#endif #endif
} }
void Replay::EndRecord() { void Replay::EndRecord(size_t size) {
if(!is_recording) if(!is_recording)
return; return;
if(is_writing)
#ifdef _WIN32 #ifdef _WIN32
CloseHandle(recording_fp); CloseHandle(recording_fp);
#else #else
...@@ -118,13 +158,13 @@ void Replay::EndRecord() { ...@@ -118,13 +158,13 @@ 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 = size;
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;
} }
void Replay::SaveReplay(const wchar_t* name) { void Replay::SaveReplay(const wchar_t* name) {
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./replay/%ls.yrp", name); myswprintf(fname, L"./replay/%ls.yrpX", name);
#ifdef WIN32 #ifdef WIN32
fp = _wfopen(fname, L"wb"); fp = _wfopen(fname, L"wb");
#else #else
...@@ -161,7 +201,7 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -161,7 +201,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 +230,23 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -190,7 +230,23 @@ 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(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::ReadStream(std::vector<ReplayPacket>* stream) {
stream->clear();
ReplayPacket p;
while (ReadNextPacket(&p)) {
stream->push_back(p);
}
return !!stream->size();
} }
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)
...@@ -238,4 +294,31 @@ void Replay::Rewind() { ...@@ -238,4 +294,31 @@ void Replay::Rewind() {
pdata = replay_data; pdata = replay_data;
} }
bool Replay::LoadYrp() {
if (pheader.flag & REPLAY_NEWREPLAY) {
pdata += (4 + ((pheader.flag & REPLAY_TAG) ? 160 : 80));
ReplayPacket p;
while (ReadNextPacket(&p))
if (p.message == OLD_REPLAY_MODE) {
char* prep = (char*)p.data;
memcpy(&pheader, prep, sizeof(ReplayHeader));
prep += sizeof(ReplayHeader);
if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = (size_t)(p.length - sizeof(ReplayHeader));
replay_size = pheader.datasize;
if (LzmaUncompress(replay_data, &replay_size, (unsigned char*)prep, &comp_size, pheader.props, 5) != SZ_OK)
return false;
} else {
comp_size = fread(replay_data, 1, 0x20000, fp);
fclose(fp);
replay_size = comp_size;
}
pdata = replay_data;
is_replaying = true;
return true;
}
}
return !(pheader.flag & REPLAY_NEWREPLAY);
}
} }
...@@ -11,6 +11,7 @@ namespace ygo { ...@@ -11,6 +11,7 @@ namespace ygo {
#define REPLAY_DECODED 0x4 #define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8 #define REPLAY_SINGLE_MODE 0x8
#define REPLAY_LUA64 0x10 #define REPLAY_LUA64 0x10
#define REPLAY_NEWREPLAY 0x20
struct ReplayHeader { struct ReplayHeader {
unsigned int id; unsigned int id;
...@@ -22,29 +23,44 @@ struct ReplayHeader { ...@@ -22,29 +23,44 @@ struct ReplayHeader {
unsigned char props[8]; unsigned char props[8];
}; };
class ReplayPacket {
public:
int message;
int length;
unsigned char data[0x2000];
ReplayPacket() {}
ReplayPacket(char * buf, int len);
ReplayPacket(int msg, char * buf, int len);
void Set(int msg, char * buf, int len);
};
class Replay { class Replay {
public: public:
Replay(); Replay();
~Replay(); ~Replay();
void BeginRecord(); void BeginRecord(bool write = true);
void WriteStream(std::vector<ReplayPacket> stream);
void WritePacket(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);
void WriteInt16(short data, bool flush = true); void WriteInt16(short data, bool flush = true);
void WriteInt8(char data, bool flush = true); void WriteInt8(char data, bool flush = true);
void Flush(); void Flush();
void EndRecord(); void EndRecord(size_t size = 0x20000);
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(ReplayPacket* packet);
bool ReadStream(std::vector<ReplayPacket>* stream);
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 ReadData(void* data, unsigned int length); void ReadData(void* data, unsigned int length);
int ReadInt32(); int ReadInt32();
short ReadInt16(); short ReadInt16();
char ReadInt8(); char ReadInt8();
void Rewind(); void Rewind();
bool LoadYrp();
FILE* fp; FILE* fp;
ReplayHeader pheader; ReplayHeader pheader;
...@@ -57,6 +73,7 @@ public: ...@@ -57,6 +73,7 @@ public:
size_t replay_size; size_t replay_size;
size_t comp_size; size_t comp_size;
bool is_recording; bool is_recording;
bool is_writing;
bool is_replaying; bool is_replaying;
}; };
......
This diff is collapsed.
...@@ -12,12 +12,14 @@ namespace ygo { ...@@ -12,12 +12,14 @@ namespace ygo {
class ReplayMode { class ReplayMode {
private: private:
static long pduel; static long pduel;
static bool yrp;
static bool is_continuing; static bool is_continuing;
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 +27,7 @@ private: ...@@ -25,6 +27,7 @@ private:
public: public:
static Replay cur_replay; static Replay cur_replay;
static std::vector<ReplayPacket> ReplayMode::current_stream;
public: public:
static bool StartReplay(int skipturn); static bool StartReplay(int skipturn);
...@@ -33,12 +36,14 @@ public: ...@@ -33,12 +36,14 @@ public:
static void Pause(bool is_pause, bool is_step); static void Pause(bool is_pause, bool is_step);
static bool ReadReplayResponse(); static bool ReadReplayResponse();
static int ReplayThread(void* param); static int ReplayThread(void* param);
static int OldReplayThread(void* param);
static bool StartDuel(); static bool StartDuel();
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(ReplayPacket p);
static bool ReplayAnalyze(char* msg, unsigned int len); static bool ReplayAnalyze(char* msg, unsigned int len);
static void ReplayRefresh(int flag = 0xf81fff); static void ReplayRefresh(int flag = 0xf81fff);
static void ReplayRefreshHand(int player, int flag = 0x781fff); static void ReplayRefreshHand(int player, int flag = 0x781fff);
static void ReplayRefreshGrave(int player, int flag = 0x181fff); static void ReplayRefreshGrave(int player, int flag = 0x181fff);
......
This diff is collapsed.
...@@ -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<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.
...@@ -18,11 +18,8 @@ public: ...@@ -18,11 +18,8 @@ public:
static int SinglePlayThread(void* param); static int SinglePlayThread(void* param);
static bool SinglePlayAnalyze(char* msg, unsigned int len); static bool SinglePlayAnalyze(char* msg, unsigned int len);
static void SinglePlayRefresh(int player, int location, int flag = 0xf81fff);
static void SinglePlayRefresh(int flag = 0xf81fff); static void SinglePlayRefresh(int flag = 0xf81fff);
static void SinglePlayRefreshHand(int player, int flag = 0x781fff);
static void SinglePlayRefreshGrave(int player, int flag = 0x181fff);
static void SinglePlayRefreshDeck(int player, int flag = 0x181fff);
static void SinglePlayRefreshExtra(int player, int flag = 0x181fff);
static void SinglePlayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff); static void SinglePlayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void SinglePlayReload(); static void SinglePlayReload();
...@@ -31,6 +28,8 @@ public: ...@@ -31,6 +28,8 @@ public:
protected: protected:
static Replay last_replay; static Replay last_replay;
static Replay new_replay;
static std::vector<ReplayPacket> replay_stream;
}; };
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
namespace ygo { namespace ygo {
std::vector<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) {
...@@ -355,13 +357,23 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -355,13 +357,23 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh.flag = REPLAY_TAG + REPLAY_LUA64; rh.flag = REPLAY_TAG + REPLAY_LUA64;
time_t seed = time(0); time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
last_replay.BeginRecord(); last_replay.BeginRecord(false);
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
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);
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.BeginRecord();
rh.id = 0x58707279;
rh.flag |= REPLAY_NEWREPLAY;
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 +407,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -395,6 +407,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 +532,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -519,8 +532,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;
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 +577,19 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -558,12 +577,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;
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 +603,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -577,6 +603,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 +630,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -603,6 +630,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 +845,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -817,6 +845,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 +904,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -875,6 +904,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 +1530,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1499,6 +1530,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 +1545,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -1513,6 +1545,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,11 +1573,29 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -1535,11 +1573,29 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
void TagDuel::EndDuel() { void TagDuel::EndDuel() {
if(!pduel) if(!pduel)
return; return;
last_replay.EndRecord(); last_replay.EndRecord(0x1000);
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
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(ReplayPacket(OLD_REPLAY_MODE, 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]);
NetServer::ReSendToPlayer(players[2]);
NetServer::ReSendToPlayer(players[3]);
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]);
NetServer::ReSendToPlayer(players[2]); NetServer::ReSendToPlayer(players[2]);
...@@ -1586,6 +1642,8 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) { ...@@ -1586,6 +1642,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);
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 +1670,8 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) { ...@@ -1612,6 +1670,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);
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 +1697,8 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) { ...@@ -1637,6 +1697,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);
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 +1732,8 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) { ...@@ -1670,6 +1732,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);
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 +1743,8 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) { ...@@ -1679,6 +1743,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);
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 +1754,8 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) { ...@@ -1688,6 +1754,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);
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 +1782,16 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) { ...@@ -1714,6 +1782,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);
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 +1813,8 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) { ...@@ -1735,6 +1813,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]);
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<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];
......
Subproject commit cbcff83c4001fb4208a530f580ad7ce0ac1fdfb2 Subproject commit 2a37a9fad5e84d06998e16eb530c0c2acdbb4e81
#The first line is used for comment #The first line is used for comment
#line doesn't start with '!' is also neglected #line doesn't start with '!' is also neglected
#called by DataManager::GetSysString(), DataManager::GetDesc()
#system #system
!system 1 Normal Summon !system 1 Normal Summon
!system 2 Special Summon !system 2 Special Summon
...@@ -375,6 +375,7 @@ ...@@ -375,6 +375,7 @@
!system 1353 Start at turn !system 1353 Start at turn
!system 1354 Hide Set Names  !system 1354 Hide Set Names 
!system 1355 Hide Chain Buttons !system 1355 Hide Chain Buttons
!system 1356 Old Replay Mode
!system 1360 Previous !system 1360 Previous
!system 1370 Level !system 1370 Level
!system 1371 Attack !system 1371 Attack
......
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