Esempio n. 1
0
void trimUTFString( UTFString &str, bool left, bool right)
{
	static const String delims = " \t\r";
	if (right)
		str.erase(str.find_last_not_of(delims)+1); // trim right
	if (left)
		str.erase(0, str.find_first_not_of(delims)); // trim left
}
Esempio n. 2
0
UTFString tryConvertUTF(const char *buffer)
{
	try
	{
		UTFString s = UTFString(buffer);
		if (s.empty())
			s = UTFString("(UTF conversion error 1)");
		return s;

	} catch(...)
	{
		return UTFString("(UTF conversion error 2)");
	}
	//return UTFString("(UTF conversion error 3)");
}
Esempio n. 3
0
void Replay::updateGUI()
{
#ifdef USE_MYGUI
	if (outOfMemory)
	{
		txt->setCaption(_L("Out of Memory"));
		pr->setProgressPosition(0);
	} else
	{
		wchar_t tmp[128] = L"";
		unsigned long t = curFrameTime;
		UTFString format = _L("Position: %0.6f s, frame %i / %i");
		swprintf(tmp, 128, format.asWStr_c_str(), ((float)t)/1000000.0f, curOffset, numFrames);
		txt->setCaption(convertToMyGUIString(tmp, 128));
		pr->setProgressPosition(abs(curOffset));
	}
#endif // MYGUI
}
void NetworkStreamManager::sendStreams(Network *net, SWInetSocket *socket)
{
	{
		std::unique_lock<std::mutex> ss_lock(m_send_work_mutex);
		m_send_work_cv.wait(ss_lock, [this]{ return send_start; });
		send_start = false;
	}

	std::lock_guard<std::mutex> lock(m_stream_mutex);

	std::map < int, std::map < unsigned int, Streamable *> >::iterator it;
	for (it=streams.begin(); it!=streams.end(); it++)
	{
		std::map<unsigned int,Streamable *>::iterator it2;
		for (it2=it->second.begin(); it2!=it->second.end(); it2++)
		{
			if (!it2->second) continue;
			std::deque <Streamable::bufferedPacket_t> *packets = it2->second->getPacketQueue();

			while (!packets->empty())
			{
				// remove oldest packet in queue
				Streamable::bufferedPacket_t packet = packets->front();

				int etype = net->sendMessageRaw(socket, packet.packetBuffer, packet.size);
				if (etype)
				{
					wchar_t emsg[256];
					UTFString tmp = _L("Error %i while sending data packet");
					swprintf(emsg, 256, tmp.asWStr_c_str(), etype);
					net->netFatalError(UTFString(emsg));
					return;
				}

				packets->pop_front();
			}

		}
	}
}
Esempio n. 5
0
GUI_Multiplayer::GUI_Multiplayer() :
	  clients(0)
	, lineheight(16)
	, msgwin(0)
{
	setSingleton(this);
	
	// allocate some buffers
	clients = (client_t *)calloc(MAX_PEERS,sizeof(client_t));
	

	// tooltip window
	tooltipPanel = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>("PanelSkin", 0, 0, 200, 20,  MyGUI::Align::Default, "ToolTip");
	tooltipText = tooltipPanel->createWidget<MyGUI::TextBox>("TextBox", 4, 2, 200, 16,  MyGUI::Align::Default);
	tooltipText->setFontName("VeraMono");
	//tooltipPanel->setAlpha(0.9f);
	tooltipText->setFontHeight(16);
	tooltipPanel->setVisible(false);
	
	// message window
	msgwin = MyGUI::Gui::getInstance().createWidget<MyGUI::Window>("WindowCSX", 0, 0, 400, 300,  MyGUI::Align::Center, "Overlapped");
	msgwin->setCaption(_L("Player Information"));
	msgtext = msgwin->createWidget<MyGUI::Edit>("EditStretch", 0, 0, 400, 300,  MyGUI::Align::Default, "helptext");
	msgtext->setCaption("");
	msgtext->setEditWordWrap(true);
	msgtext->setEditStatic(true);
	msgwin->setVisible(false);


	// network quality warning
	netmsgwin = MyGUI::Gui::getInstance().createWidget<MyGUI::Window>("FlowContainer", 5, 30, 300, 40,  MyGUI::Align::Default, "Main");
	netmsgwin->setAlpha(0.8f);
	MyGUI::ImageBox *nimg = netmsgwin->createWidget<MyGUI::ImageBox>("ImageBox", 0, 0, 16, 16,  MyGUI::Align::Default, "Main");
	nimg->setImageTexture("error.png");
	netmsgtext = netmsgwin->createWidget<MyGUI::TextBox>("TextBox", 18, 2, 300, 40,  MyGUI::Align::Default, "helptext");
	netmsgtext->setCaption(_L("Slow  Network  Download"));
	netmsgtext->setFontName("DefaultBig");
	netmsgtext->setTextColour(MyGUI::Colour::Red);
	netmsgtext->setFontHeight(lineheight);
	netmsgwin->setVisible(false);


	// now the main GUI
	MyGUI::IntSize gui_area = MyGUI::RenderManager::getInstance().getViewSize();
	int x=gui_area.width - 300, y=30;

	MyGUI::ImageBox *ib = MyGUI::Gui::getInstance().createWidget<MyGUI::ImageBox>("ImageBox", x, y, sidebarWidth, gui_area.height,  MyGUI::Align::Default, "Main");
	ib->setImageTexture("mpbg.png");

	mpPanel = ib; //->createWidget<MyGUI::Widget>("FlowContainer", x, y, sidebarWidth, gui_area.height,  MyGUI::Align::Default, "Main");
	mpPanel->setVisible(true);

	y=5;
	UTFString tmp;
	for (int i = 0; i < MAX_PEERS + 1; i++) // plus 1 for local entry
	{
		x=100; // space for icons
		player_row_t *row = &player_rows[i];
		row->playername = mpPanel->createWidget<MyGUI::TextBox>("TextBox", x, y+1, sidebarWidth, lineheight,  MyGUI::Align::Default, "Main");
		row->playername->setCaption("Player " + TOSTRING(i));
		row->playername->setFontName("DefaultBig");
		tmp = _L("user name");
		row->playername->setUserString("tooltip", tmp.asUTF8());
		row->playername->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->playername->setNeedToolTip(true);
		row->playername->setVisible(false);
		row->playername->setFontHeight(lineheight);
		row->playername->setAlpha(1);

		x -= 18;
		row->flagimg = mpPanel->createWidget<MyGUI::ImageBox>("ImageBox", x, y + 3, 16, 11,  MyGUI::Align::Default, "Main");
		tmp = _L("user country");
		row->flagimg->setUserString("tooltip", tmp.asUTF8());
		row->flagimg->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->flagimg->setNeedToolTip(true);
		row->flagimg->setVisible(false);

		x -= 18;
		row->statimg = mpPanel->createWidget<MyGUI::ImageBox>("ImageBox", x, y, 16, 16,  MyGUI::Align::Default, "Main");
		tmp = _L("user authentication level");
		row->statimg->setUserString("tooltip", tmp.asUTF8());
		row->statimg->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->statimg->setNeedToolTip(true);
		row->statimg->setVisible(false);

		x -= 18;
		row->userTruckOKImg = mpPanel->createWidget<MyGUI::ImageBox>("ImageBox", x, y, 16, 16,  MyGUI::Align::Default, "Main");
		tmp = _L("truck loading state");
		row->userTruckOKImg->setUserString("tooltip", tmp.asUTF8());
		row->userTruckOKImg->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->userTruckOKImg->setNeedToolTip(true);
		row->userTruckOKImg->setVisible(false);
		row->userTruckOKImg->eventMouseButtonClick += MyGUI::newDelegate(this, &GUI_Multiplayer::clickInfoIcon);

		x -= 18;
		row->userTruckOKRemoteImg = mpPanel->createWidget<MyGUI::ImageBox>("ImageBox", x, y, 16, 16,  MyGUI::Align::Default, "Main");
		tmp = _L("remote truck loading state");
		row->userTruckOKRemoteImg->setUserString("tooltip", tmp.asUTF8());
		row->userTruckOKRemoteImg->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->userTruckOKRemoteImg->setNeedToolTip(true);
		row->userTruckOKRemoteImg->setVisible(false);
		row->userTruckOKRemoteImg->eventMouseButtonClick += MyGUI::newDelegate(this, &GUI_Multiplayer::clickInfoIcon);
		
		x -= 18;
		row->usergoimg = mpPanel->createWidget<MyGUI::ImageBox>("ImageBox", x, y, 16, 16,  MyGUI::Align::Default, "Main");
		row->usergoimg->setUserString("num", TOSTRING(i));
		tmp = _L("go to user");
		row->usergoimg->setUserString("tooltip", tmp.asUTF8());
		row->usergoimg->setImageTexture("user_go.png");
		row->usergoimg->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		row->usergoimg->setNeedToolTip(true);
		row->usergoimg->setVisible(false);
		row->usergoimg->eventMouseButtonClick += MyGUI::newDelegate(this, &GUI_Multiplayer::clickUserGoIcon);

		/*
		img = MyGUI::Gui::getInstance().createWidget<MyGUI::ImageBox>("ImageBox", x-36, y, 16, 16,  MyGUI::Align::Default, "Overlapped");
		img->setImageTexture("information.png");
		img->eventMouseButtonClick += MyGUI::newDelegate(this, &GUI_Multiplayer::clickInfoIcon);
		img->eventToolTip += MyGUI::newDelegate(this, &GUI_Multiplayer::openToolTip);
		img->setNeedToolTip(true);
		img->setUserString("info", TOSTRING(i));
		img->setUserString("tooltip", _L("information about the user"));
		*/

		y += lineheight;
	}
}
Esempio n. 6
0
void GUI_Multiplayer::updateSlot(player_row_t *row, user_info_t *c, bool self)
{
	if (!row || !c) return;

	int x = 100;
	int y = row->playername->getPosition().top;
	// name
	row->playername->setCaption(c->username);
	ColourValue col = PlayerColours::getSingleton().getColour(c->colournum);
	row->playername->setTextColour(MyGUI::Colour(col.r, col.g, col.b, col.a));
	row->playername->setVisible(true);
	x -= 18;
	
	// flag
	StringVector parts = StringUtil::split(String(c->language), "_");
	if (parts.size() == 2)
	{
		String lang = parts[1];
		StringUtil::toLowerCase(lang);
		row->flagimg->setImageTexture(lang + ".png");
		row->flagimg->setUserString("tooltip", _L("user language: ") + parts[0] + _L(" user country: ") + parts[1]);
		row->flagimg->setVisible(true);
		row->flagimg->setPosition(x, y);
		x -= 18;
	} else
	{
		row->flagimg->setVisible(false);
	}
	
	UTFString tmp;
	// auth
	if (c->authstatus == AUTH_NONE)
	{
		row->statimg->setVisible(false);
	} else if (c->authstatus & AUTH_ADMIN)
	{
		row->statimg->setVisible(true);
		row->statimg->setImageTexture("flag_red.png");
		tmp = _L("Server Administrator");
		row->statimg->setUserString("tooltip", tmp.asUTF8());
		row->statimg->setPosition(x, y);
		x -= 18;
	} else if (c->authstatus & AUTH_MOD)
	{
		row->statimg->setVisible(true);
		row->statimg->setImageTexture("flag_blue.png");
		tmp = _L("Server Moderator");
		row->statimg->setUserString("tooltip", tmp.asUTF8());
		row->statimg->setPosition(x, y);
		x -= 18;
	} else if (c->authstatus & AUTH_RANKED)
	{
		row->statimg->setVisible(true);
		row->statimg->setImageTexture("flag_green.png");
		tmp = _L("ranked user");
		row->statimg->setUserString("tooltip", tmp.asUTF8());
		row->statimg->setPosition(x, y);
		x -= 18;
	}

	// truck ok image
	if (!self)
	{
		row->userTruckOKImg->setVisible(true);
		row->userTruckOKRemoteImg->setVisible(true);
		row->userTruckOKImg->setUserString("uid", TOSTRING(c->uniqueid));
		row->userTruckOKRemoteImg->setUserString("uid", TOSTRING(c->uniqueid));
		row->userTruckOKImg->setPosition(x, y);
		x -= 10;
		row->userTruckOKRemoteImg->setPosition(x, y);
		x -= 10;

		int ok = BeamFactory::getSingleton().checkStreamsOK(c->uniqueid);
		if (ok == 0)
		{
			row->userTruckOKImg->setImageTexture("arrow_down_red.png");
			tmp = _L("Truck loading errors");
			row->userTruckOKImg->setUserString("tooltip", tmp.asUTF8());
		} else if (ok == 1)
		{
			row->userTruckOKImg->setImageTexture("arrow_down.png");
			tmp = _L("Truck loaded correctly, no errors");
			row->userTruckOKImg->setUserString("tooltip", tmp.asUTF8());
		} else if (ok == 2)
		{
			row->userTruckOKImg->setImageTexture("arrow_down_grey.png");
			tmp = _L("no truck loaded");
			row->userTruckOKImg->setUserString("tooltip", tmp.asUTF8());
		}

		int rok = BeamFactory::getSingleton().checkStreamsRemoteOK(c->uniqueid);
		if (rok == 0)
		{
			row->userTruckOKRemoteImg->setImageTexture("arrow_up_red.png");
			tmp = _L("Remote Truck loading errors");
			row->userTruckOKRemoteImg->setUserString("tooltip", tmp.asUTF8());
		} else if (rok == 1)
		{
			row->userTruckOKRemoteImg->setImageTexture("arrow_up.png");
			tmp = _L("Remote Truck loaded correctly, no errors");
			row->userTruckOKRemoteImg->setUserString("tooltip", tmp.asUTF8());
		} else if (rok == 2)
		{
			row->userTruckOKRemoteImg->setImageTexture("arrow_up_grey.png");
			tmp = _L("No Trucks loaded");
			row->userTruckOKRemoteImg->setUserString("tooltip", tmp.asUTF8());
		}
	} else
	{
		row->userTruckOKImg->setVisible(false);
		row->userTruckOKRemoteImg->setVisible(false);
	}
	
	// user go img
	row->usergoimg->setVisible(false);
}
Esempio n. 7
0
/*
All commands are here
*/
void Console::eventCommandAccept(MyGUI::Edit* _sender)
{
	UTFString msg = convertFromMyGUIString(m_Console_TextBox->getCaption());

	// we did not autoComplete, so try to handle the message
	m_Console_TextBox->setCaption("");

	if (msg.empty())
	{
		// discard the empty message
		return;
	}
	if (msg[0] == '/' || msg[0] == '\\')
	{
		Ogre::StringVector args = StringUtil::split(msg, " ");
		sTextHistory[iText] = msg;
		iText++; //Used for text history
		if (args[0] == "/help")
		{
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_TITLE, _L("Available commands:"), "help.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/help - information on commands (this)"), "help.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/ver - shows the Rigs of Rods version"), "information.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/pos - outputs the current position"), "world.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/goto <x> <y> <z> - jumps to the mentioned position"), "world.png");


			//if (gEnv->terrainManager->getHeightFinder()) //Not needed imo -max98
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/terrainheight - get height of terrain at current position"), "world.png");

			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/log - toggles log output on the console"), "table_save.png");

			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/quit - exit Rigs of Rods"), "table_save.png");

#ifdef USE_ANGELSCRIPT	
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/as <code here> - interpret angel code using console"), "script_go.png");
#endif // USE_ANGELSCRIPT

			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/gravity <real> or <text string> - changes gravity constant. Outputs current value if no argument is given"), "script_go.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("Possible values: \n earth \n moon \n jupiter \n A random number (use negative)"), "script_go.png");

			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("/setwaterlevel <real> - changes water's level"), "script_go.png");

			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_TITLE, _L("Tips:"), "help.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, _L("- use Arrow Up/Down Keys in the InputBox to reuse old messages"), "information.png");
			return;
		} else if (args[0] == "/gravity")
		{
			float gValue;

			if (args.size() > 1)
			{
				if (args[1] == "earth")
					gValue = -9.81;
				else if (args[1] == "moon")
					gValue = -1.6;
				else if (args[1] == "jupiter")
					gValue = -50;
				else
					gValue = boost::lexical_cast<float>(args[1].c_str());
			} else
			{
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Current gravity is: ") + StringConverter::toString(gEnv->terrainManager->getGravity()), "information.png");
				return;
			}

			gEnv->terrainManager->setGravity(gValue);
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Gravity set to: ") + StringConverter::toString(gValue), "information.png");
			return;
		} else if (args[0] == "/setwaterlevel")
		{
			if (gEnv->terrainManager && gEnv->terrainManager->getWater() && args.size() > 1)
			{
				IWater* water = gEnv->terrainManager->getWater();
				water->setCamera(gEnv->mainCamera);
				water->setHeight(boost::lexical_cast<float>(args[1].c_str()));
				water->update();
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Water level set to: ") + StringConverter::toString(water->getHeight()), "information.png");
			}
			else
			{
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_ERROR, _L("Please enter a correct value. "), "information.png");
			}
			return;
		}
		else if (args[0] == "/pos" && (gEnv->frameListener->loading_state == TERRAIN_LOADED || gEnv->frameListener->loading_state == ALL_LOADED))
		{
			Beam *b = BeamFactory::getSingleton().getCurrentTruck();
			if (!b && gEnv->player)
			{
				Vector3 pos = gEnv->player->getPosition();
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Character position: ") + String("x: ") + TOSTRING(pos.x) + String(" y: ") + TOSTRING(pos.y) + String(" z: ") + TOSTRING(pos.z), "world.png");
			}
			else if (b)
			{
				Vector3 pos = b->getPosition();
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Vehicle position: ") + String("x: ") + TOSTRING(pos.x) + String(" y: ") + TOSTRING(pos.y) + String(" z: ") + TOSTRING(pos.z), "world.png");
			}

			return;
		}
		else if (args[0] == "/goto" && (gEnv->frameListener->loading_state == TERRAIN_LOADED || gEnv->frameListener->loading_state == ALL_LOADED))
		{
			if (args.size() != 4)
			{
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_HELP, ChatSystem::commandColour + _L("usage: /goto x y z"), "information.png");
				return;
			}

			Vector3 pos = Vector3(PARSEREAL(args[1]), PARSEREAL(args[2]), PARSEREAL(args[3]));

			Beam *b = BeamFactory::getSingleton().getCurrentTruck();
			if (!b && gEnv->player)
			{
				gEnv->player->setPosition(pos);
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Character position set to: ") + String("x: ") + TOSTRING(pos.x) + String(" y: ") + TOSTRING(pos.y) + String(" z: ") + TOSTRING(pos.z), "world.png");
			}
			else if (b)
			{
				b->resetPosition(pos, false);
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Vehicle position set to: ") + String("x: ") + TOSTRING(pos.x) + String(" y: ") + TOSTRING(pos.y) + String(" z: ") + TOSTRING(pos.z), "world.png");
			}

			return;
		}
		else if (args[0] == "/terrainheight" && (gEnv->frameListener->loading_state == TERRAIN_LOADED || gEnv->frameListener->loading_state == ALL_LOADED))
		{
			if (!gEnv->terrainManager->getHeightFinder()) return;
			Vector3 pos = Vector3::ZERO;

			Beam *b = BeamFactory::getSingleton().getCurrentTruck();
			if (!b && gEnv->player)
			{
				pos = gEnv->player->getPosition();
			}
			else if (b)
			{
				pos = b->getPosition();
			}

			Real h = gEnv->terrainManager->getHeightFinder()->getHeightAt(pos.x, pos.z);
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, _L("Terrain height at position: ") + String("x: ") + TOSTRING(pos.x) + String("z: ") + TOSTRING(pos.z) + _L(" = ")  + TOSTRING(h), "world.png");

			return;
		}
		else if (args[0] == "/ver")
		{
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_TITLE, "Rigs of Rods:", "information.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, " Version: " + String(ROR_VERSION_STRING), "information.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, " Protocol version: " + String(RORNET_VERSION), "information.png");
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_REPLY, " build time: " + String(__DATE__) + ", " + String(__TIME__), "information.png");
			return;

		}
		else if (args[0] == "/quit")
		{
			Application::GetMainThreadLogic()->RequestExitCurrentLoop();
			Application::GetMainThreadLogic()->RequestShutdown();
			return;

		}
#ifdef USE_ANGELSCRIPT
		else if (args[0] == "/as" && (gEnv->frameListener->loading_state == TERRAIN_LOADED || gEnv->frameListener->loading_state == ALL_LOADED))
		{
			// we want to notify any running scripts that we might change something (prevent cheating)
			ScriptEngine::getSingleton().triggerEvent(SE_ANGELSCRIPT_MANIPULATIONS);

			String command = msg.substr(args[0].length());

			StringUtil::trim(command);
			if (command.empty()) return;

			String nmsg = ChatSystem::scriptCommandColour + ">>> " + ChatSystem::normalColour + command;
			putMessage(CONSOLE_MSGTYPE_SCRIPT, CONSOLE_LOCAL_SCRIPT, nmsg, "script_go.png");
			int res = ScriptEngine::getSingleton().executeString(command);
			return;
		}
#endif //ANGELSCRIPT
		else if (args[0] == "/log")
		{
			// switch to console logging
			bool logging = BSETTING("Enable Ingame Console", false);
			if (!logging)
			{
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_NOTICE, _L(" logging to console enabled"), "information.png");
				SETTINGS.setSetting("Enable Ingame Console", "Yes");
			}
			else
			{
				putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_NOTICE, _L(" logging to console disabled"), "information.png");
				SETTINGS.setSetting("Enable Ingame Console", "No");
			}
			return;
		}
		else
		{
			//TODO: Angelscript here
			putMessage(CONSOLE_MSGTYPE_INFO, CONSOLE_SYSTEM_ERROR, _L("unknown command: ") + msg, "error.png");
		}
	}

}
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;
}
Esempio n. 9
0
bool TruckHUD::update(float dt, Beam *truck, bool visible)
{
	OverlayElement *overlayElement = 0;

	// only update every 300 ms
	if (visible)
	{
		updatetime -= dt;
		if (updatetime <= 0.0f)
		{
			// update now, reset timer
			updatetime = 0.3f;
		} else
		{
			// don't update visuals, only count stats
			visible = false;
		}
	}

	if (visible)
	{
		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Truckname");
		overlayElement->setCaption(truck->getTruckName());
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Truckauthor");
		overlayElement->setCaption(_L("(no author information available)"));
		std::vector<authorinfo_t> file_authors = truck->getAuthors();
		if (!file_authors.empty())
		{
			String authors = "";
			for (std::vector<authorinfo_t>::iterator it = file_authors.begin(); it != file_authors.end(); ++it)
			{
				authors += (*it).name + " ";
			}
			overlayElement->setCaption(_L("Authors: ") + authors);
		}
		checkOverflow(overlayElement);

		std::vector<std::string> description = truck->getDescription();
		for (unsigned int i=1; i < 3; i++)
		{
			overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/DescriptionLine" + TOSTRING(i+1));
			overlayElement->setCaption("");
			if (i < description.size())
			{
				overlayElement->setCaption(ANSI_TO_UTF(description[i]));
			}
			checkOverflow(overlayElement);
		}

		beam_t *beam = truck->getBeams();
		float average_deformation = 0.0f;
		float beamstress = 0.0f;
		float current_deformation = 0.0f;
		float mass = truck->getTotalMass();
		int beamCount = truck->getBeamCount();
		int beambroken = 0;
		int beamdeformed = 0;

		for (int i=0; i < beamCount; i++, beam++)
		{
			if (beam->broken != 0)
			{
				beambroken++;
			}
			beamstress += beam->stress;
			current_deformation = fabs(beam->L-beam->refL);
			if (fabs(current_deformation) > 0.0001f && beam->type != BEAM_HYDRO && beam->type != BEAM_INVISIBLE_HYDRO)
			{
				beamdeformed++;
			}
			average_deformation += current_deformation;
		}

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamTotal");
		overlayElement->setCaption(_L("beam count: ") + TOUTFSTRING(beamCount));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamBroken");
		overlayElement->setCaption(_L("broken: ") + TOUTFSTRING(beambroken) + U(" (") + TOUTFSTRING(Round((float)beambroken / (float)beamCount, 2) * 100.0f) + U("%)"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamHealth");
		float health = ((float)beambroken / (float)beamCount) * 10.0f + ((float)beamdeformed / (float)beamCount);
		if (health < 1.0f)
		{
			overlayElement->setCaption(_L("health: ") + TOUTFSTRING(Round((1.0f - health) * 100.0f, 2)) + U("%"));
			overlayElement->setColour(ColourValue(0.6f, 0.8f, 0.4f, 1.0f));
		} else if (health >= 1.0f)
		{
			health = ((float)beambroken / (float)beamCount) * 3.0f;
			health = std::min(health, 1.0f);
			overlayElement->setCaption(_L("destruction: ") + TOUTFSTRING(Round(health * 100.0f, 2)) + U("%"));
			overlayElement->setColour(ColourValue(0.8f, 0.4f, 0.4f, 1.0f));
		}
		checkOverflow(overlayElement);


		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamDeformed");
		overlayElement->setCaption(_L("deformed: ") + TOUTFSTRING(beamdeformed) + U(" (") + TOUTFSTRING(Round((float)beamdeformed / (float)beamCount, 2) * 100.0f) + U("%)"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageBeamDeformation");
		overlayElement->setCaption(_L("average deformation: ") + TOUTFSTRING(Round((float)average_deformation / (float)beamCount, 4) * 100.0f));
		checkOverflow(overlayElement);
		
		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageBeamStress");
		wchar_t beamstressstr[256];
		swprintf(beamstressstr, 256, L"%+08.0f", 1-(float)beamstress/(float)beamCount);
		overlayElement->setCaption(_L("average stress: ") + UTFString(beamstressstr));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/NodeCount");
		int ncount = truck->getNodeCount();
		int wcount =  truck->getWheelNodeCount();
		wchar_t nodecountstr[256];
		swprintf(nodecountstr, 256, L"%d (wheels: %d)", ncount, wcount);
		overlayElement->setCaption(_L("node count: ") + UTFString(nodecountstr));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/TruckWeight");
		wchar_t truckmassstr[256];
		UTFString massstr = _L("current mass:");
		swprintf(truckmassstr, 256, L"%ls %8.2f kg (%.2f tons)", massstr.asWStr_c_str(), mass, mass / 1000.0f);
		overlayElement->setCaption(UTFString(truckmassstr));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Gees");
		wchar_t geesstr[256];
		Vector3 gees = truck->getGForces();
		// apply deadzones ==> no flickering +/-
		if (fabs(gees.y) < 0.01) gees.y = 0.0f;
		if (fabs(gees.z) < 0.01) gees.z = 0.0f;
		UTFString tmp = _L("Gees: Vertical %1.2fg // Saggital %1.2fg // Lateral %1.2fg");
		swprintf(geesstr, 256, tmp.asWStr_c_str(), gees.x, gees.y, gees.z);
		overlayElement->setCaption(UTFString(geesstr));
		checkOverflow(overlayElement);

		// max g-forces
		if (truck->driveable == TRUCK || truck->driveable == AIRPLANE || truck->driveable == BOAT)
		{
			if (gees.x > maxPosVerG[truck->driveable])
				maxPosVerG[truck->driveable] = gees.x;
			if (gees.x < maxNegVerG[truck->driveable])
				maxNegVerG[truck->driveable] = gees.x;

			if (gees.y > maxPosSagG[truck->driveable])
				maxPosSagG[truck->driveable] = gees.y;
			if (gees.y < maxNegSagG[truck->driveable])
				maxNegSagG[truck->driveable] = gees.y;

			if (gees.z > maxPosLatG[truck->driveable])
				maxPosLatG[truck->driveable] = gees.z;
			if (gees.z < maxNegLatG[truck->driveable])
				maxNegLatG[truck->driveable] = gees.z;

			tmp = _L("maxG: V %1.2fg %1.2fg // S %1.2fg %1.2fg // L %1.2fg %1.2fg");
			swprintf(geesstr, 256, tmp.asWStr_c_str(),
					maxPosVerG[truck->driveable],
					maxNegVerG[truck->driveable],
					maxPosSagG[truck->driveable],
					maxNegSagG[truck->driveable],
					maxPosLatG[truck->driveable],
					maxNegLatG[truck->driveable]
				);

			overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Gees2");
			overlayElement->setCaption(UTFString(geesstr));
			checkOverflow(overlayElement);
		}
	}

	Vector3 hdir = Vector3::ZERO;
	if (truck->cameranodepos[0] >= 0 && truck->cameranodepos[0] < MAX_NODES)
	{
		hdir = (truck->nodes[truck->cameranodepos[0]].RelPosition - truck->nodes[truck->cameranodedir[0]].RelPosition).normalisedCopy();
	}
	float g_along_hdir = hdir.dotProduct(truck->ffforce / 10000.0f);

	// always update these statistics, also if not visible!
	overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
	overlayElement->setCaption("");
	UTFString rpmsstr = _L("current RPM:");
	if (truck->driveable == TRUCK && truck->engine)
	{
		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
		overlayElement->setCaption(rpmsstr + U(" ") + TOUTFSTRING(Round(truck->engine->getRPM())) + U(" / ") + TOUTFSTRING(Round(truck->engine->getMaxRPM())));
	} else if (truck->driveable == AIRPLANE)
	{
		for (int i=0; i < 8; i++)
		{
			if (truck->aeroengines[i])
			{
				rpmsstr = rpmsstr + U(" / ") + TOUTFSTRING(Round(truck->aeroengines[i]->getRPM()));
			}
		}
		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
		overlayElement->setCaption(UTFString(rpmsstr));
	}
	checkOverflow(overlayElement);

	UTFString cspeedstr   = _L("current Speed:") + U(" ");
	UTFString mspeedstr   = _L("max Speed:")     + U(" ");
	UTFString altitudestr = _L("Altitude:")      + U(" ");

	if (truck->driveable == TRUCK)
	{
		maxVelos[truck->driveable] = std::max(maxVelos[truck->driveable], truck->WheelSpeed);
		minVelos[truck->driveable] = std::min(truck->WheelSpeed, minVelos[truck->driveable]);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity");
		
		float velocityKMH = truck->WheelSpeed* 3.6f;
		float velocityMPH = truck->WheelSpeed * 2.23693629f;
		// apply a deadzone ==> no flickering +/-
		if (fabs(truck->WheelSpeed) < 1.0f)
		{
			velocityKMH = velocityMPH = 0.0f;
		}
		overlayElement->setCaption(cspeedstr + TOUTFSTRING(Round(velocityKMH)) + U(" km/h (") + TOUTFSTRING(Round(velocityMPH)) + U(" mph)"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity");
		float velocityMaxKMH = maxVelos[truck->driveable] * 3.6f;
		float velocityMinKMH = minVelos[truck->driveable] * 3.6f;
		float velocityMaxMPH = maxVelos[truck->driveable] * 2.23693629f;
		float velocityMinMPH = minVelos[truck->driveable] * 2.23693629f;
		overlayElement->setCaption(mspeedstr + TOUTFSTRING(Round(velocityMaxKMH)) + U("km/h (") + TOUTFSTRING(Round(velocityMaxMPH)) + U("mph)") + U(", min: ") + TOUTFSTRING(Round(velocityMinKMH)) + U("km/h (") + TOUTFSTRING(Round(velocityMinMPH)) + U("mph)"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity");
		overlayElement->setCaption("");
	} else if (truck->driveable == AIRPLANE || truck->driveable == BOAT)
	{
		float velocity = truck->nodes[0].Velocity.length();
		
		if (truck->cameranodepos[0] >= 0 && truck->cameranodedir[0] && truck->driveable == BOAT)
		{
			hdir = (truck->nodes[truck->cameranodepos[0]].RelPosition - truck->nodes[truck->cameranodedir[0]].RelPosition).normalisedCopy();
			velocity = hdir.dotProduct(truck->nodes[truck->cameranodepos[0]].Velocity);
		}
		
		maxVelos[truck->driveable] = std::max(maxVelos[truck->driveable], velocity);
		minVelos[truck->driveable] = std::min(velocity, minVelos[truck->driveable]);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity");
		float velocityKN = velocity * 1.94384449f;
		// apply a deadzone ==> no flickering +/-
		if (fabs(velocity) < 1.0f)
		{
			velocityKN = 0.0f;
		}
		overlayElement->setCaption(cspeedstr + TOUTFSTRING(Round(velocityKN)) + U(" kn"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity");
		float velocityMaxKN = maxVelos[truck->driveable] * 1.94384449f;
		float velocityMinKN = minVelos[truck->driveable] * 1.94384449f;
		overlayElement->setCaption(mspeedstr + TOUTFSTRING(Round(maxVelos[truck->driveable])) + U(" kn, min: ") + TOUTFSTRING(Round(minVelos[truck->driveable])) + U(" kn"));
		checkOverflow(overlayElement);

		overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity");
		overlayElement->setCaption("");
		if (truck->driveable == AIRPLANE)
		{
			float altitude = truck->nodes[0].AbsPosition.y * 1.1811f;
			overlayElement->setCaption(altitudestr + TOUTFSTRING(Round(altitude)) + U(" m"));
			checkOverflow(overlayElement);
		}
	} else if (truck->driveable == MACHINE)
	{
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity")->setCaption("");
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity")->setCaption("");
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity")->setCaption("");
	}

	OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/TimeStats")->setCaption("");

	if (visible)
	{
		// update commands

		// clear them first
		for (int i=1; i <= COMMANDS_VISIBLE; i++)
		{
			overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Command" + TOSTRING(i));
			overlayElement->setCaption("");
		}

		int filledCommands = 0;
		for (int i=1; i < MAX_COMMANDS && filledCommands < COMMANDS_VISIBLE; i += 2)
		{
			if(truck->commandkey[i].beams.empty() || truck->commandkey[i].description == "hide") continue;

			filledCommands++;
			char commandID[256] = {};
			String keyStr = "";

			sprintf(commandID, "COMMANDS_%02d", i);
			int eventID = RoR::Application::GetInputEngine()->resolveEventName(String(commandID));
			String keya = RoR::Application::GetInputEngine()->getEventCommand(eventID);
			sprintf(commandID, "COMMANDS_%02d", i+1);
			eventID = RoR::Application::GetInputEngine()->resolveEventName(String(commandID));
			String keyb = RoR::Application::GetInputEngine()->getEventCommand(eventID);

			// cut off expl
			if (keya.size() > 6 && keya.substr(0,5) == "EXPL+") keya = keya.substr(5);
			if (keyb.size() > 6 && keyb.substr(0,5) == "EXPL+") keyb = keyb.substr(5);

			keyStr = keya + "/" + keyb;

			overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Command" + TOSTRING(filledCommands));
			
			if (truck->commandkey[i].description.empty())
			{
				overlayElement->setCaption(keyStr + ": " + _L("unknown function"));
			} else
			{
				overlayElement->setCaption(keyStr + ": " + truck->commandkey[i].description);
			}
			checkOverflow(overlayElement);
		}

		// hide command section title if no commands
		overlayElement = overlayElement = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CommandsTitleLabel");
		overlayElement->setCaption("");
		if (filledCommands > 0)
		{
			// TODO: Fix the position of this overlay element
			//overlayElement->setCaption(_L("Commands:"));
			checkOverflow(overlayElement);
		}
	}
	return true;
}
Esempio n. 10
0
    std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
    {
        using Ogre::UTFString;
        std::vector<std::string> result;

        MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
        utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext);

        boost::algorithm::replace_all(utf8Text, "\n", "");
        boost::algorithm::replace_all(utf8Text, "\r", "");
        boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
        boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");

        UTFString text(utf8Text);
        const int spacing = 48;

        const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<');
        const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n');
        const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');

        while (!text.empty())
        {
            // read in characters until we have exceeded the size, or run out of text
            int currentWidth = 0;
            int currentHeight = 0;

            size_t currentWordStart = 0;
            size_t index = 0;
            
            {
                std::string texToTrim = text.asUTF8();
                boost::algorithm::trim( texToTrim );
                text = UTFString(texToTrim);
            }
            
            
            while (currentHeight <= height - spacing && index < text.size())
            {
                const UTFString::unicode_char ch = text.getChar(index);
                if (ch == LEFT_ANGLE)
                {
                    const size_t tagStart = index + 1;
                    const size_t tagEnd = text.find('>', tagStart);
                    if (tagEnd == UTFString::npos)
                        throw std::runtime_error("BookTextParser Error: Tag is not terminated");
                    const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();

                    if (boost::algorithm::starts_with(tag, "IMG"))
                    {
                        const int h = mHeight;
                        parseImage(tag, false);
                        currentHeight += (mHeight - h);
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "FONT"))
                    {
                        parseFont(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "DIV"))
                    {
                        parseDiv(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                    }
                    index = tagEnd;
                }
                else if (ch == NEWLINE)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    currentWordStart = index;
                }
                else if (ch == SPACE)
                {
                    currentWidth += 3; // keep this in sync with the font's SpaceWidth property
                    currentWordStart = index;
                }
                else
                {
                    currentWidth += widthForCharGlyph(ch);
                }

                if (currentWidth > width)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    // add size of the current word
                    UTFString word = text.substr(currentWordStart, index - currentWordStart);
                    for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
                        currentWidth += widthForCharGlyph(it.getCharacter());
                }
                index += UTFString::_utf16_char_length(ch);
            }
            const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
                    ? currentWordStart : index;

            result.push_back(text.substr(0, pageEnd).asUTF8());
            text.erase(0, pageEnd);
        }
        
        std::vector<std::string> nonEmptyPages;
        boost::copy(result | boost::adaptors::filtered(is_not_empty), std::back_inserter(nonEmptyPages));
        return nonEmptyPages;
    }
Esempio n. 11
0
bool TruckHUD::update(float dt, Beam *truck, SceneManager *mSceneMgr, Camera* mCamera, RenderWindow* mWindow, bool visible)
{
	OverlayElement *descl = 0;

	//only update every 300 ms
	if(visible)
	{
		updatetime -= dt;
		if(updatetime <= 0)
		{
			// update now, reset timer
			updatetime = 0.3;
		} else
			// dont update visuals, only count stats
			visible = false;
	}


	if(visible)
	{
		OverlayElement* oTruckname = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Truckname");
		oTruckname->setCaption(truck->getTruckName());
		checkOverflow(oTruckname);

		OverlayElement* oTruckauthor = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Truckauthor");
		std::vector<authorinfo_t> file_authors = truck->getAuthors();
		if(file_authors.size() > 0)
		{
			String author_string = String("");
			for(unsigned int i=0;i<file_authors.size();i++)
				author_string += file_authors[i].name + String(" ");
			oTruckauthor->setCaption(_L("Authors: ") + author_string);
		} else
		{
			oTruckauthor->setCaption(_L("(no author information available)"));
		}
		checkOverflow(oTruckauthor);
		std::vector<std::string> desc = truck->getDescription();

		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/DescriptionLine1");
		if(desc.size() > 0)
			descl->setCaption(ANSI_TO_UTF(desc[0]));
		else
			descl->setCaption("");
		checkOverflow(descl);

		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/DescriptionLine2");
		if(desc.size() > 1)
			descl->setCaption(ANSI_TO_UTF(desc[1]));
		else
			descl->setCaption("");
		checkOverflow(descl);

		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/DescriptionLine3");
		if(desc.size() > 2)
			descl->setCaption(ANSI_TO_UTF(desc[2]));
		else
			descl->setCaption("");
		checkOverflow(descl);

		int beamCount = truck->getBeamCount();
		beam_t *beam = truck->getBeams();
		int beambroken = 0;
		float beamstress = 0;
		int beamdeformed = 0;
		float average_deformation = 0;
		float current_deformation = 0;
		float mass = truck->getTotalMass();

		for(int i=0; i<beamCount; i++, beam++)
		{
			if(beam->broken != 0)
				beambroken++;
			beamstress += beam->stress;
			current_deformation = fabs(beam->L-beam->refL);
			if (fabs(current_deformation) > 0.0001f && beam->type != BEAM_HYDRO && beam->type != BEAM_INVISIBLE_HYDRO) beamdeformed++;
			average_deformation += current_deformation;
		}

		wchar_t beamcountstr[256];
		swprintf(beamcountstr, 256, L"%d", beamCount);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamTotal");
		descl->setCaption(_L("beam count: ") + UTFString(beamcountstr));
		checkOverflow(descl);

		wchar_t beambrokenstr[256];
		swprintf(beambrokenstr, 256, L"%0.2f", ((float)beambroken/(float)beamCount)*100);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamBroken");
		descl->setCaption(_L("broken: ") + TOUTFSTRING(beambroken) + U(" (") + UTFString(beambrokenstr) + U("%)"));
		checkOverflow(descl);

		wchar_t beamhealthstr[256];
		float health = ((float)beambroken/(float)beamCount) * 10 + ((float)beamdeformed/(float)beamCount);
		if(health<1)
		{
			swprintf(beamhealthstr, 256, L"%0.2f", (1-health)*100);
			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamHealth");
			descl->setCaption(_L("health: ") + UTFString(beamhealthstr) + U("%"));
			checkOverflow(descl);
			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamHealth");
			descl->setColour(ColourValue(0.6,0.8,0.4,1));
			checkOverflow(descl);
		}else if(health>1)
		{
			health = ((float)beambroken/(float)beamCount) * 3;
			if(health>1)
				health=1;
			swprintf(beamhealthstr, 256, L"%0.2f", (health)*100);
			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamHealth");
			descl->setCaption(_L("destruction: ") + UTFString(beamhealthstr) + U("%"));
			checkOverflow(descl);
			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamHealth");
			descl->setColour(ColourValue(0.8,0.4,0.4,1));
			checkOverflow(descl);
		}
		wchar_t beamdeformedstr[256];
		swprintf(beamdeformedstr, 256, L"%0.2f", ((float)beamdeformed/(float)beamCount)*100);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/BeamDeformed");
		descl->setCaption(_L("deformed: ") + TOUTFSTRING(beamdeformed) + U(" (") + UTFString(beamdeformedstr) + U("%)"));
		checkOverflow(descl);

		wchar_t beamavdeformedstr[256];
		swprintf(beamavdeformedstr, 256, L"%0.4f", ((float)average_deformation/(float)beamCount));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageBeamDeformation");
		descl->setCaption(_L("average deformation: ") + UTFString(beamavdeformedstr));
		checkOverflow(descl);

		wchar_t beamstressstr[256];
		swprintf(beamstressstr, 256, L"%+08.0f", 1-(float)beamstress/(float)beamCount);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageBeamStress");
		descl->setCaption(_L("average stress: ") + UTFString(beamstressstr));
		checkOverflow(descl);

		int nodeCount = truck->getNodeCount();
		int wcount =  truck->getWheelNodeCount();
		wchar_t nodecountstr[256];
		swprintf(nodecountstr, 256, L"%d (wheels: %d)", nodeCount, wcount);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/NodeCount");
		descl->setCaption(_L("node count: ") + UTFString(nodecountstr));
		checkOverflow(descl);

		wchar_t truckmassstr[256];
		UTFString massstr = _L("current mass:");
		swprintf(truckmassstr, 256, L"%ls %8.2f kg (%.2f tons)", massstr.asWStr_c_str(), mass, mass/1000);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/TruckWeight");
		descl->setCaption(UTFString(truckmassstr));
		checkOverflow(descl);

		wchar_t geesstr[256];
		Vector3 gees = truck->getGForces();
		UTFString tmp = _L("Gees: Vertical %1.2fg // Saggital %1.2fg // Lateral %1.2fg");
		swprintf(geesstr, 256, tmp.asWStr_c_str(), gees.x, gees.y, gees.z);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Gees");
		descl->setCaption(UTFString(geesstr));
		checkOverflow(descl);

		//maxGees
		if(truck->driveable == TRUCK || truck->driveable == AIRPLANE || truck->driveable == BOAT)
		{
			if(gees.x > maxPosVerG[truck->driveable])
				maxPosVerG[truck->driveable] = gees.x;
			if(gees.x < maxNegVerG[truck->driveable])
				maxNegVerG[truck->driveable] = gees.x;

			if(gees.y > maxPosSagG[truck->driveable])
				maxPosSagG[truck->driveable] = gees.y;
			if(gees.y < maxNegSagG[truck->driveable])
				maxNegSagG[truck->driveable] = gees.y;

			if(gees.z > maxPosLatG[truck->driveable])
				maxPosLatG[truck->driveable] = gees.z;
			if(gees.z < maxNegLatG[truck->driveable])
				maxNegLatG[truck->driveable] = gees.z;

			tmp = _L("maxG: V %1.2fg %1.2fg // S %1.2fg %1.2fg // L %1.2fg %1.2fg");
			swprintf(geesstr, 256, tmp.asWStr_c_str(), 
					maxPosVerG[truck->driveable], 
					maxNegVerG[truck->driveable], 
					maxPosSagG[truck->driveable], 
					maxNegSagG[truck->driveable], 
					maxPosLatG[truck->driveable], 
					maxNegLatG[truck->driveable]
				);

			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/Gees2");
			descl->setCaption(UTFString(geesstr));
			checkOverflow(descl);
		}
	}

	Vector3 hdir = Vector3::ZERO;
	if(truck->cameranodepos[0]>=0)
		hdir = truck->nodes[truck->cameranodepos[0]].RelPosition-truck->nodes[truck->cameranodedir[0]].RelPosition;
	hdir.normalise();
	float g_along_hdir=hdir.dotProduct(truck->ffforce/10000.0);

	//LOG("ffforce: " + TOSTRING(truck->ffforce.x) + ", " + TOSTRING(truck->ffforce.y) + ", " + TOSTRING(truck->ffforce.z) + " / direction: " + TOSTRING(hdir.x) + ", " + TOSTRING(hdir.y) + ", " + TOSTRING(hdir.z));


	// TODO: FIX THIS!
	//char rpmstring[256];
	//sprintf(rpmstring, "current GForces: %2.2f", g_along_hdir);
	//OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM")->setCaption(rpmstring);

	// always update these statistics, also if not visible!
	UTFString rpmsstr = _L("current RPM:");
	if(truck->driveable == TRUCK && truck->engine)
	{
		wchar_t rpmstring[256];
		UTFString rpmsstr = _L("current RPM:");
		swprintf(rpmstring, 256, L"%ls %.0f / %.0f", rpmsstr.asWStr_c_str(), truck->engine->getRPM(), truck->engine->getMaxRPM()*1.25);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
		descl->setCaption(UTFString(rpmstring));
		checkOverflow(descl);

	} else if (truck->driveable == AIRPLANE)
	{
		wchar_t rpmstring[256];

		if(truck->aeroengines[0] && truck->aeroengines[1] && truck->aeroengines[2] && truck->aeroengines[3])
			swprintf(rpmstring, 256, L"%ls %.0f / %.0f / %.0f / %.0f", rpmsstr.asWStr_c_str(), truck->aeroengines[0]->getRPM(), truck->aeroengines[1]->getRPM(), truck->aeroengines[2]->getRPM(), truck->aeroengines[3]->getRPM());
		else if(truck->aeroengines[0] && truck->aeroengines[1] && truck->aeroengines[2] && !truck->aeroengines[3])
			swprintf(rpmstring, 256, L"%ls %.0f / %.0f / %.0f", rpmsstr.asWStr_c_str(), truck->aeroengines[0]->getRPM(), truck->aeroengines[1]->getRPM(), truck->aeroengines[2]->getRPM());
		else if(truck->aeroengines[0] && truck->aeroengines[1] && !truck->aeroengines[2] && !truck->aeroengines[3])
			swprintf(rpmstring, 256, L"%ls %.0f / %.0f", rpmsstr.asWStr_c_str(), truck->aeroengines[0]->getRPM(), truck->aeroengines[1]->getRPM());
		else if(truck->aeroengines[0] && !truck->aeroengines[1] && !truck->aeroengines[2] && !truck->aeroengines[3])
			swprintf(rpmstring, 256, L"%ls %.0f", rpmsstr.asWStr_c_str(), truck->aeroengines[0]->getRPM());

		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
		descl->setCaption(UTFString(rpmstring));
		checkOverflow(descl);
	} else
	{
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentRPM");
		descl->setCaption("");
	}

	UTFString cspeedstr = _L("current Speed:");
	UTFString maxspstr = _L("max Speed:");

	if(truck->driveable == TRUCK)
	{
		wchar_t velostring[256];
		float velocityKMH = (truck->WheelSpeed * 3.6);
		if(velocityKMH > maxVelos[truck->driveable])
			maxVelos[truck->driveable] = velocityKMH;
		if(velocityKMH < minVelos[truck->driveable])
			minVelos[truck->driveable] = velocityKMH;

		// round values if zero ==> no flickering +/-
		if (fabs(velocityKMH) < 1)
			velocityKMH = 0;
		float velocityMPH = velocityKMH / 1.609;
			swprintf(velostring, 256, L"%ls %+.0f km/h (%+.0f mp/h)", cspeedstr.asWStr_c_str(), ceil(velocityKMH), ceil(velocityMPH));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);

		float velocityMaxMPH = maxVelos[truck->driveable] / 1.609;
		float velocityMinMPH = minVelos[truck->driveable] / 1.609;
		swprintf(velostring, 256, L"%ls %+.0fkmh/%+.0fmph, min: %+.0fkmh/%+.0fmph", maxspstr.asWStr_c_str(), ceil(maxVelos[truck->driveable]), ceil(velocityMaxMPH), ceil(minVelos[truck->driveable]), ceil(velocityMinMPH));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity");
		descl->setCaption("");
	}
		else if(truck->driveable == AIRPLANE)
	{
		wchar_t velostring[256];
		float velocity = truck->nodes[0].Velocity.length()*1.9438;

		if(velocity > maxVelos[truck->driveable])
			maxVelos[truck->driveable] = velocity;
		if(velocity < minVelos[truck->driveable])
			minVelos[truck->driveable] = velocity;

		// round values if zero ==> no flickering +/-
		if (fabs(velocity) < 1)
			velocity = 0;
		swprintf(velostring, 256, L"%ls %+.0f kn", cspeedstr.asWStr_c_str(), ceil(velocity));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);
		swprintf(velostring, 256, L"%ls %+.0fkn, min: %+.0f kn", maxspstr.asWStr_c_str(), ceil(maxVelos[truck->driveable]), ceil(minVelos[truck->driveable]));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);

		float alt = truck->nodes[0].AbsPosition.y*1.1811;
		UTFString altstr = _L("Altitude:");
		swprintf(velostring, 256, L"%ls %+.0f m", altstr.asWStr_c_str(), ceil(alt));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity");
		descl->setCaption(velostring);
		checkOverflow(descl);
	}
		else if(truck->driveable == BOAT)
	{
		wchar_t velostring[256];
		Vector3 hdir=truck->nodes[truck->cameranodepos[0]].RelPosition-truck->nodes[truck->cameranodedir[0]].RelPosition;
		hdir.normalise();
		float velocity=hdir.dotProduct(truck->nodes[truck->cameranodepos[0]].Velocity)*1.9438;

		if(velocity > maxVelos[truck->driveable])
			maxVelos[truck->driveable] = velocity;
		if(velocity < minVelos[truck->driveable])
			minVelos[truck->driveable] = velocity;

		swprintf(velostring, 256, L"%ls %+.0f kn", cspeedstr.asWStr_c_str(),ceil(velocity));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);

		swprintf(velostring, 256, L"%ls %+.0fkn, min: %+.0f kn", maxspstr.asWStr_c_str(),ceil(maxVelos[truck->driveable]), ceil(minVelos[truck->driveable]));
		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity");
		descl->setCaption(UTFString(velostring));
		checkOverflow(descl);

		descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity");
		descl->setCaption("");
	}
		else if(truck->driveable == MACHINE)
	{
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/MaxVelocity")->setCaption("");
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CurrentVelocity")->setCaption("");
		OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/AverageVelocity")->setCaption("");
	}
	OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/TimeStats")->setCaption("");

	if(visible)
	{
		// update commands

		//clear them first
		for(int i=1;i<=COMMANDS_VISIBLE;i++)
		{
			char commandOverlayID[256];
			sprintf(commandOverlayID, "tracks/TruckInfoBox/Command%d", i); // no wchar needed
			descl = OverlayManager::getSingleton().getOverlayElement(commandOverlayID);
			descl->setCaption(string(""));
		}

		int j = 0;
		for(int i=1,j=0;i<MAX_COMMANDS && j<COMMANDS_VISIBLE;i+=2)
		{
			if (truck->commandkey[i].description.size() == 0)
				continue;

			j++;
			char commandID[256];
			String keyStr="";

			sprintf(commandID, "COMMANDS_%02d", i);
			int eventID = INPUTENGINE.resolveEventName(String(commandID));
			String keya = INPUTENGINE.getEventCommand(eventID);
			sprintf(commandID, "COMMANDS_%02d", i+1);
			eventID = INPUTENGINE.resolveEventName(String(commandID));
			String keyb = INPUTENGINE.getEventCommand(eventID);
			//cut off expl
			if(keya.size()>6 && keya.substr(0,5) == "EXPL+") keya = keya.substr(5);
			if(keyb.size()>6 && keyb.substr(0,5) == "EXPL+") keyb = keyb.substr(5);

			keyStr = keya + "/" + keyb;

			char commandOverlayID[256];
			sprintf(commandOverlayID, "tracks/TruckInfoBox/Command%d", j);
			descl = OverlayManager::getSingleton().getOverlayElement(commandOverlayID);
			descl->setCaption(keyStr + ": " + truck->commandkey[i].description);
			checkOverflow(descl);
		}

		// hide command section title if no commands
		if(j == 0)
		{
			OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CommandsTitleLabel")->setCaption("");
		} else
		{
			descl = OverlayManager::getSingleton().getOverlayElement("tracks/TruckInfoBox/CommandsTitleLabel");
			descl->setCaption(_L("Commands:"));
			checkOverflow(descl);
		}


	}
	return true;
}