Commit 93ac168e authored by fallenstardust's avatar fallenstardust

sync gframe

parent 9810e1b2
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifdef _WIN32 #ifdef _WIN32
#include <WinSock2.h> #include <WinSock2.h>
#define NOMINMAX
#include <windows.h> #include <windows.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h>
#define SD_BOTH 2 #define SD_BOTH 2
#define SOCKET int #define SOCKET int
......
...@@ -67,6 +67,10 @@ bool DataManager::LoadDB(const wchar_t* wfile) { ...@@ -67,6 +67,10 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
cd.race = sqlite3_column_int(pStmt, 8); cd.race = sqlite3_column_int(pStmt, 8);
cd.attribute = sqlite3_column_int(pStmt, 9); cd.attribute = sqlite3_column_int(pStmt, 9);
cd.category = sqlite3_column_int(pStmt, 10); cd.category = sqlite3_column_int(pStmt, 10);
auto it = _datas.find(cd.code);
if(it != _datas.end())
it->second = cd;
else
_datas.insert(std::make_pair(cd.code, cd)); _datas.insert(std::make_pair(cd.code, cd));
if(const char* text = (const char*)sqlite3_column_text(pStmt, 12)) { if(const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
BufferIO::DecodeUTF8(text, strBuffer); BufferIO::DecodeUTF8(text, strBuffer);
......
#include "config.h" #include "config.h"
#include "deck_con.h" #include "deck_con.h"
#include "data_manager.h" #include "data_manager.h"
...@@ -83,6 +82,7 @@ void DeckBuilder::Initialize() { ...@@ -83,6 +82,7 @@ void DeckBuilder::Initialize() {
filterList = deckManager._lfList[0].content; filterList = deckManager._lfList[0].content;
mainGame->cbLFList->setSelected(0); mainGame->cbLFList->setSelected(0);
ClearSearch(); ClearSearch();
rnd.reset((unsigned int)time(nullptr));
mouse_pos.set(0, 0); mouse_pos.set(0, 0);
hovered_code = 0; hovered_code = 0;
hovered_pos = 0; hovered_pos = 0;
...@@ -183,7 +183,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -183,7 +183,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
} }
case BUTTON_SHUFFLE_DECK: { case BUTTON_SHUFFLE_DECK: {
std::random_shuffle(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end()); rnd.shuffle_vector(deckManager.current_deck.main);
break; break;
} }
case BUTTON_SAVE_DECK: { case BUTTON_SAVE_DECK: {
...@@ -417,7 +417,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -417,7 +417,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
if(catesel != 2) if(catesel != 2)
mainGame->cbDMCategory->addItem(dataManager.GetSysString(1452)); mainGame->cbDMCategory->addItem(dataManager.GetSysString(1452));
for(int i = 4; i < mainGame->lstCategories->getItemCount(); i++) { for(int i = 4; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(i != catesel) if(i != catesel)
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i)); mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
} }
...@@ -434,7 +434,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -434,7 +434,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int catesel = mainGame->lstCategories->getSelected(); int catesel = mainGame->lstCategories->getSelected();
if(catesel != 2) if(catesel != 2)
mainGame->cbDMCategory->addItem(dataManager.GetSysString(1452)); mainGame->cbDMCategory->addItem(dataManager.GetSysString(1452));
for(int i = 4; i < mainGame->lstCategories->getItemCount(); i++) { for(int i = 4; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(i != catesel) if(i != catesel)
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i)); mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
} }
...@@ -453,7 +453,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -453,7 +453,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->lstCategories->addItem(catename); mainGame->lstCategories->addItem(catename);
catesel = mainGame->lstCategories->getItemCount() - 1; catesel = mainGame->lstCategories->getItemCount() - 1;
} else { } else {
for(int i = 3; i < mainGame->lstCategories->getItemCount(); i++) { for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) { if(!wcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -483,7 +483,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -483,7 +483,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
catesel = mainGame->lstCategories->getItemCount() - 1; catesel = mainGame->lstCategories->getItemCount() - 1;
} else { } else {
catesel = 0; catesel = 0;
for(int i = 3; i < mainGame->lstCategories->getItemCount(); i++) { for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) { if(!wcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -534,7 +534,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -534,7 +534,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList(); RefreshDeckList();
ChangeCategory(mainGame->lstCategories->getSelected()); ChangeCategory(mainGame->lstCategories->getSelected());
} }
for(int i = 0; i < mainGame->lstDecks->getItemCount(); i++) { for(int i = 0; i < (int)mainGame->lstDecks->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(filepath); deckManager.LoadDeck(filepath);
prev_deck = i; prev_deck = i;
...@@ -568,7 +568,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -568,7 +568,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} }
RefreshDeckList(); RefreshDeckList();
ChangeCategory(catesel); ChangeCategory(catesel);
for(int i = 0; i < mainGame->lstDecks->getItemCount(); i++) { for(int i = 0; i < (int)mainGame->lstDecks->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), newdeckname, 256)) { if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), newdeckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -632,7 +632,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -632,7 +632,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList(); RefreshDeckList();
mainGame->cbDBCategory->setSelected(catesel); mainGame->cbDBCategory->setSelected(catesel);
ChangeCategory(catesel); ChangeCategory(catesel);
for(int i = 0; i < mainGame->lstDecks->getItemCount(); i++) { for(int i = 0; i < (int)mainGame->lstDecks->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -670,7 +670,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -670,7 +670,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList(); RefreshDeckList();
mainGame->cbDBCategory->setSelected(catesel); mainGame->cbDBCategory->setSelected(catesel);
ChangeCategory(catesel); ChangeCategory(catesel);
for(int i = 0; i < mainGame->lstDecks->getItemCount(); i++) { for(int i = 0; i < (int)mainGame->lstDecks->getItemCount(); i++) {
if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!wcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -1538,7 +1538,7 @@ void DeckBuilder::FilterCards() { ...@@ -1538,7 +1538,7 @@ void DeckBuilder::FilterCards() {
SortList(); SortList();
} }
void DeckBuilder::InstantSearch() { void DeckBuilder::InstantSearch() {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit)) if(mainGame->gameConf.auto_search_limit >= 0 && ((int)wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter(); StartFilter();
} }
void DeckBuilder::ClearSearch() { void DeckBuilder::ClearSearch() {
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "client_card.h" #include "client_card.h"
#include "../ocgcore/mtrandom.h"
#include "config.h"
#ifdef _IRR_ANDROID_PLATFORM_ #ifdef _IRR_ANDROID_PLATFORM_
#include <android/TouchEventTransferAndroid.h> #include <android/TouchEventTransferAndroid.h>
#include <android/android_tools.h> #include <android/android_tools.h>
...@@ -79,6 +78,7 @@ public: ...@@ -79,6 +78,7 @@ public:
int prev_sel; int prev_sel;
bool is_modified; bool is_modified;
bool readonly; bool readonly;
mt19937 rnd;
std::unordered_map<int, int>* filterList; std::unordered_map<int, int>* filterList;
std::vector<code_pointer> results; std::vector<code_pointer> results;
......
...@@ -31,7 +31,7 @@ int DuelClient::last_select_hint = 0; ...@@ -31,7 +31,7 @@ int DuelClient::last_select_hint = 0;
char DuelClient::last_successful_msg[0x2000]; char DuelClient::last_successful_msg[0x2000];
unsigned int DuelClient::last_successful_msg_length = 0; unsigned int DuelClient::last_successful_msg_length = 0;
wchar_t DuelClient::event_string[256]; wchar_t DuelClient::event_string[256];
mtrandom DuelClient::rnd; mt19937 DuelClient::rnd;
bool DuelClient::is_refreshing = false; bool DuelClient::is_refreshing = false;
int DuelClient::match_kill = 0; int DuelClient::match_kill = 0;
...@@ -60,7 +60,7 @@ bool DuelClient::StartClient(unsigned int ip, unsigned short port, bool create_g ...@@ -60,7 +60,7 @@ bool DuelClient::StartClient(unsigned int ip, unsigned short port, bool create_g
return false; return false;
} }
connect_state = 0x1; connect_state = 0x1;
rnd.reset(time(0)); rnd.reset((unsigned int)time(nullptr));
if(!create_game) { if(!create_game) {
timeval timeout = {5, 0}; timeval timeout = {5, 0};
event* resp_event = event_new(client_base, 0, EV_TIMEOUT, ConnectTimeout, 0); event* resp_event = event_new(client_base, 0, EV_TIMEOUT, ConnectTimeout, 0);
...@@ -691,7 +691,12 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -691,7 +691,12 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
char* prep = pdata; char* prep = pdata;
Replay new_replay; Replay new_replay;
memcpy(&new_replay.pheader, prep, sizeof(ReplayHeader)); memcpy(&new_replay.pheader, prep, sizeof(ReplayHeader));
time_t starttime = new_replay.pheader.seed; time_t starttime;
if (new_replay.pheader.flag & REPLAY_UNIFORM)
starttime = new_replay.pheader.start_time;
else
starttime = new_replay.pheader.seed;
tm* localedtime = localtime(&starttime); tm* localedtime = localtime(&starttime);
wchar_t timetext[40]; wchar_t timetext[40];
wcsftime(timetext, 40, L"%Y-%m-%d %H-%M-%S", localedtime); wcsftime(timetext, 40, L"%Y-%m-%d %H-%M-%S", localedtime);
...@@ -718,7 +723,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -718,7 +723,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
new_replay.comp_size = len - sizeof(ReplayHeader) - 1; new_replay.comp_size = len - sizeof(ReplayHeader) - 1;
if(mainGame->actionParam) if(mainGame->actionParam)
new_replay.SaveReplay(mainGame->ebRSName->getText()); new_replay.SaveReplay(mainGame->ebRSName->getText());
else new_replay.SaveReplay(L"_LastReplay"); else
new_replay.SaveReplay(L"_LastReplay");
} }
break; break;
} }
...@@ -1661,7 +1667,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1661,7 +1667,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
SetResponseI(-1); SetResponseI(-1);
mainGame->dField.ClearChainSelect(); mainGame->dField.ClearChainSelect();
if(mainGame->chkWaitChain->isChecked() && !mainGame->ignore_chain) { if(mainGame->chkWaitChain->isChecked() && !mainGame->ignore_chain) {
mainGame->WaitFrameSignal(rnd.real() * 20 + 20); mainGame->WaitFrameSignal(rnd.get_random_integer(20, 40));
} }
DuelClient::SendResponse(); DuelClient::SendResponse();
return true; return true;
...@@ -1761,7 +1767,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1761,7 +1767,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
if(!pzone) { if(!pzone) {
if(mainGame->chkRandomPos->isChecked()) { if(mainGame->chkRandomPos->isChecked()) {
do { do {
respbuf[2] = rnd.real() * 7; respbuf[2] = rnd.get_random_integer(0, 6);
} while(!(filter & (1 << respbuf[2]))); } while(!(filter & (1 << respbuf[2])));
} else { } else {
if (filter & 0x40) respbuf[2] = 6; if (filter & 0x40) respbuf[2] = 6;
...@@ -3719,7 +3725,14 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -3719,7 +3725,14 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int chtype = BufferIO::ReadInt8(pbuf); int chtype = BufferIO::ReadInt8(pbuf);
int value = BufferIO::ReadInt32(pbuf); int value = BufferIO::ReadInt32(pbuf);
auto& player_desc_hints = mainGame->dField.player_desc_hints[player]; auto& player_desc_hints = mainGame->dField.player_desc_hints[player];
if(value == CARD_QUESTION && player == 0) {
if(chtype == PHINT_DESC_ADD) { if(chtype == PHINT_DESC_ADD) {
mainGame->dField.cant_check_grave = true;
} else if(chtype == PHINT_DESC_REMOVE) {
mainGame->dField.cant_check_grave = false;
}
}
else if(chtype == PHINT_DESC_ADD) {
player_desc_hints[value]++; player_desc_hints[value]++;
} else if(chtype == PHINT_DESC_REMOVE) { } else if(chtype == PHINT_DESC_REMOVE) {
player_desc_hints[value]--; player_desc_hints[value]--;
......
...@@ -36,7 +36,7 @@ private: ...@@ -36,7 +36,7 @@ private:
static char last_successful_msg[0x2000]; static char last_successful_msg[0x2000];
static unsigned int last_successful_msg_length; static unsigned int last_successful_msg_length;
static wchar_t event_string[256]; static wchar_t event_string[256];
static mtrandom rnd; static mt19937 rnd;
public: public:
static bool StartClient(unsigned int ip, unsigned short port, bool create_game = true); static bool StartClient(unsigned int ip, unsigned short port, bool create_game = true);
static void ConnectTimeout(evutil_socket_t fd, short events, void* arg); static void ConnectTimeout(evutil_socket_t fd, short events, void* arg);
......
...@@ -396,7 +396,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -396,7 +396,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case BUTTON_ANNUMBER_11: case BUTTON_ANNUMBER_11:
case BUTTON_ANNUMBER_12: { case BUTTON_ANNUMBER_12: {
mainGame->soundManager->PlaySoundEffect(SoundManager::SFX::BUTTON); mainGame->soundManager->PlaySoundEffect(SoundManager::SFX::BUTTON);
for(int i = 0; i < mainGame->cbANNumber->getItemCount(); ++i) { for(int i = 0; i < (int)mainGame->cbANNumber->getItemCount(); ++i) {
if(id - BUTTON_ANNUMBER_1 + 1 == mainGame->cbANNumber->getItemData(i)) { if(id - BUTTON_ANNUMBER_1 + 1 == mainGame->cbANNumber->getItemData(i)) {
mainGame->cbANNumber->setSelected(i); mainGame->cbANNumber->setSelected(i);
break; break;
...@@ -1436,11 +1436,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -1436,11 +1436,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
clicked_card->is_selected = true; clicked_card->is_selected = true;
selected_cards.push_back(clicked_card); selected_cards.push_back(clicked_card);
} }
if(selected_cards.size() >= select_max) { if((int)selected_cards.size() >= select_max) {
SetResponseSelectedCards(); SetResponseSelectedCards();
ShowCancelOrFinishButton(0); ShowCancelOrFinishButton(0);
DuelClient::SendResponse(); DuelClient::SendResponse();
} else if(selected_cards.size() >= select_min) { } else if((int)selected_cards.size() >= select_min) {
if(selected_cards.size() == selectable_cards.size()) { if(selected_cards.size() == selectable_cards.size()) {
SetResponseSelectedCards(); SetResponseSelectedCards();
ShowCancelOrFinishButton(0); ShowCancelOrFinishButton(0);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "replay_mode.h" #include "replay_mode.h"
#include "single_mode.h" #include "single_mode.h"
#include "image_manager.h" #include "image_manager.h"
#include "sound_manager.h"
#include "game.h" #include "game.h"
namespace ygo { namespace ygo {
...@@ -540,7 +541,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -540,7 +541,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
break; break;
wchar_t infobuf[256]; wchar_t infobuf[256];
std::wstring repinfo; std::wstring repinfo;
time_t curtime = ReplayMode::cur_replay.pheader.seed; time_t curtime;
if(ReplayMode::cur_replay.pheader.flag & REPLAY_UNIFORM)
curtime = ReplayMode::cur_replay.pheader.start_time;
else
curtime = ReplayMode::cur_replay.pheader.seed;
tm* st = localtime(&curtime); tm* st = localtime(&curtime);
wcsftime(infobuf, 256, L"%Y/%m/%d %H:%M:%S\n", st); wcsftime(infobuf, 256, L"%Y/%m/%d %H:%M:%S\n", st);
repinfo.append(infobuf); repinfo.append(infobuf);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#ifdef _WIN32 #ifdef _WIN32
#define NOMINMAX
#include <Windows.h> #include <Windows.h>
class FileSystem { class FileSystem {
......
...@@ -2,15 +2,16 @@ ...@@ -2,15 +2,16 @@
#include "../ocgcore/ocgapi.h" #include "../ocgcore/ocgapi.h"
#include "../ocgcore/common.h" #include "../ocgcore/common.h"
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
#include "myfilesystem.h"
namespace ygo { namespace ygo {
Replay::Replay() { Replay::Replay()
is_recording = false; : fp(nullptr), pheader(), pdata(nullptr), replay_size(0), comp_size(0), is_recording(false), is_replaying(false) {
is_replaying = false; #ifdef _WIN32
replay_data = new unsigned char[0x20000]; recording_fp = nullptr;
comp_data = new unsigned char[0x2000]; #endif
replay_data = new unsigned char[MAX_REPLAY_SIZE];
comp_data = new unsigned char[MAX_COMP_SIZE];
} }
Replay::~Replay() { Replay::~Replay() {
delete[] replay_data; delete[] replay_data;
...@@ -33,6 +34,9 @@ void Replay::BeginRecord() { ...@@ -33,6 +34,9 @@ void Replay::BeginRecord() {
return; return;
#endif #endif
pdata = replay_data; pdata = replay_data;
replay_size = 0;
comp_size = 0;
is_replaying = false;
is_recording = true; is_recording = true;
} }
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ReplayHeader& header) {
...@@ -45,9 +49,11 @@ void Replay::WriteHeader(ReplayHeader& header) { ...@@ -45,9 +49,11 @@ void Replay::WriteHeader(ReplayHeader& header) {
fflush(fp); fflush(fp);
#endif #endif
} }
void Replay::WriteData(const void* data, unsigned int length, bool flush) { void Replay::WriteData(const void* data, int length, bool flush) {
if(!is_recording) if(!is_recording)
return; return;
if (length < 0 || (pdata - replay_data) + length > MAX_REPLAY_SIZE)
return;
memcpy(pdata, data, length); memcpy(pdata, data, length);
pdata += length; pdata += length;
#ifdef _WIN32 #ifdef _WIN32
...@@ -62,6 +68,8 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) { ...@@ -62,6 +68,8 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) {
void Replay::WriteInt32(int data, bool flush) { void Replay::WriteInt32(int data, bool flush) {
if(!is_recording) if(!is_recording)
return; return;
if ((pdata - replay_data) + 4 > MAX_REPLAY_SIZE)
return;
*((int*)(pdata)) = data; *((int*)(pdata)) = data;
pdata += 4; pdata += 4;
#ifdef _WIN32 #ifdef _WIN32
...@@ -76,6 +84,8 @@ void Replay::WriteInt32(int data, bool flush) { ...@@ -76,6 +84,8 @@ void Replay::WriteInt32(int data, bool flush) {
void Replay::WriteInt16(short data, bool flush) { void Replay::WriteInt16(short data, bool flush) {
if(!is_recording) if(!is_recording)
return; return;
if ((pdata - replay_data) + 2 > MAX_REPLAY_SIZE)
return;
*((short*)(pdata)) = data; *((short*)(pdata)) = data;
pdata += 2; pdata += 2;
#ifdef _WIN32 #ifdef _WIN32
...@@ -90,6 +100,8 @@ void Replay::WriteInt16(short data, bool flush) { ...@@ -90,6 +100,8 @@ void Replay::WriteInt16(short data, bool flush) {
void Replay::WriteInt8(char data, bool flush) { void Replay::WriteInt8(char data, bool flush) {
if(!is_recording) if(!is_recording)
return; return;
if ((pdata - replay_data) + 1 > MAX_REPLAY_SIZE)
return;
*pdata = data; *pdata = data;
pdata++; pdata++;
#ifdef _WIN32 #ifdef _WIN32
...@@ -117,11 +129,19 @@ void Replay::EndRecord() { ...@@ -117,11 +129,19 @@ void Replay::EndRecord() {
#else #else
fclose(fp); fclose(fp);
#endif #endif
pheader.datasize = pdata - replay_data; if(pdata - replay_data > 0 && pdata - replay_data <= MAX_REPLAY_SIZE)
replay_size = pdata - replay_data;
else
replay_size = 0;
pheader.datasize = replay_size;
pheader.flag |= REPLAY_COMPRESSED; pheader.flag |= REPLAY_COMPRESSED;
size_t propsize = 5; size_t propsize = 5;
comp_size = 0x1000; comp_size = MAX_COMP_SIZE;
LzmaCompress(comp_data, &comp_size, replay_data, pdata - replay_data, pheader.props, &propsize, 5, 1 << 24, 3, 0, 2, 32, 1); int ret = LzmaCompress(comp_data, &comp_size, replay_data, replay_size, pheader.props, &propsize, 5, 1 << 24, 3, 0, 2, 32, 1);
if (ret != SZ_OK) {
*((int*)(comp_data)) = ret;
comp_size = sizeof(ret);
}
is_recording = false; is_recording = false;
} }
void Replay::SaveReplay(const wchar_t* name) { void Replay::SaveReplay(const wchar_t* name) {
...@@ -163,22 +183,33 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -163,22 +183,33 @@ bool Replay::OpenReplay(const wchar_t* name) {
} }
if(!fp) if(!fp)
return false; return false;
pdata = replay_data;
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
if(fread(&pheader, sizeof(pheader), 1, fp) < 1) { if(fread(&pheader, sizeof(pheader), 1, fp) < 1) {
fclose(fp); fclose(fp);
return false; return false;
} }
if(pheader.flag & REPLAY_COMPRESSED) { if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = fread(comp_data, 1, 0x1000, fp); comp_size = fread(comp_data, 1, MAX_COMP_SIZE, fp);
fclose(fp); fclose(fp);
if ((int)pheader.datasize < 0 && (int)pheader.datasize > MAX_REPLAY_SIZE)
return false;
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)
return false;
if (replay_size != pheader.datasize) {
replay_size = 0;
return false; return false;
}
} else { } else {
comp_size = fread(replay_data, 1, 0x20000, fp); replay_size = fread(replay_data, 1, MAX_REPLAY_SIZE, fp);
fclose(fp); fclose(fp);
replay_size = comp_size; comp_size = 0;
} }
pdata = replay_data;
is_replaying = true; is_replaying = true;
return true; return true;
} }
...@@ -197,7 +228,7 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -197,7 +228,7 @@ bool Replay::CheckReplay(const wchar_t* name) {
ReplayHeader rheader; ReplayHeader rheader;
size_t count = fread(&rheader, sizeof(ReplayHeader), 1, rfp); size_t count = fread(&rheader, sizeof(ReplayHeader), 1, rfp);
fclose(rfp); fclose(rfp);
return count == 1 && rheader.id == 0x31707279 && rheader.version >= 0x12d0; return count == 1 && rheader.id == 0x31707279 && rheader.version >= 0x12d0u;
} }
bool Replay::DeleteReplay(const wchar_t* name) { bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256]; wchar_t fname[256];
...@@ -246,7 +277,7 @@ void Replay::ReadName(wchar_t* data) { ...@@ -246,7 +277,7 @@ void Replay::ReadName(wchar_t* data) {
ReadData(buffer, 40); ReadData(buffer, 40);
BufferIO::CopyWStr(buffer, data, 20); BufferIO::CopyWStr(buffer, data, 20);
} }
void Replay::ReadData(void* data, unsigned int length) { void Replay::ReadData(void* data, int length) {
if(!is_replaying) if(!is_replaying)
return; return;
memcpy(data, pdata, length); memcpy(data, pdata, length);
......
...@@ -6,10 +6,16 @@ ...@@ -6,10 +6,16 @@
namespace ygo { namespace ygo {
// replay flag
#define REPLAY_COMPRESSED 0x1 #define REPLAY_COMPRESSED 0x1
#define REPLAY_TAG 0x2 #define REPLAY_TAG 0x2
#define REPLAY_DECODED 0x4 #define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8 #define REPLAY_SINGLE_MODE 0x8
#define REPLAY_UNIFORM 0x10
// max size
#define MAX_REPLAY_SIZE 0x20000
#define MAX_COMP_SIZE 0x2000
struct ReplayHeader { struct ReplayHeader {
unsigned int id; unsigned int id;
...@@ -17,23 +23,30 @@ struct ReplayHeader { ...@@ -17,23 +23,30 @@ struct ReplayHeader {
unsigned int flag; unsigned int flag;
unsigned int seed; unsigned int seed;
unsigned int datasize; unsigned int datasize;
unsigned int hash; unsigned int start_time;
unsigned char props[8]; unsigned char props[8];
ReplayHeader()
: id(0), version(0), flag(0), seed(0), datasize(0), start_time(0), props{ 0 } {}
}; };
class Replay { class Replay {
public: public:
Replay(); Replay();
~Replay(); ~Replay();
// record
void BeginRecord(); void BeginRecord();
void WriteHeader(ReplayHeader& header); void WriteHeader(ReplayHeader& header);
void WriteData(const void* data, unsigned int length, bool flush = true); void WriteData(const void* data, 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();
void SaveReplay(const wchar_t* name); void SaveReplay(const wchar_t* name);
// play
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);
static bool DeleteReplay(const wchar_t* name); static bool DeleteReplay(const wchar_t* name);
...@@ -41,22 +54,25 @@ public: ...@@ -41,22 +54,25 @@ public:
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);
void ReadData(void* data, unsigned int length); void ReadData(void* data, int length);
int ReadInt32(); int ReadInt32();
short ReadInt16(); short ReadInt16();
char ReadInt8(); char ReadInt8();
void Rewind(); void Rewind();
FILE* fp; FILE* fp;
ReplayHeader pheader;
#ifdef _WIN32 #ifdef _WIN32
HANDLE recording_fp; HANDLE recording_fp;
#endif #endif
ReplayHeader pheader;
unsigned char* replay_data; unsigned char* replay_data;
unsigned char* comp_data; unsigned char* comp_data;
unsigned char* pdata;
size_t replay_size; size_t replay_size;
size_t comp_size; size_t comp_size;
private:
unsigned char* pdata;
bool is_recording; bool is_recording;
bool is_replaying; bool is_replaying;
}; };
......
...@@ -138,13 +138,23 @@ int ReplayMode::ReplayThread() { ...@@ -138,13 +138,23 @@ int ReplayMode::ReplayThread() {
mainGame->gMutex.unlock(); mainGame->gMutex.unlock();
} }
EndDuel(); EndDuel();
pduel = 0;
is_continuing = true;
is_closing = false;
is_pausing = false;
is_paused = false;
is_swaping = false;
is_restarting = false;
exit_pending = false;
skip_turn = 0;
current_step = 0;
skip_step = 0;
return 0; return 0;
} }
bool ReplayMode::StartDuel() { bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader; const ReplayHeader& rh = cur_replay.pheader;
mtrandom rnd; unsigned int seed = rh.seed;
int seed = rh.seed; std::mt19937 rnd(seed);
rnd.reset(seed);
if(mainGame->dInfo.isTag) { if(mainGame->dInfo.isTag) {
cur_replay.ReadName(mainGame->dInfo.hostname); cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag); cur_replay.ReadName(mainGame->dInfo.hostname_tag);
...@@ -154,7 +164,7 @@ bool ReplayMode::StartDuel() { ...@@ -154,7 +164,7 @@ bool ReplayMode::StartDuel() {
cur_replay.ReadName(mainGame->dInfo.hostname); cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname); cur_replay.ReadName(mainGame->dInfo.clientname);
} }
pduel = create_duel(rnd.rand()); pduel = create_duel(rnd());
int start_lp = cur_replay.ReadInt32(); int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32(); int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32(); int draw_count = cur_replay.ReadInt32();
...@@ -214,13 +224,18 @@ bool ReplayMode::StartDuel() { ...@@ -214,13 +224,18 @@ bool ReplayMode::StartDuel() {
} }
} else { } else {
char filename[256]; char filename[256];
size_t slen = cur_replay.ReadInt16(); int slen = cur_replay.ReadInt16();
if (slen < 0 || slen > 255) {
return false;
}
cur_replay.ReadData(filename, slen); cur_replay.ReadData(filename, slen);
filename[slen] = 0; filename[slen] = 0;
if(!preload_script(pduel, filename, 0)) { if(!preload_script(pduel, filename, 0)) {
return false; return false;
} }
} }
if (!(rh.flag & REPLAY_UNIFORM))
opt |= DUEL_OLD_REPLAY;
start_duel(pduel, opt); start_duel(pduel, opt);
return true; return true;
} }
......
...@@ -288,7 +288,8 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) { ...@@ -288,7 +288,8 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
int mainc = BufferIO::ReadInt32(deckbuf); int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf); int sidec = BufferIO::ReadInt32(deckbuf);
// verify data // verify data
if((unsigned)mainc + (unsigned)sidec > (len - 8) / 4) { const unsigned int possibleMaxLength = (len - 8) / 4;
if((unsigned)mainc > possibleMaxLength || (unsigned)sidec > possibleMaxLength || (unsigned)mainc + (unsigned)sidec > possibleMaxLength) {
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR; scem.msg = ERRMSG_DECKERROR;
scem.code = 0; scem.code = 0;
...@@ -395,7 +396,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -395,7 +396,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return; return;
duel_stage = DUEL_STAGE_DUELING; duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
pplayer[1] = players[1]; pplayer[1] = players[1];
if((tp && dp->type == 1) || (!tp && dp->type == 0)) { if((tp && dp->type == 1) || (!tp && dp->type == 0)) {
...@@ -410,34 +410,30 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -410,34 +410,30 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
swapped = true; swapped = true;
} }
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd;
unsigned int seed = rd();
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = 0; rh.flag = REPLAY_UNIFORM;
time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
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);
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { rnd.shuffle_vector(pdeck[0].main);
int swap = rnd.real() * (i + 1); rnd.shuffle_vector(pdeck[1].main);
std::swap(pdeck[0].main[i], pdeck[0].main[swap]);
}
for(size_t i = pdeck[1].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[1].main[i], pdeck[1].main[swap]);
}
} }
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)SingleDuel::MessageHandler); set_message_handler((message_handler)SingleDuel::MessageHandler);
rnd.reset(seed); pduel = create_duel(duel_seed);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16; int opt = (int)host_info.duel_rule << 16;
......
...@@ -33,9 +33,9 @@ int SingleMode::SinglePlayThread() { ...@@ -33,9 +33,9 @@ int SingleMode::SinglePlayThread() {
const int start_hand = 5; const int start_hand = 5;
const int draw_count = 1; const int draw_count = 1;
const int opt = 0; const int opt = 0;
mtrandom rnd; std::random_device rd;
time_t seed = time(0); unsigned int seed = rd();
rnd.reset(seed); mt19937 rnd(seed);
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler); set_message_handler((message_handler)MessageHandler);
...@@ -65,8 +65,9 @@ int SingleMode::SinglePlayThread() { ...@@ -65,8 +65,9 @@ int SingleMode::SinglePlayThread() {
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = REPLAY_SINGLE_MODE; rh.flag = REPLAY_UNIFORM | REPLAY_SINGLE_MODE;
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->HideElement(mainGame->wSinglePlay); mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo(); mainGame->ClearCardInfo();
......
...@@ -356,7 +356,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -356,7 +356,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return; return;
duel_stage = DUEL_STAGE_DUELING; duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
pplayer[1] = players[1]; pplayer[1] = players[1];
pplayer[2] = players[2]; pplayer[2] = players[2];
...@@ -376,44 +375,34 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -376,44 +375,34 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
cur_player[0] = players[0]; cur_player[0] = players[0];
cur_player[1] = players[3]; cur_player[1] = players[3];
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd;
unsigned int seed = rd();
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = REPLAY_TAG; rh.flag = REPLAY_UNIFORM | REPLAY_TAG;
time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
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);
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { rnd.shuffle_vector(pdeck[0].main);
int swap = rnd.real() * (i + 1); rnd.shuffle_vector(pdeck[1].main);
std::swap(pdeck[0].main[i], pdeck[0].main[swap]); rnd.shuffle_vector(pdeck[2].main);
} rnd.shuffle_vector(pdeck[3].main);
for(size_t i = pdeck[1].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[1].main[i], pdeck[1].main[swap]);
}
for(size_t i = pdeck[2].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[2].main[i], pdeck[2].main[swap]);
}
for(size_t i = pdeck[3].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[3].main[i], pdeck[3].main[swap]);
}
} }
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler); set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed); pduel = create_duel(duel_seed);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16; int opt = (int)host_info.duel_rule << 16;
......
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