Ogre::UTFString GetColouredName(Ogre::UTFString nick, int colour_number)
{
	Ogre::ColourValue col_val = PlayerColours::getSingleton().getColour(colour_number);
	char tmp[255] = {0};
	sprintf(tmp, "#%02X%02X%02X", (unsigned int)(col_val.r * 255.0f), (unsigned int)(col_val.g * 255.0f), (unsigned int)(col_val.b * 255.0f));

	// replace # with X in nickname so the user cannot fake the colour
	for (unsigned int i=0; i<nick.size(); i++)
		if (nick[i] == '#') nick[i] = 'X';

	return tryConvertUTF(tmp) + nick;
}
void ReceiveStreamData(unsigned int type, int source, char *buffer)
{
	if (type != MSG2_UTF_CHAT && type != MSG2_UTF_PRIVCHAT) return;

	Ogre::UTFString msg = tryConvertUTF(buffer);

	if (type == MSG2_UTF_CHAT)
	{
		if (source == -1)
		{
			// server said something
		} else if (source == RoR::Networking::GetUID())
		{
			// our message bounced back :D
			Ogre::UTFString local_username = GetColouredName(RoR::Networking::GetUsername(), RoR::Networking::GetUserColor());
			msg = local_username + RoR::Color::NormalColour + ": " + msg;
		} else
		{
			user_info_t user;
			if (RoR::Networking::GetUserInfo(source, user))
			{
				msg = GetColouredName(user.username, user.colournum) + RoR::Color::NormalColour + ": " + msg;
			}
		}
	} else if (type == MSG2_UTF_PRIVCHAT)
	{
		if (source == -1)
		{
			// server said something
			msg = RoR::Color::WhisperColour + _L(" [whispered] ") + RoR::Color::NormalColour + msg;
		} else
		{
			user_info_t user;
			if (RoR::Networking::GetUserInfo(source, user))
			{
				msg = GetColouredName(user.username, user.colournum) + _L(" [whispered] ") + RoR::Color::NormalColour + ": " + msg;
			}
		}
	}
#ifdef USE_MYGUI
	RoR::Application::GetGuiManager()->pushMessageChatBox(msg);
#endif //USE_MYGUI
}
int UserAuth::resolve(std::string user_token, UTFString &user_nick, int clientid)
{
    STACKLOG;

	// There's alot of other info in the user token variable, but we don't need it here.
	// We only need the first 40 characters = the actual (encoded) token.
	user_token = user_token.substr(0,40);
	
	//check cache first
	if(cache.find(user_token) != cache.end())
	{
		// cache hit!
		user_nick = cache[user_token].second;
		return cache[user_token].first;
	}
	
	// initialize the authlevel on none = normal user
	int authlevel = AUTH_NONE;

	// Only contact the master-server if we're allowed to do so
	if(trustlevel>1)
	{
		std::string msg = "";
		UTFString resultNick = L"";
	
		// not found in cache or local_auth, get auth from masterserver
		char url[2048];
		sprintf(url, "%s/authuser_utf8/?c=%s&t=%s&u=%s", REPO_URLPREFIX, challenge.c_str(), user_token.c_str(), user_nick.asUTF8_c_str());
		Logger::log(LOG_DEBUG, "UserAuth query to server: " + std::string(url));
		HttpMsg resp;
		if (HTTPGET(url, resp) < 0)
		{
			Logger::log(LOG_ERROR, "UserAuth resolve query result empty");
			return AUTH_NONE;
		}

		std::string body = resp.getBody();
		Logger::log(LOG_DEBUG,"UserAuth reply: " + body);
		
		std::vector<std::string> args;
		strict_tokenize(body, args, "\t");

		if(args.size() < 2)
		{
			Logger::log(LOG_INFO,"UserAuth: invalid return value from server: " + body);
			return AUTH_NONE;
		}
		
		authlevel = atoi(args[0].c_str());
		resultNick = tryConvertUTF(args[1].c_str());
		if(args.size() > 2)
			msg = args[2];

		// debug output the auth status
		UTFString authst;
		if(authlevel & AUTH_NONE)   authst = authst + "N";
		if(authlevel & AUTH_ADMIN)  authst = authst + "A";
		if(authlevel & AUTH_MOD)    authst = authst + "M";
		if(authlevel & AUTH_RANKED) authst = authst + "R";
		if(authlevel & AUTH_BOT)    authst = authst + "B";
		if(authst.empty()) authst = "(none)";
		Logger::log(LOG_DEBUG, UTFString("User Auth Result: ") + authst + " / " + (resultNick) + " / " + tryConvertUTF(msg.c_str()));

		if(resultNick == L"error" || resultNick == L"reserved" || resultNick == L"notranked")
		{
			resultNick = widen(getNewPlayernameByID(clientid));
			Logger::log(LOG_DEBUG, UTFString("got new random name for player: ") + resultNick);
			authlevel = AUTH_NONE;
		}

		// returned name valid, use it
		user_nick = resultNick;
	}
	
	//then check for overrides in the authorizations file (server admins, etc)
	if(local_auth.find(user_token) != local_auth.end())
	{
		// local auth hit!
		// the stored nickname can be empty if no nickname is specified.
		if(!local_auth[user_token].second.empty())
			user_nick = local_auth[user_token].second;
		authlevel |= local_auth[user_token].first;
	}

	// cache result if ranked or higher
	if(authlevel > AUTH_NONE)
	{
		user_auth_pair_t p;
		p.first = authlevel;
		p.second = user_nick;
		
		Logger::log(LOG_DEBUG, "adding entry to remote auth cache, size: %d",  cache.size());
		cache[user_token] = p;
	}

	return authlevel;
}