Commit 181afbae authored by Chen Bill's avatar Chen Bill

Replay: add ReadInfo

parent 50d5877f
#include "replay.h" #include "replay.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
namespace ygo { namespace ygo {
...@@ -28,9 +29,7 @@ void Replay::BeginRecord() { ...@@ -28,9 +29,7 @@ void Replay::BeginRecord() {
if(!fp) if(!fp)
return; return;
#endif #endif
replay_size = 0; Reset();
comp_size = 0;
is_replaying = false;
is_recording = true; is_recording = true;
} }
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ReplayHeader& header) {
...@@ -111,11 +110,7 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -111,11 +110,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
if(!rfp) if(!rfp)
return false; return false;
data_position = 0; Reset();
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) { if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) {
std::fclose(rfp); std::fclose(rfp);
return false; return false;
...@@ -138,6 +133,10 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -138,6 +133,10 @@ bool Replay::OpenReplay(const wchar_t* name) {
comp_size = 0; comp_size = 0;
} }
is_replaying = true; is_replaying = true;
if (!ReadInfo()) {
Reset();
return false;
}
return true; return true;
} }
bool Replay::CheckReplay(const wchar_t* name) { bool Replay::CheckReplay(const wchar_t* name) {
...@@ -214,5 +213,62 @@ int32_t Replay::ReadInt32() { ...@@ -214,5 +213,62 @@ int32_t Replay::ReadInt32() {
void Replay::Rewind() { void Replay::Rewind() {
data_position = 0; data_position = 0;
} }
void Replay::Reset() {
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
data_position = 0;
players.clear();
params = { 0 };
decks.clear();
script_name.clear();
}
bool Replay::ReadInfo() {
int player_count = (pheader.flag & REPLAY_TAG) ? 4 : 2;
for (int i = 0; i < player_count; ++i) {
wchar_t name[20]{};
if (!ReadName(name))
return false;
players.push_back(name);
}
if (!ReadData(&params, sizeof DuelParameters))
return false;
bool is_tag1 = pheader.flag & REPLAY_TAG;
bool is_tag2 = params.duel_flag & DUEL_TAG_MODE;
if (is_tag1 != is_tag2)
return false;
if (pheader.flag & REPLAY_SINGLE_MODE) {
uint16_t slen = Read<uint16_t>();
char filename[256]{};
if (slen == 0 || slen > sizeof(filename) - 1)
return false;
if (!ReadData(filename, slen))
return false;
filename[slen] = 0;
script_name = filename;
}
else {
for (int p = 0; p < player_count; ++p) {
ReplayDeck deck;
uint32_t main = Read<uint32_t>();
if (main > MAINC_MAX)
return false;
if (main)
deck.main.resize(main);
if (!ReadData(deck.main.data(), main * sizeof(uint32_t)))
return false;
uint32_t extra = Read<uint32_t>();
if (extra > MAINC_MAX)
return false;
if (extra)
deck.extra.resize(extra);
if (!ReadData(deck.extra.data(), extra * sizeof(uint32_t)))
return false;
decks.push_back(deck);
}
}
return true;
}
} }
...@@ -13,7 +13,7 @@ namespace ygo { ...@@ -13,7 +13,7 @@ namespace ygo {
#define REPLAY_UNIFORM 0x10 #define REPLAY_UNIFORM 0x10
// max size // max size
constexpr int MAX_REPLAY_SIZE = 0x20000; constexpr int MAX_REPLAY_SIZE = 0x80000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
struct ReplayHeader { struct ReplayHeader {
...@@ -26,6 +26,18 @@ struct ReplayHeader { ...@@ -26,6 +26,18 @@ struct ReplayHeader {
uint8_t props[8]{}; uint8_t props[8]{};
}; };
struct DuelParameters {
int32_t start_lp{};
int32_t start_hand{};
int32_t draw_count{};
uint32_t duel_flag{};
};
struct ReplayDeck {
std::vector<uint32_t> main;
std::vector<uint32_t> extra;
};
class Replay { class Replay {
public: public:
Replay(); Replay();
...@@ -61,6 +73,7 @@ public: ...@@ -61,6 +73,7 @@ public:
} }
int32_t ReadInt32(); int32_t ReadInt32();
void Rewind(); void Rewind();
void Reset();
FILE* fp{ nullptr }; FILE* fp{ nullptr };
#ifdef _WIN32 #ifdef _WIN32
...@@ -71,7 +84,15 @@ public: ...@@ -71,7 +84,15 @@ public:
unsigned char* comp_data; unsigned char* comp_data;
size_t comp_size{}; size_t comp_size{};
std::vector<std::wstring> players; // 80 or 160 bytes
DuelParameters params; // 16 bytes
std::vector<ReplayDeck> decks; // 4 bytes, main deck, 4 bytes, extra deck
std::string script_name; // 2 bytes, script name (max: 256 bytes)
private: private:
bool ReadInfo();
unsigned char* replay_data; unsigned char* replay_data;
size_t replay_size{}; size_t replay_size{};
size_t data_position{}; size_t data_position{};
......
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