Cuberite
A lightweight, fast and extensible game server for Minecraft
RecipeMapper.cpp
Go to the documentation of this file.
1 #include "Globals.h"
2 #include "RecipeMapper.h"
3 #include "../Root.h"
4 
6 {
7  AString path = "Protocol";
8  auto contents = cFile::GetFolderContents(path);
9  for (const auto & content: contents)
10  {
11  auto fullName = path + cFile::PathSeparator() + content;
12  if (cFile::IsFolder(fullName))
13  {
14  loadRecipes(content);
15  }
16  }
17 }
18 
19 
20 
21 
22 
23 void cRecipeMapper::loadRecipes(const AString & a_ProtocolVersion)
24 {
25  cFile f;
26  if (!f.Open("Protocol/" + a_ProtocolVersion + "/base.recipes.txt", cFile::fmRead))
27  {
28  LOGWARNING("Cannot open file \"Protocol/%s/base.recipes.txt\", no recipe book recipes will be available!", a_ProtocolVersion);
29  return;
30  }
31  AString Everything;
32  if (!f.ReadRestOfFile(Everything))
33  {
34  LOGWARNING("Cannot read file \"Protocol/%s/base.recipes.txt\", no recipe book recipes will be available!", a_ProtocolVersion);
35  return;
36  }
37  f.Close();
38 
39  // Split it into lines, then process each line as a single recipe:
40  AStringVector Split = StringSplit(Everything, "\n");
41  m_ProtocolVersionMap[a_ProtocolVersion] = {};
42  const auto & RecipeNameMap = cRoot::Get()->GetCraftingRecipes()->GetRecipeNameMap();
43 
44  int LineNum = 1;
45  for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum)
46  {
47  // Remove anything after a '#' sign and trim away the whitespace:
48  AString Recipe = TrimString(itr->substr(0, itr->find('#')));
49  if (Recipe.empty())
50  {
51  // Empty recipe
52  continue;
53  }
54  AddRecipeLine(a_ProtocolVersion, LineNum, Recipe, RecipeNameMap);
55  }
56  LOG("Loaded %s %zu recipe book", a_ProtocolVersion, m_ProtocolVersionMap[a_ProtocolVersion].size());
57 }
58 
59 
60 
61 
62 
64 {
65 }
66 
67 
68 
69 
70 
71 void cRecipeMapper::AddRecipeLine(const AString & a_ProtocolVersion, int a_LineNum, const AString & a_RecipeLine, const std::map<AString, UInt32> & a_RecipeNameMap)
72 {
73  AStringVector Sides = StringSplit(a_RecipeLine, " ");
74  UInt32 Id;
75  if (Sides.size() != 2)
76  {
77  LOGINFO("Recipe incompletely configured %s", a_RecipeLine);
78  return;
79  }
80  StringToInteger<UInt32>(Sides[0], Id);
81 
82  auto RecipeIndex = a_RecipeNameMap.find(Sides[1]);
83  if (RecipeIndex == a_RecipeNameMap.end())
84  {
85  return;
86  }
87  m_ProtocolVersionMap[a_ProtocolVersion].emplace(Id, RecipeIndex->second);
88 }
89 
90 
91 
92 
93 
94 std::optional<UInt32> cRecipeMapper::GetProtocolRecipeId(UInt32 a_RecipeId, UInt32 a_ProtocolVersion)
95 {
96  auto ProtocolMap = m_ProtocolVersionMap.find(cRoot::Get()->GetProtocolVersionTextFromInt(static_cast<int>(a_ProtocolVersion)));
97  if (ProtocolMap == m_ProtocolVersionMap.end())
98  {
99  return {};
100  }
101  for (const auto & item: ProtocolMap->second)
102  {
103  if (item.second == a_RecipeId)
104  {
105  return item.first;
106  }
107  }
108  return {};
109 }
110 
111 
112 
113 
114 
115 std::optional<UInt32> cRecipeMapper::GetCuberiteRecipeId(UInt32 a_ProtocolRecipeId, UInt32 a_ProtocolVersion)
116 {
117  auto ProtocolMap = m_ProtocolVersionMap.find(cRoot::Get()->GetProtocolVersionTextFromInt(static_cast<int>(a_ProtocolVersion)));
118  if (ProtocolMap == m_ProtocolVersionMap.end())
119  {
120  return {};
121  }
122  auto Element = ProtocolMap->second.find(a_ProtocolRecipeId);
123  if (Element != ProtocolMap->second.end())
124  {
125  return Element->second;
126  }
127  return {};
128 }
unsigned int UInt32
Definition: Globals.h:157
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
void LOG(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:55
void LOGINFO(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:61
AString TrimString(const AString &str)
Trims whitespace at both ends of the string.
AStringVector StringSplit(const AString &str, const AString &delim)
Split the string at any of the listed delimiters.
Definition: StringUtils.cpp:55
std::vector< AString > AStringVector
Definition: StringUtils.h:12
std::string AString
Definition: StringUtils.h:11
const std::map< AString, UInt32 > & GetRecipeNameMap()
Gets a map of all recipes with name and recipe id.
Definition: File.h:38
static bool IsFolder(const AString &a_Path)
Returns true if the specified path is a folder.
Definition: File.cpp:410
static char PathSeparator()
Definition: File.h:42
@ fmRead
Definition: File.h:54
bool Open(const AString &iFileName, eMode iMode)
Definition: File.cpp:52
static AStringVector GetFolderContents(const AString &a_Folder)
Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there).
Definition: File.cpp:498
int ReadRestOfFile(AString &a_Contents)
Reads the file from current position till EOF into an AString; returns the number of bytes read or -1...
Definition: File.cpp:263
void Close(void)
Definition: File.cpp:102
std::optional< UInt32 > GetProtocolRecipeId(UInt32 a_RecipeId, UInt32 a_ProtocolVersion)
Translates the cuberite RecipeId to the protocol specific RecipeId.
cRecipeMapper(void)
Definition: RecipeMapper.cpp:5
std::optional< UInt32 > GetCuberiteRecipeId(UInt32 a_ProtocolRecipeId, UInt32 a_ProtocolVersion)
Translates the protocol specific RecipeId to the cuberite RecipeId.
std::map< AString, std::map< UInt32, UInt32 > > m_ProtocolVersionMap
A mapping for each protocol from the protocol specific RecipeId and the cuberite RecipeId.
Definition: RecipeMapper.h:27
void AddRecipeLine(const AString &a_ProtocolVersion, int a_LineNum, const AString &a_RecipeLine, const std::map< AString, UInt32 > &a_RecipeNameMap)
Handles a single line of the protocol specific mapping file.
void loadRecipes(const AString &a_ProtocolVersion)
Load Recipes from the protocol specific mapping file.
static cRoot * Get()
Definition: Root.h:52
cCraftingRecipes * GetCraftingRecipes(void)
Definition: Root.h:92