Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
	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);
	}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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());
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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();
}
Esempio n. 10
0
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[]
}
Esempio n. 11
0
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();
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
	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;
	}
Esempio n. 15
0
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[]
}
Esempio n. 16
0
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[]
}
Esempio n. 17
0
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()));
	}
}
Esempio n. 18
0
	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);
	}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
	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;
	}
Esempio n. 23
0
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;
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
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[]
}
Esempio n. 26
0
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);
		}
	}
}
Esempio n. 27
0
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[]
}
Esempio n. 28
0
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
0
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())
}