summaryrefslogtreecommitdiffstats
path: root/atlantik/libatlantikclient
diff options
context:
space:
mode:
Diffstat (limited to 'atlantik/libatlantikclient')
-rw-r--r--atlantik/libatlantikclient/Makefile.am10
-rw-r--r--atlantik/libatlantikclient/atlantik_network.cpp928
-rw-r--r--atlantik/libatlantikclient/atlantik_network.h155
-rw-r--r--atlantik/libatlantikclient/monopdprotocol.cpp80
-rw-r--r--atlantik/libatlantikclient/monopdprotocol.h58
5 files changed, 1231 insertions, 0 deletions
diff --git a/atlantik/libatlantikclient/Makefile.am b/atlantik/libatlantikclient/Makefile.am
new file mode 100644
index 00000000..92c79eb2
--- /dev/null
+++ b/atlantik/libatlantikclient/Makefile.am
@@ -0,0 +1,10 @@
+INCLUDES = -I$(top_srcdir)/atlantik/libatlantic $(all_includes)
+lib_LTLIBRARIES = libatlantikclient.la
+libatlantikclient_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined -version-info 3:0:2
+libatlantikclient_la_LIBADD = ../libatlantic/libatlantic.la $(LIB_KIO)
+
+libatlantikclient_la_SOURCES = atlantik_network.cpp monopdprotocol.cpp
+
+noinst_HEADERS = atlantik_network.h monopdprotocol.h
+
+METASOURCES = AUTO
diff --git a/atlantik/libatlantikclient/atlantik_network.cpp b/atlantik/libatlantikclient/atlantik_network.cpp
new file mode 100644
index 00000000..7b1926d3
--- /dev/null
+++ b/atlantik/libatlantikclient/atlantik_network.cpp
@@ -0,0 +1,928 @@
+// Copyright (c) 2002-2004 Rob Kaper <cap@capsi.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; see the file COPYING.LIB. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <iostream>
+
+#include <qdom.h>
+#include <qtextcodec.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <atlantic_core.h>
+#include <auction.h>
+#include <configoption.h>
+#include <estate.h>
+#include <estategroup.h>
+#include <game.h>
+#include <player.h>
+#include <trade.h>
+
+#include "atlantik_network.h"
+
+AtlantikNetwork::AtlantikNetwork(AtlanticCore *atlanticCore) : KExtendedSocket(0, 0, KExtendedSocket::inputBufferedSocket)
+{
+ m_atlanticCore = atlanticCore;
+ m_textStream = new QTextStream(this);
+ m_textStream->setCodec(QTextCodec::codecForName("utf8"));
+ m_playerId = -1;
+ m_serverVersion = "";
+
+ QObject::connect(this, SIGNAL(readyRead()), this, SLOT(slotRead()));
+ QObject::connect(this, SIGNAL(lookupFinished(int)),
+ this, SLOT(slotLookupFinished(int)));
+ QObject::connect(this, SIGNAL(connectionSuccess()),
+ this, SLOT(slotConnectionSuccess()));
+ QObject::connect(this, SIGNAL(connectionFailed(int)),
+ this, SLOT(slotConnectionFailed(int)));
+}
+
+AtlantikNetwork::~AtlantikNetwork(void)
+{
+ delete m_textStream;
+}
+
+void AtlantikNetwork::rollDice()
+{
+ writeData(".r");
+}
+
+void AtlantikNetwork::buyEstate()
+{
+ writeData(".eb");
+}
+
+void AtlantikNetwork::auctionEstate()
+{
+ writeData(".ea");
+}
+
+void AtlantikNetwork::startGame()
+{
+ writeData(".gs");
+}
+
+void AtlantikNetwork::reconnect(const QString &cookie)
+{
+ writeData(".R" + cookie);
+}
+
+void AtlantikNetwork::leaveGame()
+{
+ writeData(".gx");
+}
+
+void AtlantikNetwork::endTurn()
+{
+ writeData(".E");
+}
+
+void AtlantikNetwork::setName(QString name)
+{
+ // Almost deprecated, will be replaced by libmonopdprotocol
+ writeData(QString(".n%1").arg(name));
+}
+
+void AtlantikNetwork::tokenConfirmation(Estate *estate)
+{
+ writeData(QString(".t%1").arg(estate ? estate->id() : -1));
+}
+
+void AtlantikNetwork::estateToggleMortgage(Estate *estate)
+{
+ writeData(QString(".em%1").arg(estate ? estate->id() : -1));
+}
+
+void AtlantikNetwork::estateHouseBuy(Estate *estate)
+{
+ writeData(QString(".hb%1").arg(estate ? estate->id() : -1));
+}
+
+void AtlantikNetwork::estateHouseSell(Estate *estate)
+{
+ writeData(QString(".hs%1").arg(estate ? estate->id() : -1));
+}
+
+void AtlantikNetwork::newGame(const QString &gameType)
+{
+ writeData(QString(".gn%1").arg(gameType));
+}
+
+void AtlantikNetwork::joinGame(int gameId)
+{
+ writeData(QString(".gj%1").arg(gameId));
+}
+
+void AtlantikNetwork::cmdChat(QString msg)
+{
+ writeData(msg);
+}
+
+void AtlantikNetwork::newTrade(Player *player)
+{
+ writeData(QString(".Tn%1").arg(player ? player->id() : -1));
+}
+
+void AtlantikNetwork::kickPlayer(Player *player)
+{
+ writeData(QString(".gk%1").arg(player ? player->id() : -1));
+}
+
+void AtlantikNetwork::tradeUpdateEstate(Trade *trade, Estate *estate, Player *player)
+{
+ writeData(QString(".Te%1:%2:%3").arg(trade ? trade->tradeId() : -1).arg(estate ? estate->id() : -1).arg(player ? player->id() : -1));
+}
+
+void AtlantikNetwork::tradeUpdateMoney(Trade *trade, unsigned int money, Player *pFrom, Player *pTo)
+{
+ writeData(QString(".Tm%1:%2:%3:%4").arg(trade ? trade->tradeId() : -1).arg(pFrom ? pFrom->id() : -1).arg(pTo ? pTo->id() : -1).arg(money));
+}
+
+void AtlantikNetwork::tradeReject(Trade *trade)
+{
+ writeData(QString(".Tr%1").arg(trade ? trade->tradeId() : -1));
+}
+
+void AtlantikNetwork::tradeAccept(Trade *trade)
+{
+ writeData(QString(".Ta%1:%2").arg(trade ? trade->tradeId() : -1).arg(trade ? trade->revision() : -1));
+}
+
+void AtlantikNetwork::auctionBid(Auction *auction, int amount)
+{
+ writeData(QString(".ab%1:%2").arg(auction ? auction->auctionId() : -1).arg(amount));
+}
+
+void AtlantikNetwork::setImage(const QString &name)
+{
+ writeData(QString(".pi%1").arg(name));
+}
+
+void AtlantikNetwork::jailPay()
+{
+ writeData(".jp");
+}
+
+void AtlantikNetwork::jailRoll()
+{
+ writeData(".jr");
+}
+
+void AtlantikNetwork::jailCard()
+{
+ writeData(".jc");
+}
+
+void AtlantikNetwork::changeOption(int configId, const QString &value)
+{
+ writeData( QString(".gc%1:%2").arg(configId).arg(value) );
+}
+
+void AtlantikNetwork::writeData(QString msg)
+{
+ emit networkEvent(msg, "1rightarrow");
+ msg.append("\n");
+ if (socketStatus() == KExtendedSocket::connected)
+ *m_textStream << msg;
+ else
+ kdDebug() << "warning: socket not connected!" << endl;
+}
+
+void AtlantikNetwork::slotRead()
+{
+ if ( socketStatus() != KExtendedSocket::connected )
+ return;
+
+ if (canReadLine())
+ {
+ processMsg(m_textStream->readLine());
+ // There might be more data
+ QTimer::singleShot(0, this, SLOT(slotRead()));
+ }
+ else
+ {
+ // Maximum message size. Messages won't get bigger than 32k anyway, so
+ // if we didn't receive a newline by now, we probably won't anyway.
+ if (bytesAvailable() > (1024 * 32))
+ flush();
+ }
+}
+
+void AtlantikNetwork::processMsg(const QString &msg)
+{
+ emit networkEvent(msg, "1leftarrow");
+
+ QDomDocument dom;
+ dom.setContent(msg);
+ QDomElement e = dom.documentElement();
+ if (e.tagName() != "monopd")
+ {
+ // Invalid data, request full update from server
+ writeData(".f");
+ return;
+ }
+ QDomNode n = e.firstChild();
+ processNode(n);
+ m_atlanticCore->printDebug();
+}
+
+void AtlantikNetwork::processNode(QDomNode n)
+{
+ QDomAttr a;
+
+ for ( ; !n.isNull() ; n = n.nextSibling() )
+ {
+ QDomElement e = n.toElement();
+ if(!e.isNull())
+ {
+ if (e.tagName() == "server")
+ {
+ a = e.attributeNode( QString("version") );
+ if ( !a.isNull() )
+ m_serverVersion = a.value();
+
+ emit receivedHandshake();
+ }
+ else if (e.tagName() == "msg")
+ {
+ a = e.attributeNode(QString("type"));
+ if (!a.isNull())
+ {
+ if (a.value() == "error")
+ emit msgError(e.attributeNode(QString("value")).value());
+ else if (a.value() == "info")
+ emit msgInfo(e.attributeNode(QString("value")).value());
+ else if (a.value() == "chat")
+ emit msgChat(e.attributeNode(QString("author")).value(), e.attributeNode(QString("value")).value());
+ }
+ }
+ else if (e.tagName() == "display")
+ {
+ int estateId = -1;
+
+ a = e.attributeNode(QString("estateid"));
+ if (!a.isNull())
+ {
+ estateId = a.value().toInt();
+ Estate *estate;
+ estate = m_atlanticCore->findEstate(a.value().toInt());
+
+ emit displayDetails(e.attributeNode(QString("text")).value(), e.attributeNode(QString("cleartext")).value().toInt(), e.attributeNode(QString("clearbuttons")).value().toInt(), estate);
+
+ bool hasButtons = false;
+ for( QDomNode nButtons = n.firstChild() ; !nButtons.isNull() ; nButtons = nButtons.nextSibling() )
+ {
+ QDomElement eButton = nButtons.toElement();
+ if (!eButton.isNull() && eButton.tagName() == "button")
+ {
+ emit addCommandButton(eButton.attributeNode(QString("command")).value(), eButton.attributeNode(QString("caption")).value(), eButton.attributeNode(QString("enabled")).value().toInt());
+ hasButtons = true;
+ }
+ }
+
+ if (!hasButtons)
+ emit addCloseButton();
+ }
+ }
+ else if (e.tagName() == "client")
+ {
+ a = e.attributeNode(QString("playerid"));
+ if (!a.isNull())
+ m_playerId = a.value().toInt();
+
+ a = e.attributeNode(QString("cookie"));
+ if (!a.isNull())
+ emit clientCookie(a.value());
+ }
+ else if (e.tagName() == "configupdate")
+ {
+ int configId = -1;
+ a = e.attributeNode(QString("configid"));
+ if (!a.isNull())
+ {
+ configId = a.value().toInt();
+ ConfigOption *configOption;
+ if (!(configOption = m_atlanticCore->findConfigOption(configId)))
+ configOption = m_atlanticCore->newConfigOption( configId );
+
+ a = e.attributeNode(QString("name"));
+ if (configOption && !a.isNull())
+ configOption->setName(a.value());
+
+ a = e.attributeNode(QString("description"));
+ if (configOption && !a.isNull())
+ configOption->setDescription(a.value());
+
+ a = e.attributeNode(QString("edit"));
+ if (configOption && !a.isNull())
+ configOption->setEdit(a.value().toInt());
+
+ a = e.attributeNode(QString("value"));
+ if (configOption && !a.isNull())
+ configOption->setValue(a.value());
+
+ if (configOption)
+ configOption->update();
+ }
+
+ int gameId = -1;
+ a = e.attributeNode(QString("gameid"));
+ if (!a.isNull())
+ {
+ gameId = a.value().toInt();
+ for( QDomNode nOptions = n.firstChild() ; !nOptions.isNull() ; nOptions = nOptions.nextSibling() )
+ {
+ QDomElement eOption = nOptions.toElement();
+ if (!eOption.isNull() && eOption.tagName() == "option")
+ emit gameOption(eOption.attributeNode(QString("title")).value(), eOption.attributeNode(QString("type")).value(), eOption.attributeNode(QString("value")).value(), eOption.attributeNode(QString("edit")).value(), eOption.attributeNode(QString("command")).value());
+ }
+ emit endConfigUpdate();
+ }
+ }
+ else if (e.tagName() == "deletegame")
+ {
+ a = e.attributeNode(QString("gameid"));
+ if (!a.isNull())
+ {
+ int gameId = a.value().toInt();
+
+ Game *game = m_atlanticCore->findGame(gameId);
+ if (game)
+ m_atlanticCore->removeGame(game);
+ }
+ }
+ else if (e.tagName() == "gameupdate")
+ {
+ int gameId = -1;
+
+ a = e.attributeNode(QString("gameid"));
+ if (!a.isNull())
+ {
+ gameId = a.value().toInt();
+
+ Player *playerSelf = m_atlanticCore->playerSelf();
+ if ( playerSelf && playerSelf->game() )
+ kdDebug() << "gameupdate for " << QString::number(gameId) << " with playerSelf in game " << QString::number(playerSelf->game()->id()) << endl;
+ else
+ kdDebug() << "gameupdate for " << QString::number(gameId) << endl;
+
+
+ Game *game = 0;
+ if (gameId == -1)
+ {
+ a = e.attributeNode(QString("gametype"));
+ if ( !a.isNull() && !(game = m_atlanticCore->findGame(a.value())) )
+ game = m_atlanticCore->newGame(gameId, a.value());
+ }
+ else if (!(game = m_atlanticCore->findGame(gameId)))
+ game = m_atlanticCore->newGame(gameId);
+
+ a = e.attributeNode(QString("canbejoined"));
+ if (game && !a.isNull())
+ game->setCanBeJoined(a.value().toInt());
+
+ a = e.attributeNode(QString("description"));
+ if (game && !a.isNull())
+ game->setDescription(a.value());
+
+ a = e.attributeNode(QString("name"));
+ if (game && !a.isNull())
+ game->setName(a.value());
+
+ a = e.attributeNode(QString("players"));
+ if (game && !a.isNull())
+ game->setPlayers(a.value().toInt());
+
+ a = e.attributeNode(QString("master"));
+ if (game && !a.isNull())
+ {
+ // Ensure setMaster succeeds by creating player if necessary
+ Player *player = m_atlanticCore->findPlayer( a.value().toInt() );
+ if ( !player )
+ player = m_atlanticCore->newPlayer( a.value().toInt() );
+ game->setMaster( player );
+ }
+
+ QString status = e.attributeNode(QString("status")).value();
+ if ( m_serverVersion.left(4) == "0.9." || (playerSelf && playerSelf->game() == game) )
+ {
+ if (status == "config")
+ emit gameConfig();
+ else if (status == "init")
+ emit gameInit();
+ else if (status == "run")
+ emit gameRun();
+ else if (status == "end")
+ emit gameEnd();
+ }
+
+ if (game)
+ game->update();
+ }
+ }
+ else if (e.tagName() == "deleteplayer")
+ {
+ a = e.attributeNode(QString("playerid"));
+ if (!a.isNull())
+ {
+ int playerId = a.value().toInt();
+
+ Player *player = m_atlanticCore->findPlayer(playerId);
+ if (player)
+ m_atlanticCore->removePlayer(player);
+ }
+ }
+ else if (e.tagName() == "playerupdate")
+ {
+ int playerId = -1;
+
+ a = e.attributeNode(QString("playerid"));
+ if (!a.isNull())
+ {
+ playerId = a.value().toInt();
+
+ Player *player;
+ if (!(player = m_atlanticCore->findPlayer(playerId)))
+ player = m_atlanticCore->newPlayer( playerId, (m_playerId == playerId) );
+
+ // Update player name
+ a = e.attributeNode(QString("name"));
+ if (player && !a.isNull())
+ player->setName(a.value());
+
+ // Update player game
+ a = e.attributeNode(QString("game"));
+ if (player && !a.isNull())
+ {
+ int gameId = a.value().toInt();
+ if (gameId == -1)
+ player->setGame( 0 );
+ else
+ {
+ // Ensure setGame succeeds by creating game if necessary
+ Game *game = m_atlanticCore->findGame(a.value().toInt());
+ if (!game)
+ game = m_atlanticCore->newGame(a.value().toInt()); //
+ player->setGame( game );
+ }
+ }
+
+ // Update player host
+ a = e.attributeNode(QString("host"));
+ if (player && !a.isNull())
+ player->setHost(a.value());
+
+ // Update player image/token
+ a = e.attributeNode(QString("image"));
+ if (player && !a.isNull())
+ player->setImage(a.value());
+
+ // Update player money
+ a = e.attributeNode(QString("money"));
+ if (player && !a.isNull())
+ player->setMoney(a.value().toInt());
+
+ a = e.attributeNode(QString("bankrupt"));
+ if (player && !a.isNull())
+ player->setBankrupt(a.value().toInt());
+
+ a = e.attributeNode(QString("hasdebt"));
+ if (player && !a.isNull())
+ player->setHasDebt(a.value().toInt());
+
+ a = e.attributeNode(QString("hasturn"));
+ if (player && !a.isNull())
+ player->setHasTurn(a.value().toInt());
+
+ // Update whether player can roll
+ a = e.attributeNode(QString("can_roll"));
+ if (player && !a.isNull())
+ player->setCanRoll(a.value().toInt());
+
+ // Update whether player can buy
+ a = e.attributeNode(QString("can_buyestate"));
+ if (player && !a.isNull())
+ player->setCanBuy(a.value().toInt());
+
+ // Update whether player can auction
+ a = e.attributeNode(QString("canauction"));
+ if (player && !a.isNull())
+ player->setCanAuction(a.value().toInt());
+
+ // Update whether player can use a card
+ a = e.attributeNode(QString("canusecard"));
+ if (player && !a.isNull())
+ player->setCanUseCard(a.value().toInt());
+
+ // Update whether player is jailed
+ a = e.attributeNode(QString("jailed"));
+ if (player && !a.isNull())
+ {
+ player->setInJail(a.value().toInt());
+ // TODO: emit signal with player ptr so board can setText and display something
+ }
+
+ // Update player location
+ a = e.attributeNode(QString("location"));
+ if (!a.isNull())
+ {
+ m_playerLocationMap[player] = a.value().toInt();
+
+ bool directMove = false;
+
+ Estate *estate = m_atlanticCore->findEstate(a.value().toInt());
+
+ a = e.attributeNode(QString("directmove"));
+ if (!a.isNull())
+ directMove = a.value().toInt();
+
+ if (player && estate)
+ {
+ if (directMove)
+ player->setLocation(estate);
+ else
+ player->setDestination(estate);
+ }
+ }
+
+ if (player)
+ player->update();
+ }
+ }
+ else if (e.tagName() == "estategroupupdate")
+ {
+ a = e.attributeNode(QString("groupid"));
+ if (!a.isNull())
+ {
+ int groupId = a.value().toInt();
+
+ EstateGroup *estateGroup = 0;
+ bool b_newEstateGroup = false;
+
+ if (!(estateGroup = m_atlanticCore->findEstateGroup(groupId)))
+ {
+ // Create EstateGroup object
+ estateGroup = m_atlanticCore->newEstateGroup(a.value().toInt());
+ b_newEstateGroup = true;
+ }
+
+ a = e.attributeNode(QString("name"));
+ if (estateGroup && !a.isNull())
+ estateGroup->setName(a.value());
+
+ // Emit signal so GUI implementations can create view(s)
+ // TODO: port to atlanticcore and create view there
+ if (estateGroup)
+ {
+ if (b_newEstateGroup)
+ emit newEstateGroup(estateGroup);
+ estateGroup->update();
+ }
+ }
+ }
+ else if (e.tagName() == "estateupdate")
+ {
+ int estateId = -1;
+
+ a = e.attributeNode(QString("estateid"));
+ if (!a.isNull())
+ {
+ estateId = a.value().toInt();
+
+ Estate *estate = 0;
+ bool b_newEstate = false;
+
+ // FIXME: allow any estateId, GUI should not use it to determin its geometry
+ if (estateId >= 0 && estateId < 100 && !(estate = m_atlanticCore->findEstate(a.value().toInt())))
+ {
+ // Create estate object
+ estate = m_atlanticCore->newEstate(estateId);
+ b_newEstate = true;
+
+ QObject::connect(estate, SIGNAL(estateToggleMortgage(Estate *)), this, SLOT(estateToggleMortgage(Estate *)));
+ QObject::connect(estate, SIGNAL(estateHouseBuy(Estate *)), this, SLOT(estateHouseBuy(Estate *)));
+ QObject::connect(estate, SIGNAL(estateHouseSell(Estate *)), this, SLOT(estateHouseSell(Estate *)));
+ QObject::connect(estate, SIGNAL(newTrade(Player *)), this, SLOT(newTrade(Player *)));
+
+ // Players without estate should get one
+ Player *player = 0;
+ QPtrList<Player> playerList = m_atlanticCore->players();
+ for (QPtrListIterator<Player> it(playerList); (player = *it) ; ++it)
+ if (m_playerLocationMap[player] == estate->id())
+ player->setLocation(estate);
+ }
+
+ a = e.attributeNode(QString("name"));
+ if (estate && !a.isNull())
+ estate->setName(a.value());
+
+ a = e.attributeNode(QString("color"));
+ if (estate && !a.isNull() && !a.value().isEmpty())
+ estate->setColor(a.value());
+
+ a = e.attributeNode(QString("bgcolor"));
+ if (estate && !a.isNull())
+ estate->setBgColor(a.value());
+
+ a = e.attributeNode(QString("owner"));
+ Player *player = m_atlanticCore->findPlayer(a.value().toInt());
+ if (estate && !a.isNull())
+ estate->setOwner(player);
+
+ a = e.attributeNode(QString("houses"));
+ if (estate && !a.isNull())
+ estate->setHouses(a.value().toInt());
+
+ a = e.attributeNode(QString("mortgaged"));
+ if (estate && !a.isNull())
+ estate->setIsMortgaged(a.value().toInt());
+
+ a = e.attributeNode(QString("group"));
+ if (!a.isNull())
+ {
+ EstateGroup *estateGroup = m_atlanticCore->findEstateGroup(a.value().toInt());
+ if (estate)
+ estate->setEstateGroup(estateGroup);
+ }
+
+ a = e.attributeNode(QString("can_toggle_mortgage"));
+ if (estate && !a.isNull())
+ estate->setCanToggleMortgage(a.value().toInt());
+
+ a = e.attributeNode(QString("can_be_owned"));
+ if (estate && !a.isNull())
+ estate->setCanBeOwned(a.value().toInt());
+
+ a = e.attributeNode(QString("can_buy_houses"));
+ if (estate && !a.isNull())
+ estate->setCanBuyHouses(a.value().toInt());
+
+ a = e.attributeNode(QString("can_sell_houses"));
+ if (estate && !a.isNull())
+ estate->setCanSellHouses(a.value().toInt());
+
+ a = e.attributeNode(QString("price"));
+ if (estate && !a.isNull())
+ estate->setPrice(a.value().toInt());
+
+ a = e.attributeNode(QString("houseprice"));
+ if (estate && !a.isNull())
+ estate->setHousePrice(a.value().toInt());
+
+ a = e.attributeNode(QString("sellhouseprice"));
+ if (estate && !a.isNull())
+ estate->setHouseSellPrice(a.value().toInt());
+
+ a = e.attributeNode(QString("mortgageprice"));
+ if (estate && !a.isNull())
+ estate->setMortgagePrice(a.value().toInt());
+
+ a = e.attributeNode(QString("unmortgageprice"));
+ if (estate && !a.isNull())
+ estate->setUnmortgagePrice(a.value().toInt());
+
+ a = e.attributeNode(QString("money"));
+ if (estate && !a.isNull())
+ estate->setMoney(a.value().toInt());
+
+ // Emit signal so GUI implementations can create view(s)
+ // TODO: port to atlanticcore and create view there
+ if (estate)
+ {
+ if (b_newEstate)
+ emit newEstate(estate);
+ estate->update();
+ }
+ }
+ }
+ else if (e.tagName() == "tradeupdate")
+ {
+ a = e.attributeNode(QString("tradeid"));
+ if (!a.isNull())
+ {
+ int tradeId = a.value().toInt();
+
+ Trade *trade = m_atlanticCore->findTrade(tradeId);
+ if (!trade)
+ {
+ // Create trade object
+ trade = m_atlanticCore->newTrade(tradeId);
+
+ QObject::connect(trade, SIGNAL(updateEstate(Trade *, Estate *, Player *)), this, SLOT(tradeUpdateEstate(Trade *, Estate *, Player *)));
+ QObject::connect(trade, SIGNAL(updateMoney(Trade *, unsigned int, Player *, Player *)), this, SLOT(tradeUpdateMoney(Trade *, unsigned int, Player *, Player *)));
+ QObject::connect(trade, SIGNAL(reject(Trade *)), this, SLOT(tradeReject(Trade *)));
+ QObject::connect(trade, SIGNAL(accept(Trade *)), this, SLOT(tradeAccept(Trade *)));
+ }
+
+ a = e.attributeNode(QString("revision"));
+ if (trade && !a.isNull())
+ trade->setRevision(a.value().toInt());
+
+ QString type = e.attributeNode(QString("type")).value();
+ if (type=="new")
+ {
+ // TODO: trade->setActor
+ // Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("actor")).value().toInt());
+ // if (trade && player)
+ // trade->setActor(player);
+
+ QDomNode n_player = n.firstChild();
+ while(!n_player.isNull())
+ {
+ QDomElement e_player = n_player.toElement();
+ if (!e_player.isNull() && e_player.tagName() == "tradeplayer")
+ {
+ Player *player = m_atlanticCore->findPlayer(e_player.attributeNode(QString("playerid")).value().toInt());
+ if (trade && player)
+ {
+ trade->addPlayer(player);
+ QObject::connect(m_atlanticCore, SIGNAL(removePlayer(Player *)), trade, SLOT(removePlayer(Player *)));
+ }
+ }
+ n_player = n_player.nextSibling();
+ }
+ }
+ else if (type=="accepted" && trade)
+ emit msgTradeUpdateAccepted(trade);
+ else if (type=="completed" && trade)
+ {
+ m_atlanticCore->removeTrade(trade);
+ trade = 0;
+ }
+ else if (type=="rejected")
+ {
+ Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("actor")).value().toInt());
+ if (trade)
+ trade->reject(player);
+ if ( player && player == m_atlanticCore->playerSelf() )
+ {
+ m_atlanticCore->removeTrade(trade);
+ trade = 0;
+ }
+ }
+ else
+ {
+ // No type specified, edit is implied.
+
+ QDomNode n_child = n.firstChild();
+ while(!n_child.isNull())
+ {
+ QDomElement e_child = n_child.toElement();
+ if (!e_child.isNull())
+ {
+ if (e_child.tagName() == "tradeplayer")
+ {
+ a = e_child.attributeNode(QString("playerid"));
+ if (!a.isNull())
+ {
+ Player *player = m_atlanticCore->findPlayer(a.value().toInt());
+
+ a = e_child.attributeNode(QString("accept"));
+ if (trade && player && !a.isNull())
+ trade->updateAccept(player, (bool)(a.value().toInt()));
+ }
+ }
+ else if (e_child.tagName() == "tradeestate")
+ {
+ a = e_child.attributeNode(QString("estateid"));
+ if (!a.isNull())
+ {
+ Estate *estate = m_atlanticCore->findEstate(a.value().toInt());
+ a = e_child.attributeNode(QString("targetplayer"));
+ if (!a.isNull())
+ {
+ Player *player = m_atlanticCore->findPlayer(a.value().toInt());
+ // Allow NULL player, it will remove the component
+ if (trade && estate)
+ trade->updateEstate(estate, player);
+ }
+ }
+ }
+ else if (e_child.tagName() == "trademoney")
+ {
+ Player *pFrom = 0, *pTo = 0;
+
+ a = e_child.attributeNode(QString("playerfrom"));
+ if (!a.isNull())
+ pFrom = m_atlanticCore->findPlayer(a.value().toInt());
+
+ a = e_child.attributeNode(QString("playerto"));
+ if (!a.isNull())
+ pTo = m_atlanticCore->findPlayer(a.value().toInt());
+
+ a = e_child.attributeNode(QString("money"));
+ kdDebug() << "tradeupdatemoney" << (pFrom ? "1" : "0") << (pTo ? "1" : "0") << (a.isNull() ? "0" : "1") << endl;
+ if (trade && pFrom && pTo && !a.isNull())
+ trade->updateMoney(a.value().toInt(), pFrom, pTo);
+ }
+ }
+ n_child = n_child.nextSibling();
+ }
+ }
+
+ if (trade)
+ trade->update();
+ }
+ }
+ else if (e.tagName() == "auctionupdate")
+ {
+ a = e.attributeNode(QString("auctionid"));
+ if (!a.isNull())
+ {
+ int auctionId = a.value().toInt();
+
+ Auction *auction;
+ bool b_newAuction = false;
+ if (!(auction = m_auctions[auctionId]))
+ {
+ // Create auction object
+ auction = m_atlanticCore->newAuction(auctionId, m_atlanticCore->findEstate(e.attributeNode(QString("estateid")).value().toInt()));
+ m_auctions[auctionId] = auction;
+
+ QObject::connect(auction, SIGNAL(bid(Auction *, int)), this, SLOT(auctionBid(Auction *, int)));
+
+ b_newAuction = true;
+ }
+
+ a = e.attributeNode(QString("highbidder"));
+ if (!a.isNull())
+ {
+ Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("highbidder")).value().toInt());
+ a = e.attributeNode(QString("highbid"));
+ if (auction && !a.isNull())
+ auction->newBid(player, a.value().toInt());
+ }
+
+ a = e.attributeNode(QString("status"));
+ if (auction && !a.isNull())
+ {
+ int status = a.value().toInt();
+ auction->setStatus(status);
+
+ // TODO: find a good way to visualise "sold!"
+ if (status == 3)
+ {
+ m_atlanticCore->delAuction(auction);
+ m_auctions[auctionId] = 0;
+ auction = 0;
+ }
+ }
+
+ // Emit signal so GUI implementations can create view(s)
+ // TODO: port to atlanticcore and create view there
+ if (auction)
+ {
+ if (b_newAuction)
+ emit newAuction(auction);
+ auction->update();
+ }
+ }
+ }
+ else
+ kdDebug() << "ignored TAG: " << e.tagName() << endl;
+ }
+ // TODO: remove permanently?
+ // QDomNode node = n.firstChild();
+ // processNode(node);
+ }
+}
+
+void AtlantikNetwork::serverConnect(const QString host, int port)
+{
+ setAddress(host, port);
+ enableRead(true);
+ emit msgStatus(i18n("Connecting to %1:%2...").arg(host).arg(QString::number(port)), "connect_creating");
+ startAsyncConnect();
+}
+
+void AtlantikNetwork::slotLookupFinished(int count)
+{
+ emit msgStatus(i18n("Server host name lookup finished..."));
+}
+
+void AtlantikNetwork::slotConnectionSuccess()
+{
+ emit msgStatus(i18n("Connected to %1:%2.").arg(host()).arg(port()), "connect_established");
+}
+
+void AtlantikNetwork::slotConnectionFailed(int error)
+{
+ emit msgStatus(i18n("Connection failed! Error code: %1").arg(error), "connect_no");
+}
+
+#include "atlantik_network.moc"
diff --git a/atlantik/libatlantikclient/atlantik_network.h b/atlantik/libatlantikclient/atlantik_network.h
new file mode 100644
index 00000000..087a01be
--- /dev/null
+++ b/atlantik/libatlantikclient/atlantik_network.h
@@ -0,0 +1,155 @@
+// Copyright (c) 2002-2003 Rob Kaper <cap@capsi.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; see the file COPYING.LIB. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#ifndef LIBATLANTIK_NETWORK_H
+#define LIBATLANTIK_NETWORK_H
+
+#include <qmap.h>
+
+#include <kextsock.h>
+#include "libatlantic_export.h"
+class QDomNode;
+class QTextStream;
+
+class AtlanticCore;
+
+class Player;
+class Estate;
+class EstateGroup;
+class Trade;
+class Auction;
+
+class LIBATLANTIC_EXPORT AtlantikNetwork : public KExtendedSocket
+{
+Q_OBJECT
+
+public:
+ AtlantikNetwork(AtlanticCore *atlanticCore);
+ virtual ~AtlantikNetwork(void);
+ void setName(QString name);
+ void cmdChat(QString msg);
+
+private slots:
+ void writeData(QString msg);
+ void rollDice();
+ void endTurn();
+ void newGame(const QString &gameType);
+ void reconnect(const QString &cookie);
+ void startGame();
+ void buyEstate();
+ void auctionEstate();
+ void estateToggleMortgage(Estate *estate);
+ void estateHouseBuy(Estate *estate);
+ void estateHouseSell(Estate *estate);
+ void jailCard();
+ void jailPay();
+ void jailRoll();
+ void newTrade(Player *player);
+ void kickPlayer(Player *player);
+ void tokenConfirmation(Estate *);
+ void tradeUpdateEstate(Trade *trade, Estate *estate, Player *player);
+ void tradeUpdateMoney(Trade *trade, unsigned int money, Player *pFrom, Player *pTo);
+ void tradeReject(Trade *trade);
+ void tradeAccept(Trade *trade);
+ void auctionBid(Auction *auction, int amount);
+ void changeOption(int, const QString &value);
+ void slotLookupFinished(int count);
+ void slotConnectionSuccess();
+ void slotConnectionFailed(int error);
+
+public slots:
+ void serverConnect(const QString host, int port);
+ void joinGame(int gameId);
+ void leaveGame();
+ void slotRead();
+ void setImage(const QString &name);
+
+signals:
+ /**
+ * A new estate was created. This signal might be replaced with one in
+ * the AtlanticCore class in the future, but it is here now because we
+ * do not want GUI implementations to create a view until the
+ * estateupdate message has been fully parsed.
+ *
+ * @param estate Created Estate object.
+ */
+ void newEstate(Estate *estate);
+
+ /**
+ * A new estate group was created. This signal might be replaced with
+ * one in the AtlanticCore class in the future, but it is here now
+ * because we do not want GUI implementations to create a view until the
+ * estategroupupdate message has been fully parsed.
+ *
+ * @param estateGroup Created EstateGroup object.
+ */
+ void newEstateGroup(EstateGroup *estateGroup);
+
+ void msgInfo(QString);
+ void msgError(QString);
+ void msgChat(QString, QString);
+ void msgStatus(const QString &data, const QString &icon = QString::null);
+ void networkEvent(const QString &data, const QString &icon);
+
+ void displayDetails(QString text, bool clearText, bool clearButtons, Estate *estate = 0);
+ void addCommandButton(QString command, QString caption, bool enabled);
+ void addCloseButton();
+
+ void gameOption(QString title, QString type, QString value, QString edit, QString command);
+ void endConfigUpdate();
+
+ void gameConfig();
+ void gameInit();
+ void gameRun();
+ void gameEnd();
+
+ /**
+ * The trade has been completed. Emitted after all necessary estate and
+ * player updates are processed.
+ *
+ * @param trade Trade
+ */
+ void msgTradeUpdateAccepted(Trade *trade);
+
+ /**
+ * One of the players rejected the trade and the trade object has been
+ * deleted from the server.
+ *
+ * @param trade Trade
+ * @param playerId Unique player identifier of rejecting player
+ */
+ void msgTradeUpdateRejected(Trade *trade, int playerId);
+
+ void newAuction(Auction *auction);
+ void auctionCompleted(Auction *auction);
+ void receivedHandshake();
+ void clientCookie(QString cookie);
+
+private:
+ void processMsg(const QString &msg);
+ void processNode(QDomNode);
+
+ AtlanticCore *m_atlanticCore;
+ QTextStream *m_textStream;
+
+ int m_playerId;
+ QString m_serverVersion;
+
+ QMap<Player *, int> m_playerLocationMap;
+ QMap<int, Auction *> m_auctions;
+};
+
+#endif
diff --git a/atlantik/libatlantikclient/monopdprotocol.cpp b/atlantik/libatlantikclient/monopdprotocol.cpp
new file mode 100644
index 00000000..5f6c401b
--- /dev/null
+++ b/atlantik/libatlantikclient/monopdprotocol.cpp
@@ -0,0 +1,80 @@
+// Copyright (c) 2002 Rob Kaper <cap@capsi.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; see the file COPYING.LIB. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <qstring.h>
+
+/*
+#include <atlantic_core.h>
+#include <player.h>
+#include <estate.h>
+#include <estategroup.h>
+#include <trade.h>
+#include <auction.h>
+*/
+
+#include <estate.h>
+
+#include "monopdprotocol.h"
+#include "monopdprotocol.moc"
+
+MonopdProtocol::MonopdProtocol() : QObject()
+{
+}
+
+void MonopdProtocol::auctionEstate()
+{
+ sendData(QString::fromLatin1(".ea"));
+}
+
+void MonopdProtocol::buyEstate()
+{
+ sendData(QString::fromLatin1(".eb"));
+}
+
+void MonopdProtocol::confirmTokenLocation(Estate *estate)
+{
+ QString data(".t");
+ data.append(QString::number(estate ? estate->id() : -1));
+ sendData(data);
+}
+
+void MonopdProtocol::endTurn()
+{
+ sendData(QString::fromLatin1(".E"));
+}
+
+void MonopdProtocol::rollDice()
+{
+ sendData(QString::fromLatin1(".r"));
+}
+
+void MonopdProtocol::setName(QString name)
+{
+ QString data(".n");
+ data.append(name);
+ sendData(data);
+}
+
+void MonopdProtocol::startGame()
+{
+ sendData(QString::fromLatin1(".gs"));
+}
+
+void MonopdProtocol::sendData(QString)
+{
+ // Your reimplementation of this method should send send data over the
+ // network.
+}
diff --git a/atlantik/libatlantikclient/monopdprotocol.h b/atlantik/libatlantikclient/monopdprotocol.h
new file mode 100644
index 00000000..0fc16ad8
--- /dev/null
+++ b/atlantik/libatlantikclient/monopdprotocol.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2002 Rob Kaper <cap@capsi.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; see the file COPYING.LIB. If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// WARNING: this codebase is not being used yet. Please use AtlantikNetwork
+// until the protocol seperation has been completed.
+
+#ifndef MONOPDPROTOCOL_H_H
+#define MONOPDPROTOCOL_H_H
+
+#include <qobject.h>
+
+class QString;
+
+/*
+class AtlanticCore;
+
+class Player;
+class EstateGroup;
+class Trade;
+class Auction;
+*/
+
+class Estate;
+
+class MonopdProtocol : public QObject
+{
+Q_OBJECT
+
+public:
+ MonopdProtocol();
+
+private slots:
+ void auctionEstate();
+ void buyEstate();
+ void confirmTokenLocation(Estate *estate);
+ void endTurn();
+ void rollDice();
+ void setName(QString name);
+ void startGame();
+
+private:
+ virtual void sendData(QString data);
+};
+
+#endif