summaryrefslogtreecommitdiff
path: root/src/gui/serverdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/serverdialog.cpp')
-rw-r--r--src/gui/serverdialog.cpp284
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;