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 }
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)"); }
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(); } } } }
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; } }
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); }
/* 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; }
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; }
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; }
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; }