Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add DarkmodTxt object and parsing code. Parsing darkmod.txt is horrib…
…ly fragile text splitting, based on the actual parsing code in the game.
- Loading branch information
1 parent
ea51070
commit 7cb9536
Showing
9 changed files
with
235 additions
and
204 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#include "DarkmodTxt.h" | ||
|
||
#include "iarchive.h" | ||
#include "itextstream.h" | ||
#include "ifilesystem.h" | ||
#include "igame.h" | ||
#include "os/fs.h" | ||
#include "string/trim.h" | ||
#include "string/convert.h" | ||
#include "string/case_conv.h" | ||
|
||
namespace map | ||
{ | ||
|
||
const std::string& DarkmodTxt::getTitle() | ||
{ | ||
return _title; | ||
} | ||
|
||
const std::string& DarkmodTxt::getAuthor() | ||
{ | ||
return _author; | ||
} | ||
|
||
const std::string& DarkmodTxt::getDescription() | ||
{ | ||
return _description; | ||
} | ||
|
||
const std::string& DarkmodTxt::getReqTdmVersion() | ||
{ | ||
return _reqTdmVersion; | ||
} | ||
|
||
void DarkmodTxt::ParseMissionTitles(std::vector<std::string>& titleList, const std::string& source) | ||
{ | ||
// TODO | ||
} | ||
|
||
DarkmodTxtPtr DarkmodTxt::CreateFromString(const std::string& contents) | ||
{ | ||
DarkmodTxtPtr info(new DarkmodTxt); | ||
|
||
// The positions need to be searched case-insensitively | ||
std::string contentsLower = string::to_lower_copy(contents); | ||
std::size_t titlePos = contentsLower.find("title:"); | ||
std::size_t descPos = contentsLower.find("description:"); | ||
std::size_t authorPos = contentsLower.find("author:"); | ||
std::size_t versionPos = contentsLower.find("required tdm version:"); | ||
std::size_t missionTitlesPos = contentsLower.find("mission 1 title:"); | ||
|
||
std::size_t len = contents.size(); | ||
|
||
if (titlePos != std::string::npos) | ||
{ | ||
info->_title = contents.substr(titlePos, (missionTitlesPos != std::string::npos) ? | ||
descPos - missionTitlesPos : (descPos != std::string::npos) ? descPos - titlePos : len - titlePos); | ||
string::trim_left(info->_title, "Title:"); | ||
string::trim(info->_title); | ||
} | ||
|
||
info->_missionTitles.clear(); | ||
info->_missionTitles.push_back(info->_title); // [0] is the title | ||
|
||
if (missionTitlesPos != std::string::npos) | ||
{ | ||
std::string missionTitles = contents.substr(missionTitlesPos, (descPos != std::string::npos) ? missionTitlesPos - descPos : len - missionTitlesPos); | ||
ParseMissionTitles(info->_missionTitles, missionTitles); | ||
} | ||
|
||
if (descPos != std::string::npos) | ||
{ | ||
info->_description = contents.substr(descPos, (authorPos != std::string::npos) ? authorPos - descPos : len - descPos); | ||
string::trim_left(info->_description, "Description:"); | ||
string::trim(info->_description); | ||
} | ||
|
||
if (authorPos != std::string::npos) | ||
{ | ||
info->_author = contents.substr(authorPos, (versionPos != std::string::npos) ? versionPos - authorPos : len - authorPos); | ||
string::trim_left(info->_author, "Author:"); | ||
string::trim(info->_author); | ||
} | ||
|
||
if (versionPos != std::string::npos) | ||
{ | ||
info->_reqTdmVersion = contents.substr(versionPos, len - versionPos); | ||
|
||
string::trim_left(info->_reqTdmVersion, "Required TDM Version:"); | ||
string::trim_left(info->_reqTdmVersion, "v"); | ||
string::trim(info->_reqTdmVersion); | ||
} | ||
|
||
return info; | ||
} | ||
|
||
DarkmodTxtPtr DarkmodTxt::CreateFromStream(std::istream& stream) | ||
{ | ||
// Read all the stream contents into a string | ||
std::string str(std::istreambuf_iterator<char>(stream), {}); | ||
return CreateFromString(str); | ||
} | ||
|
||
DarkmodTxtPtr DarkmodTxt::LoadForCurrentMod() | ||
{ | ||
std::string modPath = GlobalGameManager().getModPath(); | ||
|
||
if (modPath.empty()) | ||
{ | ||
rMessage() << "Mod path empty, falling back to mod base path..." << std::endl; | ||
modPath = GlobalGameManager().getModBasePath(); | ||
} | ||
|
||
fs::path darkmodTxtPath = fs::path(modPath) / NAME(); | ||
|
||
rMessage() << "Trying to open file " << darkmodTxtPath << std::endl; | ||
|
||
ArchiveTextFilePtr file = GlobalFileSystem().openTextFileInAbsolutePath(darkmodTxtPath.string()); | ||
|
||
if (file) | ||
{ | ||
std::istream stream(&(file->getInputStream())); | ||
return CreateFromStream(stream); | ||
} | ||
|
||
return std::make_shared<DarkmodTxt>(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <memory> | ||
#include <vector> | ||
|
||
namespace map | ||
{ | ||
|
||
class DarkmodTxt; | ||
typedef std::shared_ptr<DarkmodTxt> DarkmodTxtPtr; | ||
|
||
/** | ||
* An object representing the darkmod.txt file as found in the | ||
* mission folder's root directory. It contains information shown | ||
* in the "New Mission" section in TDM's main menu. | ||
*/ | ||
class DarkmodTxt | ||
{ | ||
private: | ||
std::string _title; | ||
std::string _author; | ||
std::string _description; | ||
std::string _reqTdmVersion; | ||
|
||
std::vector<std::string> _missionTitles; | ||
|
||
public: | ||
static const char* NAME() | ||
{ | ||
return "darkmod.txt"; | ||
} | ||
|
||
const std::string& getTitle(); | ||
const std::string& getAuthor(); | ||
const std::string& getDescription(); | ||
const std::string& getReqTdmVersion(); | ||
|
||
// Named constructor parsing the given string into a DarkmodTxt instance | ||
static DarkmodTxtPtr CreateFromString(const std::string& contents); | ||
|
||
// Named constructor parsing the given stream into a DarkmodTxt instance | ||
static DarkmodTxtPtr CreateFromStream(std::istream& stream); | ||
|
||
static DarkmodTxtPtr LoadForCurrentMod(); | ||
|
||
private: | ||
static void ParseMissionTitles(std::vector<std::string>& titleList, const std::string& source); | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters