bool cPlayer::PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template) { // Check the sub-items if they are the same or there's a wildcard: size_t lenP = a_Permission.size(); size_t lenT = a_Template.size(); size_t minLen = std::min(lenP, lenT); for (size_t i = 0; i < minLen; i++) { if (a_Template[i] == "*") { // Has matched so far and now there's a wildcard in the template, so the permission matches: return true; } if (a_Permission[i] != a_Template[i]) { // Found a mismatch return false; } } // So far all the sub-items have matched // If the sub-item count is the same, then the permission matches: if (lenP == lenT) { return true; } // There are more sub-items in either the permission or the template, not a match: return false; }
std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest * a_Request) { std::pair< AString, AString > Names; AStringVector Split = StringSplit(a_Request->Path, "/"); if( Split.size() > 1 ) { sWebPluginTab* Tab = 0; if( Split.size() > 2 ) // If we got the tab name, show that page { for( TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr ) { if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr { Tab = *itr; break; } } } else // Otherwise show the first tab { if( GetTabs().size() > 0 ) Tab = *GetTabs().begin(); } if( Tab ) { Names.first = Tab->Title; Names.second = Tab->SafeTitle; } } return Names; }
AString cWebAdmin::GetBaseURL(const AStringVector & a_URLSplit) { AString BaseURL = "./"; if (a_URLSplit.size() > 1) { for (unsigned int i = 0; i < a_URLSplit.size(); i++) { BaseURL += "../"; } BaseURL += "webadmin/"; } return BaseURL; }
void AddToMap(const AString & a_Name, const AString & a_Value) { AStringVector Split = StringSplit(a_Value, ":"); if (Split.size() == 1) { Split = StringSplit(a_Value, "^"); } if (Split.empty()) { return; } short ItemType = (short)atoi(Split[0].c_str()); short ItemDamage = (Split.size() > 1) ? (short)atoi(Split[1].c_str()) : -1; m_Map[a_Name] = std::make_pair(ItemType, ItemDamage); }
sWebAdminPage cWebAdmin::GetPage(const HTTPRequest & a_Request) { sWebAdminPage Page; AStringVector Split = StringSplit(a_Request.Path, "/"); // Find the plugin that corresponds to the requested path AString FoundPlugin; if (Split.size() > 1) { for (PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr) { if ((*itr)->GetWebTitle() == Split[1]) { Page.Content = (*itr)->HandleWebRequest(&a_Request); cWebPlugin * WebPlugin = *itr; FoundPlugin = WebPlugin->GetWebTitle(); AString TabName = WebPlugin->GetTabNameForRequest(&a_Request).first; Page.PluginName = FoundPlugin; Page.TabName = TabName; break; } } } // Return the page contents return Page; }
std::pair<AString, AString> cWebPlugin::GetTabNameForRequest(const HTTPRequest & a_Request) { AStringVector Split = StringSplit(a_Request.Path, "/"); if (Split.empty()) { return std::make_pair(AString(), AString()); } cCSLock Lock(m_CSTabs); cTabPtr Tab; if (Split.size() > 2) // If we got the tab name, show that page { for (auto itr = m_Tabs.cbegin(), end = m_Tabs.cend(); itr != end; ++itr) { if ((*itr)->m_SafeTitle.compare(Split[2]) == 0) // This is the one! { return std::make_pair((*itr)->m_Title, (*itr)->m_SafeTitle); } } // Tab name not found, display an "empty" page: return std::make_pair(AString(), AString()); } // Show the first tab: if (!m_Tabs.empty()) { return std::make_pair(m_Tabs.front()->m_SafeTitle, m_Tabs.front()->m_SafeTitle); } // No tabs at all: return std::make_pair(AString(), AString()); }
AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached) { // Convert all playernames to lowercase: AStringVector PlayerNames; for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { PlayerNames.push_back(StrToLower(*itr)); } // for itr - a_PlayerNames[] // Request the cache to populate any names not yet contained: if (!a_UseOnlyCached) { CacheNamesToUUIDs(PlayerNames); } // Retrieve from cache: size_t idx = 0; AStringVector res; res.resize(PlayerNames.size()); cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx) { cProfileMap::const_iterator itrN = m_NameToUUID.find(*itr); if (itrN != m_NameToUUID.end()) { res[idx] = itrN->second.m_UUID; } } // for itr - PlayerNames[] return res; }
bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_EXECUTE_COMMAND); ASSERT(FnName != NULL); if (!PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); // Push the split: lua_createtable(m_LuaState, a_Split.size(), 0); int newTable = lua_gettop(m_LuaState); int index = 1; std::vector<std::string>::const_iterator iter = a_Split.begin(), end = a_Split.end(); while(iter != end) { tolua_pushstring(m_LuaState, (*iter).c_str()); lua_rawseti(m_LuaState, newTable, index); ++iter; ++index; } if (!CallFunction(2, 1, FnName)) { return false; } bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); lua_pop(m_LuaState, 1); return bRetVal; }
void cPlayer::LoadPermissionsFromDisk() { m_Groups.clear(); m_Permissions.clear(); cIniFile IniFile; if (IniFile.ReadFile("users.ini")) { std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); if (!Groups.empty()) { AStringVector Split = StringSplit( Groups, "," ); for( unsigned int i = 0; i < Split.size(); i++ ) { AddToGroup( Split[i].c_str() ); } } else { AddToGroup("Default"); } m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; } else { LOGWARN("Failed to read the users.ini file. The player will be added only to the Default group."); AddToGroup("Default"); } ResolvePermissions(); }
void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { ASSERT(a_CharMapDef != NULL); // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { a_CharMapOut[i].m_BlockType = 0; a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } // Process the lines in the definition: AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { AStringVector CharDef = StringSplitAndTrim(*itr, ":"); size_t NumElements = CharDef.size(); if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty()) { LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str()); continue; } unsigned char Src = (unsigned char)CharDef[0][0]; ASSERT(a_CharMapOut[Src].m_BlockMeta == 16); // This letter has not been assigned yet? a_CharMapOut[Src].m_BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); NIBBLETYPE BlockMeta = 0; if ((NumElements >= 3) && !CharDef[2].empty()) { BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); ASSERT((BlockMeta <= 15)); } a_CharMapOut[Src].m_BlockMeta = BlockMeta; } // for itr - Lines[] }
void cHTTPFormParser::ParseFormUrlEncoded(void) { // Parse m_IncomingData for all the variables; no more data is incoming, since this is called from Finish() // This may not be the most performant version, but we don't care, the form data is small enough and we're not a full-fledged web server anyway AStringVector Lines = StringSplit(m_IncomingData, "&"); for (AStringVector::iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { AStringVector Components = StringSplit(*itr, "="); switch (Components.size()) { default: { // Neither name nor value, or too many "="s, mark this as invalid form: m_IsValid = false; return; } case 1: { // Only name present (*this)[URLDecode(ReplaceAllCharOccurrences(Components[0], '+', ' '))] = ""; break; } case 2: { // name=value format: (*this)[URLDecode(ReplaceAllCharOccurrences(Components[0], '+', ' '))] = URLDecode(ReplaceAllCharOccurrences(Components[1], '+', ' ')); break; } } } // for itr - Lines[] m_IncomingData.clear(); }
bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) { // The caller provides error logging AStringVector Split = StringSplit(a_String, "^"); if (Split.empty()) { return false; } if (!StringToItem(Split[0], a_Item)) { return false; } if (Split.size() > 1) { AString Damage = TrimString(Split[1]); if (!StringToInteger<short>(Damage.c_str(), a_Item.m_ItemDamage)) { // Parsing the number failed return false; } } // Success return true; }
bool cProbabDistrib::SetDefString(const AString & a_DefString) { AStringVector Points = StringSplitAndTrim(a_DefString, ";"); if (Points.empty()) { return false; } cPoints Pts; for (AStringVector::const_iterator itr = Points.begin(), end = Points.end(); itr != end; ++itr) { AStringVector Split = StringSplitAndTrim(*itr, ","); if (Split.size() != 2) { // Bad format return false; } int Value = atoi(Split[0].c_str()); int Prob = atoi(Split[1].c_str()); if ( ((Value == 0) && (Split[0] != "0")) || ((Prob == 0) && (Split[1] != "0")) ) { // Number parse error return false; } Pts.push_back(cPoint(Value, Prob)); } // for itr - Points[] SetPoints(Pts); return true; }
bool ResolveItem(const AString & a_ItemName, cItem & a_Item) { ItemMap::iterator itr = m_Map.find(a_ItemName); if (itr != m_Map.end()) { a_Item.m_ItemType = itr->second.first; a_Item.m_ItemDamage = itr->second.second; if (a_Item.m_ItemDamage == -1) { a_Item.m_ItemDamage = 0; } a_Item.m_ItemCount = 1; return true; } // Not a resolvable string, try pure numbers: "45:6", "45^6" etc. AStringVector Split = StringSplit(a_ItemName, ":"); if (Split.size() == 1) { Split = StringSplit(a_ItemName, "^"); } if (Split.empty()) { return false; } a_Item.m_ItemType = (short)atoi(Split[0].c_str()); if ((a_Item.m_ItemType == 0) && (Split[0] != "0")) { // Parsing the number failed return false; } if (Split.size() < 2) { a_Item.m_ItemCount = 1; return true; } a_Item.m_ItemDamage = atoi(Split[1].c_str()); if ((a_Item.m_ItemDamage == 0) && (Split[1] != "0")) { // Parsing the number failed return false; } a_Item.m_ItemCount = 1; return true; }
void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != nullptr); AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { if (itr->empty()) { continue; } // Split into components: "Type: X, Y, Z: Direction": AStringVector Defs = StringSplitAndTrim(*itr, ":"); if (Defs.size() != 3) { LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); continue; } AStringVector Coords = StringSplitAndTrim(Defs[1], ","); if (Coords.size() != 3) { LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } // Check that the Direction is valid: cPiece::cConnector::eDirection Direction; if (!cPiece::cConnector::StringToDirection(Defs[2], Direction)) { LOGWARNING("Bad prefab Connector direction: \"%s\", skipping.", Defs[2].c_str()); continue; } // Add the connector: m_Connectors.push_back(cPiece::cConnector( atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos atoi(Defs[0].c_str()), // Connector type Direction )); } // for itr - Lines[] }
void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != NULL); AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { if (itr->empty()) { continue; } // Split into components: "Type: X, Y, Z: Face": AStringVector Defs = StringSplitAndTrim(*itr, ":"); if (Defs.size() != 3) { LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); continue; } AStringVector Coords = StringSplitAndTrim(Defs[1], ","); if (Coords.size() != 3) { LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } // Check that the BlockFace is within range: int BlockFace = atoi(Defs[2].c_str()); if ((BlockFace < 0) || (BlockFace >= 6)) { LOGWARNING("Bad prefab Connector Blockface: \"%s\", skipping.", Defs[2].c_str()); continue; } // Add the connector: m_Connectors.push_back(cPiece::cConnector( atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos atoi(Defs[0].c_str()), // Connector type (eBlockFace)BlockFace )); } // for itr - Lines[] }
void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem) { AStringVector Split = StringSplit(a_String, ";"); for (size_t itr = 0; itr < Split.size(); ++itr) { if (Split[itr].empty()) { continue; } a_FireworkItem.m_FadeColours.push_back(atoi(Split[itr].c_str())); } }
void AddToMap(const AString & a_Name, const AString & a_Value) { AStringVector Split = StringSplit(a_Value, ":"); if (Split.size() == 1) { Split = StringSplit(a_Value, "^"); } if (Split.empty()) { return; } short ItemType; if (!StringToInteger(Split[0], ItemType)) { ASSERT(!"Invalid item type"); } short ItemDamage = -1; if (Split.size() > 1 && !StringToInteger(Split[1], ItemDamage)) { ASSERT(!"Invalid item damage"); } m_Map[a_Name] = std::make_pair(ItemType, ItemDamage); }
void cLuaState::Push(const AStringVector & a_Vector) { ASSERT(IsValid()); lua_createtable(m_LuaState, static_cast<int>(a_Vector.size()), 0); int newTable = lua_gettop(m_LuaState); int index = 1; for (AStringVector::const_iterator itr = a_Vector.begin(), end = a_Vector.end(); itr != end; ++itr, ++index) { tolua_pushstring(m_LuaState, itr->c_str()); lua_rawseti(m_LuaState, newTable, index); } m_NumCurrentFunctionArgs += 1; }
bool cPlayer::HasPermission(const AString & a_Permission) { if (a_Permission.empty()) { // Empty permission request is always granted return true; } AStringVector Split = StringSplit( a_Permission, "." ); PermissionMap Possibilities = m_ResolvedPermissions; // Now search the namespaces while( Possibilities.begin() != Possibilities.end() ) { PermissionMap::iterator itr = Possibilities.begin(); if( itr->second ) { AStringVector OtherSplit = StringSplit( itr->first, "." ); if( OtherSplit.size() <= Split.size() ) { unsigned int i; for( i = 0; i < OtherSplit.size(); ++i ) { if( OtherSplit[i].compare( Split[i] ) != 0 ) { if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard! break; } } if( i == Split.size() ) return true; } } Possibilities.erase( itr ); } // Nothing that matched :( return false; }
bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_ConsoleCommands.find(a_Split[0]); if (cmd == m_ConsoleCommands.end()) { LOGWARNING("Console command handler is registered in cPluginManager but not in cPlugin, wtf? Console command \"%s\", plugin \"%s\".", a_Split[0].c_str(), GetName().c_str() ); return false; } cCSLock Lock(m_CriticalSection); // Push the function to be called: lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() // Push the split: lua_createtable(m_LuaState, a_Split.size(), 0); int newTable = lua_gettop(m_LuaState); int index = 1; std::vector<std::string>::const_iterator iter = a_Split.begin(), end = a_Split.end(); while(iter != end) { tolua_pushstring(m_LuaState, (*iter).c_str()); lua_rawseti(m_LuaState, newTable, index); ++iter; ++index; } // Call function: int s = lua_pcall(m_LuaState, 1, 2, 0); if (report_errors(m_LuaState, s)) { LOGERROR("Lua error. Stack size: %i", lua_gettop(m_LuaState)); return false; } // Handle return values: if (lua_isstring(m_LuaState, -1)) { AString str = tolua_tocppstring(m_LuaState, -1, ""); a_Output.Out(str); } bool RetVal = (tolua_toboolean(m_LuaState, -2, 0) > 0); lua_pop(m_LuaState, 2); // Pop return values return RetVal; }
bool ResolveItem(const AString & a_ItemName, cItem & a_Item) { // Split into parts divided by either ':' or '^' AStringVector Split = StringSplitAndTrim(a_ItemName, ":^"); if (Split.empty()) { return false; } ItemMap::iterator itr = m_Map.find(Split[0]); if (itr != m_Map.end()) { // Resolved as a string, assign the type and the default damage / count a_Item.m_ItemType = itr->second.first; a_Item.m_ItemDamage = itr->second.second; if (a_Item.m_ItemDamage == -1) { a_Item.m_ItemDamage = 0; } } else { // Not a resolvable string, try pure numbers: "45:6", "45^6" etc. a_Item.m_ItemType = (short)atoi(Split[0].c_str()); if ((a_Item.m_ItemType == 0) && (Split[0] != "0")) { // Parsing the number failed return false; } } // Parse the damage, if present: if (Split.size() < 2) { // Not present, set the item as valid and return success: a_Item.m_ItemCount = 1; return true; } a_Item.m_ItemDamage = (short)atoi(Split[1].c_str()); if ((a_Item.m_ItemDamage == 0) && (Split[1] != "0")) { // Parsing the number failed return false; } a_Item.m_ItemCount = 1; return true; }
bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_Commands.find(a_Split[0]); if (cmd == m_Commands.end()) { LOGWARNING("Command handler is registered in cPluginManager but not in cPlugin, wtf? Command \"%s\".", a_Split[0].c_str()); return false; } cCSLock Lock(m_CriticalSection); // Push the function to be called: lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() // Push the split: lua_createtable(m_LuaState, a_Split.size(), 0); int newTable = lua_gettop(m_LuaState); int index = 1; std::vector<std::string>::const_iterator iter = a_Split.begin(), end = a_Split.end(); while(iter != end) { tolua_pushstring(m_LuaState, (*iter).c_str()); lua_rawseti(m_LuaState, newTable, index); ++iter; ++index; } // Push player: tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); // Call function: int s = lua_pcall(m_LuaState, 2, 1, 0); if (report_errors(m_LuaState, s)) { LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } // Handle return value: bool RetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); lua_pop(m_LuaState, 1); // Pop return value return RetVal; }
void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { // Create a list of names to query, by removing those that are already cached: AStringVector NamesToQuery; NamesToQuery.reserve(a_PlayerNames.size()); { cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { if (m_NameToUUID.find(*itr) == m_NameToUUID.end()) { NamesToQuery.push_back(*itr); } } // for itr - a_PlayerNames[] } // Lock(m_CSNameToUUID) QueryNamesToUUIDs(NamesToQuery); }
void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) { // The member needn't be defined at all, if so, skip: if (a_DepthWeightDef == NULL) { return; } // Split into individual records: "Record | Record | Record" AStringVector Defs = StringSplitAndTrim(a_DepthWeightDef, "|"); // Add each record's contents: for (AStringVector::const_iterator itr = Defs.begin(), end = Defs.end(); itr != end; ++itr) { // Split into components: "Depth : Weight" AStringVector Components = StringSplitAndTrim(*itr, ":"); if (Components.size() != 2) { LOGWARNING("Bad prefab DepthWeight record: \"%s\", skipping.", itr->c_str()); continue; } // Parse depth: int Depth = atoi(Components[0].c_str()); if ((Depth == 0) && (Components[0] != "0")) { LOGWARNING("Bad prefab DepthWeight record, cannot parse depth \"%s\", skipping.", Components[0].c_str()); continue; } // Parse weight: int Weight = atoi(Components[1].c_str()); if ((Weight == 0) && (Components[1] != "0")) { LOGWARNING("Bad prefab DepthWeight record, cannot parse weight \"%s\", skipping.", Components[1].c_str()); continue; } // Save to map: ASSERT(m_DepthWeight.find(Depth) == m_DepthWeight.end()); // Not a duplicate m_DepthWeight[Depth] = Weight; } // for itr - Defs[] }
void cMojangAPI::Update(void) { Int64 LimitDateTime = time(nullptr) - MAX_AGE; // Re-query all playernames that are stale: AStringVector PlayerNames; { cCSLock Lock(m_CSNameToUUID); for (const auto & NameToUUID : m_NameToUUID) { if (NameToUUID.second.m_DateTime < LimitDateTime) { PlayerNames.push_back(NameToUUID.first); } } // for itr - m_NameToUUID[] } if (!PlayerNames.empty()) { LOG("cMojangAPI: Updating name-to-uuid cache for %u names", static_cast<unsigned>(PlayerNames.size())); QueryNamesToUUIDs(PlayerNames); } // Re-query all profiles that are stale: std::vector<cUUID> ProfileUUIDs; { cCSLock Lock(m_CSUUIDToProfile); for (auto & UUIDToProfile : m_UUIDToProfile) { if (UUIDToProfile.second.m_DateTime < LimitDateTime) { ProfileUUIDs.push_back(UUIDToProfile.first); } } // for itr - m_UUIDToProfile[] } if (!ProfileUUIDs.empty()) { LOG("cMojangAPI: Updating uuid-to-profile cache for %u uuids", static_cast<unsigned>(ProfileUUIDs.size())); for (const auto & UUID : ProfileUUIDs) { QueryUUIDToProfile(UUID); } } }
void cEnchantments::AddFromString(const AString & a_StringSpec) { // Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it // Split the StringSpec into separate declarations, each in the form "id=lvl": AStringVector Decls = StringSplit(a_StringSpec, ";"); for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr) { // Split each declaration into the id and lvl part: if (itr->empty()) { // The decl is empty (may happen if there's an extra semicolon at the end), ignore silently continue; } AStringVector Split = StringSplitAndTrim(*itr, "="); if (Split.size() != 2) { // Malformed decl LOG("%s: Malformed enchantment decl: \"%s\", skipping.", __FUNCTION__, itr->c_str()); continue; } int id = atoi(Split[0].c_str()); if ((id == 0) && (Split[0] != "0")) { id = StringToEnchantmentID(Split[0]); } int lvl = atoi(Split[1].c_str()); if ( ((id <= 0) && (Split[0] != "0")) || ((lvl == 0) && (Split[1] != "0")) ) { // Numbers failed to parse LOG("%s: Failed to parse enchantment declaration for numbers: \"%s\" and \"%s\", skipping.", __FUNCTION__, Split[0].c_str(), Split[1].c_str() ); continue; } SetLevel(id, lvl); } // for itr - Decls[] }
bool cGroupManager::LoadGroups() { cIniFile IniFile; if (!IniFile.ReadFile("groups.ini")) { LOGWARNING("Regenerating groups.ini, all groups will be reset"); IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file"); IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators"); IniFile.SetValue("Owner", "Permissions", "*", true); IniFile.SetValue("Owner", "Color", "2", true); IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.tpa,core.tpaccept,core.ban,core.unban,core.save-all,core.toggledownfall"); IniFile.SetValue("Moderator", "Color", "2", true); IniFile.SetValue("Moderator", "Inherits", "Player", true); IniFile.SetValue("Player", "Permissions", "core.portal", true); IniFile.SetValue("Player", "Color", "f", true); IniFile.SetValue("Player", "Inherits", "Default", true); IniFile.SetValue("Default", "Permissions", "core.help,core.plugins,core.spawn,core.worlds,core.back,core.motd,core.build,core.locate,core.viewdistance", true); IniFile.SetValue("Default", "Color", "f", true); IniFile.WriteFile("groups.ini"); } int NumKeys = IniFile.GetNumKeys(); for (int i = 0; i < NumKeys; i++) { AString KeyName = IniFile.GetKeyName(i); cGroup * Group = GetGroup(KeyName.c_str()); Group->ClearPermission(); // Needed in case the groups are reloaded. LOGD("Loading group %s", KeyName.c_str()); Group->SetName(KeyName); AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { Group->SetColor(cChatColor::Color + Color[0]); } else { Group->SetColor(cChatColor::White); } AString Commands = IniFile.GetValue(KeyName, "Commands", ""); if (!Commands.empty()) { AStringVector Split = StringSplitAndTrim(Commands, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddCommand(Split[i]); } } AString Permissions = IniFile.GetValue(KeyName, "Permissions", ""); if (!Permissions.empty()) { AStringVector Split = StringSplitAndTrim(Permissions, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddPermission(Split[i]); } } AString Groups = IniFile.GetValue(KeyName, "Inherits", ""); if (!Groups.empty()) { AStringVector Split = StringSplitAndTrim(Groups, ","); for (size_t i = 0; i < Split.size(); i++) { Group->InheritFrom(GetGroup(Split[i].c_str())); } } } // Always return true, we can handle writefile fails later. return true; }
bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Recipe) { // a_String is in this format: "ItemType^damage, X:Y, X:Y, X:Y..." AStringVector Split = StringSplit(a_String, ","); if (Split.size() < 2) { // Not enough split items return false; } cItem Item; if (!ParseItem(Split[0], Item)) { return false; } Item.m_ItemCount = 1; cCraftingRecipes::cRecipeSlots TempSlots; for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr) { // Parse the coords in the split item: AStringVector Coords = StringSplit(*itr, ":"); if ((Coords.size() == 1) && (TrimString(Coords[0]) == "*")) { cCraftingRecipes::cRecipeSlot Slot; Slot.m_Item = Item; Slot.x = -1; Slot.y = -1; TempSlots.push_back(Slot); continue; } if (Coords.size() != 2) { return false; } Coords[0] = TrimString(Coords[0]); Coords[1] = TrimString(Coords[1]); if (Coords[0].empty() || Coords[1].empty()) { return false; } cCraftingRecipes::cRecipeSlot Slot; Slot.m_Item = Item; switch (Coords[0][0]) { case '1': Slot.x = 0; break; case '2': Slot.x = 1; break; case '3': Slot.x = 2; break; case '*': Slot.x = -1; break; default: { return false; } } switch (Coords[1][0]) { case '1': Slot.y = 0; break; case '2': Slot.y = 1; break; case '3': Slot.y = 2; break; case '*': Slot.y = -1; break; default: { return false; } } TempSlots.push_back(Slot); } // for itr - Split[] // Append the ingredients: a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end()); return true; }
void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { // Create a list of names to query, by removing those that are already cached: AStringVector NamesToQuery; NamesToQuery.reserve(a_PlayerNames.size()); { cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { if (m_NameToUUID.find(*itr) == m_NameToUUID.end()) { NamesToQuery.push_back(*itr); } } // for itr - a_PlayerNames[] } // Lock(m_CSNameToUUID) while (!NamesToQuery.empty()) { // Create the request body - a JSON containing up to MAX_PER_QUERY playernames: Json::Value root; int Count = 0; AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count) { Json::Value req(*itr); root.append(req); } // for itr - a_PlayerNames[] NamesToQuery.erase(NamesToQuery.begin(), itr); Json::FastWriter Writer; AString RequestBody = Writer.write(root); // Create the HTTP request: AString Request; Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_NameToUUIDServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Type: application/json\r\n"; Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); Request += "\r\n"; Request += RequestBody; // Get the response from the server: AString Response; if (!SecureRequest(m_NameToUUIDServer, Request, Response)) { continue; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } Response.erase(0, idxHeadersEnd + 4); // Parse the returned string into Json: Json::Reader reader; if (!reader.parse(Response, root, false) || !root.isArray()) { LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Store the returned results into cache: size_t JsonCount = root.size(); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); for (size_t idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } // cCSLock (m_CSNameToUUID) // Also cache the UUIDToName: { cCSLock Lock(m_CSUUIDToName); for (size_t idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_UUIDToName[JsonUUID] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } } // while (!NamesToQuery.empty()) }