Commit b3482765 authored by Chen Bill's avatar Chen Bill Committed by GitHub

fix: seeding std::mt19937 with only 1 uint32_t (#2820)

parent b9e1089f
...@@ -715,7 +715,7 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -715,7 +715,7 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
break; break;
} }
case STOC_REPLAY: { case STOC_REPLAY: {
if (len < 1 + (int)sizeof(ReplayHeader)) if (len < 1 + (int)sizeof(ExtendedReplayHeader))
return; return;
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->wPhase->setVisible(false); mainGame->wPhase->setVisible(false);
...@@ -726,10 +726,10 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -726,10 +726,10 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
Replay new_replay; Replay new_replay;
std::memcpy(&new_replay.pheader, prep, sizeof(new_replay.pheader)); std::memcpy(&new_replay.pheader, prep, sizeof(new_replay.pheader));
time_t starttime; time_t starttime;
if (new_replay.pheader.flag & REPLAY_UNIFORM) if (new_replay.pheader.base.flag & REPLAY_UNIFORM)
starttime = new_replay.pheader.start_time; starttime = new_replay.pheader.base.start_time;
else else
starttime = new_replay.pheader.seed; starttime = new_replay.pheader.base.seed;
wchar_t timetext[40]; wchar_t timetext[40];
std::wcsftime(timetext, sizeof timetext / sizeof timetext[0], L"%Y-%m-%d %H-%M-%S", std::localtime(&starttime)); std::wcsftime(timetext, sizeof timetext / sizeof timetext[0], L"%Y-%m-%d %H-%M-%S", std::localtime(&starttime));
...@@ -751,9 +751,9 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) { ...@@ -751,9 +751,9 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
mainGame->WaitFrameSignal(30); mainGame->WaitFrameSignal(30);
} }
if(mainGame->actionParam || !is_host) { if(mainGame->actionParam || !is_host) {
prep += sizeof(ReplayHeader); prep += sizeof new_replay.pheader;
std::memcpy(new_replay.comp_data, prep, len - sizeof(ReplayHeader) - 1); std::memcpy(new_replay.comp_data, prep, len - sizeof new_replay.pheader - 1);
new_replay.comp_size = len - sizeof(ReplayHeader) - 1; new_replay.comp_size = len - sizeof new_replay.pheader - 1;
if(mainGame->actionParam) if(mainGame->actionParam)
new_replay.SaveReplay(mainGame->ebRSName->getText()); new_replay.SaveReplay(mainGame->ebRSName->getText());
else else
......
...@@ -309,7 +309,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -309,7 +309,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
myswprintf(replay_path, L"./replay/%ls", replay_filename); myswprintf(replay_path, L"./replay/%ls", replay_filename);
if (!replay.OpenReplay(replay_path)) if (!replay.OpenReplay(replay_path))
break; break;
if (replay.pheader.flag & REPLAY_SINGLE_MODE) if (replay.pheader.base.flag & REPLAY_SINGLE_MODE)
break; break;
for (size_t i = 0; i < replay.decks.size(); ++i) { for (size_t i = 0; i < replay.decks.size(); ++i) {
BufferIO::CopyWideString(replay.players[Replay::GetDeckPlayer(i)].c_str(), namebuf[i]); BufferIO::CopyWideString(replay.players[Replay::GetDeckPlayer(i)].c_str(), namebuf[i]);
...@@ -537,24 +537,25 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -537,24 +537,25 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t infobuf[256]{}; wchar_t infobuf[256]{};
std::wstring repinfo; std::wstring repinfo;
time_t curtime; time_t curtime;
if(temp_replay.pheader.flag & REPLAY_UNIFORM) const auto& rh = temp_replay.pheader.base;
curtime = temp_replay.pheader.start_time; if(temp_replay.pheader.base.flag & REPLAY_UNIFORM)
curtime = rh.start_time;
else{ else{
curtime = temp_replay.pheader.seed; curtime = rh.seed;
wchar_t version_info[256]{}; wchar_t version_info[256]{};
myswprintf(version_info, L"version 0x%X\n", temp_replay.pheader.version); myswprintf(version_info, L"version 0x%X\n", rh.version);
repinfo.append(version_info); repinfo.append(version_info);
} }
std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime)); std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime));
repinfo.append(infobuf); repinfo.append(infobuf);
if (temp_replay.pheader.flag & REPLAY_SINGLE_MODE) { if (rh.flag & REPLAY_SINGLE_MODE) {
wchar_t path[256]{}; wchar_t path[256]{};
BufferIO::DecodeUTF8(temp_replay.script_name.c_str(), path); BufferIO::DecodeUTF8(temp_replay.script_name.c_str(), path);
repinfo.append(path); repinfo.append(path);
repinfo.append(L"\n"); repinfo.append(L"\n");
} }
const auto& player_names = temp_replay.players; const auto& player_names = temp_replay.players;
if(temp_replay.pheader.flag & REPLAY_TAG) if(rh.flag & REPLAY_TAG)
myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", player_names[0].c_str(), player_names[1].c_str(), player_names[2].c_str(), player_names[3].c_str()); myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", player_names[0].c_str(), player_names[1].c_str(), player_names[2].c_str(), player_names[3].c_str());
else else
myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str()); myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str());
......
...@@ -281,7 +281,7 @@ public: ...@@ -281,7 +281,7 @@ public:
#define STOC_LEAVE_GAME 0x14 // reserved #define STOC_LEAVE_GAME 0x14 // reserved
#define STOC_DUEL_START 0x15 // no data #define STOC_DUEL_START 0x15 // no data
#define STOC_DUEL_END 0x16 // no data #define STOC_DUEL_END 0x16 // no data
#define STOC_REPLAY 0x17 // ReplayHeader + byte array #define STOC_REPLAY 0x17 // ExtendedReplayHeader + byte array
#define STOC_TIME_LIMIT 0x18 // STOC_TimeLimit #define STOC_TIME_LIMIT 0x18 // STOC_TimeLimit
#define STOC_CHAT 0x19 // uint16_t + uint16_t array #define STOC_CHAT 0x19 // uint16_t + uint16_t array
#define STOC_HS_PLAYER_ENTER 0x20 // STOC_HS_PlayerEnter #define STOC_HS_PLAYER_ENTER 0x20 // STOC_HS_PlayerEnter
......
...@@ -32,7 +32,7 @@ void Replay::BeginRecord() { ...@@ -32,7 +32,7 @@ void Replay::BeginRecord() {
Reset(); Reset();
is_recording = true; is_recording = true;
} }
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ExtendedReplayHeader& header) {
pheader = header; pheader = header;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
...@@ -77,11 +77,11 @@ void Replay::EndRecord() { ...@@ -77,11 +77,11 @@ void Replay::EndRecord() {
#else #else
std::fclose(fp); std::fclose(fp);
#endif #endif
pheader.datasize = replay_size; pheader.base.datasize = replay_size;
pheader.flag |= REPLAY_COMPRESSED; pheader.base.flag |= REPLAY_COMPRESSED;
size_t propsize = 5; size_t propsize = 5;
comp_size = MAX_COMP_SIZE; comp_size = MAX_COMP_SIZE;
int ret = LzmaCompress(comp_data, &comp_size, replay_data, replay_size, pheader.props, &propsize, 5, 0x1U << 24, 3, 0, 2, 32, 1); int ret = LzmaCompress(comp_data, &comp_size, replay_data, replay_size, pheader.base.props, &propsize, 5, 0x1U << 24, 3, 0, 2, 32, 1);
if (ret != SZ_OK) { if (ret != SZ_OK) {
std::memcpy(comp_data, &ret, sizeof ret); std::memcpy(comp_data, &ret, sizeof ret);
comp_size = sizeof ret; comp_size = sizeof ret;
...@@ -112,27 +112,31 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -112,27 +112,31 @@ bool Replay::OpenReplay(const wchar_t* name) {
Reset(); Reset();
bool correct_header = true; bool correct_header = true;
if (std::fread(&pheader, sizeof pheader, 1, rfp) < 1) if (std::fread(&pheader, sizeof pheader.base, 1, rfp) < 1)
correct_header = false; correct_header = false;
else if (pheader.id != 0x31707279) else if (pheader.base.id != REPLAY_ID_YRP1 && pheader.base.id != REPLAY_ID_YRP2)
correct_header = false; correct_header = false;
else if (pheader.version < 0x12d0u) else if (pheader.base.version < 0x12d0u)
correct_header = false; correct_header = false;
else if (pheader.version >= 0x1353u && !(pheader.flag & REPLAY_UNIFORM)) else if (pheader.base.version >= 0x1353u && !(pheader.base.flag & REPLAY_UNIFORM))
correct_header = false; correct_header = false;
if (!correct_header) { if (!correct_header) {
std::fclose(rfp); std::fclose(rfp);
return false; return false;
} }
if(pheader.flag & REPLAY_COMPRESSED) { if (pheader.base.id == REPLAY_ID_YRP2 && std::fread(&pheader.seed_sequence, sizeof pheader.seed_sequence, 1, rfp) < 1) {
std::fclose(rfp);
return false;
}
if(pheader.base.flag & REPLAY_COMPRESSED) {
comp_size = std::fread(comp_data, 1, MAX_COMP_SIZE, rfp); comp_size = std::fread(comp_data, 1, MAX_COMP_SIZE, rfp);
std::fclose(rfp); std::fclose(rfp);
if (pheader.datasize > MAX_REPLAY_SIZE) if (pheader.base.datasize > MAX_REPLAY_SIZE)
return false; return false;
replay_size = pheader.datasize; replay_size = pheader.base.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.base.props, 5) != SZ_OK)
return false; return false;
if (replay_size != pheader.datasize) { if (replay_size != pheader.base.datasize) {
replay_size = 0; replay_size = 0;
return false; return false;
} }
...@@ -189,7 +193,7 @@ bool Replay::ReadName(wchar_t* data) { ...@@ -189,7 +193,7 @@ bool Replay::ReadName(wchar_t* data) {
BufferIO::CopyWStr(buffer, data, 20); BufferIO::CopyWStr(buffer, data, 20);
return true; return true;
} }
void Replay::ReadHeader(ReplayHeader& header) { void Replay::ReadHeader(ExtendedReplayHeader& header) {
header = pheader; header = pheader;
} }
bool Replay::ReadData(void* data, size_t length) { bool Replay::ReadData(void* data, size_t length) {
...@@ -232,7 +236,7 @@ bool Replay::IsReplaying() const { ...@@ -232,7 +236,7 @@ bool Replay::IsReplaying() const {
return is_replaying; return is_replaying;
} }
bool Replay::ReadInfo() { bool Replay::ReadInfo() {
int player_count = (pheader.flag & REPLAY_TAG) ? 4 : 2; int player_count = (pheader.base.flag & REPLAY_TAG) ? 4 : 2;
for (int i = 0; i < player_count; ++i) { for (int i = 0; i < player_count; ++i) {
wchar_t name[20]{}; wchar_t name[20]{};
if (!ReadName(name)) if (!ReadName(name))
...@@ -241,11 +245,11 @@ bool Replay::ReadInfo() { ...@@ -241,11 +245,11 @@ bool Replay::ReadInfo() {
} }
if (!ReadData(&params, sizeof params)) if (!ReadData(&params, sizeof params))
return false; return false;
bool is_tag1 = pheader.flag & REPLAY_TAG; bool is_tag1 = pheader.base.flag & REPLAY_TAG;
bool is_tag2 = params.duel_flag & DUEL_TAG_MODE; bool is_tag2 = params.duel_flag & DUEL_TAG_MODE;
if (is_tag1 != is_tag2) if (is_tag1 != is_tag2)
return false; return false;
if (pheader.flag & REPLAY_SINGLE_MODE) { if (pheader.base.flag & REPLAY_SINGLE_MODE) {
uint16_t slen = Read<uint16_t>(); uint16_t slen = Read<uint16_t>();
char filename[256]{}; char filename[256]{};
if (slen == 0 || slen > sizeof(filename) - 1) if (slen == 0 || slen > sizeof(filename) - 1)
......
...@@ -13,6 +13,9 @@ namespace ygo { ...@@ -13,6 +13,9 @@ namespace ygo {
#define REPLAY_SINGLE_MODE 0x8 #define REPLAY_SINGLE_MODE 0x8
#define REPLAY_UNIFORM 0x10 #define REPLAY_UNIFORM 0x10
#define REPLAY_ID_YRP1 0x31707279
#define REPLAY_ID_YRP2 0x32707279
// max size // max size
constexpr int MAX_REPLAY_SIZE = 0x80000; constexpr int MAX_REPLAY_SIZE = 0x80000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
...@@ -27,6 +30,15 @@ struct ReplayHeader { ...@@ -27,6 +30,15 @@ struct ReplayHeader {
uint8_t props[8]{}; uint8_t props[8]{};
}; };
struct ExtendedReplayHeader {
ReplayHeader base;
uint32_t seed_sequence[SEED_COUNT]{};
uint32_t header_version{ 1 };
uint32_t value1{};
uint32_t value2{};
uint32_t value3{};
};
struct DuelParameters { struct DuelParameters {
int32_t start_lp{}; int32_t start_lp{};
int32_t start_hand{}; int32_t start_hand{};
...@@ -41,7 +53,7 @@ public: ...@@ -41,7 +53,7 @@ public:
// record // record
void BeginRecord(); void BeginRecord();
void WriteHeader(ReplayHeader& header); void WriteHeader(ExtendedReplayHeader& header);
void WriteData(const void* data, size_t length, bool flush = true); void WriteData(const void* data, size_t length, bool flush = true);
template<typename T> template<typename T>
void Write(T data, bool flush = true) { void Write(T data, bool flush = true) {
...@@ -68,7 +80,7 @@ public: ...@@ -68,7 +80,7 @@ public:
bool OpenReplay(const wchar_t* name); bool OpenReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[]); bool ReadNextResponse(unsigned char resp[]);
bool ReadName(wchar_t* data); bool ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header); void ReadHeader(ExtendedReplayHeader& header);
bool ReadData(void* data, size_t length); bool ReadData(void* data, size_t length);
template<typename T> template<typename T>
T Read() { T Read() {
...@@ -87,7 +99,7 @@ public: ...@@ -87,7 +99,7 @@ public:
HANDLE recording_fp{ nullptr }; HANDLE recording_fp{ nullptr };
#endif #endif
ReplayHeader pheader; ExtendedReplayHeader pheader;
unsigned char* comp_data; unsigned char* comp_data;
size_t comp_size{}; size_t comp_size{};
......
...@@ -57,7 +57,7 @@ bool ReplayMode::ReadReplayResponse() { ...@@ -57,7 +57,7 @@ bool ReplayMode::ReadReplayResponse() {
return result; return result;
} }
int ReplayMode::ReplayThread() { int ReplayMode::ReplayThread() {
const ReplayHeader& rh = cur_replay.pheader; const auto& rh = cur_replay.pheader.base;
mainGame->dInfo.Clear(); mainGame->dInfo.Clear();
mainGame->dInfo.isFirst = true; mainGame->dInfo.isFirst = true;
mainGame->dInfo.isTag = !!(rh.flag & REPLAY_TAG); mainGame->dInfo.isTag = !!(rh.flag & REPLAY_TAG);
...@@ -155,9 +155,7 @@ int ReplayMode::ReplayThread() { ...@@ -155,9 +155,7 @@ int ReplayMode::ReplayThread() {
return 0; return 0;
} }
bool ReplayMode::StartDuel() { bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader; const auto& rh = cur_replay.pheader.base;
unsigned int seed = rh.seed;
std::mt19937 rnd(seed);
cur_replay.SkipInfo(); cur_replay.SkipInfo();
if(rh.flag & REPLAY_TAG) { if(rh.flag & REPLAY_TAG) {
BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
...@@ -168,7 +166,12 @@ bool ReplayMode::StartDuel() { ...@@ -168,7 +166,12 @@ bool ReplayMode::StartDuel() {
BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.clientname); BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.clientname);
} }
pduel = create_duel(rnd()); if(rh.id == REPLAY_ID_YRP1) {
std::mt19937 rnd(rh.seed);
pduel = create_duel(rnd());
} else {
pduel = create_duel_v2(cur_replay.pheader.seed_sequence);
}
mainGame->dInfo.duel_rule = cur_replay.params.duel_flag >> 16; mainGame->dInfo.duel_rule = cur_replay.params.duel_flag >> 16;
set_player_info(pduel, 0, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count); set_player_info(pduel, 0, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
set_player_info(pduel, 1, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count); set_player_info(pduel, 1, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
...@@ -214,8 +217,6 @@ bool ReplayMode::StartDuel() { ...@@ -214,8 +217,6 @@ bool ReplayMode::StartDuel() {
return false; return false;
} }
} }
if (!(rh.flag & REPLAY_UNIFORM))
cur_replay.params.duel_flag |= DUEL_OLD_REPLAY;
start_duel(pduel, cur_replay.params.duel_flag); start_duel(pduel, cur_replay.params.duel_flag);
return true; return true;
} }
......
...@@ -411,15 +411,14 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -411,15 +411,14 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
} }
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd; std::random_device rd;
unsigned int seed = rd(); ExtendedReplayHeader rh;
mt19937 rnd((uint_fast32_t)seed); rh.base.id = REPLAY_ID_YRP2;
auto duel_seed = rnd.rand(); rh.base.version = PRO_VERSION;
ReplayHeader rh; rh.base.flag = REPLAY_UNIFORM;
rh.id = 0x31707279; rh.base.start_time = (uint32_t)std::time(nullptr);
rh.version = PRO_VERSION; for (auto& x : rh.seed_sequence)
rh.flag = REPLAY_UNIFORM; x = rd();
rh.seed = seed; mtrandom rnd(rh.seed_sequence, SEED_COUNT);
rh.start_time = (unsigned int)std::time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
last_replay.WriteData(players[0]->name, 40, false); last_replay.WriteData(players[0]->name, 40, false);
...@@ -433,7 +432,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -433,7 +432,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
set_script_reader(DataManager::ScriptReaderEx); set_script_reader(DataManager::ScriptReaderEx);
set_card_reader(DataManager::CardReader); set_card_reader(DataManager::CardReader);
set_message_handler(SingleDuel::MessageHandler); set_message_handler(SingleDuel::MessageHandler);
pduel = create_duel(duel_seed); pduel = create_duel_v2(rh.seed_sequence);
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);
unsigned int opt = (unsigned int)host_info.duel_rule << 16; unsigned int opt = (unsigned int)host_info.duel_rule << 16;
...@@ -1426,10 +1425,10 @@ void SingleDuel::EndDuel() { ...@@ -1426,10 +1425,10 @@ void SingleDuel::EndDuel() {
return; return;
last_replay.EndRecord(); last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
std::memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); std::memcpy(pbuf, &last_replay.pheader, sizeof last_replay.pheader);
pbuf += sizeof(ReplayHeader); pbuf += sizeof last_replay.pheader;
std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size); std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size); NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof last_replay.pheader + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include "duelclient.h" #include "duelclient.h"
#include "game.h" #include "game.h"
#include "data_manager.h" #include "data_manager.h"
#include "../ocgcore/mtrandom.h" #include <random>
#include <thread> #include <thread>
namespace ygo { namespace ygo {
...@@ -36,12 +36,22 @@ int SingleMode::SinglePlayThread() { ...@@ -36,12 +36,22 @@ int SingleMode::SinglePlayThread() {
mainGame->dInfo.Clear(); mainGame->dInfo.Clear();
int opt = 0; int opt = 0;
std::random_device rd; std::random_device rd;
unsigned int seed = rd(); ExtendedReplayHeader rh;
mt19937 rnd((uint_fast32_t)seed); rh.base.id = REPLAY_ID_YRP2;
rh.base.version = PRO_VERSION;
rh.base.flag = REPLAY_UNIFORM | REPLAY_SINGLE_MODE;
rh.base.start_time = (uint32_t)std::time(nullptr);
for (auto& x : rh.seed_sequence)
x = rd();
std::seed_seq seed(rh.seed_sequence, rh.seed_sequence + SEED_COUNT);
std::mt19937 rnd(seed);
uint32_t duel_seed[SEED_COUNT]{};
for (auto& x : duel_seed)
x = rnd();
set_script_reader(DataManager::ScriptReaderEx); set_script_reader(DataManager::ScriptReaderEx);
set_card_reader(DataManager::CardReader); set_card_reader(DataManager::CardReader);
set_message_handler(SingleMode::MessageHandler); set_message_handler(SingleMode::MessageHandler);
pduel = create_duel(rnd.rand()); pduel = create_duel_v2(duel_seed);
set_player_info(pduel, 0, start_lp, start_hand, draw_count); set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, start_lp, start_hand, draw_count); set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = start_lp; mainGame->dInfo.lp[0] = start_lp;
...@@ -79,12 +89,6 @@ int SingleMode::SinglePlayThread() { ...@@ -79,12 +89,6 @@ int SingleMode::SinglePlayThread() {
end_duel(pduel); end_duel(pduel);
return 0; return 0;
} }
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_UNIFORM | REPLAY_SINGLE_MODE;
rh.seed = seed;
rh.start_time = (unsigned int)std::time(nullptr);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->HideElement(mainGame->wSinglePlay); mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo(); mainGame->ClearCardInfo();
......
...@@ -384,15 +384,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -384,15 +384,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
cur_player[1] = players[3]; cur_player[1] = players[3];
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd; std::random_device rd;
unsigned int seed = rd(); ExtendedReplayHeader rh;
mt19937 rnd((uint_fast32_t)seed); rh.base.id = REPLAY_ID_YRP2;
auto duel_seed = rnd.rand(); rh.base.version = PRO_VERSION;
ReplayHeader rh; rh.base.flag = REPLAY_UNIFORM | REPLAY_TAG;
rh.id = 0x31707279; rh.base.start_time = (uint32_t)std::time(nullptr);
rh.version = PRO_VERSION; for (auto& x : rh.seed_sequence)
rh.flag = REPLAY_UNIFORM | REPLAY_TAG; x = rd();
rh.seed = seed; mtrandom rnd(rh.seed_sequence, SEED_COUNT);
rh.start_time = (unsigned int)std::time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
last_replay.WriteData(players[0]->name, 40, false); last_replay.WriteData(players[0]->name, 40, false);
...@@ -410,7 +409,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -410,7 +409,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
set_script_reader(DataManager::ScriptReaderEx); set_script_reader(DataManager::ScriptReaderEx);
set_card_reader(DataManager::CardReader); set_card_reader(DataManager::CardReader);
set_message_handler(TagDuel::MessageHandler); set_message_handler(TagDuel::MessageHandler);
pduel = create_duel(duel_seed); pduel = create_duel_v2(rh.seed_sequence);
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);
unsigned int opt = (unsigned int)host_info.duel_rule << 16; unsigned int opt = (unsigned int)host_info.duel_rule << 16;
...@@ -1529,10 +1528,10 @@ void TagDuel::EndDuel() { ...@@ -1529,10 +1528,10 @@ void TagDuel::EndDuel() {
return; return;
last_replay.EndRecord(); last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf; char replaybuf[0x2000], *pbuf = replaybuf;
std::memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader)); std::memcpy(pbuf, &last_replay.pheader, sizeof last_replay.pheader);
pbuf += sizeof(ReplayHeader); pbuf += sizeof last_replay.pheader;
std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size); std::memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size); NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof last_replay.pheader + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]); NetServer::ReSendToPlayer(players[2]);
NetServer::ReSendToPlayer(players[3]); NetServer::ReSendToPlayer(players[3]);
......
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