diff options
Diffstat (limited to 'src/gui/serverdialog.cpp')
-rw-r--r-- | src/gui/serverdialog.cpp | 284 |
1 files changed, 166 insertions, 118 deletions
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index f439420b..e9f76436 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -49,23 +49,17 @@ #define MAX_SERVERLIST 5 -ServerInfo::Type stringToServerType(const std::string &type) +static ServerInfo::Type stringToServerType(const std::string &type) { if (compareStrI(type, "eathena") == 0) - { return ServerInfo::EATHENA; - } else if (compareStrI(type, "manaserv") == 0) - { return ServerInfo::MANASERV; - } - else - { - return ServerInfo::UNKNOWN; - } + + return ServerInfo::UNKNOWN; } -std::string serverTypeToString(ServerInfo::Type type) +static std::string serverTypeToString(ServerInfo::Type type) { switch (type) { @@ -78,6 +72,18 @@ std::string serverTypeToString(ServerInfo::Type type) } } +static unsigned short defaultPortForServerType(ServerInfo::Type type) +{ + switch (type) + { + default: + case ServerInfo::EATHENA: + return 6901; + case ServerInfo::MANASERV: + return 9601; + } +} + ServersListModel::ServersListModel(ServerInfos *servers, ServerDialog *parent): mServers(servers), mParent(parent) @@ -138,33 +144,33 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mServerNameField = new TextField(mServerInfo->hostname); mPortField = new TextField(toString(mServerInfo->port)); - ServerInfo currentServer; - // Add the most used servers from config if they are not in the online list - std::string currentConfig = ""; - for (int i = 0; i <= MAX_SERVERLIST; i++) + // Add the most used servers from config + for (int i = 0; i <= MAX_SERVERLIST; ++i) { - currentServer.clear(); - - currentConfig = "MostUsedServerName" + toString(i); - currentServer.hostname = config.getValue(currentConfig, ""); + const std::string index = toString(i); + const std::string nameKey = "MostUsedServerName" + index; + const std::string typeKey = "MostUsedServerType" + index; + const std::string portKey = "MostUsedServerPort" + index; - currentConfig = "MostUsedServerPort" + toString(i); - currentServer.port = (short) config.getValue(currentConfig, - DEFAULT_PORT); + ServerInfo server; + server.hostname = config.getValue(nameKey, ""); + server.type = stringToServerType(config.getValue(typeKey, "")); - currentConfig = "MostUsedServerType" + toString(i); - currentServer.type = stringToServerType(config - .getValue(currentConfig, "")); + const int defaultPort = defaultPortForServerType(server.type); + server.port = (unsigned short) config.getValue(portKey, defaultPort); - if (!currentServer.hostname.empty() && currentServer.port != 0) + if (server.isValid()) { - mServers.push_back(currentServer); + server.save = true; + mServers.push_back(server); } } mServersListModel = new ServersListModel(&mServers, this); mServersList = new ListBox(mServersListModel); + mServersList->addMouseListener(this); + ScrollArea *usedScroll = new ScrollArea(mServersList); usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); @@ -175,7 +181,8 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mQuitButton = new Button(_("Quit"), "quit", this); mConnectButton = new Button(_("Connect"), "connect", this); - mManualEntryButton = new Button(_("Add Entry"), "addEntry", this); + mManualEntryButton = new Button(_("Custom Server"), "addEntry", this); + mDeleteButton = new Button(_("Delete"), "remove", this); mServerNameField->setActionEventId("connect"); mPortField->setActionEventId("connect"); @@ -184,20 +191,20 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mPortField->addActionListener(this); mManualEntryButton->addActionListener(this); mServersList->addSelectionListener(this); - mServersList->setSelected(0); usedScroll->setVerticalScrollAmount(0); place(0, 0, serverLabel); - place(1, 0, mServerNameField, 3).setPadding(3); + place(1, 0, mServerNameField, 4).setPadding(3); place(0, 1, portLabel); - place(1, 1, mPortField, 3).setPadding(3); + place(1, 1, mPortField, 4).setPadding(3); place(0, 2, typeLabel); - place(1, 2, mTypeField, 3).setPadding(3); - place(0, 3, usedScroll, 4, 5).setPadding(3); - place(0, 8, mDescription, 4); + place(1, 2, mTypeField, 4).setPadding(3); + place(0, 3, usedScroll, 5, 5).setPadding(3); + place(0, 8, mDescription, 5); place(0, 9, mManualEntryButton); - place(2, 9, mQuitButton); - place(3, 9, mConnectButton); + place(1, 9, mDeleteButton); + place(3, 9, mQuitButton); + place(4, 9, mConnectButton); // Make sure the list has enough height getLayout().setRowHeight(3, 80); @@ -208,6 +215,7 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): center(); setFieldsReadOnly(true); + mServersList->setSelected(0); // Do this after for the Delete button setVisible(true); if (mServerNameField->getText().empty()) @@ -247,7 +255,8 @@ void ServerDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "connect") { // Check login - if (mServerNameField->getText().empty() || mPortField->getText().empty()) + if (mServerNameField->getText().empty() + || mPortField->getText().empty()) { OkDialog *dlg = new OkDialog(_("Error"), _("Please type both the address and the port of a server.")); @@ -261,7 +270,6 @@ void ServerDialog::action(const gcn::ActionEvent &event) // First, look if the entry is a new one. ServerInfo currentServer; - ServerInfo tempServer; currentServer.hostname = mServerNameField->getText(); currentServer.port = (short) atoi(mPortField->getText().c_str()); switch (mTypeField->getSelected()) @@ -284,21 +292,27 @@ void ServerDialog::action(const gcn::ActionEvent &event) serverTypeToString(currentServer.type)); // now add the rest of the list... - std::string currentConfig = ""; int configCount = 1; - for (int i = 0; i < mServersListModel->getNumberOfElements(); i++) + for (int i = 0; i < mServersListModel->getNumberOfElements(); ++i) { - tempServer = mServersListModel->getServer(i); + const ServerInfo server = mServersListModel->getServer(i); + + // Only save servers that were loaded from settings + if (!server.save) + continue; // ensure, that our server will not be added twice - if (tempServer != currentServer) + if (server != currentServer) { - currentConfig = "MostUsedServerName" + toString(configCount); - config.setValue(currentConfig, toString(tempServer.hostname)); - currentConfig = "MostUsedServerPort" + toString(configCount); - config.setValue(currentConfig, toString(tempServer.port)); - currentConfig = "MostUsedServerType" + toString(configCount); - config.setValue(currentConfig, serverTypeToString(tempServer.type)); + const std::string index = toString(configCount); + const std::string nameKey = "MostUsedServerName" + index; + const std::string typeKey = "MostUsedServerType" + index; + const std::string portKey = "MostUsedServerPort" + index; + + config.setValue(nameKey, toString(server.hostname)); + config.setValue(typeKey, serverTypeToString(server.type)); + config.setValue(portKey, toString(server.port)); + configCount++; } @@ -321,6 +335,12 @@ void ServerDialog::action(const gcn::ActionEvent &event) { setFieldsReadOnly(false); } + else if (event.getId() == "remove") + { + int index = mServersList->getSelected(); + mServersList->setSelected(0); + mServersListModel->remove(index); + } } void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent) @@ -337,11 +357,14 @@ void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent) } } -void ServerDialog::valueChanged(const gcn::SelectionEvent &event) +void ServerDialog::valueChanged(const gcn::SelectionEvent &) { const int index = mServersList->getSelected(); if (index == -1) + { + mDeleteButton->setEnabled(false); return; + } // Update the server and post fields according to the new selection const ServerInfo myServer = mServersListModel->getServer(index); @@ -350,16 +373,27 @@ void ServerDialog::valueChanged(const gcn::SelectionEvent &event) mPortField->setText(toString(myServer.port)); switch (myServer.type) { - case ServerInfo::UNKNOWN: - mTypeField->setSelected(2); - break; case ServerInfo::EATHENA: + case ServerInfo::UNKNOWN: mTypeField->setSelected(0); break; case ServerInfo::MANASERV: mTypeField->setSelected(1); + break; } setFieldsReadOnly(true); + + mDeleteButton->setEnabled(myServer.save); +} + +void ServerDialog::mouseClicked(gcn::MouseEvent &mouseEvent) +{ + if (mouseEvent.getClickCount() == 2 && + mouseEvent.getSource() == mServersList) + { + action(gcn::ActionEvent(mConnectButton, + mConnectButton->getActionEventId())); + } } void ServerDialog::logic() @@ -391,39 +425,38 @@ void ServerDialog::logic() Window::logic(); } -void ServerDialog::setFieldsReadOnly(const bool readOnly) +void ServerDialog::setFieldsReadOnly(bool readOnly) { - if (readOnly) + if (!readOnly) { - mServerNameField->setEnabled(false); - mPortField->setEnabled(false); - mManualEntryButton->setVisible(true); - mDescription->setVisible(true); - } - else - { - mManualEntryButton->setVisible(false); - - mDescription->setVisible(false); mDescription->setCaption(std::string()); mServersList->setSelected(-1); mServerNameField->setText(std::string()); - mServerNameField->setEnabled(true); - - mPortField->setText(toString(DEFAULT_PORT)); - mPortField->setEnabled(true); + mPortField->setText(std::string()); mServerNameField->requestFocus(); } + + mManualEntryButton->setEnabled(readOnly); + mDeleteButton->setEnabled(false); + mDescription->setVisible(readOnly); + + mServerNameField->setEnabled(!readOnly); + mPortField->setEnabled(!readOnly); + mTypeField->setEnabled(!readOnly); } void ServerDialog::downloadServerList() { - // try to load the configuration value for the onlineServerList - std::string listFile = config.getValue("onlineServerList", "void"); - // if there is no entry, try to load the file from the default updatehost - if (listFile == "void") + // Try to load the configuration value for the onlineServerList + std::string listFile = branding.getValue("onlineServerList", std::string()); + + if (listFile.empty()) + listFile = config.getValue("onlineServerList", std::string()); + + // Fall back to manasource.org when neither branding nor config set it + if (listFile.empty()) listFile = "http://manasource.org/serverlist.xml"; mDownload = new Net::Download(this, listFile, &downloadUpdate); @@ -433,65 +466,74 @@ void ServerDialog::downloadServerList() void ServerDialog::loadServers() { - ServerInfo currentServer; + XML::Document doc(mDir + "/serverlist.xml", false); + xmlNodePtr rootNode = doc.rootNode(); - xmlDocPtr doc = xmlReadFile((mDir + "/serverlist.xml").c_str(), NULL, 0); + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "serverlist")) + { + logger->log("Error loading server list!"); + return; + } - if (doc != NULL) + int version = XML::getProperty(rootNode, "version", 0); + if (version != 1) { - xmlNodePtr rootNode = xmlDocGetRootElement(doc); - int version = XML::getProperty(rootNode, "version", 3); + logger->log("Error: unsupported online server list version: %d", + version); + return; + } + + for_each_xml_child_node(serverNode, rootNode) + { + if (!xmlStrEqual(serverNode->name, BAD_CAST "server")) + continue; + + ServerInfo server; + + std::string type = XML::getProperty(serverNode, "type", "unknown"); - if (version != 1) + server.type = stringToServerType(type); + server.name = XML::getProperty(serverNode, "name", std::string()); + + if (server.type == ServerInfo::UNKNOWN) { - logger->log("Online server list has wrong version"); - return; + logger->log("Unknown server type: %s", type.c_str()); + continue; } - for_each_xml_child_node(server, rootNode) + for_each_xml_child_node(subNode, serverNode) { - if (xmlStrEqual(server->name, BAD_CAST "server")) - { - std::string type = XML::getProperty(server, "type", "unknown"); - - currentServer.clear(); - currentServer.name = XML::getProperty(server, "name", std::string()); + if (!xmlStrEqual(subNode->name, BAD_CAST "connection")) + continue; - for_each_xml_child_node(subnode, server) - { - if (xmlStrEqual(subnode->name, BAD_CAST "connection")) - { - currentServer.type = stringToServerType(type); - currentServer.hostname = XML::getProperty(subnode, "hostname", std::string()); - currentServer.port = XML::getProperty(subnode, "port", DEFAULT_PORT); - } - } + server.hostname = XML::getProperty(subNode, "hostname", ""); + server.port = XML::getProperty(subNode, "port", 0); + if (server.port == 0) + { + // If no port is given, use the default for the given type + server.port = defaultPortForServerType(server.type); + } + } - MutexLocker lock(&mMutex); - // add the server to the local list (if it's not already present) - ServerInfos::iterator it; - bool found = false; - for (it = mServers.begin(); it != mServers.end(); it++) - { - if ((*it) == currentServer) - { - (*it).name = currentServer.name; - found = true; - break; - } - } - - if (!found) - mServers.push_back(currentServer); + MutexLocker lock(&mMutex); + // Add the server to the local list if it's not already present + ServerInfos::iterator it; + bool found = false; + for (it = mServers.begin(); it != mServers.end(); it++) + { + if ((*it) == server) + { + // Use the name listed in the server list + (*it).name = server.name; + found = true; + break; } } - xmlFreeDoc(doc); + if (!found) + mServers.push_back(server); } - - MutexLocker lock(&mMutex); - mDownloadStatus = DOWNLOADING_COMPLETE; } int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, @@ -518,9 +560,12 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, { float progress = (float) remaining / total; - if (progress != progress) progress = 0.0f; // check for NaN - if (progress < 0.0f) progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway. - if (progress > 1.0f) progress = 1.0f; + if (progress != progress) + progress = 0.0f; // check for NaN + else if (progress < 0.0f) + progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway. + else if (progress > 1.0f) + progress = 1.0f; MutexLocker lock(&sd->mMutex); sd->mDownloadStatus = DOWNLOADING_IN_PROGRESS; @@ -530,6 +575,9 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, if (finished) { sd->loadServers(); + + MutexLocker lock(&sd->mMutex); + sd->mDownloadStatus = DOWNLOADING_COMPLETE; } return 0; |