load from zip and folder ignorecase
This commit is contained in:
parent
340096b20f
commit
465f32092a
|
@ -22,6 +22,8 @@ protected:
|
||||||
|
|
||||||
const json& base;
|
const json& base;
|
||||||
|
|
||||||
|
std::vector<Note> notes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BeatLevelImpl(std::weak_ptr<BeatSet> p, std::shared_ptr<FileReader> r, const json& j);
|
BeatLevelImpl(std::weak_ptr<BeatSet> p, std::shared_ptr<FileReader> r, const json& j);
|
||||||
virtual ~BeatLevelImpl();
|
virtual ~BeatLevelImpl();
|
||||||
|
@ -34,6 +36,7 @@ public:
|
||||||
virtual std::string getCustomData() const override;
|
virtual std::string getCustomData() const override;
|
||||||
|
|
||||||
//TODO: get level content
|
//TODO: get level content
|
||||||
|
virtual const std::vector<Note>& getNotes() const override;
|
||||||
|
|
||||||
virtual void printDebug() const override;
|
virtual void printDebug() const override;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "beatnote.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
namespace Beatsaber {
|
||||||
|
|
||||||
|
void from_json(const json& j, Note& n);
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <istream>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
// this classes form a abstraction to read from folders and zipfiles the same way. Maybe add other sources too?
|
// this classes form a abstraction to read from folders and zipfiles the same way. Maybe add other sources too?
|
||||||
|
@ -15,6 +16,7 @@ public:
|
||||||
virtual ~FileReader() {}
|
virtual ~FileReader() {}
|
||||||
|
|
||||||
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) = 0;
|
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) = 0;
|
||||||
|
virtual void getEntrys(std::vector<std::string>& out) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ public:
|
||||||
virtual ~FolderReader();
|
virtual ~FolderReader();
|
||||||
|
|
||||||
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) override;
|
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) override;
|
||||||
|
virtual void getEntrys(std::vector<std::string>& out) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BEATSABERZIPSUPPORT == 1
|
#if BEATSABERZIPSUPPORT == 1
|
||||||
|
@ -32,6 +33,7 @@ public:
|
||||||
virtual ~ZipReader();
|
virtual ~ZipReader();
|
||||||
|
|
||||||
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) override;
|
virtual std::shared_ptr<std::istream> getFileStream(const std::string& filename) override;
|
||||||
|
virtual void getEntrys(std::vector<std::string>& out) const override;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "beatnote.h"
|
||||||
#include "difficulties.h"
|
#include "difficulties.h"
|
||||||
|
|
||||||
namespace Beatsaber {
|
namespace Beatsaber {
|
||||||
|
@ -24,6 +26,7 @@ public:
|
||||||
virtual std::string getCustomData() const = 0;
|
virtual std::string getCustomData() const = 0;
|
||||||
|
|
||||||
//TODO: get level content
|
//TODO: get level content
|
||||||
|
virtual const std::vector<Note>& getNotes() const = 0;
|
||||||
|
|
||||||
virtual void printDebug() const = 0;
|
virtual void printDebug() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Beatsaber {
|
||||||
|
|
||||||
|
struct Note {
|
||||||
|
std::uint32_t time; //time in beats when the note reaches the player
|
||||||
|
std::uint_fast8_t line; //colum, 0 = most left, 3 = most right
|
||||||
|
std::uint_fast8_t layer; //layer 0 = bottom, 2 = top
|
||||||
|
std::uint_fast8_t type; //0 = rednote, 1 = bluenote, 2 = unused, 3 = bomb
|
||||||
|
std::uint_fast8_t cutdir;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "beatset.h"
|
#include "beatset.h"
|
||||||
|
#include "beatnoteimpl.h"
|
||||||
|
|
||||||
namespace Beatsaber {
|
namespace Beatsaber {
|
||||||
|
|
||||||
|
@ -18,9 +19,23 @@ BeatLevelImpl::BeatLevelImpl(std::weak_ptr<BeatSet> p, std::shared_ptr<FileReade
|
||||||
if(!filename.empty()) {
|
if(!filename.empty()) {
|
||||||
try {
|
try {
|
||||||
std::shared_ptr<std::istream> stream = r->getFileStream(filename);
|
std::shared_ptr<std::istream> stream = r->getFileStream(filename);
|
||||||
json json;
|
json diffjson;
|
||||||
(*stream) >> json;
|
(*stream) >> diffjson;
|
||||||
//TODO
|
|
||||||
|
const std::string& version = diffjson["_version"];
|
||||||
|
if(version != "2.0.0") {
|
||||||
|
//not supported
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load notes
|
||||||
|
const json& jnotes = diffjson["_notes"];
|
||||||
|
if(jnotes.is_array()) {
|
||||||
|
notes.reserve(jnotes.size());
|
||||||
|
for(const json& note : jnotes) {
|
||||||
|
notes.push_back(note);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
std::cout << "Could not load difficulty: " << filename << std::endl;
|
std::cout << "Could not load difficulty: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -56,11 +71,16 @@ std::string BeatLevelImpl::getCustomData() const {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<Note>& BeatLevelImpl::getNotes() const {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
void BeatLevelImpl::printDebug() const {
|
void BeatLevelImpl::printDebug() const {
|
||||||
std::cout <<
|
std::cout <<
|
||||||
" Difficulty: " << Difficulty::toString(dif) << " (" << diffRank << ")"
|
" Difficulty: " << Difficulty::toString(dif) << " (" << diffRank << ")"
|
||||||
<< "\n Filename: " << getFilename()
|
<< "\n Filename: " << getFilename()
|
||||||
<< "\n njs: " << getNoteJumpSpeed() << " nso: " << getNoteStartOffset()
|
<< "\n njs: " << getNoteJumpSpeed() << " nso: " << getNoteStartOffset()
|
||||||
|
<< "\n noteCount: " << notes.size()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Beatsaber {
|
||||||
|
|
||||||
bool BeatMapImpl::load() {
|
bool BeatMapImpl::load() {
|
||||||
// try to open info.dat
|
// try to open info.dat
|
||||||
std::shared_ptr<std::istream> stream = reader->getFileStream("info.dat");
|
std::shared_ptr<std::istream> stream = reader->getFileStream("Info.dat");
|
||||||
try {
|
try {
|
||||||
(*stream) >> infobase;
|
(*stream) >> infobase;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "beatnoteimpl.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
namespace Beatsaber {
|
||||||
|
|
||||||
|
void from_json(const json& j, Note& n) {
|
||||||
|
n.time = j["_time"];
|
||||||
|
n.line = j["_lineIndex"];
|
||||||
|
n.layer = j["_lineLayer"];
|
||||||
|
n.type = j["_type"];
|
||||||
|
n.cutdir = j["_cutDirection"];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,19 @@
|
||||||
#include "filereaderimpl.h"
|
#include "filereaderimpl.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <filesystem> //c++17 required
|
||||||
|
|
||||||
namespace Beatsaber {
|
namespace Beatsaber {
|
||||||
|
|
||||||
|
static const std::string* findbest(const std::vector<std::string>& haystack, const std::string& needle) {
|
||||||
|
for(const auto& it : haystack) {
|
||||||
|
if(it == needle) return ⁢
|
||||||
|
if(strcasecmp(it.c_str(), needle.c_str()) == 0) return ⁢
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FolderReader::FolderReader(const std::string& path) : path(path) {
|
FolderReader::FolderReader(const std::string& path) : path(path) {
|
||||||
// make path end with /
|
// make path end with /
|
||||||
|
@ -13,10 +23,29 @@ FolderReader::FolderReader(const std::string& path) : path(path) {
|
||||||
FolderReader::~FolderReader() {}
|
FolderReader::~FolderReader() {}
|
||||||
|
|
||||||
std::shared_ptr<std::istream> FolderReader::getFileStream(const std::string& filename) {
|
std::shared_ptr<std::istream> FolderReader::getFileStream(const std::string& filename) {
|
||||||
std::shared_ptr<std::istream> stream = std::make_shared<std::ifstream>(path + filename);
|
std::shared_ptr<std::ifstream> stream = std::make_shared<std::ifstream>(path + filename);
|
||||||
|
if(!stream->is_open()) {
|
||||||
|
//search for other files
|
||||||
|
std::vector<std::string> entrys;
|
||||||
|
getEntrys(entrys);
|
||||||
|
const std::string* best = findbest(entrys, filename);
|
||||||
|
if(best) {
|
||||||
|
return std::make_shared<std::ifstream>(path + *best);
|
||||||
|
}
|
||||||
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FolderReader::getEntrys(std::vector<std::string>& out) const {
|
||||||
|
for(const auto& i : std::filesystem::directory_iterator(path)) {
|
||||||
|
if(i.is_regular_file() && i.exists()) {
|
||||||
|
std::string filename = i.path().filename();
|
||||||
|
if(!filename.empty() && filename[0] != '.') { //ignore dotfiles
|
||||||
|
out.push_back(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if BEATSABERZIPSUPPORT == 1
|
#if BEATSABERZIPSUPPORT == 1
|
||||||
|
@ -27,7 +56,29 @@ ZipReader::~ZipReader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<std::istream> ZipReader::getFileStream(const std::string& filename) {
|
std::shared_ptr<std::istream> ZipReader::getFileStream(const std::string& filename) {
|
||||||
return file.getInputStream(filename);
|
std::shared_ptr<std::istream> stream = file.getInputStream(filename);
|
||||||
|
|
||||||
|
if(stream) {
|
||||||
|
//search for other files
|
||||||
|
std::vector<std::string> entrys;
|
||||||
|
getEntrys(entrys);
|
||||||
|
const std::string* best = findbest(entrys, filename);
|
||||||
|
if(best) {
|
||||||
|
return file.getInputStream(*best);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZipReader::getEntrys(std::vector<std::string>& out) const {
|
||||||
|
const auto entr = file.entries();
|
||||||
|
out.reserve(entr.size());
|
||||||
|
for(auto it : entr) {
|
||||||
|
if(!it->isDirectory() && it->isValid()) {
|
||||||
|
out.push_back(it->getFileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ int main(int argc, char** argv) {
|
||||||
std::shared_ptr<Beatsaber::BeatMap> bmap = Beatsaber::BeatMap::loadFromFolder("/home/yannis/Nextcloud/yannis/Beatsaber/BeatSaverLevel/1dd (Portal - Still Alive (Uppermost Remix) - kryptikos)");
|
std::shared_ptr<Beatsaber::BeatMap> bmap = Beatsaber::BeatMap::loadFromFolder("/home/yannis/Nextcloud/yannis/Beatsaber/BeatSaverLevel/1dd (Portal - Still Alive (Uppermost Remix) - kryptikos)");
|
||||||
if(!bmap) std::cout << "Could not load File" << std::endl;
|
if(!bmap) std::cout << "Could not load File" << std::endl;
|
||||||
else bmap->printDebug();
|
else bmap->printDebug();
|
||||||
|
bmap = Beatsaber::BeatMap::loadFromZip("/home/yannis/Nextcloud/yannis/Beatsaber/BeatSaverLevel/18b92 (Empress of Light - ShadowLantern).zip");
|
||||||
|
if(!bmap) std::cout << "Could not load File" << std::endl;
|
||||||
|
else bmap->printDebug();
|
||||||
|
|
||||||
return failcount > 0;
|
return failcount > 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue