Commit bd61f452 authored by mercury233's avatar mercury233

Merge branch 'server' of git.mycard.moe:mycard/ygopro into server

parents 51983cf5 c80aa6c6
......@@ -8,6 +8,7 @@
#ifdef _WIN32
#include <WinSock2.h>
#define NOMINMAX
#include <windows.h>
#include <ws2tcpip.h>
......
......@@ -82,7 +82,11 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
cd.race = sqlite3_column_int(pStmt, 8);
cd.attribute = sqlite3_column_int(pStmt, 9);
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
if(const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
BufferIO::DecodeUTF8(text, strBuffer);
......
......@@ -79,6 +79,7 @@ void DeckBuilder::Initialize() {
mainGame->btnSideReload->setVisible(false);
filterList = &deckManager._lfList[mainGame->gameConf.use_lflist ? mainGame->gameConf.default_lflist : deckManager._lfList.size() - 1].content;
ClearSearch();
rnd.reset((unsigned int)time(nullptr));
mouse_pos.set(0, 0);
hovered_code = 0;
hovered_pos = 0;
......@@ -167,7 +168,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
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;
}
case BUTTON_SAVE_DECK: {
......@@ -354,7 +355,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int catesel = mainGame->lstCategories->getSelected();
if(catesel != 2)
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)
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
}
......@@ -371,7 +372,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
int catesel = mainGame->lstCategories->getSelected();
if(catesel != 2)
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)
mainGame->cbDMCategory->addItem(mainGame->lstCategories->getListItem(i));
}
......@@ -390,7 +391,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->lstCategories->addItem(catename);
catesel = mainGame->lstCategories->getItemCount() - 1;
} 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)) {
catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474));
......@@ -420,7 +421,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
catesel = mainGame->lstCategories->getItemCount() - 1;
} else {
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)) {
catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474));
......@@ -471,7 +472,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList();
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)) {
deckManager.LoadDeck(filepath);
prev_deck = i;
......@@ -505,7 +506,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
RefreshDeckList();
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)) {
deckManager.LoadDeck(newfilepath);
prev_deck = i;
......@@ -569,7 +570,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList();
mainGame->cbDBCategory->setSelected(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)) {
deckManager.LoadDeck(newfilepath);
prev_deck = i;
......@@ -607,7 +608,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
RefreshDeckList();
mainGame->cbDBCategory->setSelected(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)) {
deckManager.LoadDeck(newfilepath);
prev_deck = i;
......@@ -1499,7 +1500,7 @@ void DeckBuilder::FilterCards() {
SortList();
}
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();
}
void DeckBuilder::ClearSearch() {
......
......@@ -5,6 +5,7 @@
#include <unordered_map>
#include <vector>
#include "client_card.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
......@@ -76,6 +77,7 @@ public:
int prev_sel;
bool is_modified;
bool readonly;
mt19937 rnd;
const std::unordered_map<int, int>* filterList;
std::vector<code_pointer> results;
......
......@@ -29,7 +29,7 @@ int DuelClient::last_select_hint = 0;
char DuelClient::last_successful_msg[0x2000];
unsigned int DuelClient::last_successful_msg_length = 0;
wchar_t DuelClient::event_string[256];
mtrandom DuelClient::rnd;
mt19937 DuelClient::rnd;
bool DuelClient::is_refreshing = false;
int DuelClient::match_kill = 0;
......@@ -58,7 +58,7 @@ bool DuelClient::StartClient(unsigned int ip, unsigned short port, bool create_g
return false;
}
connect_state = 0x1;
rnd.reset(time(0));
rnd.reset((unsigned int)time(nullptr));
if(!create_game) {
timeval timeout = {5, 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) {
char* prep = pdata;
Replay new_replay;
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);
wchar_t timetext[40];
wcsftime(timetext, 40, L"%Y-%m-%d %H-%M-%S", localedtime);
......@@ -708,7 +713,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
new_replay.comp_size = len - sizeof(ReplayHeader) - 1;
if(mainGame->actionParam)
new_replay.SaveReplay(mainGame->ebRSName->getText());
else new_replay.SaveReplay(L"_LastReplay");
else
new_replay.SaveReplay(L"_LastReplay");
}
break;
}
......@@ -1650,7 +1656,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
SetResponseI(-1);
mainGame->dField.ClearChainSelect();
if(mainGame->chkWaitChain->isChecked() && !mainGame->ignore_chain) {
mainGame->WaitFrameSignal(rnd.real() * 20 + 20);
mainGame->WaitFrameSignal(rnd.get_random_integer(20, 40));
}
DuelClient::SendResponse();
return true;
......@@ -1750,7 +1756,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
if(!pzone) {
if(mainGame->chkRandomPos->isChecked()) {
do {
respbuf[2] = rnd.real() * 7;
respbuf[2] = rnd.get_random_integer(0, 6);
} while(!(filter & (1 << respbuf[2])));
} else {
if (filter & 0x40) respbuf[2] = 6;
......
......@@ -36,7 +36,7 @@ private:
static char last_successful_msg[0x2000];
static unsigned int last_successful_msg_length;
static wchar_t event_string[256];
static mtrandom rnd;
static mt19937 rnd;
public:
static bool StartClient(unsigned int ip, unsigned short port, bool create_game = true);
static void ConnectTimeout(evutil_socket_t fd, short events, void* arg);
......
......@@ -328,7 +328,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case BUTTON_ANNUMBER_11:
case BUTTON_ANNUMBER_12: {
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)) {
mainGame->cbANNumber->setSelected(i);
break;
......@@ -1367,11 +1367,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
clicked_card->is_selected = true;
selected_cards.push_back(clicked_card);
}
if(selected_cards.size() >= select_max) {
if((int)selected_cards.size() >= select_max) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
} else if(selected_cards.size() >= select_min) {
} else if((int)selected_cards.size() >= select_min) {
if(selected_cards.size() == selectable_cards.size()) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
......
......@@ -25,7 +25,7 @@ Game* mainGame;
#ifdef YGOPRO_SERVER_MODE
unsigned short aServerPort;
unsigned short replay_mode;
time_t pre_seed[3];
unsigned int pre_seed[3];
HostInfo game_info;
void Game::MainServerLoop() {
......@@ -86,7 +86,6 @@ bool Game::Initialize() {
return false;
}
dataManager.FileSystem = device->getFileSystem();
LoadExpansions();
if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!");
return false;
......@@ -95,7 +94,7 @@ bool Game::Initialize() {
ErrorLog("Failed to load strings!");
return false;
}
dataManager.LoadStrings("./expansions/strings.conf");
LoadExpansions();
env = device->getGUIEnvironment();
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(!numFont) {
......@@ -747,7 +746,7 @@ bool Game::Initialize() {
int catewidth = 0;
for(int i = 0; i < 32; ++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;
}
for(int i = 0; i < 32; ++i)
......@@ -1098,17 +1097,20 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth,
#endif //YGOPRO_SERVER_MODE
void Game::LoadExpansions() {
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)) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
dataManager.LoadDB(fpath);
}
#ifdef YGOPRO_SERVER_MODE
});
#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))) {
wchar_t fpath[1024];
myswprintf(fpath, L"./expansions/%ls", name);
#ifdef _WIN32
dataManager.FileSystem->addFileArchive(fpath, true, false, EFAT_ZIP);
#else
......
......@@ -600,7 +600,7 @@ extern Game* mainGame;
extern unsigned short aServerPort;
extern unsigned short replay_mode;
extern HostInfo game_info;
extern time_t pre_seed[3];
extern unsigned int pre_seed[3];
#endif
}
......
......@@ -74,7 +74,7 @@ int main(int argc, char* argv[]) {
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180;
for (int i = 0; i < 3; ++i)
ygo::pre_seed[i] = (time_t)0;
ygo::pre_seed[i] = (unsigned int)0;
if (argc > 1) {
ygo::aServerPort = atoi(argv[1]);
int lflist = atoi(argv[2]);
......@@ -112,7 +112,7 @@ int main(int argc, char* argv[]) {
ygo::replay_mode = atoi(argv[12]);
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;
......
......@@ -125,7 +125,7 @@ Returns:
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);
#ifdef __cplusplus
......
......@@ -465,7 +465,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
break;
wchar_t infobuf[256];
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);
wcsftime(infobuf, 256, L"%Y/%m/%d %H:%M:%S\n", st);
repinfo.append(infobuf);
......
......@@ -14,6 +14,7 @@
#ifdef _WIN32
#define NOMINMAX
#include <Windows.h>
class FileSystem {
......
......@@ -9,11 +9,13 @@ namespace ygo {
extern unsigned short aServerPort;
extern unsigned short replay_mode;
#endif
Replay::Replay() {
is_recording = false;
is_replaying = false;
replay_data = new unsigned char[0x20000];
comp_data = new unsigned char[0x2000];
Replay::Replay()
: fp(nullptr), pheader(), pdata(nullptr), replay_size(0), comp_size(0), is_recording(false), is_replaying(false) {
#ifdef _WIN32
recording_fp = nullptr;
#endif
replay_data = new unsigned char[MAX_REPLAY_SIZE];
comp_data = new unsigned char[MAX_COMP_SIZE];
}
Replay::~Replay() {
delete[] replay_data;
......@@ -62,6 +64,9 @@ void Replay::BeginRecord() {
}
#endif //YGOPRO_SERVER_MODE
pdata = replay_data;
replay_size = 0;
comp_size = 0;
is_replaying = false;
is_recording = true;
}
void Replay::WriteHeader(ReplayHeader& header) {
......@@ -77,9 +82,11 @@ void Replay::WriteHeader(ReplayHeader& header) {
fflush(fp);
#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)
return;
if (length < 0 || (pdata - replay_data) + length > MAX_REPLAY_SIZE)
return;
memcpy(pdata, data, length);
pdata += length;
#ifdef YGOPRO_SERVER_MODE
......@@ -97,6 +104,8 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) {
void Replay::WriteInt32(int data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 4 > MAX_REPLAY_SIZE)
return;
*((int*)(pdata)) = data;
pdata += 4;
#ifdef YGOPRO_SERVER_MODE
......@@ -114,6 +123,8 @@ void Replay::WriteInt32(int data, bool flush) {
void Replay::WriteInt16(short data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 2 > MAX_REPLAY_SIZE)
return;
*((short*)(pdata)) = data;
pdata += 2;
#ifdef YGOPRO_SERVER_MODE
......@@ -131,6 +142,8 @@ void Replay::WriteInt16(short data, bool flush) {
void Replay::WriteInt8(char data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 1 > MAX_REPLAY_SIZE)
return;
*pdata = data;
pdata++;
#ifdef YGOPRO_SERVER_MODE
......@@ -170,11 +183,19 @@ void Replay::EndRecord() {
#ifdef YGOPRO_SERVER_MODE
}
#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;
size_t propsize = 5;
comp_size = 0x1000;
LzmaCompress(comp_data, &comp_size, replay_data, pdata - replay_data, pheader.props, &propsize, 5, 1 << 24, 3, 0, 2, 32, 1);
comp_size = MAX_COMP_SIZE;
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;
}
void Replay::SaveReplay(const wchar_t* name) {
......@@ -216,22 +237,33 @@ bool Replay::OpenReplay(const wchar_t* name) {
}
if(!fp)
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) {
fclose(fp);
return false;
}
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);
if ((int)pheader.datasize < 0 && (int)pheader.datasize > MAX_REPLAY_SIZE)
return false;
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;
}
} else {
comp_size = fread(replay_data, 1, 0x20000, fp);
replay_size = fread(replay_data, 1, MAX_REPLAY_SIZE, fp);
fclose(fp);
replay_size = comp_size;
comp_size = 0;
}
pdata = replay_data;
is_replaying = true;
return true;
}
......@@ -250,7 +282,7 @@ bool Replay::CheckReplay(const wchar_t* name) {
ReplayHeader rheader;
size_t count = fread(&rheader, sizeof(ReplayHeader), 1, 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) {
wchar_t fname[256];
......@@ -299,7 +331,7 @@ void Replay::ReadName(wchar_t* data) {
ReadData(buffer, 40);
BufferIO::CopyWStr(buffer, data, 20);
}
void Replay::ReadData(void* data, unsigned int length) {
void Replay::ReadData(void* data, int length) {
if(!is_replaying)
return;
memcpy(data, pdata, length);
......
......@@ -6,10 +6,16 @@
namespace ygo {
// replay flag
#define REPLAY_COMPRESSED 0x1
#define REPLAY_TAG 0x2
#define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8
#define REPLAY_UNIFORM 0x10
// max size
#define MAX_REPLAY_SIZE 0x20000
#define MAX_COMP_SIZE 0x2000
struct ReplayHeader {
unsigned int id;
......@@ -17,23 +23,30 @@ struct ReplayHeader {
unsigned int flag;
unsigned int seed;
unsigned int datasize;
unsigned int hash;
unsigned int start_time;
unsigned char props[8];
ReplayHeader()
: id(0), version(0), flag(0), seed(0), datasize(0), start_time(0), props{ 0 } {}
};
class Replay {
public:
Replay();
~Replay();
// record
void BeginRecord();
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 WriteInt16(short data, bool flush = true);
void WriteInt8(char data, bool flush = true);
void Flush();
void EndRecord();
void SaveReplay(const wchar_t* name);
// play
bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name);
......@@ -41,22 +54,25 @@ public:
bool ReadNextResponse(unsigned char resp[64]);
void ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header);
void ReadData(void* data, unsigned int length);
void ReadData(void* data, int length);
int ReadInt32();
short ReadInt16();
char ReadInt8();
void Rewind();
FILE* fp;
ReplayHeader pheader;
#ifdef _WIN32
HANDLE recording_fp;
#endif
ReplayHeader pheader;
unsigned char* replay_data;
unsigned char* comp_data;
unsigned char* pdata;
size_t replay_size;
size_t comp_size;
private:
unsigned char* pdata;
bool is_recording;
bool is_replaying;
};
......
......@@ -138,13 +138,23 @@ int ReplayMode::ReplayThread() {
mainGame->gMutex.unlock();
}
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;
}
bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
unsigned int seed = rh.seed;
std::mt19937 rnd(seed);
if(mainGame->dInfo.isTag) {
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag);
......@@ -154,7 +164,7 @@ bool ReplayMode::StartDuel() {
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname);
}
pduel = create_duel(rnd.rand());
pduel = create_duel(rnd());
#ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0);
#endif
......@@ -217,13 +227,18 @@ bool ReplayMode::StartDuel() {
}
} else {
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);
filename[slen] = 0;
if(!preload_script(pduel, filename, 0)) {
return false;
}
}
if (!(rh.flag & REPLAY_UNIFORM))
opt |= DUEL_OLD_REPLAY;
start_duel(pduel, opt);
return true;
}
......
......@@ -518,7 +518,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
pplayer[1] = players[1];
if((tp && dp->type == 1) || (!tp && dp->type == 0)) {
......@@ -533,39 +532,35 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
swapped = true;
}
dp->state = CTOS_RESPONSE;
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = 0;
time_t seed = time(0);
std::random_device rd;
unsigned int seed = rd();
#ifdef YGOPRO_SERVER_MODE
if(pre_seed[duel_count] > 0) {
seed = pre_seed[duel_count];
}
#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.start_time = (unsigned int)time(nullptr);
last_replay.BeginRecord();
last_replay.WriteHeader(rh);
rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false);
if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
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]);
}
rnd.shuffle_vector(pdeck[0].main);
rnd.shuffle_vector(pdeck[1].main);
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)SingleDuel::MessageHandler);
rnd.reset(seed);
pduel = create_duel(rnd.rand());
pduel = create_duel(duel_seed);
#ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0);
#endif
......
......@@ -33,9 +33,9 @@ int SingleMode::SinglePlayThread() {
const int start_hand = 5;
const int draw_count = 1;
const int opt = 0;
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
std::random_device rd;
unsigned int seed = rd();
mt19937 rnd(seed);
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
......@@ -77,8 +77,9 @@ int SingleMode::SinglePlayThread() {
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_SINGLE_MODE;
rh.flag = REPLAY_UNIFORM | REPLAY_SINGLE_MODE;
rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
mainGame->gMutex.lock();
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo();
......
......@@ -481,7 +481,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
pplayer[1] = players[1];
pplayer[2] = players[2];
......@@ -501,49 +500,39 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
cur_player[0] = players[0];
cur_player[1] = players[3];
dp->state = CTOS_RESPONSE;
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_TAG;
time_t seed = time(0);
rh.seed = seed;
std::random_device rd;
unsigned int seed = rd();
#ifdef YGOPRO_SERVER_MODE
if(pre_seed[0] > 0) {
seed = pre_seed[0];
}
#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.WriteHeader(rh);
rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false);
last_replay.WriteData(players[2]->name, 40, false);
last_replay.WriteData(players[3]->name, 40, false);
if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
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]);
}
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]);
}
rnd.shuffle_vector(pdeck[0].main);
rnd.shuffle_vector(pdeck[1].main);
rnd.shuffle_vector(pdeck[2].main);
rnd.shuffle_vector(pdeck[3].main);
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed);
pduel = create_duel(rnd.rand());
pduel = create_duel(duel_seed);
#ifdef YGOPRO_SERVER_MODE
preload_script(pduel, "./script/special.lua", 0);
#endif
......
Subproject commit 8b5b9b7793dfd8ad77c75fe4a27477ca2b4e6c96
Subproject commit 99934ac7ca0eec057eb7a9a29da5cccdc5f7fdaa
Subproject commit c8919a9349d0de9fa177af2c352ee3c753f57c02
Subproject commit 967a69444572c9ab9ec3cd54ab5bf8d984e37239
......@@ -261,6 +261,9 @@
!system 1164 同调召唤
!system 1165 超量召唤
!system 1166 连接召唤
!system 1167 上级召唤
!system 1168 仪式召唤
!system 1169 融合召唤
!system 1190 加入手卡
!system 1191 送去墓地
!system 1192 除外
......@@ -1107,3 +1110,7 @@
!setname 0x16c 冰水 氷水
!setname 0x16d 随风旅鸟 ふわんだりぃず
!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