Commit c80aa6c6 authored by mercury233's avatar mercury233

Merge branch 'server-merge-1353' into 'server'

A merge for 1353

See merge request mycard/ygopro!9
parents 75ed11cf 2ef8ca22
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,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>
......
...@@ -82,7 +82,11 @@ bool DataManager::LoadDB(const wchar_t* wfile) { ...@@ -82,7 +82,11 @@ 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);
_datas.insert(std::make_pair(cd.code, cd)); auto it = _datas.find(cd.code);
if(it != _datas.end())
it->second = cd;
else
_datas.insert(std::make_pair(cd.code, cd));
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
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);
......
...@@ -79,6 +79,7 @@ void DeckBuilder::Initialize() { ...@@ -79,6 +79,7 @@ void DeckBuilder::Initialize() {
mainGame->btnSideReload->setVisible(false); mainGame->btnSideReload->setVisible(false);
filterList = &deckManager._lfList[mainGame->gameConf.use_lflist ? mainGame->gameConf.default_lflist : deckManager._lfList.size() - 1].content; filterList = &deckManager._lfList[mainGame->gameConf.use_lflist ? mainGame->gameConf.default_lflist : deckManager._lfList.size() - 1].content;
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;
...@@ -167,7 +168,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -167,7 +168,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: {
...@@ -354,7 +355,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -354,7 +355,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));
} }
...@@ -371,7 +372,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -371,7 +372,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));
} }
...@@ -390,7 +391,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -390,7 +391,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(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) { if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -420,7 +421,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -420,7 +421,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(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) { if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) {
catesel = i; catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474)); mainGame->stACMessage->setText(dataManager.GetSysString(1474));
...@@ -471,7 +472,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -471,7 +472,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(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(filepath); deckManager.LoadDeck(filepath);
prev_deck = i; prev_deck = i;
...@@ -505,7 +506,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -505,7 +506,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(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), newdeckname, 256)) { if(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), newdeckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -569,7 +570,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -569,7 +570,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(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -607,7 +608,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -607,7 +608,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(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) { if(!mywcsncasecmp(mainGame->lstDecks->getListItem(i), deckname, 256)) {
deckManager.LoadDeck(newfilepath); deckManager.LoadDeck(newfilepath);
prev_deck = i; prev_deck = i;
...@@ -1501,7 +1502,7 @@ void DeckBuilder::FilterCards() { ...@@ -1501,7 +1502,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,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "client_card.h" #include "client_card.h"
#include "../ocgcore/mtrandom.h"
namespace ygo { namespace ygo {
...@@ -76,6 +77,7 @@ public: ...@@ -76,6 +77,7 @@ public:
int prev_sel; int prev_sel;
bool is_modified; bool is_modified;
bool readonly; bool readonly;
mt19937 rnd;
const std::unordered_map<int, int>* filterList; const std::unordered_map<int, int>* filterList;
std::vector<code_pointer> results; std::vector<code_pointer> results;
......
...@@ -29,7 +29,7 @@ int DuelClient::last_select_hint = 0; ...@@ -29,7 +29,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;
...@@ -58,7 +58,7 @@ bool DuelClient::StartClient(unsigned int ip, unsigned short port, bool create_g ...@@ -58,7 +58,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);
...@@ -681,7 +681,12 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -681,7 +681,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);
...@@ -708,7 +713,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -708,7 +713,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;
} }
...@@ -1650,7 +1656,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1650,7 +1656,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;
...@@ -1750,7 +1756,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1750,7 +1756,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;
......
...@@ -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);
......
...@@ -328,7 +328,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -328,7 +328,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case BUTTON_ANNUMBER_11: case BUTTON_ANNUMBER_11:
case BUTTON_ANNUMBER_12: { case BUTTON_ANNUMBER_12: {
soundManager.PlaySoundEffect(SOUND_BUTTON); soundManager.PlaySoundEffect(SOUND_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;
...@@ -1367,11 +1367,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -1367,11 +1367,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);
......
...@@ -25,7 +25,7 @@ Game* mainGame; ...@@ -25,7 +25,7 @@ Game* mainGame;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
unsigned short aServerPort; unsigned short aServerPort;
unsigned short replay_mode; unsigned short replay_mode;
time_t pre_seed[3]; unsigned int pre_seed[3];
HostInfo game_info; HostInfo game_info;
void Game::MainServerLoop() { void Game::MainServerLoop() {
...@@ -86,7 +86,6 @@ bool Game::Initialize() { ...@@ -86,7 +86,6 @@ bool Game::Initialize() {
return false; return false;
} }
dataManager.FileSystem = device->getFileSystem(); dataManager.FileSystem = device->getFileSystem();
LoadExpansions();
if(!dataManager.LoadDB(L"cards.cdb")) { if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!"); ErrorLog("Failed to load card database (cards.cdb)!");
return false; return false;
...@@ -95,7 +94,7 @@ bool Game::Initialize() { ...@@ -95,7 +94,7 @@ bool Game::Initialize() {
ErrorLog("Failed to load strings!"); ErrorLog("Failed to load strings!");
return false; return false;
} }
dataManager.LoadStrings("./expansions/strings.conf"); LoadExpansions();
env = device->getGUIEnvironment(); env = device->getGUIEnvironment();
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16); numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(!numFont) { if(!numFont) {
...@@ -749,7 +748,7 @@ bool Game::Initialize() { ...@@ -749,7 +748,7 @@ bool Game::Initialize() {
int catewidth = 0; int catewidth = 0;
for(int i = 0; i < 32; ++i) { for(int i = 0; i < 32; ++i) {
irr::core::dimension2d<unsigned int> dtxt = mainGame->guiFont->getDimension(dataManager.GetSysString(1100 + i)); irr::core::dimension2d<unsigned int> dtxt = mainGame->guiFont->getDimension(dataManager.GetSysString(1100 + i));
if(dtxt.Width + 40 > catewidth) if((int)dtxt.Width + 40 > catewidth)
catewidth = dtxt.Width + 40; catewidth = dtxt.Width + 40;
} }
for(int i = 0; i < 32; ++i) for(int i = 0; i < 32; ++i)
...@@ -1100,17 +1099,20 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, ...@@ -1100,17 +1099,20 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth,
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
void Game::LoadExpansions() { void Game::LoadExpansions() {
FileSystem::TraversalDir(L"./expansions", [](const wchar_t* name, bool isdir) { FileSystem::TraversalDir(L"./expansions", [](const wchar_t* name, bool isdir) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".cdb", 4)) { if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".cdb", 4)) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
dataManager.LoadDB(fpath); dataManager.LoadDB(fpath);
} }
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
}); });
#else #else
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".conf", 5)) {
char upath[1024];
BufferIO::EncodeUTF8(fpath, upath);
dataManager.LoadStrings(upath);
}
if(!isdir && wcsrchr(name, '.') && (!mywcsncasecmp(wcsrchr(name, '.'), L".zip", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".ypk", 4))) { if(!isdir && wcsrchr(name, '.') && (!mywcsncasecmp(wcsrchr(name, '.'), L".zip", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".ypk", 4))) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
#ifdef _WIN32 #ifdef _WIN32
dataManager.FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP); dataManager.FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP);
#else #else
......
...@@ -600,7 +600,7 @@ extern Game* mainGame; ...@@ -600,7 +600,7 @@ extern Game* mainGame;
extern unsigned short aServerPort; extern unsigned short aServerPort;
extern unsigned short replay_mode; extern unsigned short replay_mode;
extern HostInfo game_info; extern HostInfo game_info;
extern time_t pre_seed[3]; extern unsigned int pre_seed[3];
#endif #endif
} }
......
...@@ -74,7 +74,7 @@ int main(int argc, char* argv[]) { ...@@ -74,7 +74,7 @@ int main(int argc, char* argv[]) {
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE; ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180; ygo::game_info.time_limit = 180;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
ygo::pre_seed[i] = (time_t)0; ygo::pre_seed[i] = (unsigned int)0;
if (argc > 1) { if (argc > 1) {
ygo::aServerPort = atoi(argv[1]); ygo::aServerPort = atoi(argv[1]);
int lflist = atoi(argv[2]); int lflist = atoi(argv[2]);
...@@ -112,7 +112,7 @@ int main(int argc, char* argv[]) { ...@@ -112,7 +112,7 @@ int main(int argc, char* argv[]) {
ygo::replay_mode = atoi(argv[12]); ygo::replay_mode = atoi(argv[12]);
for (int i = 13; (i < argc && i <= 15) ; ++i) for (int i = 13; (i < argc && i <= 15) ; ++i)
{ {
ygo::pre_seed[i - 13] = (time_t)atoi(argv[i]); ygo::pre_seed[i - 13] = (unsigned int)atol(argv[i]);
} }
} }
ygo::mainGame = &_game; ygo::mainGame = &_game;
......
...@@ -125,7 +125,7 @@ Returns: ...@@ -125,7 +125,7 @@ Returns:
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/ */
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize); const unsigned char *props, size_t propsSize);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -465,7 +465,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -465,7 +465,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 {
......
...@@ -9,11 +9,13 @@ namespace ygo { ...@@ -9,11 +9,13 @@ namespace ygo {
extern unsigned short aServerPort; extern unsigned short aServerPort;
extern unsigned short replay_mode; extern unsigned short replay_mode;
#endif #endif
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;
...@@ -62,6 +64,9 @@ void Replay::BeginRecord() { ...@@ -62,6 +64,9 @@ void Replay::BeginRecord() {
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
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) {
...@@ -77,9 +82,11 @@ void Replay::WriteHeader(ReplayHeader& header) { ...@@ -77,9 +82,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 YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -97,6 +104,8 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) { ...@@ -97,6 +104,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 YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -114,6 +123,8 @@ void Replay::WriteInt32(int data, bool flush) { ...@@ -114,6 +123,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 YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -131,6 +142,8 @@ void Replay::WriteInt16(short data, bool flush) { ...@@ -131,6 +142,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 YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -170,11 +183,19 @@ void Replay::EndRecord() { ...@@ -170,11 +183,19 @@ void Replay::EndRecord() {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
} }
#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) {
...@@ -216,22 +237,33 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -216,22 +237,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;
} }
...@@ -250,7 +282,7 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -250,7 +282,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];
...@@ -299,7 +331,7 @@ void Replay::ReadName(wchar_t* data) { ...@@ -299,7 +331,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());
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0); preload_script(pduel, "./script/special.lua", 0);
#endif #endif
...@@ -217,13 +227,18 @@ bool ReplayMode::StartDuel() { ...@@ -217,13 +227,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;
} }
......
...@@ -516,7 +516,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -516,7 +516,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)) {
...@@ -531,39 +530,35 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -531,39 +530,35 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
swapped = true; swapped = true;
} }
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
ReplayHeader rh; std::random_device rd;
rh.id = 0x31707279; unsigned int seed = rd();
rh.version = PRO_VERSION;
rh.flag = 0;
time_t seed = time(0);
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(pre_seed[duel_count] > 0) { if(pre_seed[duel_count] > 0) {
seed = pre_seed[duel_count]; seed = pre_seed[duel_count];
} }
#endif #endif
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_UNIFORM;
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());
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0); preload_script(pduel, "./script/special.lua", 0);
#endif #endif
......
...@@ -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);
...@@ -77,8 +77,9 @@ int SingleMode::SinglePlayThread() { ...@@ -77,8 +77,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();
......
...@@ -479,7 +479,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -479,7 +479,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];
...@@ -499,49 +498,39 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -499,49 +498,39 @@ 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;
ReplayHeader rh; std::random_device rd;
rh.id = 0x31707279; unsigned int seed = rd();
rh.version = PRO_VERSION;
rh.flag = REPLAY_TAG;
time_t seed = time(0);
rh.seed = seed;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
if(pre_seed[0] > 0) { if(pre_seed[0] > 0) {
seed = pre_seed[0]; seed = pre_seed[0];
} }
#endif #endif
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_UNIFORM | REPLAY_TAG;
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());
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0); preload_script(pduel, "./script/special.lua", 0);
#endif #endif
......
Subproject commit 8b5b9b7793dfd8ad77c75fe4a27477ca2b4e6c96 Subproject commit 99934ac7ca0eec057eb7a9a29da5cccdc5f7fdaa
Subproject commit c8919a9349d0de9fa177af2c352ee3c753f57c02 Subproject commit 967a69444572c9ab9ec3cd54ab5bf8d984e37239
...@@ -261,6 +261,9 @@ ...@@ -261,6 +261,9 @@
!system 1164 同调召唤 !system 1164 同调召唤
!system 1165 超量召唤 !system 1165 超量召唤
!system 1166 连接召唤 !system 1166 连接召唤
!system 1167 上级召唤
!system 1168 仪式召唤
!system 1169 融合召唤
!system 1190 加入手卡 !system 1190 加入手卡
!system 1191 送去墓地 !system 1191 送去墓地
!system 1192 除外 !system 1192 除外
...@@ -1108,3 +1111,7 @@ ...@@ -1108,3 +1111,7 @@
!setname 0x16c 冰水 氷水 !setname 0x16c 冰水 氷水
!setname 0x16d 随风旅鸟 ふわんだりぃず !setname 0x16d 随风旅鸟 ふわんだりぃず
!setname 0x16e 拓扑 トポロジック !setname 0x16e 拓扑 トポロジック
!setname 0x16f 许珀里翁 ヒュペリオン
!setname 0x170 甲虫骑兵 Beetrooper
!setname 0x171 朋克 P.U.N.K.
!setname 0x172 救祓少女 エクソシスター
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