WorldSelectDialog::WorldSelectDialog(Worlds worlds): Window(_("Select World")) { mWorldListModel = new WorldListModel(worlds); mWorldList = new ListBox(mWorldListModel); ScrollArea *worldsScroll = new ScrollArea(mWorldList); mChangeLoginButton = new Button(_("Change Login"), "login", this); mChooseWorld = new Button(_("Choose World"), "world", this); worldsScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); place(0, 0, worldsScroll, 3, 5).setPadding(2); place(1, 5, mChangeLoginButton); place(2, 5, mChooseWorld); // Make sure the list has enough height getLayout().setRowHeight(0, 60); reflowLayout(0, 0); if (worlds.size() == 0) // Disable Ok button mChooseWorld->setEnabled(false); else // Select first server mWorldList->setSelected(0); addKeyListener(this); center(); setVisible(true); mChooseWorld->requestFocus(); }
WorldSelectDialog::WorldSelectDialog(Worlds worlds) : // TRANSLATORS: world select dialog name Window(_("Select World"), Modal_false, nullptr, "world.xml"), ActionListener(), KeyListener(), mWorldListModel(new WorldListModel(worlds)), mWorldList(new ListBox(this, mWorldListModel, "")), // TRANSLATORS: world dialog button mChangeLoginButton(new Button(this, _("Change Login"), "login", this)), // TRANSLATORS: world dialog button mChooseWorld(new Button(this, _("Choose World"), "world", this)) { mWorldList->postInit(); ScrollArea *const worldsScroll = new ScrollArea(this, mWorldList, getOptionBool("showbackground"), "world_background.xml"); worldsScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); place(0, 0, worldsScroll, 3, 5).setPadding(2); place(1, 5, mChangeLoginButton); place(2, 5, mChooseWorld); // Make sure the list has enough height getLayout().setRowHeight(0, 60); reflowLayout(0, 0); if (worlds.empty()) { // Disable Ok button mChooseWorld->setEnabled(false); } else { // Select first server mWorldList->setSelected(0); } addKeyListener(this); center(); }
int Client::exec() { int lastTickTime = tick_time; SDL_Event event; while (mState != STATE_EXIT) { if (mGame) { // Let the game handle the events while it is active mGame->handleInput(); } else { // Handle SDL events while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: mState = STATE_EXIT; break; case SDL_KEYDOWN: break; case SDL_VIDEORESIZE: handleVideoResize(event.resize.w, event.resize.h); break; } guiInput->pushInput(event); } } if (Net::getGeneralHandler()) Net::getGeneralHandler()->flushNetwork(); while (get_elapsed_time(lastTickTime) > 0) { gui->logic(); if (mGame) mGame->logic(); sound.logic(); ++lastTickTime; } // This is done because at some point tick_time will wrap. lastTickTime = tick_time; // Update the screen when application is active, delay otherwise. if (isActive()) { frame_count++; gui->draw(); graphics->updateScreen(); } else { SDL_Delay(10); } if (mLimitFps) SDL_framerateDelay(&mFpsManager); // TODO: Add connect timeouts if (mState == STATE_CONNECT_GAME && Net::getGameHandler()->isConnected()) { Net::getLoginHandler()->disconnect(); } else if (mState == STATE_CONNECT_SERVER && mOldState == STATE_CONNECT_SERVER && Net::getLoginHandler()->isConnected()) { mState = STATE_LOGIN; } else if (mState == STATE_WORLD_SELECT && mOldState == STATE_UPDATE) { if (Net::getLoginHandler()->getWorlds().size() < 2) { mState = STATE_LOGIN; } } else if (mOldState == STATE_START || (mOldState == STATE_GAME && mState != STATE_GAME)) { gcn::Container *top = static_cast<gcn::Container*>(gui->getTop()); mDesktop = new Desktop; top->add(mDesktop); mSetupButton = new Button("", "Setup", this); mSetupButton->setButtonPopupText(_("Setup")); mSetupButton->setButtonIcon("button-icon-setup.png"); mSetupButton->setPosition(top->getWidth() - mSetupButton->getWidth() - 3, 3); top->add(mSetupButton); mDesktop->setSize(graphics->getWidth(), graphics->getHeight()); } if (mState == STATE_SWITCH_LOGIN && mOldState == STATE_GAME) { Net::getGameHandler()->disconnect(); } if (mState != mOldState) { { Event event(Event::StateChange); event.setInt("oldState", mOldState); event.setInt("newState", mState); event.trigger(Event::ClientChannel); } if (mOldState == STATE_GAME) { delete mGame; mGame = 0; } mOldState = mState; // Get rid of the dialog of the previous state if (mCurrentDialog) { delete mCurrentDialog; mCurrentDialog = NULL; } // State has changed, while the quitDialog was active, it might // not be correct anymore if (mQuitDialog) mQuitDialog->scheduleDelete(); switch (mState) { case STATE_CHOOSE_SERVER: logger->log("State: CHOOSE SERVER"); // If a server was passed on the command line, or branding // provides a server and a blank server list, we skip the // server selection dialog. if ((!mOptions.serverName.empty() && mOptions.serverPort) || (!branding.getValue("defaultServer","").empty() && branding.getValue("defaultPort",0) && branding.getValue("onlineServerList", "").empty())) { mState = STATE_CONNECT_SERVER; // Reset options so that cancelling or connect // timeout will show the server dialog. mOptions.serverName.clear(); mOptions.serverPort = 0; } else { // Don't allow an alpha opacity // lower than the default value Theme::instance()->setMinimumOpacity(0.8f); mCurrentDialog = new ServerDialog(&mCurrentServer, mConfigDir); } break; case STATE_CONNECT_SERVER: logger->log("State: CONNECT SERVER"); Net::connectToServer(mCurrentServer); mCurrentDialog = new ConnectionDialog( _("Connecting to server"), STATE_SWITCH_SERVER); break; case STATE_LOGIN: logger->log("State: LOGIN"); // Don't allow an alpha opacity // lower than the default value Theme::instance()->setMinimumOpacity(0.8f); if (mOptions.username.empty() || mOptions.password.empty()) { mCurrentDialog = new LoginDialog(&loginData); } else { mState = STATE_LOGIN_ATTEMPT; // Clear the password so that when login fails, the // dialog will show up next time. mOptions.password.clear(); } break; case STATE_LOGIN_ATTEMPT: logger->log("State: LOGIN ATTEMPT"); accountLogin(&loginData); mCurrentDialog = new ConnectionDialog( _("Logging in"), STATE_SWITCH_SERVER); break; case STATE_WORLD_SELECT: logger->log("State: WORLD SELECT"); { Worlds worlds = Net::getLoginHandler()->getWorlds(); if (worlds.size() == 0) { // Trust that the netcode knows what it's doing mState = STATE_UPDATE; } else if (worlds.size() == 1) { Net::getLoginHandler()->chooseServer(0); mState = STATE_UPDATE; } else { mCurrentDialog = new WorldSelectDialog(worlds); if (mOptions.chooseDefault) { ((WorldSelectDialog*) mCurrentDialog)->action( gcn::ActionEvent(NULL, "ok")); } } } break; case STATE_WORLD_SELECT_ATTEMPT: logger->log("State: WORLD SELECT ATTEMPT"); mCurrentDialog = new ConnectionDialog( _("Entering game world"), STATE_WORLD_SELECT); break; case STATE_UPDATE: // Determine which source to use for the update host if (!mOptions.updateHost.empty()) mUpdateHost = mOptions.updateHost; else mUpdateHost = loginData.updateHost; initUpdatesDir(); if (mOptions.skipUpdate) { mState = STATE_LOAD_DATA; } else { logger->log("State: UPDATE"); mCurrentDialog = new UpdaterWindow(mUpdateHost, mLocalDataDir + "/" + mUpdatesDir,mOptions.dataPath.empty()); } break; case STATE_LOAD_DATA: logger->log("State: LOAD DATA"); // If another data path has been set, // we don't load any other files... if (mOptions.dataPath.empty()) { // Add customdata directory ResourceManager::getInstance()->searchAndAddArchives( "customdata/", "zip", false); } // Read default paths file 'data/paths.xml' paths.init("paths.xml", true); Event::trigger(Event::ClientChannel, Event::LoadingDatabases); // Load XML databases CharDB::load(); hairDB.load(); switch (Net::getNetworkType()) { case ServerInfo::TMWATHENA: itemDb = new TmwAthena::TaItemDB; break; case ServerInfo::MANASERV: itemDb = new ManaServ::ManaServItemDB; break; default: // Nothing itemDb = 0; break; } if (!itemDb || !itemDb->isLoaded()) { // Warn and return to login screen errorMessage = _("This server is missing needed world data. " "Please contact the administrator(s)."); showOkDialog(_("ItemDB: Error while loading " ITEMS_DB_FILE "!"), errorMessage, STATE_CHOOSE_SERVER); break; } MonsterDB::load(); SpecialDB::load(); NPCDB::load(); EmoteDB::load(); StatusEffect::load(); Units::loadUnits(); ActorSprite::load(); mDesktop->reloadWallpaper(); mState = STATE_GET_CHARACTERS; break; case STATE_GET_CHARACTERS: logger->log("State: GET CHARACTERS"); Net::getCharHandler()->requestCharacters(); mCurrentDialog = new ConnectionDialog( _("Requesting characters"), STATE_SWITCH_SERVER); break; case STATE_CHAR_SELECT: logger->log("State: CHAR SELECT"); // Don't allow an alpha opacity // lower than the default value Theme::instance()->setMinimumOpacity(0.8f); mCurrentDialog = new CharSelectDialog(&loginData); if (!((CharSelectDialog*) mCurrentDialog)->selectByName( mOptions.character, CharSelectDialog::Choose)) { ((CharSelectDialog*) mCurrentDialog)->selectByName( config.getStringValue("lastCharacter"), mOptions.chooseDefault ? CharSelectDialog::Choose : CharSelectDialog::Focus); } // Choosing character on the command line should work only // once, clear it so that 'switch character' works. mOptions.character.clear(); break; case STATE_CONNECT_GAME: logger->log("State: CONNECT GAME"); Net::getGameHandler()->connect(); mCurrentDialog = new ConnectionDialog( _("Connecting to the game server"), Net::getNetworkType() == ServerInfo::TMWATHENA ? STATE_CHOOSE_SERVER : STATE_SWITCH_CHARACTER); break; case STATE_CHANGE_MAP: logger->log("State: CHANGE_MAP"); Net::getGameHandler()->connect(); mCurrentDialog = new ConnectionDialog( _("Changing game servers"), STATE_SWITCH_CHARACTER); break; case STATE_GAME: logger->log("Memorizing selected character %s", local_player->getName().c_str()); config.setValue("lastCharacter", local_player->getName()); // Fade out logon-music here too to give the desired effect // of "flowing" into the game. sound.fadeOutMusic(1000); // Allow any alpha opacity Theme::instance()->setMinimumOpacity(-1.0f); delete mSetupButton; delete mDesktop; mSetupButton = NULL; mDesktop = NULL; mCurrentDialog = NULL; logger->log("State: GAME"); mGame = new Game; break; case STATE_LOGIN_ERROR: logger->log("State: LOGIN ERROR"); showErrorDialog(errorMessage, STATE_LOGIN); break; case STATE_ACCOUNTCHANGE_ERROR: logger->log("State: ACCOUNT CHANGE ERROR"); showErrorDialog(errorMessage, STATE_CHAR_SELECT); break; case STATE_REGISTER_PREP: logger->log("State: REGISTER_PREP"); Net::getLoginHandler()->getRegistrationDetails(); mCurrentDialog = new ConnectionDialog( _("Requesting registration details"), STATE_LOGIN); break; case STATE_REGISTER: logger->log("State: REGISTER"); mCurrentDialog = new RegisterDialog(&loginData); break; case STATE_REGISTER_ATTEMPT: logger->log("Username is %s", loginData.username.c_str()); Net::getLoginHandler()->registerAccount(&loginData); loginData.password = ""; break; case STATE_CHANGEPASSWORD: logger->log("State: CHANGE PASSWORD"); mCurrentDialog = new ChangePasswordDialog(&loginData); break; case STATE_CHANGEPASSWORD_ATTEMPT: logger->log("State: CHANGE PASSWORD ATTEMPT"); Net::getLoginHandler()->changePassword(loginData.username, loginData.password, loginData.newPassword); break; case STATE_CHANGEPASSWORD_SUCCESS: logger->log("State: CHANGE PASSWORD SUCCESS"); showOkDialog(_("Password Change"), _("Password changed successfully!"), STATE_CHAR_SELECT); loginData.password = ""; loginData.newPassword = ""; break; case STATE_CHANGEEMAIL: logger->log("State: CHANGE EMAIL"); mCurrentDialog = new ChangeEmailDialog(&loginData); break; case STATE_CHANGEEMAIL_ATTEMPT: logger->log("State: CHANGE EMAIL ATTEMPT"); Net::getLoginHandler()->changeEmail(loginData.email); break; case STATE_CHANGEEMAIL_SUCCESS: logger->log("State: CHANGE EMAIL SUCCESS"); showOkDialog(_("Email Change"), _("Email changed successfully!"), STATE_CHAR_SELECT); break; case STATE_UNREGISTER: logger->log("State: UNREGISTER"); mCurrentDialog = new UnRegisterDialog(&loginData); break; case STATE_UNREGISTER_ATTEMPT: logger->log("State: UNREGISTER ATTEMPT"); Net::getLoginHandler()->unregisterAccount( loginData.username, loginData.password); break; case STATE_UNREGISTER_SUCCESS: logger->log("State: UNREGISTER SUCCESS"); Net::getLoginHandler()->disconnect(); showOkDialog(_("Unregister Successful"), _("Farewell, come back any time..."), STATE_CHOOSE_SERVER); loginData.clear(); break; case STATE_SWITCH_SERVER: logger->log("State: SWITCH SERVER"); Net::getLoginHandler()->disconnect(); Net::getGameHandler()->disconnect(); mState = STATE_CHOOSE_SERVER; break; case STATE_SWITCH_LOGIN: logger->log("State: SWITCH LOGIN"); Net::getLoginHandler()->disconnect(); mState = STATE_CONNECT_SERVER; break; case STATE_SWITCH_CHARACTER: logger->log("State: SWITCH CHARACTER"); // Done with game Net::getGameHandler()->disconnect(); mState = STATE_GET_CHARACTERS; break; case STATE_LOGOUT_ATTEMPT: logger->log("State: LOGOUT ATTEMPT"); // TODO break; case STATE_WAIT: logger->log("State: WAIT"); break; case STATE_EXIT: logger->log("State: EXIT"); Net::unload(); break; case STATE_FORCE_QUIT: logger->log("State: FORCE QUIT"); if (Net::getGeneralHandler()) Net::getGeneralHandler()->unload(); mState = STATE_EXIT; break; case STATE_ERROR: logger->log("State: ERROR"); logger->log("Error: %s", errorMessage.c_str()); showErrorDialog(errorMessage, STATE_CHOOSE_SERVER); Net::getGameHandler()->disconnect(); break; default: mState = STATE_FORCE_QUIT; break; } } } return 0; }