summaryrefslogtreecommitdiffstats
path: root/src/Protocol/RecipeMapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Protocol/RecipeMapper.cpp')
-rw-r--r--src/Protocol/RecipeMapper.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/Protocol/RecipeMapper.cpp b/src/Protocol/RecipeMapper.cpp
new file mode 100644
index 000000000..2757fdfd6
--- /dev/null
+++ b/src/Protocol/RecipeMapper.cpp
@@ -0,0 +1,128 @@
+#include "Globals.h"
+#include "RecipeMapper.h"
+#include "../Root.h"
+
+cRecipeMapper::cRecipeMapper(void)
+{
+ AString path = "Protocol";
+ auto contents = cFile::GetFolderContents(path);
+ for (const auto & content: contents)
+ {
+ auto fullName = path + cFile::PathSeparator() + content;
+ if (cFile::IsFolder(fullName))
+ {
+ loadRecipes(content);
+ }
+ }
+}
+
+
+
+
+
+void cRecipeMapper::loadRecipes(const AString & a_ProtocolVersion)
+{
+ cFile f;
+ if (!f.Open("Protocol/" + a_ProtocolVersion + "/base.recipes.txt", cFile::fmRead))
+ {
+ LOGWARNING("Cannot open file \"Protocol/%s/base.recipes.txt\", no recipe book recipes will be available!", a_ProtocolVersion);
+ return;
+ }
+ AString Everything;
+ if (!f.ReadRestOfFile(Everything))
+ {
+ LOGWARNING("Cannot read file \"Protocol/%s/base.recipes.txt\", no recipe book recipes will be available!", a_ProtocolVersion);
+ return;
+ }
+ f.Close();
+
+ // Split it into lines, then process each line as a single recipe:
+ AStringVector Split = StringSplit(Everything, "\n");
+ m_ProtocolVersionMap[a_ProtocolVersion] = {};
+ const auto & RecipeNameMap = cRoot::Get()->GetCraftingRecipes()->GetRecipeNameMap();
+
+ int LineNum = 1;
+ for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum)
+ {
+ // Remove anything after a '#' sign and trim away the whitespace:
+ AString Recipe = TrimString(itr->substr(0, itr->find('#')));
+ if (Recipe.empty())
+ {
+ // Empty recipe
+ continue;
+ }
+ AddRecipeLine(a_ProtocolVersion, LineNum, Recipe, RecipeNameMap);
+ }
+ LOG("Loaded %s %zu recipe book", a_ProtocolVersion, m_ProtocolVersionMap[a_ProtocolVersion].size());
+}
+
+
+
+
+
+cRecipeMapper::~cRecipeMapper()
+{
+}
+
+
+
+
+
+void cRecipeMapper::AddRecipeLine(const AString & a_ProtocolVersion, int a_LineNum, const AString & a_RecipeLine, const std::map<AString, UInt32> & a_RecipeNameMap)
+{
+ AStringVector Sides = StringSplit(a_RecipeLine, " ");
+ UInt32 Id;
+ if (Sides.size() != 2)
+ {
+ LOGINFO("Recipe incompletely configured %s", a_RecipeLine);
+ return;
+ }
+ StringToInteger<UInt32>(Sides[0], Id);
+
+ auto RecipeIndex = a_RecipeNameMap.find(Sides[1]);
+ if (RecipeIndex == a_RecipeNameMap.end())
+ {
+ return;
+ }
+ m_ProtocolVersionMap[a_ProtocolVersion].emplace(Id, RecipeIndex->second);
+}
+
+
+
+
+
+std::optional<UInt32> cRecipeMapper::GetProtocolRecipeId(UInt32 a_RecipeId, UInt32 a_ProtocolVersion)
+{
+ auto ProtocolMap = m_ProtocolVersionMap.find(cRoot::Get()->GetProtocolVersionTextFromInt(static_cast<int>(a_ProtocolVersion)));
+ if (ProtocolMap == m_ProtocolVersionMap.end())
+ {
+ return {};
+ }
+ for (const auto & item: ProtocolMap->second)
+ {
+ if (item.second == a_RecipeId)
+ {
+ return item.first;
+ }
+ }
+ return {};
+}
+
+
+
+
+
+std::optional<UInt32> cRecipeMapper::GetCuberiteRecipeId(UInt32 a_ProtocolRecipeId, UInt32 a_ProtocolVersion)
+{
+ auto ProtocolMap = m_ProtocolVersionMap.find(cRoot::Get()->GetProtocolVersionTextFromInt(static_cast<int>(a_ProtocolVersion)));
+ if (ProtocolMap == m_ProtocolVersionMap.end())
+ {
+ return {};
+ }
+ auto Element = ProtocolMap->second.find(a_ProtocolRecipeId);
+ if (Element != ProtocolMap->second.end())
+ {
+ return Element->second;
+ }
+ return {};
+}