diff options
Diffstat (limited to 'libkdegames/kgame')
53 files changed, 0 insertions, 16221 deletions
diff --git a/libkdegames/kgame/COMPAT b/libkdegames/kgame/COMPAT deleted file mode 100644 index 4551c679..00000000 --- a/libkdegames/kgame/COMPAT +++ /dev/null @@ -1,55 +0,0 @@ -06.09.2001: replace the signal signalCreatePlayer by the virtual function - createPlayer. It has the same arguments but the return value - is the new player -06.09.2001: the KGameConfig dialog changes the parameter initConfigs from bool - to long. Use the ConfigOptions to specify what options you want - to have enabled. Default is all -06.09.2001: some int->Q_UINT32 in sender, receiver and player parameters. maybe - more will follow. -06.09.2001: KGameIO::signalPrepareMove(..., bool&) -> - KGameIO::signalPrepareMove(..., bool*): don't know why this was - necessary but it didn't work anymore... -16.09.2001: KGamePropertyHandler uses bool* for the sent parameter now. This is - because QT3 obviously doesn't honor referneces in Q_SIGNALS/Q_SLOTS. - This might even be a QT bug. Bad situation - we use references - everywhere in KGame... hope nothing else is affecterd by this - problem (signalPrepareMove was fixed already by me) -18.09.2001: bool* for Key/Mouseevents and IOAdded in kgameio.h too -19.09.2001: Kgame:nextPlayer retunrs the KPlayer *nextplayer instead of bool -19.09.2001: gameOver() renamed to checkGameOver() !!!!! -18.09.2001: Question: Should the signal signalPlayerInput(QDataStream &,KPlayer *)) - be made a virtual function? - MH: This is done now. As this is a central function your programs will - not run anymore. Fix: rename your slot which is connected to the above - signal to playerInput() and return TRUE in it. This will make it 100% - compatible to the old version. I think this chagne is necessary especially - as a signal is of no use here as you cannot read twice from the same stream. - Therefore there can be only one function processing the input. If you really - need a signal, you can of course simply emit it in the overwritten playerInput - function -20.09.2001 playerInputFinished(void->KPlayer *) ---------------------- KGAME_ALPHA_1 --------------------- -06.10.2001 adding KGameNetwork::signalAdminStatusChanged - needed for - KGameDialog -06.10.2001 KGame::loadGame() doesn't call setPolicy() anymore! -08.10.2001 KGamePropertyList now honor policies! Use setPolicy(PolicyDirty) to - get the old behavior! - The behavior of KGamePropertyArray may have changed in this turn, - too! - The API stays the same. -11.10.2001 KGameDialogGeneralConfig now doesn't provide setMin/maxPlayers() - anymore. The game should manage this internally. tqlayout() is - obsolete as well -18.10.2001 KPlayer::signalNetworkData contained QDataStream& instead of const - QByteArray& parameter (oops!). This is fixed now. All apps which - used this signal must be changed. -18.10.2001 KGame::sendProperty(), KGame::sendPlayerProperty(), - KPlayer::sendProperty() and related functions contain a "int msgid" - parameter. This is the id() of the property handler. This parameter - enables us to easily add any number of property handler to a game - just by connecting it to existing send Q_SLOTS and call - processMessage() in slotNetworkData() -03.11.2001 KPlayer::signalNetworkData now emits msgid-KGameMessage::IdUser just - like KGame::signalNetworkData does -06.11.2001 KGameDialog has some small improvements - easier and IMHO better - constructor code. Most code should be compatible :-) diff --git a/libkdegames/kgame/DESIGN b/libkdegames/kgame/DESIGN deleted file mode 100644 index cd737e3a..00000000 --- a/libkdegames/kgame/DESIGN +++ /dev/null @@ -1,407 +0,0 @@ -This document tries to describe the design of KGame - the KDE multiplayer -library. -This document has been written by: - Andreas Beckermann <[email protected]> - M. Heni <[email protected]> - Burkhard Lehner <[email protected]> - -This document is published under the terms of the GNU FDL - -!!! -Note that this is the initial version of this document and has not yet been -aproved by all core developers (and is far from being complete) -AB: please remove this comments as soon as all KGame hackers have read the -document -!!! - -Please refer the API documentation of every KGame class if you want up tp date -information. - - -0. Contents ------------ - -1. DEFINITIONS -1.1 Message Server -1.2 Client or Message Client -1.3 Master -1.4 Admin -1.5 Server -1.6 Player - -2. Game Negotiation (M.Heni 20.05.2001) - -AB: 3.x is obsolete! -3. Game Properties (Andreas Beckermann 28.07.2001) ( not yet completed ) -3.1 Using KGameProperty -3.2 Custom Classes -3.3 Concepts - -4. KGameIO (Andreas Beckermann 10.08.2001) - -5. Debugging (Andreas Beckermann 06.10.2001) TODO! -5.1 KGameDebugDialog -5.1.1 Debug KGame -5.1.3 Debug Messages - ---------------------------------------------------------------------- -1. DEFINITIONS --------------- - -First we have to clear some words. The main expressions used in KGame which -need a definition are - -1.1 Message Server -1.2 Client or Message Client -1.3 Master -1.4 Admin -1.5 Server -1.6 Player - -The most important and confusing ones are Master, Admin and Server. We make -quite big differerences between those inside KGame. - -1.1 Message Server: -------------------- -A game has always exactly one object of this class, for local games as well as -for network games. For network games, this object can be on one of the users -processes (usually inside KGame), or it can also be on an independant computer, -that has no idea about what game is played on it. - -A KMessageClient object can connect to it. It's main purpose is transmitting -messages between KMessageClient objects. - -The Message Server is the main communication object. It is represented by the -class KMessageServer. Note that there is also a "Master" and a "Server" which -both differ heavily from the Message Server! - -1.2 Client, Message Client: ---------------------------- -Each process that wants to take part in the game must have a -KMessageClient object, that is connected to the Message Server. KGame creates -this object and connects it to the Messager Server, so that you usually don't -need to create these of your own. Even in a local game (no network) there -must be a message server and one message client connected to it. This is usually -done by the KGame object itself. - -Each message client has a unique ID number (a positive integer value, not zero). -The KMessageClient object, which does the communication with the Message Server -is called "Message Client" and to simplify the use we call any KGame object (or -even the game process) that is connected to a game (i.e. even the Master) just -"Client". - -The main purpose of a Client is to connect to a Master (i.e. to a game) and to -communicate with it. A client has always a KGame object. - -1.3 Master: ------------ -The process that contains the Message Server is called "Master". In any local -game this is the game process. The Message Server is started by KGame using -KGame::setMaster(true) which is automatically done on startup. The Message -Server is deleted automatically as soon as you connect to another Master. -So in most cases there is exactly one KGame object / Client which is Master. But -in one case there can be no KGame object / Client that is Master - if the -Message Server is started as an own process. This "Message-Server-only" process -is called "Master" then, although there is no KGame object which is Master. See -also the definition of Admin! - -1.4 Admin: ----------- -One (and only one) of the Clients is the Admin. He can configure the Message -Server and the game in general in several ways. He can limit the maximum number -of connected message clients and can drop the connection to some other clients, -as well as he can configure game specific ssettings (like max/min players, start -money, ...). The Admin also initializes newly connected Clients. If the Admin -himself disconnects, another Client becomes Admin (The Admin can himself elect -some other Client to become Admin. He himself loses that Admin status then). -An Admin is *alway* a KGame object. The Admin is usually the same as the Master, -but if the Master is an own process (i.e. the Message Server has been started -outside KGame) then Master and Admin differ. An Admin *must* be a KGame object -while the Master doesn't have to be. - -1.5 Server: ------------ -The definition of Server differs quite much from the definition of Master. -A Master just accepts connections and forwards messages. The Server on the other -side checks these messages, calculates results and sends the results to the -Clients. That means the Server does all game calculations and doesn't directly -forward the messages from one Clients to all other Clients. -KGamer makes it possible to write multiplayer games even without a Server. All -Clients just send their moves to the Master which forwards them to all Clients. -Now all Clients calculate the result. -E.g. in a poker game a player selects two of five cards to be exchanges and -clicks on "draw" then the client sends the message "Exchange Card-1 and Card-2" -to the Master. A no-Server solution forwards this to all Clients, and these -Clients exchange the cards of the player. Note that in a no-Server solution -(you can also see it as a "every-Client-is-a-Server solution") all Clients must -have the same random seed and must be of the same version, i.e. the result must -be the same on all Clients. -In a Server-Solution on the other hand the Master forwards the Message -("Exchange Card-1 and Card-2") to the Server only. This Server now calculates -the result, and sends the new cards back to the Client. -Both concepts have advantages and disadvantages. It is on you - the game -developer - to decide which way is better for you. -E.g. the Server-Solution makes it easier for you to write games. The version -must not necessarily be the same, you have one central computer which does the -calcultations. The No-Server-Solution on the other hand decreases network -traffik as the Clients just send their moves and all Clients can calculate the -reactions. I'm sure there are a lot of advantages/disadvantages more for both -concepts. - -1.6 Player: ------------ -A KPlayer object is always connected to a KGame object and represents a -player that participates the game. In a network game, every KPlayer object is -duplicated on every other KGame object connected to the message server with -virtual KPlayer objects. So at every time in the game, every KGame object has -the same number of KPlayer objects. - - -2. Game negotiation -------------------- -Upon connection of a client the admin and the client try to negotiate -the game setup. Basically this means the game of the admin is transferred -(saved) on the client. However, the client's players are added to the game -as far as possible. If the addition of the client's players would add more -players than allowed some players are inactivated. Which players are -inactivated depends on their networkPriority(). This procedure allows -easy replacement of players in a constant number game (e.g. chess). If -this feature is of no interest simply keep the priorities equal (all 0) -and the client will only add only players if the number of players is -less or equal the maximum player number. - -The following is the negotiation procedure as started by the connection -of a client. It is initiated in the negotiateNetworkGame() virtual function -of KGame: - -admin: client: ------------- ------------ -IdSetupGame - QINT16 Library - Version - QINT32 Application - cookie - IdSetupGameContinue; - QValueList<int> player id's - QValueList<int> network priority's - -IdGameLoad - all game data - -IdGameReactivate - QValueList<int> id's - -IdSyncRandom - int randomseed - - -3. Game Properties ------------------- -A very hard task in a network game is consistency. You have to achieve that all -properties of the game and of all players have the same value on all clients -every time. This is because -a) the user might be confused if he sees "Player has $0" on client A but -"Player has $10" on client B and -b) Often game handling depends on those values, e.g. if the example above -happens the computer might quit the game for the Player on client A because -he/she doesn't have enough money. But the game continues on client B. -Another not that easy task is the network protocol itself. You have to write -several send() and receive() functions which apply changed values of properties -to the local property. - -KGameProperty is designed to do all of this for you. KGameProperty is -implemented as a template so you can use it theoretically for every type of data -- even for your self defined classes. - - -3.1 Using KGameProperty ------------------------ -It is basically very easy to use a KGameProperty. You first create your own -class containing the property, e.g: -class MyGame : public KGame -{ -[...] -protected: - KGamePropertyInt money; - KGamePropertyQString name; - KGameProperty<AntotherClass> myProperty; -}; -KGamePropertyInt is just a typedef for KGameProperty<int> - just like -KGamePropertyQString. Now you need to register the properties in the constructor -of the class to the KGamePropertyHandler: -MyGame::MyGame() : KGame(myCookie) -{ - money.registerData(KGamePropertyBase::IdUser+1, dataHandler(), "Money"); - name.registerData(KGamePropertyBase::IdUser+2, this, "Name"); - myProperty.registerData(KGamePropertyBase::IdUser+3, dataHandler(), "MyProperty"); -} --> You need to specify a *unique* ID. This ID must be greater than -KGamePropertyBase::IdUser. IDs below this are reserved for KGame. Probably this -will be changed so that you cannot use IDs below IdUser in the future. Then you -have to specify the dataHandler(). You can also use a KGame or KPlayer pointer. -This will automatically use KGame::dataHandler() or KPlayer::dataHandler(). -Finally you *can* provide a name for the property. This will be used for -debugging in KGameDebugDialog. If you want to save some memory you can leave -this out. -Note that if you use pointers to create the properties dynamically they are -*not* deleted automatically! You MUST delete them yourself! -Now you can use the KGameProperty like every variable else. See also Section -"3.3 Concepts" for restrictions in use. - -3.2 Custom Classes ------------------- -To make custom classes possible you have to implement several operators for your -them: you need at least << and >> for QDataStream as well as "==" for your own -class. To overload the "<<" you would e.g. do something like this: -QDataStream& operator<<(QDataStream& stream, MyData& data) -{ - int type = data.type; - QString name = data.name; - stream << type << name; - return stream; -} -So you basically just have to split your class to several basic types and stream -them. - -3.3 Concepts ------------- -You can use KGameProperty basically in two completely different ways. You can -also use a mixture of both but this is not recommended. The default behaviour -and therefore also the recommended is the "clean" way: -a) Always Consistent. This means that a KGameProperty has always the same value -on *every* client. This is achieved by using KGameProperty::send() whenever you -want to change the value using "=". You can still use changeValue() or -setLocal() but send() will be the default. If you use send() then the value of -the property does *NOT* change immediately. It is just sent to the -KMessageServer which forwards the value to all clients. As soon as the new value -is received from the message server the KGamePropertyHandler (a collection class -for KGameProperty) calls KGameProperty::load() and changes the value of the -property. So the game first has to go into the event loop, where the message is -received. This means to you that you cannot do this: -myIntProperty = 10; -int value = myIntProperty; -As myIntPoperty still has the old value when "value = myIntProperty" is called. -This might seem to be quite complex, but -KGamePropertyHandler::signalPropertyChanged() is emitted whenever a new value is -assigned so you can connect to this and work immediately with the new value. -You gain the certainty that the value is the same on every client every time. -That will safe you a lot of time debugging! -Another way is the "dirty" way: -b) Not Always Consistent. Sometimes you really *want* to do something like -myIntProperty = 10; -int value = myIntProperty; -but this is not possible with the default behaviour. If you call -KGameProperty::setAlwaysConsistent(false) in the constructor (right after -registerData()) you get another behaviour. "=" means changeValue() now. -changeValue() also uses send() to change the value but additionally calls -setLocal() to create a local copy of the property. This copy now has the value -you supplied with "=" and is deleted again as soon as any value from the network -is received. - -4. KGameIO ----------- -The class KGameIO is used to let the players communicate with the server. You -can plug as many KGameIO objects into a player as you want, e.g. you can plug a -KGameMouseIO and a KGameKeyIO into a player so that you can control the player -with the mouse and the keyboard - e.g. in a breakout game. -You can probably see the advantage: as most of the control stuff is common in a -lot of games you can use the same IO class in many different games with very -small adjustments. -You could also put all the IO stuff directly into your KPlayer object, like -sendBet(int money) for a poker game. But there is a major disadvantage and I'm -very sure you don't want to use a KPlayer object for your IO stuff as soon as -you know which disadvantage: -KGameIO is designed to be able to switch between different IOs "on the fly". So -you might have a KGamePlayerIO, derived from KGameIO, for your game. But now -this player (who "owns"/uses the KGamePlayerIO) leaves the game (e.g. because he -was a remote player). So now the game would be over for every player as one -player is now out of order. But with KGameIO you can just let any of the -remaining clients create a KGameComputerIO and plug this into the player. So the -player now is controlled by the computer and the game can continue. - -Think about it! You don't have to care about removing players when a player -leaves as you can just replace it! The same works the other way round: imagine a -game with 10 player (e.g. 5 human and 5 computer players) that has already -started. You cannot add any further players without restarting. So if there are -any additional player you can just call KPlayer::removeGameIO() which removes -the IO of a computer player and then call KPlayer::addGameIO() for the same -player which adds a GameIO for new human player. That's all! - -To achieve this you just have to make sure that you make *all* of your IO -operations through a KGameIO! So instead of using MyPlayer::sendBet(int money) -you should use something like MyIO::sendBet(). The amount of money would -probably be calculated by the game IO itself. - - - -5. Debugging ------------- -The general debugging concept (if there is one at all) or general debugging -hints are not yet written. Feel free to do so - -5.1 KGameDebugDialog --------------------- -A nice way of debugging a KGame based game is the KGameDebugDialog. Basically -all you have to do is to add something like "Debug" to your game's menu and add -a slot like -slotDebug() -{ - KGameDebugDialog* dialog = new KGameDebugDialog(mGame, this); - connect(dialog, SIGNAL(finished()), dialog, SLOT(slotDelayedDestruct())); - dialog->show(); -} -that's it. -You can now click on that menu entry and you get a non-modal dialog where you -can start to debug :-) -The dialog consist of several pages. You can easily add your own using -KDialogBase::addVBoxPage() (for example). - -5.1.1 Debug KGame ------------------ -The first page, "Debug KGame" shows on the left most or even all status values of -KGame. That contains e.g. minPlayers(), isAdmin(), gametqStatus(), ... -The right side is probably the more important one. It lists *all* KGameProperties -which have been inserted to this KGame object (only to this KGame object - not -the ones that have been added to the players!). Most of the status variables of -the left side are here again as they are implemented as KGameProperty. You can -see the name of the property (together with its ID), its value and the policy -this property uses. Note that "unknwon" will be displayed as name of the -property if you haven't supplied one. See KGamePropertyBase::registerData() for -info. You probably always want to supply a name for the property to debug it -easily. In the future there will be something like -KGamePropertyHandler::setDebug() so that you can switch off debugging and save -the memory of the names in a release version. -For as long as you use standard types for your properties (int, long, bool, -...) you should always be able to see the value of the property. If you just see -"unknown" then this type has not been implemented. You can connect to the signal -KGamePropertyHandler::signalRequestValue() and supply a QString with the value -yourself. If you do so for a standard type please also submit a bug report! - -Currently the dialog does *not* update automatically! So you alway have to click -the "update" button when you want a current value. There are several reasons for -this (and one of them is that i'm too lazy to implement the update ;)). E.g. -often (very often) a property is just in the background - stores e.g. the -available money in a game. But you don't want it to update whenever the value -changes (a player receives/pays money) but only when the value on the screen -changes. - -5.1.2 Debug Players -------------------- -This page consists of three widgets. On the very left there is a list of all -players in the game. Only the IDs are displayed to save space. If you click one -the other widgets are filled with content. These widgets are quite much the same -as the ones in "Debug KGame" - the left shows the value of the functions and the -right one displays all KProperties of a player. Not much to say here - except: -See "Debug KGame". - -If you change to another player the value are also updated. - -5.1.3 Debug Messages --------------------- -This page is probably not as important as the other ones. It displays *every* -message that is sent through the KGame object. As a KGameProperry also send -messages you probably get a lot of them... -You can exclude message IDs from being displayed (e.g. all game properties). -You can also change the sorting of the list to see all messages of a certain ID. -The default is to sort by time (which is displayed on the left side). - diff --git a/libkdegames/kgame/Makefile.am b/libkdegames/kgame/Makefile.am deleted file mode 100644 index f49bc653..00000000 --- a/libkdegames/kgame/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ - -noinst_LTLIBRARIES = libkgame.la - -# compile-order doesn't matter here but maybe we will split these section soon - -KGAME = kgame.cpp kplayer.cpp kgamenetwork.cpp kgameproperty.cpp \ - kgamemessage.cpp kgameio.cpp kgameprocess.cpp kgamechat.cpp \ - kgamepropertyhandler.cpp kgameerror.cpp kgamesequence.cpp -KGAME_H = kgame.h kplayer.h kgamenetwork.h kgameproperty.h kgamemessage.h \ - kgameio.h kgameprocess.h kgamepropertyarray.h \ - kgamepropertylist.h kgamechat.h kgamepropertyhandler.h \ - kgameerror.h kgamesequence.h kgameversion.h - -KMESSAGE = kmessageio.cpp kmessageserver.cpp kmessageclient.cpp -KMESSAGE_H = kmessageio.h kmessageserver.h kmessageclient.h - -libkgameincludedir=$(includedir)/kgame -libkgame_la_SOURCES = $(KMESSAGE) $(KGAME) - -libkgameinclude_HEADERS = $(KMESSAGE_H) $(KGAME_H) - -INCLUDES = -I$(top_srcdir)/libtdegames $(all_includes) -METASOURCES = AUTO - -SUBDIRS = . dialogs - -messages: -# $(XGETTEXT) `find . -name \*.h -o -name \*.cpp -o -name \*.cc` -o $(podir)/libtdegames.pot - diff --git a/libkdegames/kgame/README.LIB b/libkdegames/kgame/README.LIB deleted file mode 100644 index 512edbac..00000000 --- a/libkdegames/kgame/README.LIB +++ /dev/null @@ -1,12 +0,0 @@ -some thoughts and comments about the lib - usually for KGame hackers - -- setMin/MaxPlayers() etc. use KGameProperty::changeValue() which is slightly - unclean but as these functions can only called by the ADMIN it doesn't matter. -- AB: KGamePropertyList && KGamePropertyArray: - for PolicyClean||PolicyDirty the values are streamed into a QDataStream as usual - for PolicyDirty||PolicyLocal the values are streamed as well but - additionally command() is called immediately. The values are read from - the stream there. This is some kind of performance loss as it would be - faster *not* to stream it but imediately call e.g. insert(). But it will - probably save a *lot* of bugs! - diff --git a/libkdegames/kgame/TODO b/libkdegames/kgame/TODO deleted file mode 100644 index 2f100b8a..00000000 --- a/libkdegames/kgame/TODO +++ /dev/null @@ -1,41 +0,0 @@ -- 28.02.2001: Direct computer player for kpoker like games support needs to be - improved. UPDATE (01/10/06): but what is needed there? -- 05.03.2001: Documentation. I am thinking of an explaination of the - class + methods and example code for the "key" methods. A sample - implementation in a small game (like the current kdenonbeta/kgame - but with a real sense - mabye use the QT tic-tac-toe example?) - would be very great (this could be stuff of a tutorial instead of - KGame documentation) - MH: Even better idea -- 03.06.2001: can KGameNetwork::sendSystemMessage be made protected (maybe using - friends)? sendSystenMessage AND sendMessage is very confusing to - the user... -- 03.06.2001: can we translate the group of a KPlayer? Probably not as there are - no international connections possible then... maybe a group id? -- 05.06.2001: KGameDialog::saveConfig(KConfig*) might be useful (as well as - KGameDialog::loadConfig(KConfig*). Should set an own group in the - config file (setGroup("KGameDialog")). Problem: shalll network - settings be saved? Could be used for startup configuration (i.e. - load the config of the previous game) otherwise. -- 21.06.2001: KPlayerPropertyArray does not yet support at() and operator[] - assignments. Need to check whether the method from QBitArray - can be applied -- 02.04.2001: VERY DANGEROUS: property1=property2 does NOT assign the values, e.g. int - but assignes the whole property, i.e. you have then two properties with - the same id and everything is wrong - 01/09/09: FIXED! (AB) TODO: check if this behavior also appears in - KGamePropertyList and KGamePropertyArray. Althogh this should not - be the case -- 23.09.2001: does the virtual destructor make sense for KGamePropertyBase? -- 29.09.2001: GGZ integration. I (Andi) already volunteered for this - it's just - here so that I don't forget it -- 06.10.2001: add KGamePropertyHandler::setDebug(false) to clear all debug names - (and to not accept new names) of KGameProperty. Will save some - memory -- 06.10.2001: If one kicks a player (in KGameDialog) the client should be kicked - as well. Perhaps always disconnect a client when all players from - it have disappeared? -- 07.10.2001: display (List) or (Array) for KGameProperty[List|Array] in - KGameDebugDialog as value -- 08.10.2001: KGamePropertyList|KGamePropertyArray must be ported to new QT3 API - (e.g. erase instead of remove, ...) diff --git a/libkdegames/kgame/dialogs/Makefile.am b/libkdegames/kgame/dialogs/Makefile.am deleted file mode 100644 index f3c1adbe..00000000 --- a/libkdegames/kgame/dialogs/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ - -noinst_LTLIBRARIES = libkgamedialogs.la - -# compile-order doesn't matter here but maybe we will split these section soon - - -libkgamedialogs_la_SOURCES = kgamedialog.cpp kgameconnectdialog.cpp kgameerrordialog.cpp kgamedebugdialog.cpp kgamedialogconfig.cpp - -libkgamedialogsincludedir=$(includedir)/kgame -libkgamedialogsinclude_HEADERS = kgamedialog.h kgameconnectdialog.h kgameerrordialog.h kgamedebugdialog.h kgamedialogconfig.h - -INCLUDES = -I$(top_srcdir)/libtdegames -I$(top_srcdir)/libtdegames/kgame $(all_includes) -METASOURCES = AUTO - -messages: -# $(XGETTEXT) `find . -name \*.h -o -name \*.cpp -o -name \*.cc` -o $(podir)/libtdegames.pot - diff --git a/libkdegames/kgame/dialogs/kgameconnectdialog.cpp b/libkdegames/kgame/dialogs/kgameconnectdialog.cpp deleted file mode 100644 index 98958ffd..00000000 --- a/libkdegames/kgame/dialogs/kgameconnectdialog.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 "kgameconnectdialog.h" - -#include <knuminput.h> -#include <klocale.h> - -#include <tqlineedit.h> -#include <tqcombobox.h> -#include <tqvbuttongroup.h> -#include <tqlayout.h> -#include <tqradiobutton.h> -#include <tqlabel.h> -#include <dnssd/servicebrowser.h> -#include <tqpushbutton.h> -#include <tqgrid.h> - -class KGameConnectWidgetPrivate -{ - public: - KGameConnectWidgetPrivate() - { - mPort = 0; - mHost = 0; - mButtonGroup = 0; - mBrowser = 0; - } - - KIntNumInput* mPort; - TQLineEdit* mHost; //KLineEdit? - TQVButtonGroup* mButtonGroup; - TQComboBox *mClientName; - TQLabel *mClientNameLabel; - DNSSD::ServiceBrowser *mBrowser; - TQLabel *mServerNameLabel; - TQLineEdit *mServerName; - TQString mType; -}; - -KGameConnectWidget::KGameConnectWidget(TQWidget* parent) : TQWidget(parent) -{ - d = new KGameConnectWidgetPrivate; - - TQVBoxLayout* vb = new TQVBoxLayout(this, KDialog::spacingHint()); - d->mButtonGroup = new TQVButtonGroup(this); - vb->addWidget(d->mButtonGroup); - connect(d->mButtonGroup, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotTypeChanged(int))); - (void)new TQRadioButton(i18n("Create a network game"), d->mButtonGroup); - (void)new TQRadioButton(i18n("Join a network game"), d->mButtonGroup); - - TQGrid* g = new TQGrid(2, this); - vb->addWidget(g); - g->setSpacing(KDialog::spacingHint()); - d->mServerNameLabel = new TQLabel(i18n("Game name:"), g); - d->mServerName = new TQLineEdit(g); - d->mClientNameLabel = new TQLabel(i18n("Network games:"), g); - d->mClientName = new TQComboBox(g); - connect(d->mClientName,TQT_SIGNAL(activated(int)),TQT_SLOT(slotGameSelected(int))); - (void)new TQLabel(i18n("Port to connect to:"), g); - d->mPort = new KIntNumInput(g); - (void)new TQLabel(i18n("Host to connect to:"), g); - d->mHost = new TQLineEdit(g); - - TQPushButton *button=new TQPushButton(i18n("&Start Network"), this); - connect(button, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(signalNetworkSetup())); - vb->addWidget(button); - // Hide until type is set - d->mClientName->hide(); - d->mClientNameLabel->hide(); - d->mServerName->hide(); - d->mServerNameLabel->hide(); -} - -void KGameConnectWidget::showDnssdControls() -{ - if (!d->mBrowser) return; - if (d->mHost->isEnabled()) { // client - d->mClientName->show(); - d->mClientNameLabel->show(); - d->mServerName->hide(); - d->mServerNameLabel->hide(); - slotGameSelected(d->mClientName->currentItem()); - } else { - d->mClientName->hide(); - d->mClientNameLabel->hide(); - d->mServerName->show(); - d->mServerNameLabel->show(); - } -} - -void KGameConnectWidget::setType(const TQString& type) -{ - d->mType = type; - delete d->mBrowser; - d->mBrowser = new DNSSD::ServiceBrowser(type); - connect(d->mBrowser,TQT_SIGNAL(finished()),TQT_SLOT(slotGamesFound())); - d->mBrowser->startBrowse(); - showDnssdControls(); -} - -void KGameConnectWidget::slotGamesFound() -{ - bool autoselect=false; - if (!d->mClientName->count()) autoselect=true; - d->mClientName->clear(); - TQStringList names; - TQValueList<DNSSD::RemoteService::Ptr>::ConstIterator itEnd = d->mBrowser->services().end(); - for (TQValueList<DNSSD::RemoteService::Ptr>::ConstIterator it = d->mBrowser->services().begin(); - it!=itEnd; ++it) names << (*it)->serviceName(); - d->mClientName->insertStringList(names); - if (autoselect && d->mClientName->count()) slotGameSelected(0); -} - -void KGameConnectWidget::setName(const TQString& name) -{ - d->mServerName->setText(name); -} - -TQString KGameConnectWidget::gameName() const -{ - return d->mServerName->text(); -} - -TQString KGameConnectWidget::type() const -{ - return d->mType; -} - -void KGameConnectWidget::slotGameSelected(int nr) -{ - if (nr>=(d->mBrowser->services().count()) || nr<0) return; - if (!d->mHost->isEnabled()) return; // this is server mode, do not overwrite host and port controls - DNSSD::RemoteService::Ptr srv = d->mBrowser->services()[nr]; - if (!srv->isResolved() && !srv->resolve()) return; - d->mHost->setText(srv->hostName()); - d->mPort->setValue(srv->port()); -} -KGameConnectWidget::~KGameConnectWidget() -{ - delete d->mBrowser; - delete d; -} - -TQString KGameConnectWidget::host() const -{ - if (d->mHost->isEnabled()) { - return d->mHost->text(); - } else { - return TQString(); - } -} - -unsigned short int KGameConnectWidget::port() const -{ - return d->mPort->value(); -} - -void KGameConnectWidget::setHost(const TQString& host) -{ - d->mHost->setText(host); -} - -void KGameConnectWidget::setPort(unsigned short int port) -{ - d->mPort->setValue(port); -} - -void KGameConnectWidget::setDefault(int state) -{ - d->mButtonGroup->setButton(state); - slotTypeChanged(state); -} - -void KGameConnectWidget::slotTypeChanged(int t) -{ - if (t == 0) { - d->mHost->setEnabled(false); - } else if (t == 1) { - d->mHost->setEnabled(true); - } - showDnssdControls(); - emit signalServerTypeChanged(t); -} - -class KGameConnectDialogPrivate -{ - public: - KGameConnectDialogPrivate() - { - mConnect = 0; - } - - KGameConnectWidget* mConnect; -}; - -// buttonmask =Ok|Cancel -KGameConnectDialog::KGameConnectDialog(TQWidget* parent,int buttonmask) : KDialogBase(Plain, - i18n("Network Game"),buttonmask , Ok, parent, 0, true, buttonmask!=0) -{ - d = new KGameConnectDialogPrivate; - TQVBoxLayout* vb = new TQVBoxLayout(plainPage(), spacingHint()); - d->mConnect = new KGameConnectWidget(plainPage()); - vb->addWidget(d->mConnect); -} - -KGameConnectDialog::~KGameConnectDialog() -{ - delete d; -} - -int KGameConnectDialog::initConnection( unsigned short int& port, - TQString& host, TQWidget* parent, bool server) -{ - KGameConnectDialog d(parent); - d.setHost(host); - d.setPort(port); - if (server) { - d.setDefault(0); - } else { - d.setDefault(1); - } - - int result = d.exec(); - if (result == TQDialog::Accepted) { - host = d.host(); - port = d.port(); - } - return result; -} - -TQString KGameConnectDialog::host() const -{ - return d->mConnect->host(); -} - -unsigned short int KGameConnectDialog::port() const -{ - return d->mConnect->port(); -} - -void KGameConnectDialog::setHost(const TQString& host) -{ - d->mConnect->setHost(host); -} - -void KGameConnectDialog::setPort(unsigned short int port) -{ - d->mConnect->setPort(port); -} - -void KGameConnectDialog::setDefault(int state) -{ - d->mConnect->setDefault(state); -} - - - -#include "kgameconnectdialog.moc" - diff --git a/libkdegames/kgame/dialogs/kgameconnectdialog.h b/libkdegames/kgame/dialogs/kgameconnectdialog.h deleted file mode 100644 index 0a14183d..00000000 --- a/libkdegames/kgame/dialogs/kgameconnectdialog.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMECONNECTDIALOG_H__ -#define __KGAMECONNECTDIALOG_H__ - -#include <kdialogbase.h> - -class KGameConnectDialogPrivate; -class KGameConnectWidgetPrivate; - -class KGameConnectWidget : public TQWidget -{ - Q_OBJECT - TQ_OBJECT -public: - KGameConnectWidget(TQWidget* parent); - virtual ~KGameConnectWidget(); - - /** - * @param host The host to connect to by default - **/ - void setHost(const TQString& host); - - /** - * @return The host to connect to or TQString() if the user wants to - * be the MASTER - **/ - TQString host() const; - - /** - * @param port The port that will be shown by default - **/ - void setPort(unsigned short int port); - - /** - * @return The port to connect to / to listen - **/ - unsigned short int port() const; - - /** - * Specifies which state is the default (0 = server game; 1 = join game) - * @param state The default state. 0 For a server game, 1 to join a game - **/ - void setDefault(int state); - - /** - * Sets DNS-SD service type, both for publishing and browsing - * @param type Service type (something like _kwin4._tcp). - * It should be unique for application. - * @since 3.4 - **/ - void setType(const TQString& type); - - /** - * @return service type - */ - TQString type() const; - - /** - * Set game name for publishing. - * @param name Game name. Important only for server mode. If not - * set hostname will be used. In case of name conflict -2, -3 and so on will be added to name. - */ - void setName(const TQString& name); - - /** - * @return game name. - */ - TQString gameName() const; - -protected slots: - /** - * The type has changed, ie the user switched between creating or - * joining. - **/ - void slotTypeChanged(int); - void slotGamesFound(); - void slotGameSelected(int); - -signals: - void signalNetworkSetup(); - void signalServerTypeChanged(int); - -private: - void showDnssdControls(); - KGameConnectWidgetPrivate* d; - -}; - -/** - * @short Dialog to ask for host and port - * - * This Dialog is used to create a game. You call initConnection(port, - * TQString(), parent, true) to create a network game (as a server) - * or initConnection(port, host, parent) to join a network game. - * - * @author Andreas Beckermann <[email protected]> - **/ -class KGameConnectDialog : public KDialogBase -{ - Q_OBJECT - TQ_OBJECT -public: - KGameConnectDialog(TQWidget* parent = 0,int buttonmask=Ok|Cancel); - virtual ~KGameConnectDialog(); - - /** - * Shows a dialog to either connect to an existing game or to create a - * server game, depending on user's choice. - * @param port The port the user wants to connect to. - * @param host The host the user wants to connect to. Will be - * TQString() if server game is chosen - * @param parent The parent of the dialog - * @param server True to create a network game per default, false to - * join a game by default - **/ - static int initConnection(unsigned short int& port, TQString& host, TQWidget* parent, bool server = false); - - /** - * @param host The host to connect to by default - **/ - void setHost(const TQString& host); - - /** - * @return The host to connect to or TQString() if the user wants to - * be the MASTER - **/ - TQString host() const; - - /** - * @param port The port that will be shown by default - **/ - void setPort(unsigned short int port); - - /** - * @return The port to connect to / to listen - **/ - unsigned short int port() const; - - /** - * Specifies which state is the default (0 = server game; 1 = join game) - * @param state The default state. 0 For a server game, 1 to join a game - **/ - void setDefault(int state); - -signals: - void signalNetworkSetup(); - -private: - KGameConnectDialogPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/dialogs/kgamedebugdialog.cpp b/libkdegames/kgame/dialogs/kgamedebugdialog.cpp deleted file mode 100644 index 49623238..00000000 --- a/libkdegames/kgame/dialogs/kgamedebugdialog.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 "kgamedebugdialog.h" - -#include "kgamemessage.h" -#include "kgame.h" -#include "kplayer.h" -#include "kgamepropertyhandler.h" - -#include <klistview.h> -#include <klistbox.h> -#include <klocale.h> -#include <kdebug.h> -#include <kpushbutton.h> -#include <kstdguiitem.h> - -#include <tqlayout.h> -#include <tqstring.h> -#include <tqintdict.h> -#include <tqlabel.h> -#include <tqdatetime.h> - -#include <typeinfo> - - -class KGameDebugDialogPrivate -{ -public: - KGameDebugDialogPrivate() - { - mGame = 0; - - mGamePage = 0; - mGameProperties = 0; - mGameAddress = 0; - mGameId = 0; - mGameCookie = 0; - mGameMaster = 0; - mGameAdmin = 0; - mGameOffering = 0; - mGametqStatus = 0; - mGameRunning = 0; - mGameMaxPlayers = 0; - mGameMinPlayers = 0; - mGamePlayerCount = 0; - - mPlayerPage = 0; - mPlayerList = 0; - mPlayerProperties = 0; - mPlayerAddress = 0; - mPlayerId = 0; - mPlayerName = 0; - mPlayerGroup = 0; - mPlayerUserId = 0; - mPlayerMyTurn = 0; - mPlayerAsyncInput= 0; - mPlayerKGameAddress = 0; - mPlayerVirtual = 0; - mPlayerActive = 0; - mPlayerRtti = 0; - mPlayerNetworkPriority = 0; - - mMessagePage = 0; - mMessageList = 0; - mHideIdList = 0; - } - - const KGame* mGame; - - TQFrame* mGamePage; - KListView* mGameProperties; - TQListViewItem* mGameAddress; - TQListViewItem* mGameId; - TQListViewItem* mGameCookie; - TQListViewItem* mGameMaster; - TQListViewItem* mGameAdmin; - TQListViewItem* mGameOffering; - TQListViewItem* mGametqStatus; - TQListViewItem* mGameRunning; - TQListViewItem* mGameMaxPlayers; - TQListViewItem* mGameMinPlayers; - TQListViewItem* mGamePlayerCount; - - TQFrame* mPlayerPage; - KListBox* mPlayerList; - KListView* mPlayerProperties; - TQListViewItem* mPlayerAddress; - TQListViewItem* mPlayerId; - TQListViewItem* mPlayerName; - TQListViewItem* mPlayerGroup; - TQListViewItem* mPlayerUserId; - TQListViewItem* mPlayerMyTurn; - TQListViewItem* mPlayerAsyncInput; - TQListViewItem* mPlayerKGameAddress; - TQListViewItem* mPlayerVirtual; - TQListViewItem* mPlayerActive; - TQListViewItem* mPlayerRtti; - TQListViewItem* mPlayerNetworkPriority; - - TQFrame* mMessagePage; - KListView* mMessageList; - KListBox* mHideIdList; -}; - -KGameDebugDialog::KGameDebugDialog(KGame* g, TQWidget* parent, bool modal) : - KDialogBase(Tabbed, i18n("KGame Debug Dialog"), Close, Close, - parent, 0, modal, true) -{ - d = new KGameDebugDialogPrivate; - - initGamePage(); - initPlayerPage(); - initMessagePage(); - - setKGame(g); -} - -KGameDebugDialog::~KGameDebugDialog() -{ - delete d; -} - -void KGameDebugDialog::initGamePage() -{ - d->mGamePage = addPage(i18n("Debug &KGame")); - TQVBoxLayout* topLayout = new TQVBoxLayout(d->mGamePage, marginHint(), spacingHint()); - TQHBoxLayout* tqlayout = new TQHBoxLayout(topLayout); - - KListView* v = new KListView(d->mGamePage); - v->addColumn(i18n("Data")); - v->addColumn(i18n("Value")); - tqlayout->addWidget(v); - - d->mGameProperties = new KListView(d->mGamePage); - d->mGameProperties->addColumn(i18n("Property")); - d->mGameProperties->addColumn(i18n("Value")); - d->mGameProperties->addColumn(i18n("Policy")); - tqlayout->addWidget(d->mGameProperties); - - TQPushButton* b = new TQPushButton(i18n("Update"), d->mGamePage); - connect(b, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotUpdateGameData())); - topLayout->addWidget(b); - -// game data - d->mGameAddress = new TQListViewItem(v, i18n("KGame Pointer")); - d->mGameId = new TQListViewItem(v, i18n("Game ID")); - d->mGameCookie = new TQListViewItem(v, i18n("Game Cookie")); - d->mGameMaster = new TQListViewItem(v, i18n("Is Master")); - d->mGameAdmin = new TQListViewItem(v, i18n("Is Admin")); - d->mGameOffering = new TQListViewItem(v, i18n("Is Offering Connections")); - d->mGametqStatus = new TQListViewItem(v, i18n("Game Status")); - d->mGameRunning = new TQListViewItem(v, i18n("Game is Running")); - d->mGameMaxPlayers = new TQListViewItem(v, i18n("Maximal Players")); - d->mGameMinPlayers = new TQListViewItem(v, i18n("Minimal Players")); - d->mGamePlayerCount = new TQListViewItem(v, i18n("Players")); -} - -void KGameDebugDialog::initPlayerPage() -{ - d->mPlayerPage = addPage(i18n("Debug &Players")); - TQVBoxLayout* topLayout = new TQVBoxLayout(d->mPlayerPage, marginHint(), spacingHint()); - TQHBoxLayout* tqlayout = new TQHBoxLayout(topLayout); - - //TODO: connect to the KGame signals for joined/removed players!!! - TQVBoxLayout* listLayout = new TQVBoxLayout(tqlayout); - TQLabel* listLabel = new TQLabel(i18n("Available Players"), d->mPlayerPage); - listLayout->addWidget(listLabel); - d->mPlayerList = new KListBox(d->mPlayerPage); - connect(d->mPlayerList, TQT_SIGNAL(executed(TQListBoxItem*)), this, TQT_SLOT(slotUpdatePlayerData(TQListBoxItem*))); - listLayout->addWidget(d->mPlayerList); - d->mPlayerList->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding)); - - KListView* v = new KListView(d->mPlayerPage); - tqlayout->addWidget(v); - v->addColumn(i18n("Data")); - v->addColumn(i18n("Value")); - - d->mPlayerProperties = new KListView(d->mPlayerPage); - d->mPlayerProperties->addColumn(i18n("Property")); - d->mPlayerProperties->addColumn(i18n("Value")); - d->mPlayerProperties->addColumn(i18n("Policy")); - tqlayout->addWidget(d->mPlayerProperties); - - TQPushButton* b = new TQPushButton(i18n("Update"), d->mPlayerPage); - connect(b, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotUpdatePlayerList())); - topLayout->addWidget(b); - - d->mPlayerAddress = new TQListViewItem(v, i18n("Player Pointer")); - d->mPlayerId = new TQListViewItem(v, i18n("Player ID")); - d->mPlayerName = new TQListViewItem(v, i18n("Player Name")); - d->mPlayerGroup = new TQListViewItem(v, i18n("Player Group")); - d->mPlayerUserId = new TQListViewItem(v, i18n("Player User ID")); - d->mPlayerMyTurn = new TQListViewItem(v, i18n("My Turn")); - d->mPlayerAsyncInput = new TQListViewItem(v, i18n("Async Input")); - d->mPlayerKGameAddress = new TQListViewItem(v, i18n("KGame Address")); - d->mPlayerVirtual = new TQListViewItem(v, i18n("Player is Virtual")); - d->mPlayerActive = new TQListViewItem(v, i18n("Player is Active")); - d->mPlayerRtti = new TQListViewItem(v, i18n("RTTI")); - d->mPlayerNetworkPriority = new TQListViewItem(v, i18n("Network Priority")); -} - -void KGameDebugDialog::initMessagePage() -{ - d->mMessagePage = addPage(i18n("Debug &Messages")); - TQGridLayout* tqlayout = new TQGridLayout(d->mMessagePage, 11, 7, marginHint(), spacingHint()); - d->mMessageList = new KListView(d->mMessagePage); - tqlayout->addMultiCellWidget(d->mMessageList, 0, 9, 0, 3); - d->mMessageList->addColumn(i18n("Time")); - d->mMessageList->addColumn(i18n("ID")); - d->mMessageList->addColumn(i18n("Receiver")); - d->mMessageList->addColumn(i18n("Sender")); - d->mMessageList->addColumn(i18n("ID - Text")); - - TQPushButton* hide = new TQPushButton(i18n("&>>"), d->mMessagePage); - connect(hide, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotHideId())); - tqlayout->addWidget(hide, 4, 4); - - TQPushButton* show = new TQPushButton(i18n("&<<"), d->mMessagePage); - connect(show, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotShowId())); - tqlayout->addWidget(show, 6, 4); - - TQLabel* l = new TQLabel(i18n("Do not show IDs:"), d->mMessagePage); - tqlayout->addMultiCellWidget(l, 0, 0, 5, 6); - d->mHideIdList = new KListBox(d->mMessagePage); - tqlayout->addMultiCellWidget(d->mHideIdList, 1, 8, 5, 6); - - TQPushButton* clear = new KPushButton(KStdGuiItem::clear(), d->mMessagePage); - connect(clear, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotClearMessages())); - tqlayout->addMultiCellWidget(clear, 10, 10, 0, 6); - //TODO: "show all but..." and "show nothing but..." -} - -void KGameDebugDialog::clearPlayerData() -{ - d->mPlayerAddress->setText(1, ""); - d->mPlayerId->setText(1, ""); - d->mPlayerName->setText(1, ""); - d->mPlayerGroup->setText(1, ""); - d->mPlayerUserId->setText(1, ""); - d->mPlayerMyTurn->setText(1, ""); - d->mPlayerAsyncInput->setText(1, ""); - d->mPlayerKGameAddress->setText(1, ""); - d->mPlayerVirtual->setText(1, ""); - d->mPlayerActive->setText(1, ""); - d->mPlayerRtti->setText(1, ""); - d->mPlayerNetworkPriority->setText(1, ""); - - d->mPlayerProperties->clear(); -} - -void KGameDebugDialog::clearGameData() -{ - d->mGameAddress->setText(1, ""); - d->mGameId->setText(1, ""); - d->mGameCookie->setText(1, ""); - d->mGameMaster->setText(1, ""); - d->mGameAdmin->setText(1, ""); - d->mGameOffering->setText(1, ""); - d->mGametqStatus->setText(1, ""); - d->mGameRunning->setText(1, ""); - d->mGameMaxPlayers->setText(1, ""); - d->mGameMinPlayers->setText(1, ""); - - d->mGameProperties->clear(); -} - -void KGameDebugDialog::slotUpdatePlayerData() -{ - if (!d->mGame || d->mPlayerList->currentItem() == -1) { - return; - } - slotUpdatePlayerData(d->mPlayerList->item(d->mPlayerList->currentItem())); -} - -void KGameDebugDialog::slotUpdatePlayerList() -{ - TQListBoxItem* i = d->mPlayerList->firstItem(); - for (; i; i = d->mPlayerList->firstItem()) { - removePlayer(i); - } - - TQPtrList<KPlayer> list = *d->mGame->playerList(); - for (KPlayer* p = list.first(); p; p = list.next()) { - addPlayer(p); - } -} - -void KGameDebugDialog::slotUpdateGameData() -{ - if (!d->mGame) { - d->mGameAddress->setText(1, i18n("NULL pointer")); - return; -} - - clearGameData(); - - TQString buf; - buf.sprintf("%p", d->mGame); - d->mGameAddress->setText(1, buf); - d->mGameId->setText(1, TQString::number(d->mGame->gameId())); - d->mGameCookie->setText(1, TQString::number(d->mGame->cookie())); - d->mGameMaster->setText(1, d->mGame->isMaster() ? i18n("True") : i18n("False")); - d->mGameAdmin->setText(1, d->mGame->isAdmin() ? i18n("True") : i18n("False")); - d->mGameOffering->setText(1, d->mGame->isOfferingConnections() ? i18n("True") : i18n("False")); - d->mGametqStatus->setText(1, TQString::number(d->mGame->gametqStatus())); - d->mGameRunning->setText(1, d->mGame->isRunning() ? i18n("True") : i18n("False")); - d->mGameMaxPlayers->setText(1, TQString::number(d->mGame->maxPlayers())); - d->mGameMinPlayers->setText(1, TQString::number(d->mGame->minPlayers())); - d->mGamePlayerCount->setText(1, TQString::number(d->mGame->playerCount())); - -//TODO ios - - KGamePropertyHandler* handler = d->mGame->dataHandler(); - TQIntDictIterator<KGamePropertyBase> it(handler->dict()); - while (it.current()) { - TQString policy; - switch (it.current()->policy()) { - case KGamePropertyBase::PolicyClean: - policy = i18n("Clean"); - break; - case KGamePropertyBase::PolicyDirty: - policy = i18n("Dirty"); - break; - case KGamePropertyBase::PolicyLocal: - policy = i18n("Local"); - break; - case KGamePropertyBase::PolicyUndefined: - default: - policy = i18n("Undefined"); - break; - } - (void) new TQListViewItem(d->mGameProperties, - handler->propertyName(it.current()->id()), - handler->propertyValue(it.current()), - policy); -// kdDebug(11001) << k_funcinfo << ": checking for all game properties: found property name " << name << endl; - ++it; - } -} - -void KGameDebugDialog::slotUpdatePlayerData(TQListBoxItem* item) -{ - if (!item || !d->mGame) { - return; - } - - KPlayer* p = d->mGame->findPlayer(item->text().toInt()); - - if (!p) { - kdError(11001) << k_funcinfo << ": cannot find player" << endl; - return; - } - - clearPlayerData(); - - TQString buf; - buf.sprintf("%p", p); - d->mPlayerAddress->setText(1, buf); - d->mPlayerId->setText(1, TQString::number(p->id())); - d->mPlayerName->setText(1, p->name()); - d->mPlayerGroup->setText(1, p->group()); - d->mPlayerUserId->setText(1, TQString::number(p->userId())); - d->mPlayerMyTurn->setText(1, p->myTurn() ? i18n("True") : i18n("False")); - d->mPlayerAsyncInput->setText(1, p->asyncInput() ? i18n("True") : i18n("False")); - buf.sprintf("%p", p->game()); - d->mPlayerKGameAddress->setText(1, buf); - d->mPlayerVirtual->setText(1, p->isVirtual() ? i18n("True") : i18n("False")); - d->mPlayerActive->setText(1, p->isActive() ? i18n("True") : i18n("False")); - d->mPlayerRtti->setText(1, TQString::number(p->rtti())); - d->mPlayerNetworkPriority->setText(1, TQString::number(p->networkPriority())); - -//TODO ios - -// Properties - KGamePropertyHandler * handler = p->dataHandler(); - TQIntDictIterator<KGamePropertyBase> it((handler->dict())); - while (it.current()) { - TQString policy; - switch (it.current()->policy()) { - case KGamePropertyBase::PolicyClean: - policy = i18n("Clean"); - break; - case KGamePropertyBase::PolicyDirty: - policy = i18n("Dirty"); - break; - case KGamePropertyBase::PolicyLocal: - policy = i18n("Local"); - break; - case KGamePropertyBase::PolicyUndefined: - default: - policy = i18n("Undefined"); - break; - } - (void)new TQListViewItem(d->mPlayerProperties, - handler->propertyName(it.current()->id()), - handler->propertyValue(it.current()), - policy); - ++it; - } -} - -void KGameDebugDialog::clearPages() -{ - clearPlayerData(); - clearGameData(); - d->mPlayerList->clear(); - slotClearMessages(); -} - -void KGameDebugDialog::setKGame(const KGame* g) -{ - slotUnsetKGame(); - d->mGame = g; - if (g) { - //TODO: connect to the KGame signals for joined/removed players!!! - connect(d->mGame, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotUnsetKGame())); -// connect(); - - TQPtrList<KPlayer> list = *d->mGame->playerList(); - for (KPlayer* p = list.first(); p; p = list.next()) { - addPlayer(p); - } - - slotUpdateGameData(); - - connect(d->mGame, TQT_SIGNAL(signalMessageUpdate(int, TQ_UINT32, TQ_UINT32)), this, TQT_SLOT(slotMessageUpdate(int, TQ_UINT32, TQ_UINT32))); - } -} - -void KGameDebugDialog::slotUnsetKGame() -{ - if (d->mGame) { - disconnect(d->mGame, 0, this, 0); - } - d->mGame = 0; - clearPages(); -} - -void KGameDebugDialog::addPlayer(KPlayer* p) -{ - if (!p) { - kdError(11001) << "trying to add NULL player" << endl; - return; - } - - (void) new TQListBoxText(d->mPlayerList, TQString::number(p->id())); - //TODO connect to signals, like deleted/removed, ... -} - -void KGameDebugDialog::removePlayer(TQListBoxItem* i) -{ - if (!i || !d->mGame) { - return; - } - KPlayer* p = d->mGame->findPlayer(i->text().toInt()); - if (!p) { - return; - } - disconnect(p, 0, this, 0); - if (i->isSelected()) { - clearPlayerData(); - } - delete i; -} - -void KGameDebugDialog::slotMessageUpdate(int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - if (!showId(msgid)) { - return; - } - TQString msgidText = KGameMessage::messageId2Text(msgid); - if (msgidText.isNull()) { - if (msgid > KGameMessage::IdUser) { - emit signalRequestIdName(msgid-KGameMessage::IdUser, true, msgidText); - } else { - emit signalRequestIdName(msgid, false, msgidText); - } - if (msgidText.isNull()) { - msgidText = i18n("Unknown"); - } - } - (void) new TQListViewItem( d->mMessageList, TQTime::currentTime().toString(), - TQString::number(msgid), TQString::number(receiver), - TQString::number(sender), msgidText); -} - -void KGameDebugDialog::slotClearMessages() -{ - d->mMessageList->clear(); -} - -void KGameDebugDialog::slotShowId() -{ -/* TQListBoxItem* i = d->mHideIdList->firstItem(); - for (; i; i = i->next()) { - if (i->selected()) { - d->mHideIdList->removeItem(i->); - } - }*/ - if (!d->mHideIdList->currentItem()) { - return; - } - d->mHideIdList->removeItem(d->mHideIdList->currentItem()); -} - -void KGameDebugDialog::slotHideId() -{ - if (!d->mMessageList->currentItem()) { - return; - } - int msgid = d->mMessageList->currentItem()->text(1).toInt(); - if (!showId(msgid)) { - return; - } - (void)new TQListBoxText(d->mHideIdList, TQString::number(msgid)); -} - -bool KGameDebugDialog::showId(int msgid) -{ - TQListBoxItem* i = d->mHideIdList->firstItem(); - for (; i; i = i->next()) { - if (i->text().toInt() == msgid) { - return false; - } - } - return true; -} - - -#include "kgamedebugdialog.moc" diff --git a/libkdegames/kgame/dialogs/kgamedebugdialog.h b/libkdegames/kgame/dialogs/kgamedebugdialog.h deleted file mode 100644 index 92b35597..00000000 --- a/libkdegames/kgame/dialogs/kgamedebugdialog.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEDEBUGDIALOG_H__ -#define __KGAMEDEBUGDIALOG_H__ - -#include <kdialogbase.h> -#include <kdemacros.h> - -class KGame; -class KGameIO; -class KPlayer; -class KGamePropertyBase; - -class KGameDebugDialogPrivate; - -class KDE_EXPORT KGameDebugDialog : public KDialogBase -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDebugDialog(KGame* g, TQWidget* parent, bool modal = false); - ~KGameDebugDialog(); - - /** - * Automatically connects the KGame object to all error dependant slots. - * Create a KGameErrorDialog object, call this function and forget - * everything. - * @param g The KGame which will emit the erorrs (or not ;-) ) - **/ - void setKGame(const KGame* g); - -public slots: - /** - * Unsets a @ref KGame which has been set using @ref setKGame before. - * This is called automatically when the @ref KGame object is destroyed - * and you normally don't have to call this yourself. - * - * Note that @ref setKGame also unsets an already existing @ref KGame - * object if exising. - **/ - void slotUnsetKGame(); - - /** - * Update the data of the @ref KGame object - **/ - void slotUpdateGameData(); - - /** - * Update the properties of the currently selected player - **/ - void slotUpdatePlayerData(); - - /** - * Updates the list of players and calls @ref clearPlayerData. Note that - * after this call NO player is selected anymore. - **/ - void slotUpdatePlayerList(); - - void slotClearMessages(); - -signals: - /** - * This signal is emitted when the "debug messages" page couldn't find - * the name of a message id. This is usually the case for user-defined - * messages. KGameDebugDialog asks you to give the msgid a name. - * @param messageid The ID of the message. As given to @ref - * KGame::sendMessage - * @param userid User defined msgIds are internally increased by - * @ref KGameMessage::IdUser. You don't have to care about this but if - * this signal is emitted with userid=false (shouldn't happen) then the - * name of an internal message as defined in @ref - * KGameMessage::GameMessageIds couldn't be found. - * @param name The name of the msgid. You have to fill this! - **/ - void signalRequestIdName(int messageid, bool userid, TQString& name); - -protected: - void clearPages(); - - /** - * Clear the data of the player view. Note that the player list is NOT - * cleared. - **/ - void clearPlayerData(); - - /** - * Clear the data view of the @ref KGame object - **/ - void clearGameData(); - - /** - * Add a new player to the player list - **/ - void addPlayer(KPlayer* p); - - /** - * Remove a player from the list - **/ - void removePlayer(TQListBoxItem* item); - - /** - * @return Whether messages with this msgid shall be displayed or not - **/ - bool showId(int msgid); - -protected slots: - /** - * Update the data of the player specified in item - * @param item The @ref TQListBoxItem of the player to be updated. Note - * that the text of this item MUST be the ID of the player - **/ - void slotUpdatePlayerData(TQListBoxItem* item); - - void slotShowId(); - void slotHideId(); - - /** - * A message has been received - see @ref KGame::signalMessageUpdate - **/ - void slotMessageUpdate(int msgid, TQ_UINT32 receiver, TQ_UINT32 sender); - -private: - void initGamePage(); - void initPlayerPage(); - void initMessagePage(); - -private: - KGameDebugDialogPrivate* d; -}; - - -#endif diff --git a/libkdegames/kgame/dialogs/kgamedialog.cpp b/libkdegames/kgame/dialogs/kgamedialog.cpp deleted file mode 100644 index c03df4ff..00000000 --- a/libkdegames/kgame/dialogs/kgamedialog.cpp +++ /dev/null @@ -1,347 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 <tqlayout.h> -#include <tqvbox.h> - -#include <klocale.h> - -#include "kgame.h" -#include "kplayer.h" -#include "kgamedialogconfig.h" - -#include "kgamedialog.h" - -#include "kgamedialog.moc" - -class KGameDialogPrivate -{ -public: - KGameDialogPrivate() - { - mGamePage = 0; - mNetworkPage = 0; - mMsgServerPage = 0; - mTopLayout = 0; - - mNetworkConfig = 0; - mGameConfig = 0; - - mOwner = 0; - mGame = 0; - } - - TQVBox* mGamePage; - TQVBox* mNetworkPage; - TQVBox* mMsgServerPage;// unused here? - TQVBoxLayout* mTopLayout; - KGameDialogNetworkConfig* mNetworkConfig; - KGameDialogGeneralConfig* mGameConfig; - -// a list of all config widgets added to this dialog - TQPtrList<KGameDialogConfig> mConfigWidgets; - -// just pointers: - KPlayer* mOwner; - KGame* mGame; -}; - -KGameDialog::KGameDialog(KGame* g, KPlayer* owner, const TQString& title, - TQWidget* parent, bool modal) - : KDialogBase(Tabbed, title, Ok|Default|Apply, - Ok, parent, 0, modal, true) -{ - init(g, owner); -} - -KGameDialog::KGameDialog(KGame* g, KPlayer* owner, const TQString& title, - TQWidget* parent, long initConfigs, int chatMsgId, bool modal) - : KDialogBase(Tabbed, title, Ok|Default|Apply, - Ok, parent, 0, modal, true) -{ - init(g, owner); - if ((ConfigOptions)initConfigs!=NoConfig) { - initDefaultDialog((ConfigOptions)initConfigs, chatMsgId); - } -} - -void KGameDialog::init(KGame* g, KPlayer* owner) -{ -//AB: do we need a "Cancel" Button? currently removed - -// kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - d = new KGameDialogPrivate; - - setOwner(owner); - setKGame(g); - if (g) { - setAdmin(g->isAdmin()); - } else { - setAdmin(false); - } -} - -void KGameDialog::initDefaultDialog(ConfigOptions initConfigs, int chatMsgId) -{ - if (initConfigs & GameConfig) { - kdDebug() << "add gameconf" << endl; - addGameConfig(new KGameDialogGeneralConfig(0)); - } - if (initConfigs & NetworkConfig) { - addNetworkConfig(new KGameDialogNetworkConfig(0)); - } - if (initConfigs & (MsgServerConfig) ) { - addMsgServerConfig(new KGameDialogMsgServerConfig(0)); - } - if (initConfigs & ChatConfig) { - KGameDialogChatConfig * c = new KGameDialogChatConfig(chatMsgId, 0); - if (d->mGamePage) { - addChatWidget(c, d->mGamePage); - } else { - addConfigPage(c, i18n("&Chat")); - } - } - if (initConfigs & BanPlayerConfig) { - // add the connection management system - ie the widget where the ADMIN can - // kick players out - if (d->mNetworkPage) { - // put it on the network page - addConnectionList(new KGameDialogConnectionConfig(0), d->mNetworkPage); - } else { - // if no network page available put it on an own page - addConfigPage(new KGameDialogConnectionConfig(0), i18n("C&onnections")); - } - } -} - -KGameDialog::~KGameDialog() -{ -// kdDebug(11001) << "DESTRUCT KGameDialog" << this << endl; - d->mConfigWidgets.setAutoDelete(true); - d->mConfigWidgets.clear(); - delete d; -} - -void KGameDialog::addGameConfig(KGameDialogGeneralConfig* conf) -{ - if (!conf) { - return; - } - d->mGameConfig = conf; - d->mGamePage = addConfigPage(d->mGameConfig, i18n("&Game")); -} - -void KGameDialog::addNetworkConfig(KGameDialogNetworkConfig* netConf) -{ - if (!netConf) { - return; - } - d->mNetworkConfig = netConf; - d->mNetworkPage = addConfigPage(netConf, i18n("&Network")); -} - -void KGameDialog::addMsgServerConfig(KGameDialogMsgServerConfig* msgConf) -{ - if (!msgConf) { - return; - } - d->mMsgServerPage = addConfigPage(msgConf, i18n("&Message Server")); -} - -void KGameDialog::addChatWidget(KGameDialogChatConfig* chat, TQVBox* parent) -{ - if (!chat) { - return; - } - if (!parent) { - parent = d->mGamePage; - } - if (!parent) { - kdError(11001) << "cannot add chat widget without page" << endl; - return; - } - addConfigWidget(chat, parent); -} - -void KGameDialog::addConnectionList(KGameDialogConnectionConfig* c, TQVBox* parent) -{ - if (!c) { - return; - } - if (!parent) { - parent = d->mNetworkPage; - } - if (!parent) { - kdError(11001) << "Cannot add connection list without page" << endl; - return; - } - addConfigWidget(c, parent); -} - -TQVBox *KGameDialog::configPage(ConfigOptions which) -{ - TQVBox *box = 0; - switch(which) - { - case NetworkConfig: - box = d->mNetworkPage; - break; - case GameConfig: - box = d->mGamePage; - break; - case MsgServerConfig: - box = d->mMsgServerPage; - break; - default: - kdError(11001) << k_funcinfo << ": Parameter " << which << " not supported" << endl; - } - return box; -} - -TQVBox* KGameDialog::addConfigPage(KGameDialogConfig* widget, const TQString& title) -{ - if (!widget) { - kdError(11001) << "Cannot add NULL config widget" << endl; - return 0; - } - TQVBox* page = addVBoxPage(title); - addConfigWidget(widget, page); - return page; -} - -void KGameDialog::addConfigWidget(KGameDialogConfig* widget, TQWidget* parent) -{ - if (!widget) { - kdError(11001) << "Cannot add NULL config widget" << endl; - return; - } - if (!parent) { - kdError(11001) << "Cannot reparent to NULL widget" << endl; - return; - } -// kdDebug(11001) << "reparenting widget" << endl; - widget->reparent(parent, TQPoint(0,0)); - d->mConfigWidgets.append(widget); - connect(widget, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(slotRemoveConfigWidget(TQObject*))); - if (!d->mGame) { - kdWarning(11001) << "No game has been set!" << endl; - } else { - widget->setKGame(d->mGame); - widget->setAdmin(d->mGame->isAdmin()); - } - if (!d->mOwner) { - kdWarning(11001) << "No player has been set!" << endl; - } else { - widget->setOwner(d->mOwner); - } - widget->show(); -} - -KGameDialogGeneralConfig* KGameDialog::gameConfig() const -{ return d->mGameConfig; } -KGameDialogNetworkConfig* KGameDialog::networkConfig() const -{ return d->mNetworkConfig; } - -void KGameDialog::slotApply() -{ - submitToKGame(); -} - -void KGameDialog::slotDefault() -{ - if (!d->mGame) { - return; - } - -//TODO *only* call setKGame/setOwner for the *current* page!! - setKGame(d->mGame); - setOwner(d->mOwner); -} - -void KGameDialog::slotOk() -{ - slotApply(); - TQDialog::accept(); -} - -void KGameDialog::setOwner(KPlayer* owner) -{ -//AB: note: NULL player is ok! - d->mOwner = owner; - for (int unsigned i = 0; i < d->mConfigWidgets.count(); i++) { - if (d->mConfigWidgets.at(i)) { - d->mConfigWidgets.at(i)->setOwner(d->mOwner); - //TODO: hide playerName in KGameDialogGeneralConfig - } else { - kdError(11001) << "NULL widget??" << endl; - } - } -} - -void KGameDialog::setKGame(KGame* g) -{ - if (d->mGame) { - disconnect(d->mGame, 0, this, 0); - } - d->mGame = g; - for (int unsigned i = 0; i < d->mConfigWidgets.count(); i++) { - d->mConfigWidgets.at(i)->setKGame(d->mGame); - } - if (d->mGame) { - setAdmin(d->mGame->isAdmin()); - connect(d->mGame, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotUnsetKGame())); - connect(d->mGame, TQT_SIGNAL(signalAdminStatusChanged(bool)), - this, TQT_SLOT(setAdmin(bool))); - } -} - -void KGameDialog::setAdmin(bool admin) -{ - for (int unsigned i = 0; i < d->mConfigWidgets.count(); i++) { - d->mConfigWidgets.at(i)->setAdmin(admin); - } -} - -void KGameDialog::slotUnsetKGame() // called when KGame is destroyed -{ setKGame(0); } - -void KGameDialog::submitToKGame() -{ - if (!d->mGame) { - kdError(11001) << k_funcinfo << ": no game has been set" << endl; - return; - } - if (!d->mOwner) { - kdError(11001) << k_funcinfo << ": no player has been set" << endl; - return; - } - - for (int unsigned i = 0; i < d->mConfigWidgets.count(); i++) { -// kdDebug(11001) << "submit to kgame " << i << endl; - d->mConfigWidgets.at(i)->submitToKGame(d->mGame, d->mOwner); -// kdDebug(11001) << "done: submit to kgame " << i << endl; - } -} - -void KGameDialog::slotRemoveConfigWidget(TQObject* configWidget) -{ - d->mConfigWidgets.removeRef((KGameDialogConfig*)configWidget); -} - diff --git a/libkdegames/kgame/dialogs/kgamedialog.h b/libkdegames/kgame/dialogs/kgamedialog.h deleted file mode 100644 index 423f5de1..00000000 --- a/libkdegames/kgame/dialogs/kgamedialog.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ - -// NAMING -// please follow these naming rules if you add/change classes: -// the main dialog is named KGameDialog and the base config widget -// KGameDialogConfig. All config widgets are named KGameDialogXYZConfig (where -// XYZ = the name of the config widget, like "general" or "network") and are -// inherited from KGameDialogConfig. - -#ifndef __KGAMEDIALOG_H__ -#define __KGAMEDIALOG_H__ - -#include <kdialogbase.h> -#include <kdemacros.h> -class TQGridLayout; -class TQVBoxLayout; -class TQListBoxItem; - -class KGame; -class KPlayer; -class KGamePropertyBase; - -class KGameDialogConfig; -class KGameDialogGeneralConfig; -class KGameDialogNetworkConfig; -class KGameDialogMsgServerConfig; -class KGameDialogChatConfig; -class KGameDialogConnectionConfig; - -class KGameDialogPrivate; -/** - * TODO: rewrite entire documentation. Nearly nothing is valid anymore. - * The main configuration dialog for KGame. Here all players meat each other, - * every player can see how many players connected (and their names) and the - * ADMIN can even "kick" players out. You can talk to each other (using - * KGameChat and the ADMIN can define the maxPlayers/minPlayers as well as the - * number of computer players. - * - * - * AB: setDefaultXYZ is obsolete!! - * You will usually create an instance of KGameDialog or any derived class and - * call setDefaultXYZ methods. Example (maybe - * obsoleted parameters - docu is currently changing very fast): - * \code - * KGameDialog dlg(kgame, i18n("New Game"), localPlayer, this, true, - * ID_CHAT); - * dlg.setDefaultNetworkInfo(port, host); // AB: obsolete! - * dlg.exec(); - * \endcode - * This will create a default modal dialog with the title "New Game". You don't - * have to do more than this. - * - * @short Main configuration dialog for KGame - * @author Andreas Beckermann <[email protected]> - **/ -class KDE_EXPORT KGameDialog : public KDialogBase -{ - Q_OBJECT - TQ_OBJECT -public: - - enum ConfigOptions - { - NoConfig = 0, - ChatConfig = 1, - GameConfig = 2, - NetworkConfig = 4, - MsgServerConfig = 8, - BanPlayerConfig = 16, - AllConfig = 0xffff - }; - - /** - * Create an empty KGameDialog. You can add widgets using - * addConfigPage. - * @param g The KGame object of this game - * @param owner The KPlayer object who is responsible for this - * dialog, aka "the local player" - * @param title The title of the dialog - see KDialog::setCaption - * @param parent The parent of the dialog - * @param modal Whether the dialog is modal or not - **/ - KGameDialog(KGame* g, KPlayer* owner, const TQString& title, - TQWidget* parent, bool modal = false); - - /** - * Create a KGameDialog with the standard configuration widgets. This - * creates the following widgets: - * <ul> - * <li> KGameDialogGeneralConfig - * <li> KGameDialogNetworkConfig - * <li> KGameDialogMsgServerConfig - * <li> KGameDialogChatConfig - * <li> KGameDialogConnectionConfig - * </ul> - * If you want to use your own implementations (or none) of the widgets - * above you should subclass KGameDialog. Use addGameConfig, - * addNetworkConfig, addMsgConfig, addChatWidget and - * addConnectionList in this case. - * - * If you want to add further configuration widget you can simply use - * addConfigPage - * @param g The KGame object of this game - * @param owner The KPlayer object who is responsible for this - * dialog, aka "the local player" - * @param title The title of the dialog - see KDialog::setCaption - * @param parent The parent of the dialog - * @param modal Whether the dialog is modal or not - * @param initConfigs whether the default KGameDialogConfig widgets - * shall be created using initDefaultDialog. Use false if you want - * to use custom widgets. - * @param chatMsgId The ID of Chat messages. See KGameChat. Unused - * if initConfigs = false - **/ - KGameDialog(KGame* g, KPlayer* owner, const TQString& title, - TQWidget* parent, long initConfigs = AllConfig, - int chatMsgId = 15432, bool modal = false); - - virtual ~KGameDialog(); - - - /** - * Change the owner of the dialog. This will be used as the fromPlayer in - * KGameChat and will receive the entered player name. - * @param owner The owner of the dialog. It must already be added to the - * KGame object! - * - * Calls the KGameDialogConfig::setOwner implementation of all - * widgets that have been added by addConfigWidget - * @param owner The new owner player of this dialog must already be - * added to the KGame object. Can even be NULL (then no player - * configuration is made) - **/ - void setOwner(KPlayer* owner); - - /** - * Change the KGame object this dialog is used for. - * - * Calls the KGameDialogConfig::setKGame implementation of all - * widgets that have been added by addConfigWidget - * @param g The new KGame object - **/ - void setKGame(KGame* g); - - /** - * This will submit all configuration data to the KGame object. - * Automatically called by slotApply and slotOk - * There is no need to replace this unless you - * want to add widgets which are not derived from those classes - **/ - virtual void submitToKGame(); - - /** - * Adds a KGameChat to the dialog. If no parent is specified the - * game page will be used. - * @param chat The chat widget - * @param parent The parent of the chat widget. This MUST be an - * already added config widget. Note that the game page will be used - * if parent is 0. - **/ - void addChatWidget(KGameDialogChatConfig* chat, TQVBox* parent = 0); - - /** - * Add a connection list to the dialog. The list consists of a - * KLisBox containing all players in the current game (see - * KGame::playerList). The admin can "ban" players, ie kick them out of - * the game. - * - * This is another not-really-config-config-widget. It just displays the - * connections and lets you ban players. - * @param c The KGameDialogConnectionConfig object - * @param parent The parent of the widget. If 0 the networkConfig - * page is used. - **/ - void addConnectionList(KGameDialogConnectionConfig* c, TQVBox* parent = 0); - - /** - * Add a new page to the dialog. The page will contain you new config - * widget and will have your provided title. - * - * The widget will be reparented to this dialog. This also calls - * KGameDialogConfig::setKGame and KGameDialogConfig::setOwner. - * @param widget The new config widget - * @param title The title of the newly added page. - * @return The newly added page which contains your config widget. - **/ - TQVBox* addConfigPage(KGameDialogConfig* widget, const TQString& title); - - /** - * @return The TQVBox of the given key, The key is from ConfigOptions - * Note that not all are supported yet - **/ - TQVBox *configPage(ConfigOptions which); - - /** - * @return The default netowrk config. Note that this always returns 0 if - * you did not specify NetworkConfig in the constructor! - **/ - KGameDialogNetworkConfig* networkConfig() const; - - /** - * @return The default game config. Note that this always returns 0 if - * you did not specify GameConfig in the constructor! - **/ - KGameDialogGeneralConfig* gameConfig() const; - - /** - * Add a config widget to the specified parent. Usually you call - * addConfigPage for one widget and addConfigWidget for another to add - * it to the same page. Just use the returned page of - * addConfigPage. - **/ - void addConfigWidget(KGameDialogConfig* widget, TQWidget* parent); - - /** - * Used to add the main network config widget in a new page. Use this to - * make networkConfig return something useful. - **/ - void addNetworkConfig(KGameDialogNetworkConfig* netConf); - - /** - * Add the main game config widget in a new page. Use this to make - * gameConfig return something useful. - **/ - void addGameConfig(KGameDialogGeneralConfig* conf); - - /** - * Used to add the message server config widget in a new page. - **/ - void addMsgServerConfig(KGameDialogMsgServerConfig* conf); - -protected: - - /** - * This is used to create a dialog containing all the default widgets. - * - * You may want to use this if you just want to use your own - * configuration widgets which inherit the standard ones. - * - * Note that if one of the widgets is NULL the default implementation - * will be used! (except the chat widget - you need to create it - * yourself as you have to provide a message id) - * @param initConfigs The widgets to be created - * @param chatMsgId The msgid for the chat config (only if specified in - * initConfigs) - see KGameDialogChatConfig - **/ - void initDefaultDialog(ConfigOptions initConfigs, int chatMsgId = 15432); - - /** - * Go through all config widgets and call their - * KGameDialogConfig::setKGame and KGameDialogConfig::setOwner implementation - * - * This function could be private and probably will be very soon. - * Don't use it yourself - **/ - void configureConfigWidgets(); - -protected slots: - /** - * Called when the user clicks on Ok. Calls slotApply and - * TQDialog::accept() - **/ - virtual void slotOk(); - - /** - * Just calls submitToKGame() - **/ - virtual void slotApply(); - - /** - * Sets the default values for the configuration widgets. Set these - * values by (e.g.) setDefaultMaxPlayers() - * @deprecated - **/ - virtual void slotDefault(); - - /** - * Called when the KGame object is destroyed. Calls setKGame(0) so - * that all widgets can disconnect their slots and so on. - **/ - void slotUnsetKGame(); - - /** - * Called when the ADMIN status of this KGame client changes. See - * KGameNetwork::signalAdminStatusChanged - * @param isAdmin TRUE if this client is now the ADMIN otherwise FALSE - **/ - void setAdmin(bool isAdmin); - - /** - * Remove a config widget from the widget list. - * @see TQObject::destroyed - **/ - void slotRemoveConfigWidget(TQObject* configWidget); - -private: - void init(KGame*, KPlayer*); - -private: - KGameDialogPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/dialogs/kgamedialogconfig.cpp b/libkdegames/kgame/dialogs/kgamedialogconfig.cpp deleted file mode 100644 index f6845650..00000000 --- a/libkdegames/kgame/dialogs/kgamedialogconfig.cpp +++ /dev/null @@ -1,773 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 "kgamedialogconfig.h" - -#include "kgame.h" -#include "kplayer.h" -#include "kgamechat.h" -#include "kgameconnectdialog.h" - -#include <klocale.h> -#include <knuminput.h> -#include <kdialog.h> -#include <klistbox.h> -#include <kmessagebox.h> - -#include <tqlayout.h> -#include <tqhgroupbox.h> -#include <tqlabel.h> -#include <tqpushbutton.h> -#include <tqlineedit.h> -#include <tqvbox.h> -#include <tqptrdict.h> - -#include "kgamedialogconfig.moc" - -class KGameDialogConfigPrivate -{ -public: - KGameDialogConfigPrivate() - { - mOwner = 0; - mGame = 0; - - mAdmin = false; - } - - bool mAdmin; - KGame* mGame; - KPlayer* mOwner; -}; - -KGameDialogConfig::KGameDialogConfig(TQWidget* parent) : TQWidget(parent) -{ - d = new KGameDialogConfigPrivate; -} - -KGameDialogConfig::~KGameDialogConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameDialogConfig::setKGame(KGame* g) -{ - d->mGame = g; -} - -void KGameDialogConfig::setOwner(KPlayer* p) -{ - d->mOwner = p; -} - -void KGameDialogConfig::setAdmin(bool a) -{ - d->mAdmin = a; -} - -KGame* KGameDialogConfig::game() const -{ return d->mGame; } -bool KGameDialogConfig::admin() const -{ return d->mAdmin; } -KPlayer* KGameDialogConfig::owner() const -{ return d->mOwner; } - -/////////////////////////// KGameDialogNetworkConfig ///////////////////////// -class KGameDialogNetworkConfigPrivate -{ -public: - KGameDialogNetworkConfigPrivate() - { - mInitConnection = 0; - mNetworkLabel = 0; - mDisconnectButton = 0; - mConnect = 0; - mDefaultServer=true; - - } - - // TQPushButton* mInitConnection; - TQHGroupBox* mInitConnection; - TQLabel* mNetworkLabel; - TQPushButton *mDisconnectButton; - - bool mDefaultServer; - TQString mDefaultHost; - unsigned short int mDefaultPort; - KGameConnectWidget *mConnect; -}; - - -KGameDialogNetworkConfig::KGameDialogNetworkConfig(TQWidget* parent) - : KGameDialogConfig(parent) -{ -// kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - d = new KGameDialogNetworkConfigPrivate(); - - TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint(), "toptqlayout"); - - TQHBoxLayout *hb = new TQHBoxLayout(topLayout, KDialog::spacingHint()); - - d->mNetworkLabel = new TQLabel(this); - hb->addWidget(d->mNetworkLabel); - - d->mDisconnectButton=new TQPushButton(i18n("Disconnect"),this); - connect(d->mDisconnectButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotExitConnection())); - hb->addWidget(d->mDisconnectButton); - - d->mInitConnection = new TQHGroupBox(i18n("Network Configuration"), this); - topLayout->addWidget(d->mInitConnection); - - d->mConnect = new KGameConnectWidget(d->mInitConnection); - connect(d->mConnect, TQT_SIGNAL(signalNetworkSetup()), this, TQT_SLOT(slotInitConnection())); - connect(d->mConnect, TQT_SIGNAL(signalServerTypeChanged(int)), - this, TQT_SIGNAL(signalServerTypeChanged(int))); - - // Needs to be AFTER the creation of the dialogs - setConnected(false); - setDefaultNetworkInfo("localhost", 7654,true); -} - -KGameDialogNetworkConfig::~KGameDialogNetworkConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameDialogNetworkConfig::slotExitConnection() -{ - kdDebug(11001) << k_funcinfo << " !!!!!!!!!!!!!!!!!!!!!!!" << endl; - if (game()) game()->disconnect(); - setConnected(false,false); -} - -void KGameDialogNetworkConfig::slotInitConnection() -{ - kdDebug(11001) << k_funcinfo << endl; - bool connected = false; - bool master = true; - unsigned short int port = d->mConnect->port(); - TQString host = d->mConnect->host(); - - if (host.isNull()) { - master = true; - if (game()) { - game()->setDiscoveryInfo(d->mConnect->type(),d->mConnect->gameName()); - connected = game()->offerConnections(port); - } - } else { - master = false; - if (game()) { - connected = game()->connectToServer(host, port); - } - // We need to learn about failed connections - if (game()) { - connect(game(), TQT_SIGNAL(signalConnectionBroken()), - this, TQT_SLOT(slotConnectionBroken())); - } - } - setConnected(connected, master); -} - -void KGameDialogNetworkConfig::slotConnectionBroken() -{ - kdDebug(11001) << k_funcinfo << endl; - setConnected(false,false); - KMessageBox::error(this, i18n("Cannot connect to the network")); -} - -void KGameDialogNetworkConfig::setConnected(bool connected, bool master) -{ - if (!connected) { - d->mNetworkLabel->setText(i18n("Network status: No Network")); - d->mInitConnection->setEnabled(true); - d->mDisconnectButton->setEnabled(false); - return; - } - if (master) { - d->mNetworkLabel->setText(i18n("Network status: You are MASTER")); - } else { - d->mNetworkLabel->setText(i18n("Network status: You are connected")); - } - d->mInitConnection->setEnabled(false); - d->mDisconnectButton->setEnabled(true); -} - -void KGameDialogNetworkConfig::submitToKGame(KGame* , KPlayer* ) -{ -} - -void KGameDialogNetworkConfig::setKGame(KGame* g) -{ - KGameDialogConfig::setKGame(g); - if (!game()) { - setConnected(false); - return; - } - setConnected(game()->isNetwork(), game()->isMaster()); -} - -void KGameDialogNetworkConfig::setDefaultNetworkInfo(const TQString& host, unsigned short int port,bool server) -{ - d->mDefaultPort = port; - d->mDefaultHost = host; - d->mDefaultServer = server; - - d->mConnect->setHost(host); - d->mConnect->setPort(port); - if (server) { - d->mConnect->setDefault(0); - } else { - d->mConnect->setDefault(1); - } -} - -void KGameDialogNetworkConfig::setDiscoveryInfo(const TQString& type, const TQString& name) -{ - d->mConnect->setType(type); - d->mConnect->setName(name); -} - -/////////////////////////// KGameDialogGeneralConfig ///////////////////////// -class KGameDialogGeneralConfigPrivate -{ -public: - KGameDialogGeneralConfigPrivate() - { - mTopLayout = 0; - mName = 0; - } - - TQLineEdit* mName; - - TQVBoxLayout* mTopLayout; -}; - -KGameDialogGeneralConfig::KGameDialogGeneralConfig(TQWidget* parent, bool initializeGUI) - : KGameDialogConfig(parent) -{ -// kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - d = new KGameDialogGeneralConfigPrivate; - - if (initializeGUI) { - d->mTopLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); - d->mTopLayout->setAutoAdd(true); - - TQWidget* nameWidget = new TQWidget(this); - TQHBoxLayout* l = new TQHBoxLayout(nameWidget); - TQLabel* nameLabel = new TQLabel(i18n("Your name:"), nameWidget); - l->addWidget(nameLabel); - d->mName = new TQLineEdit(nameWidget); - l->addWidget(d->mName); - } -} - -KGameDialogGeneralConfig::~KGameDialogGeneralConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameDialogGeneralConfig::setPlayerName(const TQString& name) -{ - if (d->mName) { - d->mName->setText(name); - } -} - -TQString KGameDialogGeneralConfig::playerName() const -{ - return d->mName ? d->mName->text() : TQString(); -} - -void KGameDialogGeneralConfig::setOwner(KPlayer* p) -{ - if (owner()) { - owner()->disconnect(this); - } - KGameDialogConfig::setOwner(p); - if (!owner()) { - // can this config be used at all? - // maybe call hide() - return; - } - connect(owner(), TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)), - this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*))); - setPlayerName(p->name()); - //TODO: connect signalPropertyChanged and check for playername changes! -} - -void KGameDialogGeneralConfig::setKGame(KGame* g) -{ - KGameDialogConfig::setKGame(g); - if (!g) { - // TODO - // can this config be used at all? - // maybe call hide() - return; - } -} - -void KGameDialogGeneralConfig::setAdmin(bool admin) -{ - KGameDialogConfig::setAdmin(admin); -// enable/disable widgets - -} - -void KGameDialogGeneralConfig::submitToKGame(KGame* g, KPlayer* p) -{ -//FIXME - if (p) { - p->setName(playerName()); - } - if (g) { - } -} - -void KGameDialogGeneralConfig::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* p) -{ - if (!prop || !p || p != owner()) { - return; - } - switch (prop->id()) { - case KGamePropertyBase::IdName: - setPlayerName(p->name()); - break; - default: - break; - } -} - -class KGameDialogMsgServerConfigPrivate -{ -public: - KGameDialogMsgServerConfigPrivate() - { - senderLayout = 0; - localLayout = 0; - - changeMaxClients = 0; - changeAdmin= 0; - removeClient= 0; - noAdmin = 0; - - noMaster = 0; - } - - TQVBoxLayout* senderLayout; - TQHBoxLayout* localLayout; - - TQPushButton* changeMaxClients; - TQPushButton* changeAdmin; - TQPushButton* removeClient; - TQLabel* noAdmin; - - TQLabel* noMaster; -}; - - -// TODO: change ADMIN ID, remove CLIENTS, change MAXCLIENTS -// we do everything here with TQPushButtons as we want to wait a moment before -// continuing - the message must be sent over network first -KGameDialogMsgServerConfig::KGameDialogMsgServerConfig(TQWidget* parent) - : KGameDialogConfig(parent) -{ - d = new KGameDialogMsgServerConfigPrivate; - - TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); - d->senderLayout = new TQVBoxLayout(topLayout); - d->localLayout = new TQHBoxLayout(topLayout); -} - -KGameDialogMsgServerConfig::~KGameDialogMsgServerConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameDialogMsgServerConfig::setKGame(KGame* g) -{ - KGameDialogConfig::setKGame(g); - //TODO display the ID of the admin if we aren't - // connect(g, TQT_SIGNAL(signalAdminChanged(int)), this, TQT_SLOT(slotChangeIsAdmin(int)));//TODO - if (!game()) { - // we cannot do anything without a KGame object! - setAdmin(false); - return; - } - setAdmin(game()->isAdmin()); - setHasMsgServer(game()->messageServer()); -} - - -void KGameDialogMsgServerConfig::slotChangeMaxClients() -{ - if (!game()) { - kdError(11001) << k_funcinfo << ": no valid game object available!" << endl; - return; - } - if (!game()->isAdmin()) { - kdError(11001) << k_funcinfo << ": only ADMIN is allowed to call this!" << endl; - return; - } - int max; -// edit->setText(TQString::number()); // current max clients! //TODO - - TQDialog* dialog = new TQDialog(); - dialog->setCaption(i18n("Maximal Number of Clients")); - TQHBoxLayout* l = new TQHBoxLayout(dialog, KDialog::marginHint(), KDialog::spacingHint()); - l->setAutoAdd(true); - - (void) new TQLabel(i18n("Maximal number of clients (-1 = infinite):"), dialog); - TQLineEdit* edit = new TQLineEdit(dialog);//TODO: use KIntNumInput -// edit->setText(TQString::number(max)); // current max clients! //TODO - if (dialog->exec() == TQDialog::Accepted) { - bool ok; - max = edit->text().toInt(&ok); - if (ok) { - game()->setMaxClients(max); - } - } - -} - -void KGameDialogMsgServerConfig::slotRemoveClient() -{ -} - -void KGameDialogMsgServerConfig::slotChangeAdmin() -{ - if (!game()) { - kdError(11001) << k_funcinfo << ": no valid game object available!" << endl; - return; - } - if (!admin()) { - kdError(11001) << k_funcinfo << ": only ADMIN is allowed to call this!" << endl; - return; - } - //TODO - TQ_UINT32 newAdmin = 0; -// newAdmin = ; - game()->electAdmin(newAdmin); -} - -void KGameDialogMsgServerConfig::removeClient(TQ_UINT32 /*id*/) -{ -//TODO -} - -void KGameDialogMsgServerConfig::setAdmin(bool a) -{ - if (admin() == a) { - // no need to do anything - return; - } - KGameDialogConfig::setAdmin(a); - if (admin()) { - if (d->noAdmin) { - delete d->noAdmin; - d->noAdmin = 0; - } - d->changeMaxClients = new TQPushButton(i18n("Change Maximal Number of Clients"), this); - connect(d->changeMaxClients, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotChangeMaxClients())); - d->changeAdmin = new TQPushButton(i18n("Change Admin"), this); - connect(d->changeAdmin, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotChangeAdmin())); - d->removeClient = new TQPushButton(i18n("Remove Client with All Players"), this); - connect(d->removeClient, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotRemoveClient())); - d->senderLayout->addWidget(d->changeMaxClients); - d->senderLayout->addWidget(d->changeAdmin); - d->senderLayout->addWidget(d->removeClient); - } else { - if (d->changeMaxClients) { - delete d->changeMaxClients; - d->changeMaxClients = 0; - } - if (d->changeAdmin) { - delete d->changeAdmin; - d->changeAdmin = 0; - } - if (d->removeClient) { - delete d->removeClient; - d->removeClient = 0; - } - d->noAdmin = new TQLabel(i18n("Only the admin can configure the message server!"), this); - d->senderLayout->addWidget(d->noAdmin); - } -} - - -void KGameDialogMsgServerConfig::setHasMsgServer(bool has) -{ - if (!has) { - // delete all inputs - if (!d->noMaster) { - d->noMaster = new TQLabel(i18n("You don't own the message server"), this); - d->localLayout->addWidget(d->noMaster); - } - return; - } - if (d->noMaster) { - delete d->noMaster; - d->noMaster = 0; - } - //TODO - // list all connections, data (max clients) and so on - // cannot be done above (together with TQPushButtons) as it is possible that - // this client is ADMIN but not MASTER (i.e. doesn't own the messageserver) -} - - -class KGameDialogChatConfigPrivate -{ -public: - KGameDialogChatConfigPrivate() - { - mChat = 0; - } - - KGameChat* mChat; -}; - -KGameDialogChatConfig::KGameDialogChatConfig(int chatMsgId, TQWidget* parent) - : KGameDialogConfig(parent) -{ - d = new KGameDialogChatConfigPrivate; - TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); - topLayout->setAutoAdd(true); - TQHGroupBox* b = new TQHGroupBox(i18n("Chat"), this); - d->mChat = new KGameChat(0, chatMsgId, b); -} - -KGameDialogChatConfig::~KGameDialogChatConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameDialogChatConfig::setKGame(KGame* g) -{ - KGameDialogConfig::setKGame(g); - d->mChat->setKGame(game()); - if (!game()) { - hide(); - } else { - show(); - } -} - -void KGameDialogChatConfig::setOwner(KPlayer* p) -{ - KGameDialogConfig::setOwner(p); - if (!owner()) { - hide(); - return; - } - d->mChat->setFromPlayer(owner()); - show(); -} - - - -class KGameDialogConnectionConfigPrivate -{ -public: - KGameDialogConnectionConfigPrivate() - { - mPlayerBox = 0; - } - - TQPtrDict<KPlayer> mItem2Player; - KListBox* mPlayerBox; -}; - -KGameDialogConnectionConfig::KGameDialogConnectionConfig(TQWidget* parent) - : KGameDialogConfig(parent) -{ - //TODO: prevent player to ban himself - d = new KGameDialogConnectionConfigPrivate; - TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); - topLayout->setAutoAdd(true); - TQHGroupBox* b = new TQHGroupBox(i18n("Connected Players"), this); - d->mPlayerBox = new KListBox(b); - setMinimumHeight(100); -} - -KGameDialogConnectionConfig::~KGameDialogConnectionConfig() -{ - kdDebug(11001) << k_funcinfo << endl; - // d->mIem2Player.clear(); - delete d; -} - -void KGameDialogConnectionConfig::setKGame(KGame* g) -{ - if (game()) { - disconnect(game(), 0, this, 0); - } - KGameDialogConfig::setKGame(g); - slotClearPlayers(); - if (game()) { -// react to changes in KGame::playerList() - connect(game(), TQT_SIGNAL(signalPlayerJoinedGame(KPlayer*)), - this, TQT_SLOT(slotPlayerJoinedGame(KPlayer*))); - connect(game(), TQT_SIGNAL(signalPlayerLeftGame(KPlayer*)), - this, TQT_SLOT(slotPlayerLeftGame(KPlayer*))); - - KGame::KGamePlayerList l = *game()->playerList(); - for (KPlayer* p = l.first(); p; p = l.next()) { - slotPlayerJoinedGame(p); - } - } -} - -void KGameDialogConnectionConfig::setOwner(KPlayer* p) -{ - KGameDialogConfig::setOwner(p); -} - -void KGameDialogConnectionConfig::setAdmin(bool a) -{ - if (!game()) {// not possible... in theory - return; - } - if (admin()) { - disconnect(game(), TQT_SIGNAL(executed(TQListBoxItem*)), this, 0); - } - KGameDialogConfig::setAdmin(a); - if (admin()) { - connect(d->mPlayerBox, TQT_SIGNAL(executed(TQListBoxItem*)), this, - TQT_SLOT(slotKickPlayerOut(TQListBoxItem*))); - } -} - -TQListBoxItem* KGameDialogConnectionConfig::item(KPlayer* p) const -{ - TQPtrDictIterator<KPlayer> it(d->mItem2Player); - while (it.current()) { - if (it.current() == p) { - return (TQListBoxItem*)it.currentKey(); - } - ++it; - } - return 0; -} - -void KGameDialogConnectionConfig::slotClearPlayers() -{ - TQPtrDictIterator<KPlayer> it(d->mItem2Player); - while (it.current()) { - slotPlayerLeftGame(it.current()); - ++it; - } - - if (d->mItem2Player.count() > 0) { - kdWarning(11001) << k_funcinfo << ": itemList wasn't cleared properly" << endl; - d->mItem2Player.clear(); - } - if (d->mPlayerBox->count() > 0) { - kdWarning(11001) << k_funcinfo << ": listBox wasn't cleared properly" << endl; - d->mPlayerBox->clear(); - } - -} - -void KGameDialogConnectionConfig::slotPlayerJoinedGame(KPlayer* p) -{ - if (!p) { - kdError(11001) << k_funcinfo << ": Cannot add NULL player" << endl; - } - if (d->mItem2Player[p]) { - kdError(11001) << k_funcinfo << ": attempt to double add player" << endl; - return; - } - kdDebug(11001) << k_funcinfo << ": add player " << p->id() << endl; - TQListBoxText* t = new TQListBoxText(p->name()); - d->mItem2Player.insert(t, p); - d->mPlayerBox->insertItem(t); - - connect(p, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)), - this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*))); - -} - -void KGameDialogConnectionConfig::slotPlayerLeftGame(KPlayer* p) -{ - // disconnect first - this->disconnect(p); - if (!item(p)) { - kdError(11001) << k_funcinfo << ": cannot find " << p->id() - << " in list" << endl; - return; - } - d->mPlayerBox->removeItem(d->mPlayerBox->index(item(p))); - -} - -void KGameDialogConnectionConfig::slotKickPlayerOut(TQListBoxItem* item) -{ - kdDebug(11001) << "kick player out" << endl; - KPlayer* p = d->mItem2Player[item]; - if (!p) { - kdError(11001) << "invalid item selected - no player found" << endl; - return; - } - if (!game()) { - kdWarning(11001) << "no game set" << endl; - return; - } - if (!admin()) { - kdDebug(11001) << "Only the ADMIN can kick players" << endl; - return; - } - if (p == owner()) { // you wanna ban the ADMIN ?? - kdDebug(11001) << "you cannot kick the ADMIN" << endl; - return; - } - - if (KMessageBox::questionYesNo(this, i18n("Do you want to ban player \"%1\" from the game?").tqarg( - p->name()), TQString(), i18n("Ban Player"), i18n("Do Not Ban")) == KMessageBox::Yes) { - kdDebug(11001) << "will remove player " << p << endl; - game()->removePlayer(p); -// d->mPlayerBox->removeItem(d->mPlayerBox->index(item)); // should be done by signalPlayerLeftGame - } else { - kdDebug(11001) << "will NOT remove player " << p << endl; - } -} - -void KGameDialogConnectionConfig::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player) -{ - if(prop->id() == KGamePropertyBase::IdName) { - TQListBoxText* old = 0; - TQPtrDictIterator<KPlayer> it(d->mItem2Player); - while (it.current() && !old) { - if (it.current() == player) { - old = (TQListBoxText*)it.currentKey(); - } - ++it; - } - TQListBoxText* t = new TQListBoxText(player->name()); - d->mPlayerBox->changeItem(t, d->mPlayerBox->index(old)); - d->mItem2Player.remove(old); - d->mItem2Player.insert(t, player); - } -} - diff --git a/libkdegames/kgame/dialogs/kgamedialogconfig.h b/libkdegames/kgame/dialogs/kgamedialogconfig.h deleted file mode 100644 index a7f309ac..00000000 --- a/libkdegames/kgame/dialogs/kgamedialogconfig.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ - -// NAMING -// please follow these naming rules if you add/change classes: -// the main dialog is named KGameDialog and the base config widget -// KGameDialogConfig. All config widgets are named KGameDialogXYZConfig (where -// XYZ = the name of the config widget, like "general" or "network") and are -// inherited from KGameDialogConfig. - -#ifndef __KGAMEDIALOGCONFIG_H__ -#define __KGAMEDIALOGCONFIG_H__ - -#include <tqwidget.h> -#include <kdemacros.h> - -class TQGridLayout; -class TQVBoxLayout; -class TQListBoxItem; - -class KGame; -class KPlayer; -class KGamePropertyBase; - -class KGameDialogConfigPrivate; -/** - * Base class for configuration widgets. - * - * You can inherit from this and implement @ref submitToKGame, @ref - * setOwner and @ref setKGame to create your personal @ref KGame configuration widget :-) - * @short Base class for configuration widgets - * @author Andreas Beckermann <[email protected]> - **/ -class KDE_EXPORT KGameDialogConfig : public TQWidget -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDialogConfig(TQWidget* parent = 0); - virtual ~KGameDialogConfig(); - - /** - * Called by @ref KGameDialog to submit all settings to the KGame - * Object. - * You have to replace this if you add your own widgets! - * @param g A pointer to your KGame. - * @param p A pointer to the player owning this dialog - **/ - virtual void submitToKGame(KGame* g, KPlayer* p) = 0; - - /** - * The owner player of the dialog has been changed. The default - * changes the pointer for owner so don't forget to call the - * default implementation if you overwrite this! - * - * You can use this e.g. to change a line edit widget containing the - * player name. - * - * Note: even NULL players are allowed! - * @param p The new owner player of the dialog - **/ - virtual void setOwner(KPlayer* p); - - /** - * The KGame object of the dialog has been changed. The default - * implementation changes the pointer for game so don't forget to - * call the default implementation if you overwrite this! - * - * You can use this e.g. to re-read the min/max player settings. - * @param g The KGame object - **/ - virtual void setKGame(KGame* g); - - /** - * The admin status has been changed. - * If the KGame object of this config widget is the - * admin the user is allowed to configure it. Otherwise most - * widgets will have to be disabled. Note that you don't necessarily - * need to deactivate all widget - e.g. the player name must be - * configured by the player. Mainly the KGame configuration can be done - * by the admin only. - * - * By default this does nothing. Changes the value for admin so - * don't forget to call the default implementation in derived classes! - * @param admin Whether the KGame object of this dialog can be - * configured - **/ - virtual void setAdmin(bool admin); - - /** - * A pointer to the KGame object that has been set by @ref setKGame. - * - * Note that NULL is allowed! - * @return The KGame object assigned to this dialog - **/ - KGame* game() const; - - /** - * A pointer to the KPlayer object that has been set by @ref - * setOwner. - * - * Note that NULL is allowed! - * @return The owner of the dialog - **/ - KPlayer* owner() const; - - /** - * @return True if the owner is ADMIN otherwise FALSE. See also - * @ref setAdmin - **/ - bool admin() const; - -protected: - -private: - KGameDialogConfigPrivate* d; -}; - -/** - * The main game configuration widget. - * - * It currently contains a line edit for the name of the player only. You can - * add widgets by using the KGameDialogGeneralConfig as parent parameter as it - * uses TQLayout::autoAdd == true. - * @author Andreas Beckermann <[email protected]> - **/ -class KGameDialogGeneralConfigPrivate; -class KGameDialogGeneralConfig : public KGameDialogConfig -{ - Q_OBJECT - TQ_OBJECT -public: - /** - * Construct a KGameDialogGeneralConfig. Currently it contains a line - * edit widget to change the player name only. - * - * If you just want to add more widgets you can just create your widgets - * with the KGameDialogGeneralConfig as parent as it uses - * TQLayout::setAutoAdd(true). - * - * @param parent Parent widget for this dialog. - * @param initializeGUI If you really don't want to use the - * predefined widget and/or tqlayout use FALSE here. Note that then none - * of the predefined widgets (currently only the name of the player) - * will exist anymore. - * - **/ - KGameDialogGeneralConfig(TQWidget* parent = 0, bool initializeGUI = true); - virtual ~KGameDialogGeneralConfig(); - - /** - * Called by @ref KGameDialog to submit all settings to the KGame - * Object. - * You have to replace this if you add your own widgets! - * @param g A pointer to your KGame. - * @param p A pointer to the player owning this dialog - **/ - virtual void submitToKGame(KGame* g, KPlayer* p); - - /** - * Change the owner of the config widget. - * - * Changes the playername in the line edit - * @param p The new owner player - **/ - virtual void setOwner(KPlayer* p); - - /** - * See @ref KGameDialogConfig::setKGame - * - * Sets the default values of all KGame related predefined widgets - * (currently none) - **/ - virtual void setKGame(KGame* g); - - /** - * See @ref KGameDialogConfig::setAdmin - * - * This deactivates the min/max player widgets - **/ - virtual void setAdmin(bool admin); - -protected slots: - void slotPropertyChanged(KGamePropertyBase*, KPlayer*); - -protected: - void setPlayerName(const TQString& name); - - TQString playerName() const; - -private: - KGameDialogGeneralConfigPrivate* d; -}; - -class KGameDialogNetworkConfigPrivate; -class KDE_EXPORT KGameDialogNetworkConfig : public KGameDialogConfig -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDialogNetworkConfig(TQWidget* parent = 0); - virtual ~KGameDialogNetworkConfig(); - - - void disableInitConnection(); - - /** - * Called by @ref KGameDialog to submit all settings to the KGame - * Object. - * You have to replace this if you add your own widgets! - * @param g A pointer to your KGame. - * @param p A pointer to the player owning this dialog - **/ - virtual void submitToKGame(KGame* g, KPlayer* p); - - virtual void setKGame(KGame* g); - - /** - * This sets the default port and host used in @ref KGameConnectDialog. - * The user will be able to change these defaults! - * - * If you don't call this then host "localhost" and port "0" is used. - * You are strongly encouraged to change at least the port! - * @param port The default port to connect to / listen on - * @param host The default host to connect to - **/ - void setDefaultNetworkInfo(const TQString& host, unsigned short int port,bool server=true); - - /** - * Set service type that will be published or browsed for and game name that will be displayed in - * server browser. Without this publishing and discovery of LAN servers will not be enabled. - * @param name Game name. Important only for server mode. If not - * set hostname will be used. In case of name conflict -2, -3 and so on will be added to name. - * @param type Service type (something like _kwin4._tcp). It should be unique for application. - * @since 3.4 - **/ - void setDiscoveryInfo(const TQString& type, const TQString& name=TQString()); - -signals: - /** - * This signal is emmited if the user changes the server type (client/server) - * in the network configuration dialog. - * - * @param t - type type (0/1) of the connection - **/ - void signalServerTypeChanged(int); - - -protected: - void setConnected(bool connected, bool master = false); - -protected slots: - void slotInitConnection(); - void slotExitConnection(); - void slotConnectionBroken(); - - -private: - KGameDialogNetworkConfigPrivate* d; -}; - -class KGameDialogMsgServerConfigPrivate; -class KGameDialogMsgServerConfig : public KGameDialogConfig -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDialogMsgServerConfig(TQWidget* parent = 0); - virtual ~KGameDialogMsgServerConfig(); - - virtual void submitToKGame(KGame*, KPlayer*) {} - - void setHasMsgServer(bool); - - virtual void setKGame(KGame* g); - virtual void setAdmin(bool); - -protected slots: - void slotChangeMaxClients(); - void slotChangeAdmin(); - void slotRemoveClient(); - -protected: - void removeClient(TQ_UINT32 id); - -private: - KGameDialogMsgServerConfigPrivate* d; -}; - -class KGameDialogChatConfigPrivate; -/** - * This is not really a configuration widget but rather a simple chat widget. - * This widget does nothing but just providing a @ref KGameChat object. - * @short A chat widget inside a @ref KGameDialog - * @author Andreas Beckermann <[email protected]> - **/ -class KGameDialogChatConfig : public KGameDialogConfig -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDialogChatConfig(int chatMsgId, TQWidget* parent = 0); - virtual ~KGameDialogChatConfig(); - - virtual void setKGame(KGame* g); - virtual void setOwner(KPlayer* p); - - virtual void submitToKGame(KGame* g, KPlayer* p) { Q_UNUSED(g); Q_UNUSED(p); } - -private: - KGameDialogChatConfigPrivate* d; -}; - -/** - * @short Lists all connected players and gives the ability to kick them off the - * game - **/ -class KGameDialogConnectionConfigPrivate; -class KGameDialogConnectionConfig : public KGameDialogConfig -{ - Q_OBJECT - TQ_OBJECT -public: - KGameDialogConnectionConfig(TQWidget* parent = 0); - virtual ~KGameDialogConnectionConfig(); - - virtual void setKGame(KGame* g); - virtual void setOwner(KPlayer* p); - virtual void setAdmin(bool admin); - - virtual void submitToKGame(KGame* g, KPlayer* p) { Q_UNUSED(g); Q_UNUSED(p); } - -protected: - /** - * @param p A player - * @return The TQListBoxItem that belongs to the player @p p - **/ - TQListBoxItem* item(KPlayer* p) const; - -protected slots: - void slotKickPlayerOut(TQListBoxItem* item); - void slotPropertyChanged(KGamePropertyBase* prop, KPlayer* p); - void slotPlayerLeftGame(KPlayer* p); - void slotPlayerJoinedGame(KPlayer* p); - void slotClearPlayers(); - -private: - KGameDialogConnectionConfigPrivate* d; - -}; -#endif diff --git a/libkdegames/kgame/dialogs/kgameerrordialog.cpp b/libkdegames/kgame/dialogs/kgameerrordialog.cpp deleted file mode 100644 index 6ab9d71c..00000000 --- a/libkdegames/kgame/dialogs/kgameerrordialog.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 <kmessagebox.h> -#include <klocale.h> -#include <kdebug.h> - -#include "kgame.h" - -#include "kgameerrordialog.h" - -class KGameErrorDialogPrivate -{ -public: - KGameErrorDialogPrivate() - { - mGame = 0; - } - - const KGame* mGame; -}; - -KGameErrorDialog::KGameErrorDialog(TQWidget* parent) : TQObject(parent) -{ - d = new KGameErrorDialogPrivate; -} - -KGameErrorDialog::~KGameErrorDialog() -{ - delete d; -} - -void KGameErrorDialog::setKGame(const KGame* g) -{ - slotUnsetKGame(); - d->mGame = g; - - connect(d->mGame, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotUnsetKGame())); - -// the error signals: - connect(d->mGame, TQT_SIGNAL(signalNetworkErrorMessage(int, TQString)), - this, TQT_SLOT(slotError(int, TQString))); - connect(d->mGame, TQT_SIGNAL(signalConnectionBroken()), - this, TQT_SLOT(slotServerConnectionLost())); - connect(d->mGame, TQT_SIGNAL(signalClientDisconnected(TQ_UINT32,bool)), - this, TQT_SLOT(slotClientConnectionLost(TQ_UINT32,bool))); -} - -void KGameErrorDialog::slotUnsetKGame() -{ - if (d->mGame) { - disconnect(d->mGame, 0, this, 0); - } - d->mGame = 0; -} - -void KGameErrorDialog::error(const TQString& errorText, TQWidget* parent) -{ KMessageBox::error(parent, errorText); } - -void KGameErrorDialog::slotServerConnectionLost() -{ -// TODO: add IP/port of the server - TQString message = i18n("Connection to the server has been lost!"); - error(message, (TQWidget*)parent()); -} - -void KGameErrorDialog::slotClientConnectionLost(TQ_UINT32 /*id*/,bool) -{ -//TODO: add IP/port of the client - TQString message; -// if (c) { -// message = i18n("Connection to client has been lost!\nID: %1\nIP: %2").tqarg(c->id()).tqarg(c->IP()); -// } else { -// message = i18n("Connection to client has been lost!"); -// } - message = i18n("Connection to client has been lost!"); - error(message, (TQWidget*)parent()); -} - -void KGameErrorDialog::slotError(int errorNo, TQString text) -{ - TQString message = i18n("Received a network error!\nError number: %1\nError message: %2").tqarg(errorNo).tqarg(text); - error(message, (TQWidget*)parent()); -} - -void KGameErrorDialog::connectionError(TQString s) -{ - TQString message; - if (s.isNull()) { - message = i18n("No connection could be created."); - } else { - message = i18n("No connection could be created.\nThe error message was:\n%1").tqarg(s); - } - error(message, (TQWidget*)parent()); -} - - - -// should become the real dialog - currently we just use messageboxes -// -> maybe unused forever -KGameErrorMessageDialog::KGameErrorMessageDialog(TQWidget* parent) - : KDialogBase(Plain, i18n("Error"), Ok, Ok, parent, 0, true, true) -{ -} - -KGameErrorMessageDialog::~KGameErrorMessageDialog() -{ -} - - - -#include "kgameerrordialog.moc" diff --git a/libkdegames/kgame/dialogs/kgameerrordialog.h b/libkdegames/kgame/dialogs/kgameerrordialog.h deleted file mode 100644 index 08726dc2..00000000 --- a/libkdegames/kgame/dialogs/kgameerrordialog.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEERRORDIALOG_H__ -#define __KGAMEERRORDIALOG_H__ - -#include <kdialogbase.h> - -class KGame; -class KGameErrorDialogPrivate; - -/** - * Use error(), warning() and information() to display the information about a - * network game. Maybe a better solution is to use KMessageBoxes - * You can connect to the public slots, too - they will call the static - * functions, so that you can always have a KGameErrorDialog object lying around - * without losing much memory (a KGameErrorMessageDialog Object will be - * created) - * @short Error handling for KGame - * @author Andreas Beckermann <[email protected]> - **/ -class KGameErrorDialog : public TQObject -{ - Q_OBJECT - TQ_OBJECT -public: - KGameErrorDialog(TQWidget* parent); - ~KGameErrorDialog(); - - /** - * Automatically connects the KGame object to all error dependant slots. - * Create a KGameErrorDialog object, call this function and forget - * everything. - * @param g The KGame which will emit the erorrs (or not ;-) ) - **/ - void setKGame(const KGame* g); - - /** - * KGame couldn't establish a connection. Use this if - * KGame::initConnection returns false - * @param s A string that describes the error further (like port is - * already in use). Will be ignored if TQString() - **/ - void connectionError(TQString s = TQString()); - -public slots: - void slotError(int error, TQString text); - - /** - * The connection to the @ref KMessageServer has been lost - * - * See @ref KGameNetwork::signalConnectionBroken - **/ - void slotServerConnectionLost(); - - /** - * The connection to a client has been lost by accident - * - * See @ref KGameNetwork::signalClientDisconnected - **/ - void slotClientConnectionLost(TQ_UINT32 clientID,bool broken); - - /** - * Unsets a @ref KGame which has been set using @ref setKGame before. - * This is called automatically when the @ref KGame object is destroyed - * and you normally don't have to call this yourself. - * - * Note that @ref setKGame also unsets an already existing @ref KGame - * object if exising. - **/ - void slotUnsetKGame(); - -protected: - void error(const TQString& errorText, TQWidget* parent = 0); - -private: - KGameErrorDialogPrivate* d; -}; - -/** - * The real class for error messages. KGameErrorDialog uses this to create error - * messages (not yet). - * Use @ref KGameErrorDialog instead. - * @short Internally used by @ref KGameErrorDialog - * @author Andreas Beckermann <[email protected]> - **/ -class KGameErrorMessageDialog : public KDialogBase -{ - Q_OBJECT - TQ_OBJECT -public: - KGameErrorMessageDialog(TQWidget* parent); - ~KGameErrorMessageDialog(); - -private: -}; - -#endif diff --git a/libkdegames/kgame/kgame.cpp b/libkdegames/kgame/kgame.cpp deleted file mode 100644 index 2eebac64..00000000 --- a/libkdegames/kgame/kgame.cpp +++ /dev/null @@ -1,1475 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgame.h" -#include "kgame.moc" -#include "kgamepropertyhandler.h" -#include "kgameproperty.h" -#include "kplayer.h" -#include "kgameio.h" -#include "kgameerror.h" -#include "kgamesequence.h" - -#include "kgamemessage.h" - -#include <unistd.h> -#include <stdio.h> -#include <assert.h> - -#include <tqbuffer.h> -#include <tqtimer.h> -#include <tqptrqueue.h> -#include <tqfile.h> - -#include <klocale.h> -#include <krandomsequence.h> -#include <kdebug.h> - -#define KGAME_LOAD_COOKIE 4210 - -// try to place as much as possible here -// many things are *not* possible here as KGame has to use some inline function -class KGamePrivate -{ -public: - KGamePrivate() - { - mUniquePlayerNumber = 0; - mPolicy=KGame::PolicyLocal; - mGameSequence = 0; - } - - int mUniquePlayerNumber; - TQPtrQueue<KPlayer> mAddPlayerList;// this is a list of to-be-added players. See addPlayer() docu - KRandomSequence* mRandom; - KGame::GamePolicy mPolicy; - KGameSequence* mGameSequence; - - - KGamePropertyHandler* mProperties; - - // player lists - KGame::KGamePlayerList mPlayerList; - KGame::KGamePlayerList mInactivePlayerList; - - //KGamePropertys - KGamePropertyInt mMaxPlayer; - KGamePropertyUInt mMinPlayer; - KGamePropertyInt mGametqStatus; // Game running? - TQValueList<int> mInactiveIdList; - -}; - -// ------------------- GAME CLASS -------------------------- -KGame::KGame(int cookie,TQObject* parent) : KGameNetwork(cookie,parent) -{ - kdDebug(11001) << k_funcinfo << " - " << this << ", sizeof(KGame)=" << sizeof(KGame) << endl; - d = new KGamePrivate; - - d->mProperties = new KGamePropertyHandler(this); - - d->mProperties->registerHandler(KGameMessage::IdGameProperty, - this,TQT_SLOT(sendProperty(int, TQDataStream&, bool* )), - TQT_SLOT(emitSignal(KGamePropertyBase *))); - d->mMaxPlayer.registerData(KGamePropertyBase::IdMaxPlayer, this, i18n("MaxPlayers")); - d->mMaxPlayer.setLocal(-1); // Infinite - d->mMinPlayer.registerData(KGamePropertyBase::IdMinPlayer, this, i18n("MinPlayers")); - d->mMinPlayer.setLocal(0); // Always ok - d->mGametqStatus.registerData(KGamePropertyBase::IdGametqStatus, this, i18n("GameStatus")); - d->mGametqStatus.setLocal(Init); - // d->mUniquePlayerNumber = 0; - d->mRandom = new KRandomSequence; - d->mRandom->setSeed(0); - - connect(this, TQT_SIGNAL(signalClientConnected(TQ_UINT32)), - this, TQT_SLOT(slotClientConnected(TQ_UINT32))); - connect(this, TQT_SIGNAL(signalClientDisconnected(TQ_UINT32,bool)), - this, TQT_SLOT(slotClientDisconnected(TQ_UINT32,bool))); - connect(this, TQT_SIGNAL(signalConnectionBroken()), - this, TQT_SLOT(slotServerDisconnected())); - - setGameSequence(new KGameSequence()); - - // BL: FIXME This signal does no longer exist. When we are merging - // MH: super....and how do I find out about the lost conenction now? - // KGame and KGameNetwork, this could be improved! -// connect(this,TQT_SIGNAL(signalConnectionLost(KGameClient *)), -// this,TQT_SLOT(slotConnectionLost(KGameClient *))); -} - -KGame::~KGame() -{ - kdDebug(11001) << k_funcinfo << endl; -// Debug(); - reset(); - delete d->mGameSequence; - delete d->mRandom; - delete d; - kdDebug(11001) << k_funcinfo << " done" << endl; -} - -bool KGame::reset() -{ - deletePlayers(); - deleteInactivePlayers(); - return true; -} - -void KGame::deletePlayers() -{ -// kdDebug(11001) << k_funcinfo << endl; - KGamePlayerList tmp = d->mPlayerList; // in case of PolicyClean player=d->mPlayerList.first() is infinite - KPlayer *player; - while((player=tmp.first())) - { - delete player; // delete and removes the player - tmp.removeFirst(); - } -// kdDebug(11001) << k_funcinfo << " done" << endl; -} - -void KGame::deleteInactivePlayers() -{ - KPlayer *player; - while((player=d->mInactivePlayerList.first())) - { - //player->setGame(0); // prevent call backs - d->mInactivePlayerList.remove(player); - delete player; - } -} - -bool KGame::load(TQString filename,bool reset) -{ - if (filename.isNull()) - { - return false; - } - TQFile f(filename); - if (!f.open(IO_ReadOnly)) - { - return false; - } - TQDataStream s( &f ); - load(s,reset); - f.close(); - return true; -} - -bool KGame::load(TQDataStream &stream,bool reset) -{ return loadgame(stream, false,reset); } - -bool KGame::loadgame(TQDataStream &stream, bool network,bool resetgame) -{ - // Load Game Data - - // internal data - TQ_INT32 c; - stream >> c; // cookie - - if (c!=cookie()) - { - kdWarning(11001) << "Trying to load different game version we="<<cookie() << " saved=" << c << endl; - bool result=false; - emit signalLoadError(stream,network,(int)c,result); - return result; - } - if (resetgame) reset(); - - uint i; - stream >> i; -// setPolicy((GamePolicy)i); - - stream >> d->mUniquePlayerNumber; - - if (gameSequence()) - { - gameSequence()->setCurrentPlayer(0); // TODO !!! - } - int newseed; - stream >> newseed; - d->mRandom->setSeed(newseed); - - // Switch off the direct emitting of signals while - // loading properties. This can cause inconsistencies - // otherwise if a property emits and this emit accesses - // a property not yet loaded - // Note we habe to have this external locking to prevent the games unlocking - // to access the players - dataHandler()->lockDirectEmit(); - KPlayer *player; - for ( player=playerList()->first(); player != 0; player=playerList()->next() ) - { - player->dataHandler()->lockDirectEmit(); - // kdDebug(11001) << "Player "<<player->id() << " to indirect emit" <<endl; - } - - // Properties - dataHandler()->load(stream); - - // If there is additional data to be loaded before players are loaded then do - // this here. - emit signalLoadPrePlayers(stream); - - // Load Playerobjects - uint playercount; - stream >> playercount; - kdDebug(11001) << "Loading KGame " << playercount << " KPlayer objects " << endl; - for (i=0;i<playercount;i++) - { - KPlayer *newplayer=loadPlayer(stream,network); - systemAddPlayer(newplayer); - } - - TQ_INT16 cookie; - stream >> cookie; - if (cookie==KGAME_LOAD_COOKIE) { - kdDebug(11001) << " Game loaded propertly"<<endl; - } else { - kdError(11001) << " Game loading error. probably format error"<<endl; - } - - // Switch back on the direct emitting of signals and emit the - // queued signals. - // Note we habe to have this external locking to prevent the games unlocking - // to access the players - dataHandler()->unlockDirectEmit(); - for ( player=playerList()->first(); player != 0; player=playerList()->next() ) - { - player->dataHandler()->unlockDirectEmit(); - // kdDebug(11001) << "Player "<<player->id() << " to direct emit" <<endl; - } - - emit signalLoad(stream); - return true; -} - -bool KGame::save(TQString filename,bool saveplayers) -{ - if (filename.isNull()) - { - return false; - } - TQFile f(filename); - if (!f.open(IO_WriteOnly)) - { - return false; - } - TQDataStream s( &f ); - save(s,saveplayers); - f.close(); - return true; -} - -bool KGame::save(TQDataStream &stream,bool saveplayers) -{ return savegame(stream, false,saveplayers); } - -bool KGame::savegame(TQDataStream &stream,bool /*network*/,bool saveplayers) -{ - // Save Game Data - - // internal variables - TQ_INT32 c=cookie(); - stream << c; - - uint p=(uint)policy(); - stream << p; - stream << d->mUniquePlayerNumber; - int newseed=(int)d->mRandom->getLong(65535); - stream << newseed; - d->mRandom->setSeed(newseed); - - // Properties - dataHandler()->save(stream); - - // Save all data that need to be saved *before* the players are saved - emit signalSavePrePlayers(stream); - - if (saveplayers) - { - savePlayers(stream,playerList()); - } - else - { - stream << (uint)0; // no players saved - } - - stream << (TQ_INT16)KGAME_LOAD_COOKIE; - - emit signalSave(stream); - return true; -} - -void KGame::savePlayer(TQDataStream &stream,KPlayer* p) -{ -// this could be in KGameMessage as well - stream << (TQ_INT32)p->rtti(); - stream << (TQ_INT32)p->id(); - stream << (TQ_INT32)p->calcIOValue(); - p->save(stream); -} - -void KGame::savePlayers(TQDataStream &stream, KGamePlayerList *list) -{ - if (!list) - { - list=playerList(); - } - - TQ_INT32 cnt=list->count(); - kdDebug(11001) << "Saving KGame " << cnt << " KPlayer objects " << endl; - stream << cnt; - KPlayer *player; - for ( player=list->first(); player != 0; player=list->next() ) - { - savePlayer(stream,player); - } -} - -KPlayer *KGame::createPlayer(int /*rtti*/,int /*io*/,bool /*isvirtual*/) -{ - kdWarning(11001) << " No user defined player created. Creating default KPlayer. This crashes if you have overwritten KPlayer!!!! " << endl; - return new KPlayer; -} -KPlayer *KGame::loadPlayer(TQDataStream& stream,bool isvirtual) -{ - TQ_INT32 rtti,id,iovalue; - stream >> rtti >> id >> iovalue; - KPlayer *newplayer=findPlayer(id); - if (!newplayer) - { - kdDebug(11001) << k_funcinfo << "Player "<< id << " not found...asking user to create one " << endl; - newplayer=createPlayer(rtti,iovalue,isvirtual); - //emit signalCreatePlayer(newplayer,rtti,iovalue,isvirtual,this); - } - /* - if (!newplayer) - { - kdWarning(11001) << " No user defined player created. Creating default KPlayer. This crashes if you have overwritten KPlayer!!!! " << endl; - newplayer=new KPlayer; - } - else - { - kdDebug(11001) << " USER Player " << newplayer << " done player->rtti=" << newplayer->rtti() << " rtti=" << rtti << endl; - } - */ - newplayer->load(stream); - if (isvirtual) - { - newplayer->setVirtual(true); - } - return newplayer; -} - -// ----------------- Player handling ----------------------- - -KPlayer * KGame::findPlayer(TQ_UINT32 id) const -{ - for (TQPtrListIterator<KPlayer> it(d->mPlayerList); it.current(); ++it) - { - if (it.current()->id() == id) - { - return it.current(); - } - } - for (TQPtrListIterator<KPlayer> it(d->mInactivePlayerList); it.current(); ++it) - { - if (it.current()->id() == id) - { - return it.current(); - } - } - return 0; -} - -// it is necessary that addPlayer and systemAddPlayer are called in the same -// order. Ie if addPlayer(foo) followed by addPlayer(bar) is called, you must -// not call systemAddPlayer(bar) followed by systemAddPlayer(foo), as the -// mAddPlayerList would get confused. Should be no problem as long as comServer -// and the clients are working correctly. -// BUT: if addPlayer(foo) does not arrive by any reason while addPlayer(bar) -// does, we would be in trouble... -void KGame::addPlayer(KPlayer* newplayer) -{ - kdDebug(11001) << k_funcinfo << ": " << "; maxPlayers=" << maxPlayers() << " playerCount=" << playerCount() << endl; - if (!newplayer) - { - kdFatal(11001) << "trying to add NULL player in KGame::addPlayer()" << endl; - return ; - } - - if (maxPlayers() >= 0 && (int)playerCount() >= maxPlayers()) - { - kdWarning(11001) << "cannot add more than " << maxPlayers() << " players - deleting..." << endl; - delete newplayer; - return; - } - - if (newplayer->id() == 0) - { - d->mUniquePlayerNumber++; - newplayer->setId(KGameMessage::createPlayerId(d->mUniquePlayerNumber, gameId())); - kdDebug(11001) << k_funcinfo << "NEW!!! player " << newplayer << " now has id " << newplayer->id() << endl; - } - else - { - // this could happen in games which use their own ID management by certain - // reasons. that is NOT recommended - kdDebug(11001) << k_funcinfo << "player " << newplayer << " already has an id: " << newplayer->id() << endl; - } - - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - // We distinguis here what policy we have - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - systemAddPlayer(newplayer); - } - if (policy()==PolicyClean || policy()==PolicyDirty) - { - savePlayer(stream,newplayer); - // Store the player for delayed clean adding - if (policy()==PolicyClean) - { - d->mAddPlayerList.enqueue(newplayer); - } - sendSystemMessage(stream,(int)KGameMessage::IdAddPlayer, 0); - } -} - -void KGame::systemAddPlayer(KPlayer* newplayer) -{ - if (!newplayer) - { - kdFatal(11001) << "trying to add NULL player in KGame::systemAddPlayer()" << endl; - return ; - } - if (newplayer->id() == 0) - { - kdWarning(11001) << k_funcinfo << "player " << newplayer << " has no ID" << endl; - } - - if (findPlayer(newplayer->id())) - { - kdError(11001) << "ERROR: Double adding player !!!!! NOT GOOD !!!!!! " << newplayer->id() << "...I delete it again" << endl; - delete newplayer; - } - else - { - kdDebug(11001) << "Trying to add player " << newplayer <<" maxPlayers="<<maxPlayers()<<" playerCount="<<playerCount() << endl; - // Add the player to the game - d->mPlayerList.append(newplayer); - newplayer->setGame(this); - kdDebug(11001) << "Player: isVirtual=" << newplayer->isVirtual() << endl; - kdDebug(11001) << " id=" << newplayer->id() << " #Players=" - << d->mPlayerList.count() << " added " << newplayer - << " (virtual=" << newplayer->isVirtual() << ")" << endl; - emit signalPlayerJoinedGame(newplayer); - } -} - -// Called by the KPlayer destructor -void KGame::playerDeleted(KPlayer *player) -{ - kdDebug(11001) << k_funcinfo << ": id (" << player->id() << ") to be removed " << player << endl; - - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - systemRemovePlayer(player,false); - } - if (policy()==PolicyClean || policy()==PolicyDirty) - { - if (!player->isVirtual()) - { - kdDebug(11001) << k_funcinfo << ": sending IdRemovePlayer "<<player->id() << endl; - sendSystemMessage(player->id(), KGameMessage::IdRemovePlayer, 0); - } - } -} - -bool KGame::removePlayer(KPlayer * player, TQ_UINT32 receiver) -{//transmit to all clients, or to receiver only - if (!player) - { - kdFatal(11001) << "trying to remove NULL player in KGame::removePlayer()" << endl; - return false; - } - kdDebug(11001) << k_funcinfo << ": id (" << player->id() << ") to be removed " << player << endl; - - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - systemRemovePlayer(player,true); - } - if (policy()==PolicyClean || policy()==PolicyDirty) - { - kdDebug(11001) << k_funcinfo << ": sending IdRemovePlayer "<<player->id() << endl; - sendSystemMessage(player->id(),KGameMessage::IdRemovePlayer, receiver); - } - return true; - // we will receive the message in networkTransmission() -} - -void KGame::systemRemovePlayer(KPlayer* player,bool deleteit) -{ - kdDebug(11001) << k_funcinfo << endl; - if (!player) - { - kdWarning(11001) << "cannot remove NULL player" << endl; - return; - } - if (!systemRemove(player,deleteit)) - { - kdWarning(11001) << "player " << player << "(" << player->id() << ") Could not be found!" << endl; - } - - if (gametqStatus()==(int)Run && playerCount()<minPlayers()) - { - kdWarning(11001) << k_funcinfo ": not enough players, PAUSING game\n" << endl; - setGametqStatus(Pause); - } -} - -bool KGame::systemRemove(KPlayer* p,bool deleteit) -{ - if (!p) - { - kdWarning(11001) << "cannot remove NULL player" << endl; - return false; - } - bool result; - kdDebug(11001) << k_funcinfo << ": Player (" << p->id() << ") to be removed " << p << endl; - - if (d->mPlayerList.count() == 0) - { - result = false; - } - else - { - result = d->mPlayerList.remove(p); - } - - emit signalPlayerLeftGame(p); - - p->setGame(0); - if (deleteit) - { - delete p; - } - - return result; -} - -bool KGame::inactivatePlayer(KPlayer* player) -{ - if (!player) - { - return false; - } - kdDebug(11001) << "Inactivate player " << player->id() << endl; - - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - systemInactivatePlayer(player); - } - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendSystemMessage(player->id(), KGameMessage::IdInactivatePlayer); - } - - return true; -} - -bool KGame::systemInactivatePlayer(KPlayer* player) -{ - if (!player || !player->isActive()) - { - return false; - } - kdDebug(11001) << " Inactivate player " << player->id() << endl; - - int pid=player->id(); - // Virtual players cannot be deactivated. They will be removed - if (player->isVirtual()) - { - systemRemovePlayer(player,true); - } - else - { - d->mPlayerList.remove(player); - d->mInactivePlayerList.prepend(player); - player->setActive(false); - } - emit signalPlayerLeftGame(player); - if (isAdmin()) - { - d->mInactiveIdList.prepend(pid); - } - return true; -} - -bool KGame::activatePlayer(KPlayer * player) -{ - if (!player) - { - return false; - } - kdDebug(11001) << k_funcinfo << ": activate " << player->id() << endl; - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - systemActivatePlayer(player); - } - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendSystemMessage(player->id(), KGameMessage::IdActivatePlayer); - } - return true; -} - -bool KGame::systemActivatePlayer(KPlayer* player) -{ - if (!player || player->isActive()) - { - return false; - } - kdDebug(11001) << k_funcinfo << ": activate " << player->id() << endl; - - d->mInactivePlayerList.remove(player); - player->setActive(true); - addPlayer(player); - if (isAdmin()) - { - d->mInactiveIdList.remove(player->id()); - } - return true; -} - -// -------------------- Properties --------------------------- - -void KGame::setMaxPlayers(uint maxnumber) -{ if (isAdmin()) { d->mMaxPlayer.changeValue(maxnumber); } } - -void KGame::setMinPlayers(uint minnumber) -{ if (isAdmin()) { d->mMinPlayer.changeValue(minnumber); } } - -uint KGame::minPlayers() const -{ return d->mMinPlayer.value(); } - -int KGame::maxPlayers() const -{ return d->mMaxPlayer.value(); } - -uint KGame::playerCount() const -{ return d->mPlayerList.count(); } - -int KGame::gametqStatus() const -{ return d->mGametqStatus.value(); } - -bool KGame::isRunning() const -{ return d->mGametqStatus.value() == Run; } - -KGamePropertyHandler* KGame::dataHandler() const -{ return d->mProperties; } - - -KGame::KGamePlayerList* KGame::inactivePlayerList() -{ return &d->mInactivePlayerList; } - -const KGame::KGamePlayerList* KGame::inactivePlayerList() const -{ return &d->mInactivePlayerList; } - -KGame::KGamePlayerList* KGame::playerList() -{ return &d->mPlayerList; } - -const KGame::KGamePlayerList* KGame::playerList() const -{ return &d->mPlayerList; } - -KRandomSequence* KGame::random() const -{ return d->mRandom; } - - -bool KGame::sendPlayerInput(TQDataStream &msg, KPlayer *player, TQ_UINT32 sender) -{ - if (!player) - { - kdError(11001) << k_funcinfo << ": NULL player" << endl; - return false; - } - if (!isRunning()) - { - kdError(11001) << k_funcinfo << ": game not running" << endl; - return false; - } - - kdDebug(11001) << k_funcinfo << ": transmitting playerInput over network" << endl; - sendSystemMessage(msg, (int)KGameMessage::IdPlayerInput, player->id(), sender); - return true; -} - -bool KGame::systemPlayerInput(TQDataStream &msg, KPlayer *player, TQ_UINT32 sender) -{ - if (!player) - { - kdError(11001) << k_funcinfo << ": NULL player" << endl; - return false; - } - if (!isRunning()) - { - kdError(11001) << k_funcinfo << ": game not running" << endl; - return false; - } - kdDebug(11001) << "KGame: Got playerInput from messageServer... sender: " << sender << endl; - if (playerInput(msg,player)) - { - playerInputFinished(player); - } - else - { - kdDebug(11001) << k_funcinfo<<": switching off player input"<<endl; - // TODO: (MH 03-2003): We need an return option from playerInput so that - // the player's is not automatically disabled here - if (!player->asyncInput()) - { - player->setTurn(false); // in turn based games we have to switch off input now - } - } - return true; -} - - -KPlayer * KGame::playerInputFinished(KPlayer *player) -{ - kdDebug(11001) << k_funcinfo<<"player input finished for "<<player->id()<<endl; - // Check for game over and if not allow the next player to move - int gameOver = 0; - if (gameSequence()) - { - gameSequence()->setCurrentPlayer(player); - } - // do not call gameSequence()->checkGameOver() to keep backward compatibility! - gameOver = checkGameOver(player); - if (gameOver!=0) - { - if (player) - { - player->setTurn(false); - } - setGametqStatus(End); - emit signalGameOver(gameOver,player,this); - } - else if (!player->asyncInput()) - { - player->setTurn(false); // in turn based games we have to switch off input now - if (gameSequence()) - { - TQTimer::singleShot(0,this,TQT_SLOT(prepareNext())); - } - } - return player; -} - -// Per default we do not do anything -int KGame::checkGameOver(KPlayer *player) -{ - if (gameSequence()) - { - return gameSequence()->checkGameOver(player); - } - return 0; -} - -void KGame::setGameSequence(KGameSequence* sequence) -{ - delete d->mGameSequence; - d->mGameSequence = sequence; - if (d->mGameSequence) - { - d->mGameSequence->setGame(this); - } -} - -KGameSequence* KGame::gameSequence() const -{ - return d->mGameSequence; -} - -void KGame::prepareNext() -{ - if (gameSequence()) - { - // we don't call gameSequence->nextPlayer() to keep old code working - nextPlayer(gameSequence()->currentPlayer()); - } -} - -KPlayer *KGame::nextPlayer(KPlayer *last,bool exclusive) -{ - if (gameSequence()) - { - return gameSequence()->nextPlayer(last, exclusive); - } - return 0; -} - -void KGame::setGametqStatus(int status) -{ - kdDebug(11001) << k_funcinfo << ": GAMESTATUS CHANGED to" << status << endl; - if (status==(int)Run && playerCount()<minPlayers()) - { - kdDebug(11001) << k_funcinfo << ": not enough players, pausing game\n" << endl; - status=Pause; - } - d->mGametqStatus = status; -} - -void KGame::networkTransmission(TQDataStream &stream, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender, TQ_UINT32 /*clientID*/) -{//clientID is unused - // message targets a playerobject. If we find it we forward the message to the - // player. Otherwise we proceed here and hope the best that the user processes - // the message - -// kdDebug(11001) << k_funcinfo << ": we="<<(int)gameId()<<" id="<<msgid<<" recv=" << receiver << " sender=" << sender << endl; - - - // *first* notice the game that something has changed - so no return prevents - // this - emit signalMessageUpdate(msgid, receiver, sender); - if (KGameMessage::isPlayer(receiver)) - { - //kdDebug(11001) << "message id " << msgid << " seems to be for a player ("<<active=p->isActive()<<" recv="<< receiver << endl; - KPlayer *p=findPlayer(receiver); - if (p && p->isActive()) - { - p->networkTransmission(stream,msgid,sender); - return; - } - if (p) - { - kdDebug(11001) << "player is here but not active" << endl; - } - else - { - kdDebug(11001) << "no player found" << endl; - } - } - // If it is not for a player it is meant for us!!!! Otherwise the - // gamenetwork would not have passed the message to us! - - // GameProperties processed - if (d->mProperties->processMessage(stream, msgid, sender == gameId())) - { -// kdDebug(11001 ) << "KGame: message taken by property - returning" << endl; - return ; - } - - switch(msgid) - { - case KGameMessage::IdSetupGame: // Client: First step in setup game - { - TQ_INT16 v; - TQ_INT32 c; - stream >> v >> c; - kdDebug(11001) << " ===================> (Client) " << k_funcinfo << ": Got IdSetupGame ================== " << endl; - kdDebug(11001) << "our game id is " << gameId() << " Lib version=" << v << " App Cookie=" << c << endl; - // Verify identity of the network partners - if (c!=cookie()) - { - kdError(11001) << "IdGameSetup: Negotiate Game: cookie mismatch I'am="<<cookie()<<" master="<<c<<endl; - sendError(KGameError::Cookie, KGameError::errCookie(cookie(), c)); - disconnect(); // disconnect from master - } - else if (v!=KGameMessage::version()) - { - sendError(KGameError::Version, KGameError::errVersion(v)); - disconnect(); // disconnect from master - } - else - { - setupGame(sender); - } - kdDebug(11001) << "========== (Client) Setup game done\n"; - } - break; - case KGameMessage::IdSetupGameContinue: // Master: second step in game setup - { - kdDebug(11001) << "=====>(Master) " << k_funcinfo << " - IdSetupGameContinue" << endl; - setupGameContinue(stream, sender); - } - break; - case KGameMessage::IdActivatePlayer: // Activate Player - { - int id; - stream >> id; - kdDebug(11001) << "Got IdActivatePlayer id=" << id << endl; - if (sender!=gameId() || policy()!=PolicyDirty) - { - systemActivatePlayer(findPlayer(id)); - } - } - break; - case KGameMessage::IdInactivatePlayer: // Inactivate Player - { - int id; - stream >> id; - kdDebug(11001) << "Got IdInactivatePlayer id=" << id << endl; - if (sender!=gameId() || policy()!=PolicyDirty) - { - systemInactivatePlayer(findPlayer(id)); - } - } - break; - case KGameMessage::IdAddPlayer: - { - kdDebug(11001) << k_funcinfo << ": Got IdAddPlayer" << endl; - if (sender!=gameId() || policy()!=PolicyDirty) - { - KPlayer *newplayer=0; - // We sent the message so the player is already available - if (sender==gameId()) - { - kdDebug(11001) << "dequeue previously added player" << endl; - newplayer = d->mAddPlayerList.dequeue(); - } - else - { - newplayer=loadPlayer(stream,true); - } - systemAddPlayer(newplayer);// the final, local, adding - //systemAddPlayer(stream); - } - } - break; - case KGameMessage::IdRemovePlayer: // Client should delete player id - { - int id; - stream >> id; - kdDebug(11001) << k_funcinfo << ": Got IdRemovePlayer " << id << endl; - KPlayer *p=findPlayer(id); - if (p) - { - // Otherwise the player is already removed - if (sender!=gameId() || policy()!=PolicyDirty) - { - systemRemovePlayer(p,true); - } - } - else - { - kdWarning(11001) << k_funcinfo << "Cannot find player " << id << endl; - } - } - break; - case KGameMessage::IdGameLoad: - { - kdDebug(11001) << "====> (Client) " << k_funcinfo << ": Got IdGameLoad" << endl; - loadgame(stream,true,false); - } - break; - case KGameMessage::IdGameSetupDone: - { - int cid; - stream >> cid; - kdDebug(11001) << "====> (CLIENT) " << k_funcinfo << ": Got IdGameSetupDone for client " - << cid << " we are =" << gameId() << endl; - sendSystemMessage(gameId(), KGameMessage::IdGameConnected, 0); - } - break; - case KGameMessage::IdGameConnected: - { - int cid; - stream >> cid; - kdDebug(11001) << "====> (ALL) " << k_funcinfo << ": Got IdGameConnected for client "<< cid << " we are =" << gameId() << endl; - emit signalClientJoinedGame(cid,this); - } - break; - - case KGameMessage::IdSyncRandom: // Master forces a new random seed on us - { - int newseed; - stream >> newseed; - kdDebug(11001) << "CLIENT: setting random seed to " << newseed << endl; - d->mRandom->setSeed(newseed); - } - break; - case KGameMessage::IdDisconnect: - { - // if we disconnect we *always* start a local game. - // this could lead into problems if we just change the message server - if (sender != gameId()) - { - kdDebug(11001) << "client " << sender << " leaves game" << endl; - return; - } - kdDebug(11001) << "leaving the game" << endl; - // start a new local game - // no other client is by default connected to this so this call should be - // enough - setMaster(); - } - break; - default: - { - if (msgid < KGameMessage::IdUser) - { - kdError(11001) << "incorrect message id " << msgid << " - emit anyway" - << endl; - } - kdDebug(11001) << k_funcinfo << ": User data msgid " << msgid << endl; - emit signalNetworkData(msgid - KGameMessage::IdUser,((TQBuffer*)stream.device())->readAll(),receiver,sender); - } - break; - } - -} - -// called by the IdSetupGameContinue Message - MASTER SIDE -// Here the master needs to decide which players can take part at the game -// and which will be deactivated -void KGame::setupGameContinue(TQDataStream& stream, TQ_UINT32 sender) -{ - KPlayer *player; - TQ_INT32 cnt; - int i; - stream >> cnt; - - TQValueList<int> inactivateIds; - - KGamePlayerList newPlayerList; - newPlayerList.setAutoDelete(true); - for (i=0;i<cnt;i++) - { - player=loadPlayer(stream,true); - kdDebug(11001) << " Master got player " << player->id() <<" rawgame=" << KGameMessage::rawGameId(player->id()) << " from sender " << sender << endl; - if (KGameMessage::rawGameId(player->id()) != sender) - { - kdError(11001) << "Client tries to add player with wrong game id - cheat possible" << endl; - } - else - { - newPlayerList.append(player); - kdDebug(11001) << " newplayerlist appended " << player->id() << endl; - } - } - - newPlayersJoin(playerList(),&newPlayerList,inactivateIds); - - - kdDebug(11001) << " Master calculates how many players to activate client has cnt=" << cnt << endl; - kdDebug(11001) << " The game has " << playerCount() << " active players" << endl; - kdDebug(11001) << " The user deactivated "<< inactivateIds.count() << " player already " << endl; - kdDebug(11001) << " MaxPlayers for this game is " << maxPlayers() << endl; - - // Do we have too many players? (After the programmer disabled some?) - // MH: We cannot use have player here as it CHANGES in the loop - // int havePlayers = cnt+playerCount()-inactivateIds.count(); - kdDebug(11001) << " havePlayers " << cnt+playerCount()-inactivateIds.count() << endl; - while (maxPlayers() > 0 && maxPlayers() < (int)(cnt+playerCount() - inactivateIds.count())) - { - kdDebug(11001) << " Still to deacticvate " - << (int)(cnt+playerCount()-inactivateIds.count())-(int)maxPlayers() - << endl; - KPlayer *currentPlayer=0; - int currentPriority=0x7fff; // MAX_UINT (16bit?) to get the maximum of the list - // find lowest network priority which is not yet in the newPlayerList - // do this for the new players - for ( player=newPlayerList.first(); player != 0; player=newPlayerList.next() ) - { - // Already in the list - if (inactivateIds.find(player->id())!=inactivateIds.end()) - { - continue; - } - if (player->networkPriority()<currentPriority) - { - currentPriority=player->networkPriority(); - currentPlayer=player; - } - } - - // find lowest network priority which is not yet in the newPlayerList - // Do this for the network players - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - // Already in the list - if (inactivateIds.find(player->id())!=inactivateIds.end()) - { - continue; - } - if (player->networkPriority()<currentPriority) - { - currentPriority=player->networkPriority(); - currentPlayer=player; - } - } - - // add it to inactivateIds - if (currentPlayer) - { - kdDebug(11001) << "Marking player " << currentPlayer->id() << " for inactivation" << endl; - inactivateIds.append(currentPlayer->id()); - } - else - { - kdError(11001) << "Couldn't find a player to dectivate..That is not so good..." << endl; - break; - } - } - - kdDebug(11001) << "Alltogether deactivated " << inactivateIds.count() << " players" << endl; - - TQValueList<int>::Iterator it; - for ( it = inactivateIds.begin(); it != inactivateIds.end(); ++it ) - { - int pid=*it; - kdDebug(11001) << " pid=" << pid << endl; - } - - // Now deactivate the network players from the inactivateId list - //TQValueList<int>::Iterator it; - for ( it = inactivateIds.begin(); it != inactivateIds.end(); ++it ) - { - int pid=*it; - if (KGameMessage::rawGameId(pid) == sender) - { - continue; // client's player - } - kdDebug(11001) << " -> the network needs to deactivate " << pid <<endl; - player=findPlayer(pid); - if (player) - { - // We have to make REALLY sure that the player is gone. With any policy - systemInactivatePlayer(player); - if (policy()!=PolicyLocal) - { - sendSystemMessage(player->id(), KGameMessage::IdInactivatePlayer); - } - } - else - { - kdError(11001) << " We should deactivate a player, but cannot find it...not good." << endl; - } - } - - // Now send out the player list which the client can activate - for ( player=newPlayerList.first(); player != 0; player=newPlayerList.next() ) - { - kdDebug(11001) << " newplayerlist contains " << player->id() << endl; - // Only activate what is not in the list - if (inactivateIds.find(player->id())!=inactivateIds.end()) - { - continue; - } - kdDebug(11001) << " -> the client can ******** reactivate ******** " << player->id() << endl; - sendSystemMessage(player->id(), KGameMessage::IdActivatePlayer, sender); - } - - // Save the game over the network - TQByteArray bufferS; - TQDataStream streamS(bufferS,IO_WriteOnly); - // Save game over netowrk and save players - savegame(streamS,true,true); - sendSystemMessage(streamS,KGameMessage::IdGameLoad,sender); - - - // Only to the client first , as the client will add players - sendSystemMessage(sender, KGameMessage::IdGameSetupDone, sender); -} - -// called by the IdSetupGame Message - CLIENT SIDE -// Client needs to prepare for network transfer -void KGame::setupGame(TQ_UINT32 sender) -{ - TQByteArray bufferS; - TQDataStream streamS(bufferS,IO_WriteOnly); - - // Deactivate all players - KGamePlayerList mTmpList(d->mPlayerList); // we need copy otherwise the removal crashes - TQ_INT32 cnt=mTmpList.count(); - kdDebug(11001) << "Client: playerlistcount=" << d->mPlayerList.count() << " tmplistcout=" << cnt << endl; - - streamS << cnt; - - TQPtrListIterator<KPlayer> it(mTmpList); - KPlayer *player; - while (it.current()) - { - player=it.current(); - systemInactivatePlayer(player); - // Give the new game id to all players (which are inactivated now) - player->setId(KGameMessage::createPlayerId(player->id(),gameId())); - - // Save it for the master to decide what to do - savePlayer(streamS,player); - - ++it; - --cnt; - } - if (d->mPlayerList.count() > 0 || cnt!=0) - { - kdFatal(11001) << "KGame::setupGame(): Player list is not empty! or cnt!=0=" <<cnt << endl; - } - - sendSystemMessage(streamS,KGameMessage::IdSetupGameContinue,sender); -} - -// unused by KGame -void KGame::syncRandom() -{ - int newseed=(int)d->mRandom->getLong(65535); - sendSystemMessage(newseed,KGameMessage::IdSyncRandom); // Broadcast - d->mRandom->setSeed(newseed); -} - -void KGame::Debug() -{ - KGameNetwork::Debug(); - kdDebug(11001) << "------------------- KGAME -------------------------" << endl; - kdDebug(11001) << "this: " << this << endl; - kdDebug(11001) << "uniquePlayer " << d->mUniquePlayerNumber << endl; - kdDebug(11001) << "gameStatus " << gametqStatus() << endl; - kdDebug(11001) << "MaxPlayers : " << maxPlayers() << endl; - kdDebug(11001) << "NoOfPlayers : " << playerCount() << endl; - kdDebug(11001) << "NoOfInactive: " << d->mInactivePlayerList.count() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - -void KGame::slotClientConnected(TQ_UINT32 clientID) -{ - if (isAdmin()) - { - negotiateNetworkGame(clientID); - } -} - -void KGame::slotServerDisconnected() // Client side -{ - kdDebug(11001) << "======= SERVER DISCONNECT ======="<<endl; - kdDebug(11001) << "+++ (CLIENT)++++++++" << k_funcinfo << ": our GameID="<<gameId() << endl; - - int oldgamestatus=gametqStatus(); - - KPlayer *player; - KGamePlayerList removeList; - kdDebug(11001) << "Playerlist of client=" << d->mPlayerList.count() << " count" << endl; - kdDebug(11001) << "Inactive Playerlist of client=" << d->mInactivePlayerList.count() << " count" << endl; - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - // TODO: CHECK: id=0, could not connect to server in the first place?? - if (KGameMessage::rawGameId(player->id()) != gameId() && gameId()!=0) - { - kdDebug(11001) << "Player " << player->id() << " belongs to a removed game" << endl; - removeList.append(player); - } - } - - for ( player=removeList.first(); player != 0; player=removeList.next() ) - { - bool remove = true; - emit signalReplacePlayerIO(player, &remove); - if (remove) - { - kdDebug(11001) << " ---> Removing player " << player->id() << endl; - systemRemovePlayer(player,true); // no network necessary - } - } - - setMaster(); - kdDebug(11001) << " our game id is after setMaster " << gameId() << endl; - - KGamePlayerList mReList(d->mInactivePlayerList); - for ( player=mReList.first(); player != 0; player=mReList.next() ) - { - // TODO ?check for priority? Sequence should be ok - if ((int)playerCount()<maxPlayers() || maxPlayers()<0) - { - systemActivatePlayer(player); - } - } - kdDebug(11001) << " Players activated player-cnt=" << playerCount() << endl; - - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - int oldid=player->id(); - d->mUniquePlayerNumber++; - player->setId(KGameMessage::createPlayerId(d->mUniquePlayerNumber,gameId())); - kdDebug(11001) << "Player id " << oldid <<" changed to " << player->id() << " as we are now local" << endl; - } - // TODO clear inactive lists ? - Debug(); - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - player->Debug(); - } - kdDebug(11001) << "+++++++++++" << k_funcinfo << " DONE=" << endl; - emit signalClientLeftGame(0,oldgamestatus,this); -} - -void KGame::slotClientDisconnected(TQ_UINT32 clientID,bool /*broken*/) // server side -{ - kdDebug(11001) << "++++(SERVER)+++++++" << k_funcinfo << " clientId=" << clientID << endl; - - int oldgamestatus=gametqStatus(); - - KPlayer *player; - KGamePlayerList removeList; - kdDebug(11001) << "Playerlist of client=" << d->mPlayerList.count() << " count" << endl; - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - if (KGameMessage::rawGameId(player->id())==clientID) - { - kdDebug(11001) << "Player " << player->id() << " belongs to the removed game" << endl; - removeList.append(player); - } - } - - for ( player=removeList.first(); player != 0; player=removeList.next() ) - { - // try to replace the KGameIO first - bool remove = true; - emit signalReplacePlayerIO(player, &remove); - if (remove) { - // otherwise (no new KGameIO) remove the player - kdDebug(11001) << " ---> Removing player " << player->id() << endl; - removePlayer(player,0); - } - } - - // Now add inactive players - sequence should be ok - // TODO remove players from removed game - for (unsigned int idx=0;idx<d->mInactiveIdList.count();idx++) - { - TQValueList<int>::Iterator it1 = d->mInactiveIdList.at(idx); - player = findPlayer(*it1); - if (((int)playerCount() < maxPlayers() || maxPlayers() < 0) && player && KGameMessage::rawGameId(*it1) != clientID) - { - activatePlayer(player); - } - } - emit signalClientLeftGame(clientID,oldgamestatus,this); -} - - -// -------------------- Synchronisation ----------------------- - -// this initializes a newly connected client. -// we send the number of players (including type) as well as game status and -// properties to the client. After the initialization has been completed both -// clients should have the same status (ie players, properties, etc) -void KGame::negotiateNetworkGame(TQ_UINT32 clientID) -{ - kdDebug(11001) << "===========================" << k_funcinfo << ": clientID=" << clientID << " =========================== "<< endl; - if (!isAdmin()) - { - kdError(11001) << k_funcinfo << ": Serious WARNING..only gameAdmin should call this" << endl; - return ; - } - - TQByteArray buffer; - TQDataStream streamGS(buffer,IO_WriteOnly); - - // write Game setup specific data - //streamGS << (TQ_INT32)maxPlayers(); - //streamGS << (TQ_INT32)minPlayers(); - - // send to the newly connected client *only* - TQ_INT16 v=KGameMessage::version(); - TQ_INT32 c=cookie(); - streamGS << v << c; - sendSystemMessage(streamGS, KGameMessage::IdSetupGame, clientID); -} - -bool KGame::sendGroupMessage(const TQByteArray &msg, int msgid, TQ_UINT32 sender, const TQString& group) -{ -// AB: group must not be i18n'ed!! we should better use an id for group and use -// a groupName() for the name // FIXME - KPlayer *player; - for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() ) - { - if (player && player->group()==group) - { - sendMessage(msg,msgid,player->id(), sender); - } - } - return true; -} - -bool KGame::sendGroupMessage(const TQDataStream &msg, int msgid, TQ_UINT32 sender, const TQString& group) -{ return sendGroupMessage(((TQBuffer*)msg.device())->buffer(), msgid, sender, group); } - -bool KGame::sendGroupMessage(const TQString& msg, int msgid, TQ_UINT32 sender, const TQString& group) -{ - TQByteArray buffer; - TQDataStream stream(buffer, IO_WriteOnly); - stream << msg; - return sendGroupMessage(stream, msgid, sender, group); -} - -bool KGame::addProperty(KGamePropertyBase* data) -{ return dataHandler()->addProperty(data); } - -bool KGame::sendPlayerProperty(int msgid, TQDataStream& s, TQ_UINT32 playerId) -{ return sendSystemMessage(s, msgid, playerId); } - -void KGame::sendProperty(int msgid, TQDataStream& stream, bool* sent) -{ - bool s = sendSystemMessage(stream, msgid); - if (s) - { - *sent = true; - } -} - -void KGame::emitSignal(KGamePropertyBase *me) -{ - emit signalPropertyChanged(me,this); -} - -KGamePropertyBase* KGame::findProperty(int id) const -{ return d->mProperties->find(id); } - -KGame::GamePolicy KGame::policy() const -{ - return d->mPolicy; -} -void KGame::setPolicy(GamePolicy p,bool recursive) -{ - // Set KGame policy - d->mPolicy=p; - if (recursive) - { - // Set all KGame property policy - dataHandler()->setPolicy((KGamePropertyBase::PropertyPolicy)p,false); - - // Set all KPLayer (active or inactive) property policy - for (TQPtrListIterator<KPlayer> it(d->mPlayerList); it.current(); ++it) - { - it.current()->dataHandler()->setPolicy((KGamePropertyBase::PropertyPolicy)p,false); - } - for (TQPtrListIterator<KPlayer> it(d->mInactivePlayerList); it.current(); ++it) - { - it.current()->dataHandler()->setPolicy((KGamePropertyBase::PropertyPolicy)p,false); - } - } -} - -/* - * vim: et sw=2 - */ diff --git a/libkdegames/kgame/kgame.h b/libkdegames/kgame/kgame.h deleted file mode 100644 index bf66dcb8..00000000 --- a/libkdegames/kgame/kgame.h +++ /dev/null @@ -1,933 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAME_H_ -#define __KGAME_H_ - -#include <tqstring.h> -#include <tqptrlist.h> -#include <tqvaluelist.h> - -#include "kgamenetwork.h" -#include <kdemacros.h> -class KRandomSequence; - -class KPlayer; -class KGamePropertyBase; -class KGamePropertyHandler; -class KGameSequence; - -class KGamePrivate; - -/** - * @short The main KDE game object - * - * The KGame class is the central game object. A game basically - * consists of following features: - * - Player handling (add, remove,...) - * - Game status (end,start,pause,...) - * - load/save - * - Move (and message) handling - * - nextPlayer and gameOver() - * - Network connection (for KGameNetwork) - * - * Example: - * \code - * KGame *game=new KGame; - * \endcode - * - * - * @author Martin Heni <[email protected]> - * - */ -class KDE_EXPORT KGame : public KGameNetwork -{ - Q_OBJECT - TQ_OBJECT - -public: - typedef TQPtrList<KPlayer> KGamePlayerList; - - /** - * The policy of the property. This can be PolicyClean (setVale uses - * send), PolicyDirty (setValue uses changeValue) or - * PolicyLocal (setValue uses setLocal). - * - * A "clean" policy means that the property is always the same on every - * client. This is achieved by calling send which actually changes - * the value only when the message from the MessageServer is received. - * - * A "dirty" policy means that as soon as setValue is called the - * property is changed immediately. And additionally sent over network. - * This can sometimes lead to bugs as the other clients do not - * immediately have the same value. For more information see - * changeValue. - * - * PolicyLocal means that a KGameProperty behaves like ever - * "normal" variable. Whenever setValue is called (e.g. using "=") - * the value of the property is changes immediately without sending it - * over network. You might want to use this if you are sure that all - * clients set the property at the same time. - **/ - enum GamePolicy - { - PolicyUndefined = 0, - PolicyClean = 1, - PolicyDirty = 2, - PolicyLocal = 3 - }; - - /** - * Create a KGame object. The cookie is used to identify your - * game in load/save and network operations. Change this between - * games. - */ - KGame(int cookie=42,TQObject* parent=0); - - /** - * Destructs the game - */ - virtual ~KGame(); - - /** - * Gives debug output of the game status - */ - virtual void Debug(); - - /** - * Game status - Use this to Control the game flow. - * The KGame e.g. sets the status to Pause when you have - * less player than the minimum amount - */ - enum GametqStatus - { - Init = 0, - Run = 1, - Pause = 2, - End = 3, - Abort = 4, - SystemPause = 5, - Intro = 6, - UsertqStatus = 7 - }; - - // Properties - /** - * Returns a list of all active players - * - * @return the list of players - */ - KGamePlayerList *playerList(); - - /** - * The same as @ref playerList but returns a const pointer. - **/ - const KGamePlayerList *playerList() const; - - /** - * Returns a list of all inactive players - * @return the list of players - */ - KGamePlayerList *inactivePlayerList(); - - /** - * The same as @ref inactivePlayerList but returns a const pointer. - **/ - const KGamePlayerList *inactivePlayerList() const; - - /** - * Returns a pointer to the game's KRandomSequence. This sequence is - * identical for all network players! - * @return KRandomSequence pointer - */ - KRandomSequence *random() const; - - /** - * @return The KGameSequence object that is currently in use. - * @see setGameSequence - **/ - KGameSequence *gameSequence() const; - - /** - * Is the game running - * @return true/false - */ - bool isRunning() const; - - // Player handling - /** - * Returns the player object for a given player id - * @param id Player id - * @return player object - */ - KPlayer *findPlayer(TQ_UINT32 id) const; - - /** - * Set a new @ref KGameSequence to control player management. By default - * KGame uses a normal @ref KGameSequence object. You might want to subclass - * that and provide your own object. - * - * The previous sequence will get deleted. - * @param sequence The new game sequence object. KGame takes ownership and - * will delete it on destruction! - **/ - void setGameSequence(KGameSequence* sequence); - - /** - * Note that KPlayer::save must be implemented properly, as well as - * KPlayer::rtti - * This will only send a message to all clients. The player is _not_ added - * directly! - * See also playerInput which will be called as soon as the - * player really has been added. - * - * Note that an added player will first get into a "queue" and won't be in - * the game. It will be added to the game as soon as systemAddPlayer is - * called what will happen as soon as IdAddPlayer is received. - * - * Note: you probably want to connect to signalPlayerJoinedGame for - * further initialization! - * @param newplayer The player you want to add. KGame will send a message to - * all clients and add the player using systemAddPlayer - **/ - void addPlayer(KPlayer* newplayer); - - /** - * Sends a message over the network, msgid=IdRemovePlayer. - * - * As soon as this message is received by networkTransmission - * systemRemovePlayer is called and the player is removed. - **/ - //AB: TODO: make sendMessage to return if the message will be able to be - //sent, eg if a socket is connected, etc. If sendMessage returns false - //remove the player directly using systemRemovePlayer - bool removePlayer(KPlayer * player) { return removePlayer(player, 0); } - - /** - * Called by the destructor of KPlayer to remove itself from the game - * - **/ - void playerDeleted(KPlayer * player); - - /** - * sends activate player: internal use only? - */ - bool activatePlayer(KPlayer *player); - - /** - * sends inactivate player: internal use only? - */ - bool inactivatePlayer(KPlayer *player); - - /** - * Set the maximal number of players. After this is - * reached no more players can be added. You must be ADMIN to call this (@see - * isAdmin). - * @param maxnumber maximal number of players - */ - void setMaxPlayers(uint maxnumber); - - /** - * What is the maximal number of players? - * @return maximal number of players - */ - int maxPlayers() const; - - /** - * Set the minimal number of players. A game can not be started - * with less player resp. is paused when already running. You must be ADMIN - * to call this (see @ref isAdmin)! - * @param minnumber minimal number of players - */ - void setMinPlayers(uint minnumber); - - /** - * What is the minimal number of players? - * @return minimal number of players - */ - uint minPlayers() const; - - /** - * Returns how many players are plugged into the game - * @return number of players - */ - uint playerCount() const; - - /** - * @deprecated - * Use @ref KGameSequence::nextPlayer instead - **/ - virtual KPlayer * nextPlayer(KPlayer *last,bool exclusive=true); - - // Input events - /** - * Called by KPlayer to send a player input to the - * KMessageServer. - **/ - virtual bool sendPlayerInput(TQDataStream &msg,KPlayer *player,TQ_UINT32 sender=0); - - /** - * Called when a player input arrives from KMessageServer. - * - * Calls prepareNext (using TQTimer::singleShot) if gameOver() - * returns 0. This function should normally not be used outside KGame. - * It could be made non-virtual,protected in a later version. At the - * moment it is a virtual function to give you more control over KGame. - * - * For documentation see playerInput. - **/ - virtual bool systemPlayerInput(TQDataStream &msg,KPlayer *player,TQ_UINT32 sender=0); - - /** - * This virtual function is called if the KGame needs to create a new player. - * This happens only over a network and with load/save. Doing nothing - * will create a default KPlayer. If you want to have your own player - * you have to create one with the given rtti here. - * Note: If your game uses a player class derived from KPlayer you MUST - * override this function and create your player here. Otherwise the - * game will crash. - * Example: - * \code - * KPlayer *MyGame::createPlayer(int rtti,int io,bool isvirtual) - * { - * KPlayer *player=new MyPlayer; - * if (!isvirtual) // network player ? - * { - * // Define something like this to add the IO modules - * createIO(player,(KGameIO::IOMode)io); - * } - * return player; - * } - * \endcode - * - * @param rtti is the type of the player (0 means default KPlayer) - * @param io is the 'or'ed rtti of the KGameIO's - * @param isvirtual true if player is virtual - */ - virtual KPlayer *createPlayer(int rtti,int io,bool isvirtual); - - // load/save - /** - * Load a saved game, from file OR network. This function has - * to be overwritten or you need to connect to the load signal - * if you have game data other than KGameProperty. - * For file load you should reset() the game before any load attempt - * to make sure you load into an clear state. - * - * @param stream a data stream where you can stream the game from - * @param reset - shall the game be reset before loading - * - * @return true? - */ - virtual bool load(TQDataStream &stream,bool reset=true); - - /** - * Same as above function but with different parameters - * - * @param filename - the filename of the file to be opened - * @param reset - shall the game be reset before loading - * - * @return true? - **/ - virtual bool load(TQString filename,bool reset=true); - - /** - * Save a game to a file OR to network. Otherwise the same as - * the load function - * - * @param stream a data stream to load the game from - * @param saveplayers If true then all players wil be saved too - * - * @return true? - */ - virtual bool save(TQDataStream &stream,bool saveplayers=true); - - /** - * Same as above function but with different parameters - * - * @param filename the filename of the file to be saved - * @param saveplayers If true then all players wil be saved too - * - * @return true? - **/ - virtual bool save(TQString filename,bool saveplayers=true); - - /** - * Resets the game, i.e. puts it into a state where everything - * can be started from, e.g. a load game - * Right now it does only need to delete all players - * - * @return true on success - */ - virtual bool reset(); - - - // Game sequence - /** - * returns the game status, ie running,pause,ended,... - * - * @return game status - */ - int gametqStatus() const; - - /** - * sets the game status - * - * @param status the new status - */ - void setGametqStatus(int status); - - /** - * docu: see KPlayer - **/ - bool addProperty(KGamePropertyBase* data); - - /** - * This is called by KPlayer::sendProperty only! Internal function! - **/ - bool sendPlayerProperty(int msgid, TQDataStream& s, TQ_UINT32 playerId); - - /** - * This function allows to find the pointer to a player - * property when you know it's id - */ - KGamePropertyBase* findProperty(int id) const; - - /** - * Changes the consistency policy of a property. The - * GamePolicy is one of PolicyClean (default), PolicyDirty or PolicyLocal. - * - * It is up to you to decide how you want to work. - **/ - void setPolicy(GamePolicy p,bool recursive=true); - - /** - * @return The default policy of the property - **/ - GamePolicy policy() const; - - /** - * See KGameNetwork::sendMessage - * - * Send a network message msg with a given message ID msgid to all players of - * a given group (see KPlayer::group) - * @param msg the message which will be send. See messages.txt for contents - * @param msgid an id for this message - * @param sender the id of the sender - * @param group the group of the tqreceivers - * @return true if worked - */ - bool sendGroupMessage(const TQByteArray& msg, int msgid, TQ_UINT32 sender, const TQString& group); - bool sendGroupMessage(const TQDataStream &msg, int msgid, TQ_UINT32 sender, const TQString& group); - bool sendGroupMessage(int msg, int msgid, TQ_UINT32 sender, const TQString& group); - bool sendGroupMessage(const TQString& msg, int msgid, TQ_UINT32 sender, const TQString& group); - - /** - * This will either forward an incoming message to a specified player - * (see KPlayer::networkTransmission) or - * handle the message directly (e.g. if msgif==IdRemovePlayer it will remove - * the (in the stream) specified player). If both is not possible (i.e. the - * message is user specified data) the signal signalNetworkData is - * emitted. - * - * This emits signalMessageUpdate <em>before</em> doing anything with - * the message. You can use this signal when you want to be notified about - * an update/change. - * @param msgid Specifies the kind of the message. See messages.txt for - * further information - * @param stream The message that is being sent - * @param receiver The is of the player this message is for. 0 For broadcast. - * @param sender - * @param clientID the client from which we received the transmission - hardly used - **/ - virtual void networkTransmission(TQDataStream &stream, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender, TQ_UINT32 clientID); - - /** - * Returns a pointer to the KGame property handler - **/ - KGamePropertyHandler* dataHandler() const; - -protected slots: - /** - * Called by KGamePropertyHandler only! Internal function! - **/ - void sendProperty(int msgid, TQDataStream& stream, bool* sent); - - /** - * Called by KGamePropertyHandler only! Internal function! - **/ - void emitSignal(KGamePropertyBase *me); - - /** - * @deprecated - * Use KGameSequence::prepareNext() instead - **/ - virtual void prepareNext(); - - - /** - * Calls negotiateNetworkGame() - * See KGameNetwork::signalClientConnected - **/ - void slotClientConnected(TQ_UINT32 clientId); - - /** - * This slot is called whenever the connection to a client is lost (ie the - * signal KGameNetwork::signalClientDisconnected is emitted) and will remove - * the players from that client. - * @param clientId The client the connection has been lost to - * @param broken (ignore this - not used) - **/ - void slotClientDisconnected(TQ_UINT32 clientId,bool broken); - - /** - * This slot is called whenever the connection to the server is lost (ie the - * signal KGameNetwork::signalConnectionBroken is emitted) and will - * switch to local game mode - **/ - void slotServerDisconnected(); - -signals: - /** - * When a client disconnects from the game usually all players from that - * client are removed. But if you use completely the KGame structure you - * probably don't want this. You just want to replace the KGameIO of the - * (human) player by a computer KGameIO. So this player continues game but - * is from this point on controlled by the computer. - * - * You achieve this by connecting to this signal. It is emitted as soon as a - * client disconnects on <em>all</em> other clients. Make sure to add a new - * KGameIO only once! you might want to use @ref isAdmin for this. If you - * added a new KGameIO set *remove=false otherwise the player is completely - * removed. - * @param player The player that is about to be removed. Add your new - * KGameIO here - but only on <em>one</em> client! - * @param remove Set this to FALSE if you don't want this player to be - * removed completely. - **/ - void signalReplacePlayerIO(KPlayer* player, bool* remove); - - /** - * The game will be loaded from the given stream. Load from here - * the data which is NOT a game or player property. - * It is not necessary to use this signal for a full property game. - * - * This signal is emitted <em>before</em> the players are loaded by - * KGame. See also signalLoad - * - * You must load <em>exactly</em> the same data from the stream that you have saved - * in signalSavePrePlayers. Otherwise player loading will not work - * anymore. - * - * @param stream the load stream - */ - void signalLoadPrePlayers(TQDataStream &stream); - - /** - * The game will be loaded from the given stream. Load from here - * the data which is NOT a game or player property. - * It is not necessary to use this signal for a full property game. - * - * @param stream the load stream - */ - void signalLoad(TQDataStream &stream); - - /** - * The game will be saved to the given stream. Fill this with data - * which is NOT a game or player property. - * It is not necessary to use this signal for a full property game. - * - * This signal is emitted <em>before</em> the players are saved by - * KGame. See also signalSave - * - * If you can choose between signalSavePrePlayers and signalSave then - * better use signalSave - * - * @param stream the save stream - **/ - void signalSavePrePlayers(TQDataStream &stream); - - /** - * The game will be saved to the given stream. Fill this with data - * which is NOT a game or player property. - * It is not necessary to use this signal for a full property game. - * - * @param stream the save stream - */ - void signalSave(TQDataStream &stream); - - /** - * Is emmited if a game with a different version cookie is loaded. - * Normally this should result in an error. But maybe you do support - * loading of older game versions. Here would be a good place to do a - * conversion. - * - * @param stream - the load stream - * @param network - true if this is a network connect. False for load game - * @param cookie - the saved cookie. It differs from KGame::cookie() - * @param result - set this to true if you managed to load the game - */ - void signalLoadError(TQDataStream &stream,bool network,int cookie, bool &result); - - /** - * We got an user defined update message. This is usually done - * by a sendData in a inherited KGame Object which defines its - * own methods and has to syncronise them over the network. - * Reaction to this is usually a call to a KGame function. - */ - void signalNetworkData(int msgid,const TQByteArray& buffer, TQ_UINT32 receiver, TQ_UINT32 sender); - - /** - * We got an network message. this can be used to notify us that something - * changed. What changed can be seen in the message id. Whether this is - * the best possible method to do this is unclear... - */ - void signalMessageUpdate(int msgid,TQ_UINT32 receiver,TQ_UINT32 sender); - - /** - * a player left the game because of a broken connection or so! - * - * Note that when this signal is emitted the player is not part of @ref - * playerList anymore but the pointer is still valid. You should do some - * final cleanups here since the player is usually deleted after the signal - * is emitted. - * - * @param player the player who left the game - */ - void signalPlayerLeftGame(KPlayer *player); - - /** - * a player joined the game - * - * @param player the player who joined the game - */ - void signalPlayerJoinedGame(KPlayer *player); - - - /** - * This signal is emmited if a player property changes its value and - * the property is set to notify this change - */ - void signalPropertyChanged(KGamePropertyBase *property, KGame *me); - - /** - * Is emitted after a call to gameOver() returns a non zero - * return code. This code is forwarded to this signal as 'status'. - * - * @param status the return code of gameOver() - * @param current the player who did the last move - * @param me a pointer to the KGame object - */ - void signalGameOver(int status, KPlayer *current, KGame *me); - - /** - * Is emmited after a client is successfully connected to the game. - * The client id is the id of the new game client. An easy way to - * check whether that's us is - * \code - * if (clientid==gameid()) .. // we joined - * else ... // someone joined the game - * \endcode - * @param clientid - The id of the new client - * @param me - our game pointer - */ - void signalClientJoinedGame(TQ_UINT32 clientid,KGame *me); - - /** - * This signal is emitted after a network partner left the - * game (either by a broken connection or voluntarily). - * All changes to the network players have already be done. - * If there are not enough players left, the game might have - * been paused. To check this you get the old gamestatus - * before the disconnection as argument here. The id of the - * client who left the game allows to distinguish who left the - * game. If it is 0, the server disconnected and you were a client - * which has been switched back to local play. - * You can use this signal to, e.g. set some menues back to local - * player when they were network before. - * - * @param clientID - 0:server left, otherwise the client who left - * @param oldgamestatus - the gamestatus before the loss - * @param me - our game pointer - **/ - void signalClientLeftGame(int clientID,int oldgamestatus,KGame *me); - - -protected: - /** - * A player input occurred. This is the most important function - * as the given message will contain the current move made by - * the given player. - * Note that you HAVE to overwrite this function. Otherwise your - * game makes no sense at all. - * Generally you have to return TRUE in this function. Only then - * the game sequence is proceeded by calling @ref playerInputFinished - * which in turn will check for game over or the next player - * However, if you have a delayed move, because you e.g. move a - * card or a piece you want to return FALSE to pause the game sequence - * and then manually call @ref playerInputFinished to resume it. - * Example: - * \code - * bool MyClass::playerInput(TQDataStream &msg,KPlayer *player) - * { - * TQ_INT32 move; - * msg >> move; - * kdDebug() << " Player " << player->id() << " moved to " << move << - * endl; - * return true; - * } - * \endcode - * - * @param msg the move message - * @param player the player who did the move - * @return true - input ready, false: input manual - */ - virtual bool playerInput(TQDataStream &msg,KPlayer *player)=0; - - - /** - * Called after the player input is processed by the game. Here the - * checks for game over and nextPlayer (in the case of turn base games) - * are processed. - * Call this manually if you have a delayed move, i.e. your playerInput - * function returns FALSE. If it returns true you need not do anything - * here. - * - * @return the current player - * - **/ - KPlayer *playerInputFinished(KPlayer *player); - - - /** - * This virtual function can be overwritten for your own player management. - * It is called when a new game connects to an existing network game or - * to the network master. In case you do not want all players of both games - * to be present in the new network game, you can deactivate players here. - * This is of particular importance if you have a game with fixed number of - * player like e.g. chess. A network connect needs to disable one player of - * each game to make sense. - * - * Not overwriting this function will activate a default behaviour which - * will deactivate players until the @ref maxPlayers() numebr is reached - * according to the KPlayer::networkPriority() value. Players with a low - * value will be kicked out first. With equal priority players of the new - * client will leave first. This means, not setting this value and not - * overwriting this function will never allow a chess game to add client - * players!!! - * On the other hand setting one player of each game to a networkPriorty of - * say 10, already does most of the work for you. - * - * The parameters of this function are the playerlist of the network game, - * which is @ref playerList(). The second argument is the player list of - * the new client who wants to join and the third argument serves as return - * parameter. All <em>player ID's</em> which are written into this list - * will be <em>removed</em> from the created game. You do this by an - * \code - * inactivate.append(player->id()); - * \endcode - * - * @param oldplayer - the list of the network players - * @param newplayer - the list of the client players - * @param inactivate - the value list of ids to be deactivated - * - **/ - virtual void newPlayersJoin(KGamePlayerList *oldplayer, - KGamePlayerList *newplayer, - TQValueList<int> &inactivate) { - Q_UNUSED( oldplayer ); - Q_UNUSED( newplayer ); - Q_UNUSED( inactivate ); - } - - /** - * Save the player list to a stream. Used for network game and load/save. - * Can be overwritten if you know what you are doing - * - * @param stream is the stream to save the player ot - * @param list the optional list is the player list to be saved, default is playerList() - * - **/ - void savePlayers(TQDataStream &stream,KGamePlayerList *list=0); - - /** - * Prepare a player for being added. Put all data about a player into the - * stream so that it can be sent to the KGameCommunicationServer using - * addPlayer (e.g.) - * - * This function ensures that the code for adding a player is the same in - * addPlayer as well as in negotiateNetworkGame - * @param stream is the stream to add the player - * @param player The player to add - **/ - void savePlayer(TQDataStream& stream,KPlayer* player); - - /** - * Load the player list from a stream. Used for network game and load/save. - * Can be overwritten if you know what you are doing - * - * @param stream is the stream to save the player to - * @param isvirtual will set the virtual flag true/false - * - **/ - KPlayer *loadPlayer(TQDataStream& stream,bool isvirtual=false); - - - /** - * inactivates player. Use @ref inactivatePlayer instead! - */ - bool systemInactivatePlayer(KPlayer *player); - - /** - * activates player. Use @ref activatePlayer instead! - */ - bool systemActivatePlayer(KPlayer *player); - - /** - * Adds a player to the game - * - * Use @ref addPlayer to send @ref KGameMessage::IdAddPlayer. As soon as - * this Id is received this function is called, where the player (see @ref - * KPlayer::rtti) is added as well as its properties (see @ref KPlayer::save - * and @ref KPlayer::load) - * - * This method calls the overloaded @ref systemAddPlayer with the created - * player as argument. That method will really add the player. - * If you need to do some changes to your newly added player just connect to - * @ref signalPlayerJoinedGame - */ - - /** - * Finally adds a player to the game and therefore to the list. - **/ - void systemAddPlayer(KPlayer* newplayer); - - /** - * Removes a player from the game - * - * Use removePlayer to send KGameMessage::IdRemovePlayer. As soon - * as this Id is received systemRemovePlayer is called and the player is - * removed directly. - **/ - void systemRemovePlayer(KPlayer* player,bool deleteit); - - /** - * This member function will transmit e.g. all players to that client, as well as - * all properties of these players (at least if they have been added by - * @ref KPlayer::addProperty) so that the client will finally have the same - * status as the master. You want to overwrite this function if you expand - * KGame by any properties which have to be known by all clients. - * - * Only the ADMIN is allowed to call this. - * @param clientID The ID of the message client which has connected - **/ - virtual void negotiateNetworkGame(TQ_UINT32 clientID); - - /** - * syncronise the random numbers with all network clients - * not used by KGame - if it should be kept then as public method - */ - void syncRandom(); - - void deletePlayers(); - void deleteInactivePlayers(); - - /** - * @deprecated - * Use @ref KGameSequence instead. - * - * @param player the player who made the last move - * @return anything else but 0 is considered as game over - */ - virtual int checkGameOver(KPlayer *player); - - /** - * Load a saved game, from file OR network. Internal. - * Warning: loadgame must not rely that all players all already - * activated. Actually the network will activate a player AFTER - * the loadgame only. This is not true anymore. But be careful - * anyway. - * - * @param stream a data stream where you can stream the game from - * @param network is it a network call -> make players virtual - * @param reset shall the game be reset before loading - * - * @return true? - */ - virtual bool loadgame(TQDataStream &stream, bool network, bool reset); - - /** - * Save a game, to file OR network. Internal. - * - * @param stream a data stream where you can stream the game from - * @param network is it a call from the network or from a file (unused but informative) - * @param saveplayers shall the players be saved too (should be TRUE) - * - * @return true? - */ - virtual bool savegame(TQDataStream &stream, bool network,bool saveplayers); - -private: - //AB: this is to hide the "receiver" parameter from the user. It shouldn't be - //used if possible (except for init). - /** - * This is an overloaded function. Id differs from the public one only in - * its parameters: - * - * @param receiver The Client that will receive the message. You will hardly - * ever need this. It it internally used to initialize a newly connected - * client. - **/ - //void addPlayer(KPlayer* newplayer, TQ_UINT32 receiver); - - /** - * Just the same as the public one except receiver: - * @param receiver 0 for broadcast, otherwise the receiver. Should only be - * used in special circumstances and not outside KGame. - **/ - bool removePlayer(KPlayer * player, TQ_UINT32 receiver); - - /** - * Helping function - game negotiation - **/ - void setupGame(TQ_UINT32 sender); - - /** - * Helping function - game negotiation - **/ - void setupGameContinue(TQDataStream& msg, TQ_UINT32 sender); - - /** - * Removes a player from all lists, removes the @ref KGame pointer from the - * @ref KPlayer and deletes the player. Used by (e.g.) @ref - * systemRemovePlayer - * @return True if the player has been removed, false if the current is not - * found - **/ - bool systemRemove(KPlayer* player,bool deleteit); - - -private: - KGamePrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/kgamechat.cpp b/libkdegames/kgame/kgamechat.cpp deleted file mode 100644 index 11f47f7b..00000000 --- a/libkdegames/kgame/kgamechat.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001-2002 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 "kgamechat.h" -#include "kgamechat.moc" - -#include "kgame.h" -#include "kplayer.h" -#include "kgameproperty.h" -#include "kgamemessage.h" - -#include <klocale.h> -#include <kdebug.h> - -#include <tqmap.h> -#include <tqintdict.h> - -//FIXME: -#define FIRST_ID 2 // first id, that is free of use, aka not defined above - -class KGameChatPrivate -{ -public: - KGameChatPrivate() - { - mFromPlayer = 0; - mGame = 0; - - mToMyGroup = -1; - } - - KGame* mGame; - KPlayer* mFromPlayer; - int mMessageId; - - - TQIntDict<KPlayer> mIndex2Player; - - TQMap<int, int> mSendId2PlayerId; - int mToMyGroup; // just as the above - but for the group, not for players -}; - -KGameChat::KGameChat(KGame* g, int msgid, TQWidget* parent) : KChatBase(parent) -{ - init(g, msgid); -} - -KGameChat::KGameChat(KGame* g, int msgid, KPlayer* fromPlayer, TQWidget* parent) : KChatBase(parent) -{ - init(g, msgid); - setFromPlayer(fromPlayer); -} - -KGameChat::KGameChat(TQWidget* parent) : KChatBase(parent) -{ - init(0, -1); -} - -KGameChat::~KGameChat() -{ - kdDebug(11001) << k_funcinfo << endl; - delete d; -} - -void KGameChat::init(KGame* g, int msgId) -{ - kdDebug(11001) << k_funcinfo << endl; - d = new KGameChatPrivate; - setMessageId(msgId); - - setKGame(g); -} - -void KGameChat::addMessage(int fromId, const TQString& text) -{ - if (!d->mGame) { - kdWarning(11001) << "no KGame object has been set" << endl; - addMessage(i18n("Player %1").tqarg(fromId), text); - } else { - KPlayer* p = d->mGame->findPlayer(fromId); - if (p) { - kdDebug(11001) << "adding message of player " << p->name() << "id=" << fromId << endl; - addMessage(p->name(), text); - } else { - kdWarning(11001) << "Could not find player id " << fromId << endl; - addMessage(i18n("Unknown"), text); - } - } -} - -void KGameChat::returnPressed(const TQString& text) -{ - if (!d->mFromPlayer) { - kdWarning(11001) << k_funcinfo << ": You must set a player first!" << endl; - return; - } - if (!d->mGame) { - kdWarning(11001) << k_funcinfo << ": You must set a game first!" << endl; - return; - } - - kdDebug(11001) << "from: " << d->mFromPlayer->id() << "==" << d->mFromPlayer->name() << endl; - - int id = sendingEntry(); - - if (isToGroupMessage(id)) { - // note: there is currently no support for other groups than the players - // group! It might be useful to send to other groups, too - TQString group = d->mFromPlayer->group(); - kdDebug(11001) << "send to group " << group << endl; - int sender = d->mFromPlayer->id(); - d->mGame->sendGroupMessage(text, messageId(), sender, group); - - //TODO - //AB: this message is never received!! we need to connect to - //KPlayer::networkData!!! - //TODO - - } else { - int toPlayer = 0; - if (!isSendToAllMessage(id) && isToPlayerMessage(id)) { - toPlayer = playerId(id); - if (toPlayer == -1) { - kdError(11001) << k_funcinfo << ": don't know that player " - << "- internal ERROR" << endl; - } - } - int receiver = toPlayer; - int sender = d->mFromPlayer->id(); - d->mGame->sendMessage(text, messageId(), receiver, sender); - } -} - -void KGameChat::setMessageId(int msgid) -{ d->mMessageId = msgid; } - -int KGameChat::messageId() const -{ return d->mMessageId; } - -bool KGameChat::isSendToAllMessage(int id) const -{ return (id == KChatBase::SendToAll); } - -bool KGameChat::isToGroupMessage(int id) const -{ return (id == d->mToMyGroup); } - -bool KGameChat::isToPlayerMessage(int id) const -{ -return d->mSendId2PlayerId.contains(id); } - -TQString KGameChat::sendToPlayerEntry(const TQString& name) const -{ return i18n("Send to %1").tqarg(name); } - -int KGameChat::playerId(int id) const -{ - if (!isToPlayerMessage(id)) { - return -1; - } - - return d->mSendId2PlayerId[id]; -} - -int KGameChat::sendingId(int playerId) const -{ - TQMap<int, int>::Iterator it; - for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) { - if (it.data() == playerId) { - return it.key(); - } - } - return -1; -} - -const TQString& KGameChat::fromName() const -{ return d->mFromPlayer ? d->mFromPlayer->name() : TQString(); } - -bool KGameChat::hasPlayer(int id) const -{ - return (sendingId(id) != -1); -} - -void KGameChat::setFromPlayer(KPlayer* p) -{ - if (!p) { - kdError(11001) << k_funcinfo << ": NULL player" << endl; - removeSendingEntry(d->mToMyGroup); - d->mFromPlayer = 0; - return; - } - if (d->mFromPlayer) { - changeSendingEntry(p->group(), d->mToMyGroup); - } else { - if (d->mToMyGroup != -1) { - kdWarning(11001) << "send to my group exists already - removing" << endl; - removeSendingEntry(d->mToMyGroup); - } - d->mToMyGroup = nextId(); - addSendingEntry(i18n("Send to My Group (\"%1\")").tqarg(p->group()), d->mToMyGroup); - } - d->mFromPlayer = p; - kdDebug(11001) << k_funcinfo << " player=" << p << endl; -} - - -void KGameChat::setKGame(KGame* g) -{ - if (d->mGame) { - slotUnsetKGame(); - } - kdDebug(11001) << k_funcinfo << " game=" << g << endl; - d->mGame = g; - - if (d->mGame) { - connect(d->mGame, TQT_SIGNAL(signalPlayerJoinedGame(KPlayer*)), - this, TQT_SLOT(slotAddPlayer(KPlayer*))); - connect(d->mGame, TQT_SIGNAL(signalPlayerLeftGame(KPlayer*)), - this, TQT_SLOT(slotRemovePlayer(KPlayer*))); - connect(d->mGame, TQT_SIGNAL(signalNetworkData(int, const TQByteArray&, TQ_UINT32, TQ_UINT32)), - this, TQT_SLOT(slotReceiveMessage(int, const TQByteArray&, TQ_UINT32, TQ_UINT32))); - connect(d->mGame, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotUnsetKGame())); - - TQPtrList<KPlayer> playerList = *d->mGame->playerList(); - for (int unsigned i = 0; i < playerList.count(); i++) { - slotAddPlayer(playerList.at(i)); - } - } -} - -KGame* KGameChat::game() const -{ - return d->mGame; -} - -KPlayer* KGameChat::fromPlayer() const -{ - return d->mFromPlayer; -} - -void KGameChat::slotUnsetKGame() -{ -//TODO: test this method! - - if (!d->mGame) { - return; - } - disconnect(d->mGame, 0, this, 0); - removeSendingEntry(d->mToMyGroup); - TQMap<int, int>::Iterator it; - for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) { - removeSendingEntry(it.data()); - } -} - -void KGameChat::slotAddPlayer(KPlayer* p) -{ - if (!p) { - kdError(11001) << k_funcinfo << ": cannot add NULL player" << endl; - return; - } - if (hasPlayer(p->id())) { - kdError(11001) << k_funcinfo << ": player was added before" << endl; - return; - } - - int sendingId = nextId(); - addSendingEntry(comboBoxItem(p->name()), sendingId); - d->mSendId2PlayerId.insert(sendingId, p->id()); - connect(p, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)), - this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*))); - connect(p, TQT_SIGNAL(signalNetworkData(int, const TQByteArray&, TQ_UINT32, KPlayer*)), - this, TQT_SLOT(slotReceivePrivateMessage(int, const TQByteArray&, TQ_UINT32, KPlayer*))); -} - -void KGameChat::slotRemovePlayer(KPlayer* p) -{ - if (!p) { - kdError(11001) << k_funcinfo << ": NULL player" << endl; - return; - } - if (!hasPlayer(p->id())) { - kdError(11001) << k_funcinfo << ": cannot remove non-existent player" << endl; - return; - } - - int id = sendingId(p->id()); - removeSendingEntry(id); - p->disconnect(this); - d->mSendId2PlayerId.remove(id); -} - -void KGameChat::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player) -{ - if (prop->id() == KGamePropertyBase::IdName) { -// kdDebug(11001) << "new Name" << endl; - changeSendingEntry(player->name(), sendingId(player->id())); -/* - mCombo->changeItem(comboBoxItem(player->name()), index); - */ - } else if (prop->id() == KGamePropertyBase::IdGroup) { - //TODO - } -} - -void KGameChat::slotReceivePrivateMessage(int msgid, const TQByteArray& buffer, TQ_UINT32 sender, KPlayer* me) -{ - if (!me || me != fromPlayer()) { - kdDebug() << k_funcinfo << "nope - not for us!" << endl; - return; - } - slotReceiveMessage(msgid, buffer, me->id(), sender); -} - -void KGameChat::slotReceiveMessage(int msgid, const TQByteArray& buffer, TQ_UINT32 , TQ_UINT32 sender) -{ - TQDataStream msg(buffer, IO_ReadOnly); - if (msgid != messageId()) { - return; - } - - TQString text; - msg >> text; - - addMessage(sender, text); -} - diff --git a/libkdegames/kgame/kgamechat.h b/libkdegames/kgame/kgamechat.h deleted file mode 100644 index 88139d33..00000000 --- a/libkdegames/kgame/kgamechat.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001-2002 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMECHAT_H__ -#define __KGAMECHAT_H__ - -#include <tqstring.h> - -#include "kchatbase.h" -#include <kdemacros.h> -class KPlayer; -class KGame; -class KGamePropertyBase; - -class KGameChatPrivate; - -/** - * @short A Chat widget for KGame-based games - * - * Call @ref setFromPlayer() first - this will be used as the "from" part of - * every message you will send. Otherwise it won't work! You can also use the - * fromPlayer parameter in the constructor though... - * - * @author Andreas Beckermann <[email protected]> - **/ -class KDE_EXPORT KGameChat : public KChatBase -{ - Q_OBJECT - TQ_OBJECT -public: - /** - * Construct a @ref KGame chat widget on @p game that used @p msgid for - * the chat message. The @p fromPlayer is the local player (see @ref - * setFromPlayer). - **/ - KGameChat(KGame* game, int msgid, KPlayer* fromPlayer, TQWidget * parent); - - /** - * @overload - * To make use of this widget you need to call @ref setFromPlayer - * manually. - **/ - KGameChat(KGame* game, int msgId, TQWidget* parent); - - /** - * @overload - * This constructs a widget that is not usable. You must call at least - * setGame, setFromPlayer and setMessageId manually. - * @since 3.2 - **/ - KGameChat(TQWidget* parent); - - virtual ~KGameChat(); - - enum SendingIds { - SendToGroup = 1 - }; - - /** - * This sets the fromPlayer to @p player. The fromPlayer is the - * player that will appear as "from" when you send messages through this - * widget. - * @param player The player of this widget - **/ - void setFromPlayer(KPlayer* player); - - KPlayer* fromPlayer() const; - - /** - * Set the @ref KGame object for this chat widget. All messages will be - * sent through this object. You don't have to implement any send - * functions, just call this function, call @ref setFromPlayer and be - * done :-) - * @param g The @ref KGame object the messages will be sent through - **/ - void setKGame(KGame* g); - - KGame* game() const; - - /** - * @return The id of the messages produced by KGameChat. The id will be - * used in @ref KGame as parameter msgid in the method @ref KGame::sendMessage - **/ - int messageId() const; - - /** - * Change the message id of the chat widget. It is recommended that you - * don't use this but prefer the constructor instead, but in certain - * situations (such as using this widget in TQt designer) it may be - * useful to change the message id. - * - * See also @ref messageId - * @since 3.2 - **/ - void setMessageId(int msgid); - - /** - * reimplemented from @ref KChatBase - * @return @ref KPlayer::name() for the player set by @ref setFromPlayer - **/ - virtual const TQString& fromName() const; - - -public slots: - virtual void addMessage(const TQString& fromName, const TQString& text) { KChatBase::addMessage(fromName, text);} - virtual void addMessage(int fromId, const TQString& text); - - void slotReceiveMessage(int, const TQByteArray&, TQ_UINT32 receiver, TQ_UINT32 sender); - -protected: - /** - * @param id The ID of the sending entry, as returned by @ref - * KChatBase::sendingEntry - * @return True if the entry "send to all" was selected, otherwise false - **/ - bool isSendToAllMessage(int id) const; - - /** - * Used to indicate whether a message shall be sent to a group of - * players. Note that this was not yet implemented when this doc was - * written so this description might be wrong. (FIXME) - * @param id The ID of the sending entry, as returned by @ref - * KChatBase::sendingEntry - * @return True if the message is meant to be sent to a group (see @ref - * KPlayer::group), e.g. if "send to my group" was selected. - **/ - bool isToGroupMessage(int id) const; - - - /** - * Used to indicate whether the message shall be sent to a single player - * only. Note that you can also call @ref isSendToAllMessage and @ref - * isToGroupMessage - if both return false it must be a player message. - * This behaviour might be changed later - so don't depend on it. - * - * See also toPlayerId - * @param id The ID of the sending entry, as returned by - * KChatBase::sendingEntry - * @return True if the message shall be sent to a special player, - * otherwise false. - **/ - bool isToPlayerMessage(int id) const; - - /** - * @param id The ID of the sending entry, as returned by - * KChatBase::sendingEntry - * @return The ID of the player (see KPlayer::id) the sending entry - * belongs to. Note that the parameter id is an id as returned by ref - * KChatBase::sendingEntry and the id this method returns is a - * KPlayer ID. If isToPlayerMessage returns false this method - * returns -1 - **/ - int playerId(int id) const; - - /** - * @param playerId The ID of the KPlayer object - * @return The ID of the sending entry (see KChatBase) or -1 if - * the player id was not found. - **/ - int sendingId(int playerId) const; - - /** - * @return True if the player with this ID was added before (see - * slotAddPlayer) - **/ - bool hasPlayer(int id) const; - - /** - * @param name The name of the added player - * @return A string that will be added as sending entry in @ref - * KChatBase. By default this is "send to name" where name is the name - * that you specify. See also KChatBase::addSendingEntry - **/ - virtual TQString sendToPlayerEntry(const TQString& name) const; - - -protected slots: - /** - * Unsets a KGame object that has been set using setKGame - * before. You don't have to call this - this is usually done - * automatically. - **/ - void slotUnsetKGame(); - - - void slotPropertyChanged(KGamePropertyBase*, KPlayer*); - void slotAddPlayer(KPlayer*); - void slotRemovePlayer(KPlayer*); - - /** - * Called when KPlayer::signalNetworkData is emitted. The message - * gets forwarded to slotReceiveMessage if @p me equals - * fromPlayer. - **/ - void slotReceivePrivateMessage(int msgid, const TQByteArray& buffer, TQ_UINT32 sender, KPlayer* me); - -protected: - virtual void returnPressed(const TQString& text); - -private: - void init(KGame* g, int msgid); - -private: - KGameChatPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/kgameerror.cpp b/libkdegames/kgame/kgameerror.cpp deleted file mode 100644 index ef6145fb..00000000 --- a/libkdegames/kgame/kgameerror.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgameerror.h" -#include "kgamemessage.h" - -#include <klocale.h> - -TQByteArray KGameError::errVersion(int remoteVersion) -{ - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - s << (TQ_INT32)KGameMessage::version(); - s << (TQ_INT32)remoteVersion; - return b; -} - -TQByteArray KGameError::errCookie(int localCookie, int remoteCookie) -{ - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - s << (TQ_INT32)localCookie; - s << (TQ_INT32)remoteCookie; - return b; -} - -TQString KGameError::errorText(int errorCode, const TQByteArray& message) -{ - TQDataStream s(message, IO_ReadOnly); - return errorText(errorCode, s); -} - -TQString KGameError::errorText(int errorCode, TQDataStream& s) -{ - TQString text; - switch (errorCode) { - case Cookie: - { - TQ_INT32 cookie1; - TQ_INT32 cookie2; - s >> cookie1; - s >> cookie2; - text = i18n("Cookie mismatch!\nExpected Cookie: %1\nReceived Cookie: %2").tqarg(cookie1).tqarg(cookie2); - break; - } - case Version: - { - TQ_INT32 version1; - TQ_INT32 version2; - s >> version1; - s >> version2; - text = i18n("KGame Version mismatch!\nExpected Version: %1\nReceived Version: %2\n").tqarg(version1).tqarg(version2); - break; - } - default: - text = i18n("Unknown error code %1").tqarg(errorCode); - } - return text; -} - diff --git a/libkdegames/kgame/kgameerror.h b/libkdegames/kgame/kgameerror.h deleted file mode 100644 index 071737cc..00000000 --- a/libkdegames/kgame/kgameerror.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMEERROR_H_ -#define __KGAMEERROR_H_ - -#include <tqstring.h> - - -class KGameError -{ -public: - KGameError() { } - ~KGameError() { } - - enum ErrorCodes { - Cookie = 0, // Cookie mismatch - Version = 1 // Version mismatch - }; - - /** - * Generate an error message with Erorr Code = ErrCookie - **/ - static TQByteArray errCookie(int localCookie, int remoteCookie); - static TQByteArray errVersion(int remoteVersion); - - /** - * Create an erorr text using a TQDataStream (TQByteArray) which was - * created using @ref KGameError. This is the opposite function to all - * the errXYZ() function (e.g. @ref errVersion). - * You want to use this to generate the message that shall be - * displayed to the user. - * @return an error message - **/ - static TQString errorText(int errorCode, TQDataStream& message); - static TQString errorText(int errorCode, const TQByteArray& message); - -}; - -#endif diff --git a/libkdegames/kgame/kgameio.cpp b/libkdegames/kgame/kgameio.cpp deleted file mode 100644 index 5b736ea0..00000000 --- a/libkdegames/kgame/kgameio.cpp +++ /dev/null @@ -1,539 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgameio.h" -#include "kgameio.moc" -#include "kgame.h" -#include "kplayer.h" -#include "kgamemessage.h" -#include "kmessageio.h" - -#include <kdebug.h> - -#include <tqwidget.h> -#include <tqbuffer.h> -#include <tqtimer.h> - -#include <stdlib.h> - -// ----------------------- Generic IO ------------------------- -KGameIO::KGameIO() : TQObject(0,0) -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl; - mPlayer = 0; -} - -KGameIO::KGameIO(KPlayer* player) : TQObject(0,0) -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl; - mPlayer = 0; - if (player) - { - player->addGameIO(this); - } -} - -KGameIO::~KGameIO() -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - // unregister ourselves - if (player()) - { - player()->removeGameIO(this, false); - } -} - -void KGameIO::initIO(KPlayer *p) -{ - setPlayer(p); -} - -void KGameIO::notifyTurn(bool b) -{ - if (!player()) - { - kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl; - return; - } - bool sendit=false; - TQByteArray buffer; - TQDataStream stream(buffer, IO_WriteOnly); - emit signalPrepareTurn(stream, b, this, &sendit); - if (sendit) - { - TQDataStream ostream(buffer,IO_ReadOnly); - TQ_UINT32 sender = player()->id(); // force correct sender - kdDebug(11001) << "Prepare turn sendInput" << endl; - sendInput(ostream, true, sender); - } -} - -KGame* KGameIO::game() const -{ - if (!player()) - { - return 0; - } - return player()->game(); -} - -bool KGameIO::sendInput(TQDataStream& s, bool transmit, TQ_UINT32 sender) -{ - if (!player()) - { - return false; - } - return player()->forwardInput(s, transmit, sender); -} - -void KGameIO::Debug() -{ - kdDebug(11001) << "------------------- KGAMEINPUT --------------------" << endl; - kdDebug(11001) << "this: " << this << endl; - kdDebug(11001) << "rtti : " << rtti() << endl; - kdDebug(11001) << "Player: " << player() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - - -// ----------------------- Key IO --------------------------- -KGameKeyIO::KGameKeyIO(TQWidget *parent) - : KGameIO() -{ - if (parent) - { - kdDebug(11001) << "Key Event filter installed" << endl; - parent->installEventFilter(this); - } -} - -KGameKeyIO::~KGameKeyIO() -{ - if (parent()) - { - parent()->removeEventFilter(this); - } -} - -int KGameKeyIO::rtti() const { return KeyIO; } - -bool KGameKeyIO::eventFilter( TQObject *o, TQEvent *e ) -{ - if (!player()) - { - return false; - } - - // key press/release - if ( e->type() == TQEvent::KeyPress || - e->type() == TQEvent::KeyRelease ) - { - TQKeyEvent *k = (TQKeyEvent*)e; - // kdDebug(11001) << "KGameKeyIO " << this << " key press/release " << k->key() << endl ; - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - bool eatevent=false; - emit signalKeyEvent(this,stream,k,&eatevent); - TQDataStream msg(buffer,IO_ReadOnly); - - if (eatevent && sendInput(msg)) - { - return eatevent; - } - return false; // do not eat otherwise - } - return TQObject::eventFilter( o, e ); // standard event processing -} - - -// ----------------------- Mouse IO --------------------------- -KGameMouseIO::KGameMouseIO(TQWidget *parent,bool trackmouse) - : KGameIO() -{ - if (parent) - { - kdDebug(11001) << "Mouse Event filter installed tracking=" << trackmouse << endl; - parent->installEventFilter(this); - parent->setMouseTracking(trackmouse); - } -} - -KGameMouseIO::~KGameMouseIO() -{ - if (parent()) - { - parent()->removeEventFilter(this); - } -} - -int KGameMouseIO::rtti() const -{ - return MouseIO; -} - -void KGameMouseIO::setMouseTracking(bool b) -{ - if (parent()) - { - ((TQWidget*)parent())->setMouseTracking(b); - } -} - -bool KGameMouseIO::eventFilter( TQObject *o, TQEvent *e ) -{ - if (!player()) - { - return false; - } -// kdDebug(11001) << "KGameMouseIO " << this << endl ; - - // mouse action - if ( e->type() == TQEvent::MouseButtonPress || - e->type() == TQEvent::MouseButtonRelease || - e->type() == TQEvent::MouseButtonDblClick || - e->type() == TQEvent::Wheel || - e->type() == TQEvent::MouseMove - ) - { - TQMouseEvent *k = (TQMouseEvent*)e; - // kdDebug(11001) << "KGameMouseIO " << this << endl ; - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - bool eatevent=false; - emit signalMouseEvent(this,stream,k,&eatevent); -// kdDebug(11001) << "################# eatevent=" << eatevent << endl; - TQDataStream msg(buffer,IO_ReadOnly); - if (eatevent && sendInput(msg)) - { - return eatevent; - } - return false; // do not eat otherwise - } - return TQObject::eventFilter( o, e ); // standard event processing -} - - -// ----------------------- KGameProcesPrivate --------------------------- -class KGameProcessIO::KGameProcessIOPrivate -{ -public: - KGameProcessIOPrivate() - { - //mMessageServer = 0; - //mMessageClient = 0; - mProcessIO=0; - } - //KMessageServer *mMessageServer; - //KMessageClient *mMessageClient; - KMessageProcess *mProcessIO; -}; - -// ----------------------- Process IO --------------------------- -KGameProcessIO::KGameProcessIO(const TQString& name) - : KGameIO() -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)=" << sizeof(KGameProcessIO) << endl; - d = new KGameProcessIOPrivate; - - //kdDebug(11001) << "================= KMEssageServer ==================== " << endl; - //d->mMessageServer=new KMessageServer(0,this); - //kdDebug(11001) << "================= KMEssageClient ==================== " << endl; - //d->mMessageClient=new KMessageClient(this); - kdDebug(11001) << "================= KMEssageProcessIO ==================== " << endl; - d->mProcessIO=new KMessageProcess(this,name); - kdDebug(11001) << "================= KMEssage Add client ==================== " << endl; - //d->mMessageServer->addClient(d->mProcessIO); - //kdDebug(11001) << "================= KMEssage SetSErver ==================== " << endl; - //d->mMessageClient->setServer(d->mMessageServer); - kdDebug(11001) << "================= KMEssage: Connect ==================== " << endl; - //connect(d->mMessageClient, TQT_SIGNAL(broadcastReceived(const TQByteArray&, TQ_UINT32)), - // this, TQT_SLOT(clientMessage(const TQByteArray&, TQ_UINT32))); - //connect(d->mMessageClient, TQT_SIGNAL(forwardReceived(const TQByteArray&, TQ_UINT32, const TQValueList <TQ_UINT32> &)), - // this, TQT_SLOT(clientMessage(const TQByteArray&, TQ_UINT32, const TQValueList <TQ_UINT32> &))); - connect(d->mProcessIO, TQT_SIGNAL(received(const TQByteArray&)), - this, TQT_SLOT(receivedMessage(const TQByteArray&))); - //kdDebug(11001) << "Our client is id="<<d->mMessageClient->id() << endl; -} - -KGameProcessIO::~KGameProcessIO() -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - kdDebug(11001) << "player="<<player() << endl; - if (player()) - { - player()->removeGameIO(this,false); - } - if (d->mProcessIO) - { - delete d->mProcessIO; - d->mProcessIO=0; - } - delete d; -} - -int KGameProcessIO::rtti() const -{ - return ProcessIO; -} - -void KGameProcessIO::initIO(KPlayer *p) -{ - KGameIO::initIO(p); - // Send 'hello' to process - TQByteArray buffer; - TQDataStream stream(buffer, IO_WriteOnly); - TQ_INT16 id = p->userId(); - stream << id; - - bool sendit=true; - if (p) - { - emit signalIOAdded(this,stream,p,&sendit); - if (sendit ) - { - TQ_UINT32 sender = p->id(); - kdDebug(11001) << "Sending IOAdded to process player !!!!!!!!!!!!!! " << endl; - sendSystemMessage(stream, KGameMessage::IdIOAdded, 0, sender); - } - } -} - -void KGameProcessIO::notifyTurn(bool b) -{ - if (!player()) - { - kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl; - return; - } - bool sendit=true; - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - stream << (TQ_INT8)b; - emit signalPrepareTurn(stream,b,this,&sendit); - if (sendit) - { - TQ_UINT32 sender=player()->id(); - kdDebug(11001) << "Sending Turn to process player !!!!!!!!!!!!!! " << endl; - sendSystemMessage(stream, KGameMessage::IdTurn, 0, sender); - } -} - -void KGameProcessIO::sendSystemMessage(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - sendAllMessages(stream, msgid, receiver, sender, false); -} - -void KGameProcessIO::sendMessage(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - sendAllMessages(stream, msgid, receiver, sender, true); -} - -void KGameProcessIO::sendAllMessages(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender, bool usermsg) -{ - kdDebug(11001) << "==============> KGameProcessIO::sendMessage (usermsg="<<usermsg<<")" << endl; - // if (!player()) return ; - //if (!player()->isActive()) return ; - - if (usermsg) - { - msgid+=KGameMessage::IdUser; - } - - kdDebug(11001) << "=============* ProcessIO (" << msgid << "," << receiver << "," << sender << ") ===========" << endl; - - TQByteArray buffer; - TQDataStream ostream(buffer,IO_WriteOnly); - TQBuffer *device=(TQBuffer *)stream.device(); - TQByteArray data=device->buffer();; - - KGameMessage::createHeader(ostream,sender,receiver,msgid); - // ostream.writeRawBytes(data.data()+device->at(),data.size()-device->at()); - ostream.writeRawBytes(data.data(),data.size()); - kdDebug(11001) << " Adding user data from pos="<< device->at() <<" amount= " << data.size() << " byte " << endl; - //if (d->mMessageClient) d->mMessageClient->sendBroadcast(buffer); - if (d->mProcessIO) - { - d->mProcessIO->send(buffer); - } -} - -//void KGameProcessIO::clientMessage(const TQByteArray& receiveBuffer, TQ_UINT32 clientID, const TQValueList <TQ_UINT32> &recv) -void KGameProcessIO::receivedMessage(const TQByteArray& receiveBuffer) -{ - TQDataStream stream(receiveBuffer,IO_ReadOnly); - int msgid; - TQ_UINT32 sender; - TQ_UINT32 receiver; - KGameMessage::extractHeader(stream,sender,receiver,msgid); - - kdDebug(11001) << "************* Got process message sender =" << sender - << " receiver=" << receiver << " msgid=" << msgid << endl; - - - // Cut out the header part...to not confuse network code - TQBuffer *buf=(TQBuffer *)stream.device(); - TQByteArray newbuffer; - newbuffer.setRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at()); - TQDataStream ostream(newbuffer,IO_ReadOnly); - kdDebug(11001) << "Newbuffer size=" << newbuffer.size() << endl; - - - -// This is a dummy message which allows us the process to talk with its owner - if (msgid==KGameMessage::IdProcessQuery) - { - emit signalProcessQuery(ostream,this); - } - else if (player()) - { - sender = player()->id(); // force correct sender - if (msgid==KGameMessage::IdPlayerInput) - { - sendInput(ostream,true,sender); - } - else - { - player()->forwardMessage(ostream,msgid,receiver,sender); - } - } - else - { - kdDebug(11001) << k_funcinfo << ": Got message from process but no player defined!" << endl; - } - newbuffer.resetRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at()); -} - - -// ----------------------- Computer IO -------------------------- -class KGameComputerIO::KGameComputerIOPrivate -{ -//TODO: maybe these should be KGameProperties!! -public: - KGameComputerIOPrivate() - { - mAdvanceCounter = 0; - mReactionPeriod = 0; - - mPauseCounter = 0; - - mAdvanceTimer = 0; - } - int mAdvanceCounter; - int mReactionPeriod; - - int mPauseCounter; - - TQTimer* mAdvanceTimer; -}; - -KGameComputerIO::KGameComputerIO() : KGameIO() -{ - init(); -} - -KGameComputerIO::KGameComputerIO(KPlayer* p) : KGameIO(p) -{ - init(); -} - -void KGameComputerIO::init() -{ - d = new KGameComputerIOPrivate; -} - -KGameComputerIO::~KGameComputerIO() -{ - if (d->mAdvanceTimer) - { - delete d->mAdvanceTimer; - } - delete d; -} - -int KGameComputerIO::rtti() const -{ - return ComputerIO; -} - -void KGameComputerIO::setReactionPeriod(int calls) -{ - d->mReactionPeriod = calls; -} - -int KGameComputerIO::reactionPeriod() const -{ - return d->mReactionPeriod; -} - -void KGameComputerIO::setAdvancePeriod(int ms) -{ - stopAdvancePeriod(); - d->mAdvanceTimer = new TQTimer(this); - connect(d->mAdvanceTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(advance())); - d->mAdvanceTimer->start(ms); -} - -void KGameComputerIO::stopAdvancePeriod() -{ - if (d->mAdvanceTimer) - { - d->mAdvanceTimer->stop(); - delete d->mAdvanceTimer; - } -} - -void KGameComputerIO::pause(int calls) -{ - d->mPauseCounter = calls; -} - -void KGameComputerIO::unpause() -{ - pause(0); -} - -void KGameComputerIO::advance() -{ - if (d->mPauseCounter > 0) - { - d->mPauseCounter--; - return; - } - else if (d->mPauseCounter < 0) - { - return; - } - d->mAdvanceCounter++; - if (d->mAdvanceCounter >= d->mReactionPeriod) - { - d->mAdvanceCounter = 0; - reaction(); - } -} - -void KGameComputerIO::reaction() -{ - emit signalReaction(); -} - - diff --git a/libkdegames/kgame/kgameio.h b/libkdegames/kgame/kgameio.h deleted file mode 100644 index 510ab0b7..00000000 --- a/libkdegames/kgame/kgameio.h +++ /dev/null @@ -1,571 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMEIO_H__ -#define __KGAMEIO_H__ - -#include <tqstring.h> -#include <tqobject.h> -#include <kdemacros.h> -class KPlayer; -class KGame; -class KProcess; - -/** - * \short Base class for IO devices for games - * - * This is the master class for - * creating IO game devices. You cannot use it directly. - * Either take one of the classes derived from it or - * you have to create your own IO class derived from it (more probably). - * - * The idea behind this class is to provide a common interface - * for input devices into your game. By programming a KGameIO - * device you need not distinguish the actual IO in the game - * anymore. All work is done by the IO's. This allows very - * easy reuse in other games as well. - * A further advantage of using the IO's is that you can exchange - * the control of a player at runtime. E.g. you switch a player - * to be controlled by the computer or vice versa. - * - * To achieve this you have to make all of your player inputs through a - * KGameIO. You will usually call KGameIO::sendInput to do so. - * - * @author Martin Heni <[email protected]> - */ -class KDE_EXPORT KGameIO : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Constructs a KGameIO object - */ - KGameIO(); - KGameIO(KPlayer*); - virtual ~KGameIO(); - - /** - * Gives debug output of the game status - */ - void Debug(); - - /** - * Identifies the KGameIO via the rtti function - */ - enum IOMode {GenericIO=1,KeyIO=2,MouseIO=4,ProcessIO=8,ComputerIO=16}; - /** - * Run time idendification. Predefined values are from IOMode - * You MUST overwrite this in derived classes! - * - * @return rtti value - */ - virtual int rtti() const = 0; // Computer, network, local, ... - - /** - * This function returns the player who owns this IO - * - * @return the player this IO device is plugged into - */ - KPlayer *player() const {return mPlayer;} - - /** - * Equivalent to player()->game() - * @return the @ref KGame object of this player - **/ - KGame* game() const; - - /** - * Sets the player to which this IO belongs to. This - * is done automatically when adding a device to a - * player - * - * @param p the player - */ - void setPlayer(KPlayer *p) {mPlayer=p;} - - /** - * Init this device by setting the player and e.g. sending an - * init message to the device. This initialisation message is - * very useful for computer players as you can transmit the - * game status to them and only update this status in the setTurn - * commands. - * - * Called by @ref KPlayer::addGameIO only! - */ - virtual void initIO(KPlayer *p); - - /** - * Notifies the IO device that the player's setTurn had been called - * Called by KPlayer - * - * This emits @ref signalPrepareTurn and sends the turn if the send - * parameter is set to true. - * - * @param b turn is true/false - */ - virtual void notifyTurn(bool b); - - /** - * Send an input message using @ref KPlayer::forwardInput - **/ - bool sendInput(TQDataStream& stream, bool transmit = true, TQ_UINT32 sender = 0); - -signals: - /** - * Signal generated when @ref KPlayer::myTurn changes. This can either be - * when you get the turn status or when you lose it. - * - * The datastream has to be filled with a move. If you set (or leave) the - * send parameter to FALSE then nothing happens: the datastream will be - * ignored. If you set it to TRUE @ref sendInput is used to - * send the move. - * - * Often you want to ignore this signal (leave send=FALSE) and send the - * message later. This is usually the case for a human player as he probably - * doesn't react immediately. But you can still use this e.g. to notify the - * player about the turn change. - * - * Example: - * \code - * void GameWindow::slotPrepareTurn(TQDataStream &stream,bool b,KGameIO *input,bool * ) - * { - * KPlayer *player=input->player(); - * if (!player->myTurn()) return ; - * if (!b) return ; // only do something on setTurn(true) - * stream << 1 << 2 << 3; // Some data for the process - * } - * \endcode - * - * @param io the KGameIO object itself - * @param stream the stream into which the move will be written - * @param turn the argument of setTurn - * @param send set this to true to send the generated move using @ref - * sendInput - **/ - void signalPrepareTurn(TQDataStream & stream, bool turn, KGameIO *io, bool * send); - - -private: - KPlayer *mPlayer; -}; - -/** - * The KGameKeyIO class. It is used to process keyboard input - * from a widget and create moves for the player it belongs to. - * @author Martin Heni <[email protected]> - */ -class KDE_EXPORT KGameKeyIO : public KGameIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Create a keyboard input devices. All keyboards - * inputs of the given widgets are passed through a signal - * handler signalKeyEvent and can be used to generate - * a valid move for the player. - * Note the widget you pass to the constructor must be - * the main window of your application, e.g. view->parentWidget() - * as QT does not forward your keyevents otherwise. This means - * that this might be a different widget comapred to the one you - * use for mouse inputs! - * Example: - * \code - * KGameKeyIO *input; - * input=new KGameKeyIO(myWidget); - * connect(input,TQT_SIGNAL(signalKeyEvent(KGameIO *,TQDataStream &,TQKeyEvent *,bool *)), - * this,TQT_SLOT(slotKeyInput(KGameIO *,TQDataStream &,TQKeyEvent *,bool *))); - * \endcode - * - * @param parent The parents widget whose keyboard events * should be grabbed - */ - KGameKeyIO(TQWidget *parent); - virtual ~KGameKeyIO(); - - /** - * The idendification of the IO - * - * @return KeyIO - */ - virtual int rtti() const; - -signals: - /** - * Signal handler for keyboard events. This function is called - * on every keyboard event. If appropriate it can generate a - * move for the player the device belongs to. If this is done - * and the event is eaten eatevent needs to be set to true. - * What move you generate (i.e. what you write to the stream) - * is totally up to you as it will not be evaluated but forwared - * to the player's/game's input move function - * Example: - * \code - * KPlayer *player=input->player(); // Get the player - * TQ_INT32 key=e->key(); - * stream << key; - * eatevent=true; - * \endcode - * - * @param io the IO device we belong to - * @param stream the stream where we write our move into - * @param m The TQKeyEvent we can evaluate - * @param eatevent set this to true if we processed the event - */ - void signalKeyEvent(KGameIO *io,TQDataStream &stream,TQKeyEvent *m,bool *eatevent); - -protected: - /** - * Internal method to process the events - */ - bool eventFilter( TQObject *o, TQEvent *e ); -}; - -/** - * The KGameMouseIO class. It is used to process mouse input - * from a widget and create moves for the player it belongs to. - * @author Martin Heni <[email protected]> - */ -class KDE_EXPORT KGameMouseIO : public KGameIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Creates a mouse IO device. It captures all mouse - * event of the given widget and forwards them to the - * signal handler signalMouseEvent. - * Example: - * \code - * KGameMouseIO *input; - * input=new KGameMouseIO(mView); - * connect(input,TQT_SIGNAL(signalMouseEvent(KGameIO *,TQDataStream &,TQMouseEvent *,bool *)), - * this,TQT_SLOT(slotMouseInput(KGameIO *,TQDataStream &,TQMouseEvent *,bool *))); - * \endcode - * - * @param parent The widget whose events should be captured - * @param trackmouse enables mouse tracking (gives mouse move events) - */ - KGameMouseIO(TQWidget *parent,bool trackmouse=false); - virtual ~KGameMouseIO(); - - /** - * Manually activate or deactivate mouse tracking - * - * @param b true = tracking on - */ - void setMouseTracking(bool b); - /** - * The idendification of the IO - * - * @return MouseIO - */ - virtual int rtti() const; - -signals: - /** - * Signal handler for mouse events. This function is called - * on every mouse event. If appropriate it can generate a - * move for the player the device belongs to. If this is done - * and the event is eaten eatevent needs to be set to true. - * @see signalKeyEvent - * Example: - * \code - * KPlayer *player=input->player(); // Get the player - * TQ_INT32 button=e->button(); - * stream << button; - * eatevent=true; - * \endcode - * - * @param io the IO device we belong to - * @param stream the stream where we write our move into - * @param m The TQMouseEvent we can evaluate - * @param eatevent set this to true if we processed the event - */ - void signalMouseEvent(KGameIO *io,TQDataStream &stream,TQMouseEvent *m,bool *eatevent); - -protected: - /** - * Internal event filter - */ - bool eventFilter( TQObject *o, TQEvent *e ); - -}; - - -/** - * The KGameProcessIO class. It is used to create a computer player - * via a separate process and communicate transparetly with it. - * Its counterpart is the @ref KGameProcess class which needs - * to be used by the computer player. See its documentation - * for the definition of the computer player. - * @author Martin Heni <[email protected]> - */ -class KDE_EXPORT KGameProcessIO : public KGameIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Creates a computer player via a separate process. The process - * name is given as fully qualified filename. - * Example: - * \code - * KGameProcessIO *input; - * input=new KGameProcessIO(executable_file); - * connect(input,TQT_SIGNAL(signalPrepareTurn(TQDataStream &,bool,KGameIO *,bool *)), - * this,TQT_SLOT(slotPrepareTurn(TQDataStream &,bool,KGameIO *,bool *))); - * connect(input,TQT_SIGNAL(signalProcessQuery(TQDataStream &,KGameProcessIO *)), - * this,TQT_SLOT(slotProcessQuery(TQDataStream &,KGameProcessIO *))); - * \endcode - * - * @param name the filename of the process to start - */ - KGameProcessIO(const TQString& name); - - /** - * Deletes the process input devices - */ - virtual ~KGameProcessIO(); - - /** - * The idendification of the IO - * - * @return ProcessIO - */ - int rtti() const; - - /** - * Send a message to the process. This is analogous to the sendMessage - * commands of KGame. It will result in a signal of the computer player - * on which you can react in the process player. - * - * @param stream - the actual data - * @param msgid - the id of the message - * @param receiver - not used - * @param sender - who send the message - */ - void sendMessage(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender); - - /** - * Send a system message to the process. This is analogous to the sendMessage - * commands of KGame. It will result in a signal of the computer player - * on which you can react in the process player. - * - * @param stream - the actual data - * @param msgid - the id of the message - * @param receiver - not used - * @param sender - who send the message - */ - void sendSystemMessage(TQDataStream &stream, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender); - - /** - * Init this device by setting the player and e.g. sending an - * init message to the device. Calling this function will emit - * the IOAdded signal on which you can react and initilise the - * computer player. - * This function is called automatically when adding the IO to - * a player. - */ - void initIO(KPlayer *p); - - /** - * Notifies the IO device that the player's setTurn had been called - * Called by KPlayer. You can react on the @ref signalPrepareTurn to - * prepare a message for the process, i.e. either update it on - * the changes made to the game since the last turn or the initIO - * has been called or transmit your gamestatus now. - * - * @param turn is true/false - */ - virtual void notifyTurn(bool turn); - - protected: - /** - * Internal ~ombined function for all message handling - **/ - void sendAllMessages(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender, bool usermsg); - - protected slots: - /** - * Internal message handler to receive data from the process - */ - void receivedMessage(const TQByteArray& receiveBuffer); - - -signals: - /** - * A computer query message is received. This is a 'dummy' - * message sent by the process if it needs to communicate - * with us. It is not forwarded over the network. - * Reacting to this message allows you to 'answer' questions - * of the process, e.g. sending addition data which the process - * needs to calculate a move. - * - * Example: - * \code - * void GameWindow::slotProcessQuery(TQDataStream &stream,KGameProcessIO *reply) - * { - * int no; - * stream >> no; // We assume the process sends us an integer question numner - * if (no==1) // but YOU have to do this in the process player - * { - * TQByteArray buffer; - * TQDataStream out(buffer,IO_WriteOnly); - * reply->sendSystemMessage(out,4242,0,0); // lets reply something... - * } - * } - * \endcode - */ - void signalProcessQuery(TQDataStream &stream,KGameProcessIO *me); - - /** - * Signal generated when the computer player is added. - * You can use this to communicated with the process and - * e.g. send initialisation information to the process. - * - * @param game the KGameIO object itself - * @param stream the stream into which the move will be written - * @param p the player itself - * @param send set this to false if no move should be generated - */ - void signalIOAdded(KGameIO *game,TQDataStream &stream,KPlayer *p,bool *send); - - -protected: - -private: - class KGameProcessIOPrivate; - KGameProcessIOPrivate* d; -}; - -/** - * \brief KGameIO variant for real-time games - * - * The KGameComputerIO class. It is used to create a LOCAL computer player - * and communicate transparently with it. - * Question: Is this needed or is it overwritten anyway for a real game? - * - * You most probably don't want to use this if you want to design a turn based - * game/player. You'll rather use @ref KGameIO directly, i.e. subclass it - * yourself. You just need to use @ref KGameIO::signalPrepareTurn and/or @ref - * KGameIO::notifyTurn there. - * - * This is rather meant to be of use in real time games. - * - * @author <[email protected]> - */ -class KDE_EXPORT KGameComputerIO : public KGameIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Creates a LOCAL computer player - * - */ - KGameComputerIO(); - KGameComputerIO(KPlayer* player); - ~KGameComputerIO(); - - int rtti() const; - - /** - * The number of advance calls until the player (or rather: the IO) - * does something (default: 1). - **/ - void setReactionPeriod(int advanceCalls); - int reactionPeriod() const; - - /** - * Start a TQTimer which calls advance every @p ms milli seconds. - **/ - void setAdvancePeriod(int ms); - - void stopAdvancePeriod(); - - /** - * Ignore calls number of advance calls. if calls is -1 then all - * following advance calls are ignored until unpause is called. - * - * This simply prevents the internal advance counter to be increased. - * - * You may want to use this to emulate a "thinking" computer player. Note - * that this means if you increase the advance period (see - * setAdvancePeriod), i.e. if you change the speed of your game, your - * computer player thinks "faster". - * @param calls Number of advance calls to be ignored - **/ - void pause(int calls = -1); - - /** - * Equivalent to pause(0). Immediately continue to increase the internal - * advance counter. - **/ - void unpause(); - -public slots: - /** - * Works kind of similar to TQCanvas::advance. Increase the internal - * advance counter. If @p reactionPeriod is reached the counter is set back to - * 0 and @ref signalReaction is emitted. This is when the player is meant - * to do something (move its units or so). - * - * This is very useful if you use TQCanvas as you can use this in your - * TQCanvas::advance call. The advantage is that if you change the speed - * of the game (i.e. change TQCanvas::setAdvancePeriod) the computer - * player gets slower as well. - * - * If you don't use TQCanvas you can use setAdvancePeriod to get - * the same result. Alternatively you can just use a TQTimer. - * - **/ - virtual void advance(); - -signals: - /** - * This signal is emitted when your computer player is meant to do - * something, or better is meant to be allowed to do something. - **/ - void signalReaction(); - -protected: - /** - * Default implementation simply emits signalReaction - **/ - virtual void reaction(); - -private: - void init(); - -private: - class KGameComputerIOPrivate; - KGameComputerIOPrivate* d; -}; - - -#endif diff --git a/libkdegames/kgame/kgamemessage.cpp b/libkdegames/kgame/kgamemessage.cpp deleted file mode 100644 index 9f5e4694..00000000 --- a/libkdegames/kgame/kgamemessage.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgamemessage.h" - -#include <klocale.h> - -#define MESSAGE_VERSION 2 - -TQ_UINT32 KGameMessage::createPlayerId(int oldplayerid,TQ_UINT32 gameid) -{ - int p; - p = oldplayerid & 0x3ff; // remove game id - p |= (gameid << 10); - return p; -} - -int KGameMessage::rawPlayerId(TQ_UINT32 playerid) -{ - return playerid & 0x03ff; -} - -TQ_UINT32 KGameMessage::rawGameId(TQ_UINT32 playerid) -{ - return (playerid & 0xfc00) >> 10; -} - -bool KGameMessage::isPlayer(TQ_UINT32 msgid) -{ - if (msgid & 0xfc00) { - return true; - } else { - return false; - } -} - -bool KGameMessage::isGame(TQ_UINT32 msgid) -{ - return !isPlayer(msgid); -} - - -void KGameMessage::createHeader(TQDataStream &msg,TQ_UINT32 sender,TQ_UINT32 receiver,int msgid) -{ - msg << (TQ_INT16)sender << (TQ_INT16)receiver << (TQ_INT16)msgid; -} - -void KGameMessage::extractHeader(TQDataStream &msg,TQ_UINT32 &sender,TQ_UINT32 &receiver,int &msgid) -{ - TQ_INT16 d3,d4,d5; - msg >> d3 >> d4 >> d5; - sender=d3;receiver=d4;msgid=d5; -} - -void KGameMessage::createPropertyHeader(TQDataStream &msg,int id) -{ - msg << (TQ_INT16)id; -} - -void KGameMessage::extractPropertyHeader(TQDataStream &msg,int &id) -{ - TQ_INT16 d1; - msg >> d1; - id=d1; -} - -void KGameMessage::createPropertyCommand(TQDataStream &msg,int cmdid,int pid,int cmd) -{ - createPropertyHeader(msg,cmdid); - msg << (TQ_INT16)pid ; - msg << (TQ_INT8)cmd ; -} - -void KGameMessage::extractPropertyCommand(TQDataStream &msg,int &pid,int &cmd) -{ - TQ_INT16 d1; - TQ_INT8 d2; - msg >> d1 >> d2; - pid=d1; - cmd=d2; -} - -int KGameMessage::version() -{ - return MESSAGE_VERSION; -} - -TQString KGameMessage::messageId2Text(int msgid) -{ -// this should contain all KGameMessage::GameMessageIds -// feel free to add missing ones, to remove obsolete one and even feel free to -// let it be ;-) - switch (msgid) { - case KGameMessage::IdSetupGame: - return i18n("Setup Game"); - case KGameMessage::IdSetupGameContinue: - return i18n("Setup Game Continue"); - case KGameMessage::IdGameLoad: - return i18n("Load Game"); - case KGameMessage::IdGameConnected: - return i18n("Client game connected"); - case KGameMessage::IdGameSetupDone: - return i18n("Game setup done"); - case KGameMessage::IdSyncRandom: - return i18n("Synchronize Random"); - case KGameMessage::IdDisconnect: - return i18n("Disconnect"); - case KGameMessage::IdPlayerProperty: - return i18n("Player Property"); - case KGameMessage::IdGameProperty: - return i18n("Game Property"); - case KGameMessage::IdAddPlayer: - return i18n("Add Player"); - case KGameMessage::IdRemovePlayer: - return i18n("Remove Player"); - case KGameMessage::IdActivatePlayer: - return i18n("Activate Player"); - case KGameMessage::IdInactivatePlayer: - return i18n("Inactivate Player"); - case KGameMessage::IdTurn: - return i18n("Id Turn"); - case KGameMessage::IdError: - return i18n("Error Message"); - case KGameMessage::IdPlayerInput: - return i18n("Player Input"); - case KGameMessage::IdIOAdded: - return i18n("An IO was added"); - case KGameMessage::IdProcessQuery: - return i18n("Process Query"); - case KGameMessage::IdPlayerId: - return i18n("Player ID"); - case KGameMessage::IdUser: // IdUser must be unknown for use, too! - default: - return TQString(); - } -} diff --git a/libkdegames/kgame/kgamemessage.h b/libkdegames/kgame/kgamemessage.h deleted file mode 100644 index f4029895..00000000 --- a/libkdegames/kgame/kgamemessage.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMEMSG_H_ -#define __KGAMEMSG_H_ - -#include <tqdatastream.h> -#include <kdemacros.h> - -class KDE_EXPORT KGameMessage -{ - public: - /** - * Creates a fully qualified player ID which contains the original - * player id in the lower bits and the game number in the higher bits. - * Do not rely on the exact bit positions as they are internal. - * - * See also @ref rawPlayerId and @ref rawGameId which are the inverse - * operations - * - * @param playerid the player id - can include a gameid (will get removed) - * @param gameid The game id (<64). 0 For broadcast. - * @return the new player id - */ - static TQ_UINT32 createPlayerId(int player, TQ_UINT32 game); - - /** - * Returns the raw playerid, that is, a id which does not - * contain the game number encoded in it. See also @ref createPlayerId which - * is the inverse operation. - * - * @param the player id - * @return the raw player id - **/ - static int rawPlayerId(TQ_UINT32 playerid); - - /** - * Returns the raw game id, that is, the game id the player - * belongs to. Se also @ref createPlayerId which is the inverse operation. - * - * @param the player id - * @return the raw game id - **/ - static TQ_UINT32 rawGameId(TQ_UINT32 playerid); - - /** - * Checks whether a message receiver/sender is a player - * - * @param id The ID of the sender/receiver - * @return true/false - */ - static bool isPlayer(TQ_UINT32 id); - - /** - * Checks whether the sender/receiver of a message is a game - * - * @param id The ID of the sender/receiver - * @return true/false - */ - static bool isGame(TQ_UINT32 id); - - /** - * Creates a message header given cookie,sender,receiver,... - * - * Also puts "hidden" header into the stream which are used by KGameClient - * (message length and magic cookie). If you don't need them remove them - * with @ref dropExternalHeader - */ - static void createHeader(TQDataStream &msg, TQ_UINT32 sender, TQ_UINT32 receiver, int msgid); - - /** - * Retrieves the information like cookie,sender,receiver,... from a message header - * - * Note that it could be necessary to call @ref dropExternalHeader first - */ - static void extractHeader(TQDataStream &msg,TQ_UINT32 &sender, TQ_UINT32 &receiver, int &msgid); - - /** - * Creates a property header given the property id - */ - static void createPropertyHeader(TQDataStream &msg, int id); - - /** - * Retrieves the property id from a property message header - */ - static void extractPropertyHeader(TQDataStream &msg, int &id); - - /** - * Creates a property header given the property id - */ - static void createPropertyCommand(TQDataStream &msg, int cmdid, int pid, int cmd); - - /** - * Retrieves the property id from a property message header - */ - static void extractPropertyCommand(TQDataStream &msg, int &pid, int &cmd); - - /** - * @return Version of the network library - */ - static int version(); - - /** - * This function takes a @ref GameMessageIds as argument and returns a - * suitable string for it. This string can't be used to identify a message - * (as it is i18n'ed) but it can make debugging more easy. See also @ref - * KGameDebugDialog. - * @return Either a i18n'ed string (the name of the id) or TQString() if - * the msgid is unknown - **/ - static TQString messageId2Text(int msgid); - - - /** - * Message Ids used inside @ref KGame. - * - * You can use your own custom message Id by adding @p IdUser to it. - **/ -// please document every new id with a short comment - enum GameMessageIds { -// game init, game load, disconnect, ... - IdSetupGame=1, // sent to a newly connected player - IdSetupGameContinue=2, // continue the setup - IdGameLoad=3, // load/save the game to the client - IdGameConnected=4, // Client successfully connected to master - IdSyncRandom=5, // new random seed set - sync games - IdDisconnect=6, // KGame object disconnects from game - IdGameSetupDone=7, // New game client is now operational - -// properties - IdPlayerProperty=20, // a player property changed - IdGameProperty=21, // a game property changed - -// player management - IdAddPlayer=30, // add a player - IdRemovePlayer=31, // the player will be removed - IdActivatePlayer=32, // Activate a player - IdInactivatePlayer=33, // Inactivate a player - IdTurn=34, // Turn to be prepared - -// to-be-categorized - IdError=100, // an error occurred - IdPlayerInput=101, // a player input occurred - IdIOAdded=102, // KGameIO got added to a player...init this IO - -// special ids for computer player - IdProcessQuery=220, // Process queries data (process only) - IdPlayerId=221, // PlayerId got changed (process only) - - IdUser=256 // a user specified message - }; -}; - -#endif diff --git a/libkdegames/kgame/kgamenetwork.cpp b/libkdegames/kgame/kgamenetwork.cpp deleted file mode 100644 index a3548579..00000000 --- a/libkdegames/kgame/kgamenetwork.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgamenetwork.h" -#include "kgamenetwork.moc" -#include "kgamemessage.h" -#include "kgameerror.h" - -#include "kmessageserver.h" -#include "kmessageclient.h" -#include "kmessageio.h" -#include <dnssd/publicservice.h> - -#include <kdebug.h> - -#include <tqbuffer.h> - - -class KGameNetworkPrivate -{ -public: - KGameNetworkPrivate() - { - mMessageClient = 0; - mMessageServer = 0; - mDisconnectId = 0; - mService = 0; - } - -public: - KMessageClient* mMessageClient; - KMessageServer* mMessageServer; - TQ_UINT32 mDisconnectId; // Stores gameId() over a disconnect process - DNSSD::PublicService* mService; - TQString mType; - TQString mName; - - int mCookie; -}; - -// ------------------- NETWORK GAME ------------------------ -KGameNetwork::KGameNetwork(int c, TQObject* parent) : TQObject(parent, 0) -{ - d = new KGameNetworkPrivate; - d->mCookie = (TQ_INT16)c; - - // Init the game as a local game, i.e. - // create your own KMessageServer and a KMessageClient connected to it. - setMaster(); - - kdDebug(11001) << k_funcinfo << "this=" << this <<", cookie=" << cookie() << " sizeof(this)="<<sizeof(KGameNetwork) << endl; -} - -KGameNetwork::~KGameNetwork() -{ - kdDebug(11001) << k_funcinfo << "this=" << this << endl; -// Debug(); - delete d->mService; - delete d; -} - -// ----------------------------- status methods -bool KGameNetwork::isNetwork() const -{ return isOfferingConnections() || d->mMessageClient->isNetwork();} - -TQ_UINT32 KGameNetwork::gameId() const -{ - //return d->mMessageClient->id() ; - // Return stored id in the case of disconnect. In any other - // case the disconnect id is 0 - if (d->mMessageClient->id()!=0 ) { - return d->mMessageClient->id() ; - } else { - return d->mDisconnectId; - } -} - -int KGameNetwork::cookie() const -{ return d->mCookie; } - -bool KGameNetwork::isMaster() const -{ return (d->mMessageServer != 0); } - -bool KGameNetwork::isAdmin() const -{ return (d->mMessageClient->isAdmin()); } - -KMessageClient* KGameNetwork::messageClient() const -{ return d->mMessageClient; } - -KMessageServer* KGameNetwork::messageServer() const -{ return d->mMessageServer; } - -// ----------------------- network init -void KGameNetwork::setMaster() -{ - if (!d->mMessageServer) { - d->mMessageServer = new KMessageServer (cookie(), this); - } else { - kdWarning(11001) << k_funcinfo << "Server already running!!" << endl; - } - if (!d->mMessageClient) { - d->mMessageClient = new KMessageClient (this); - connect (d->mMessageClient, TQT_SIGNAL(broadcastReceived(const TQByteArray&, TQ_UINT32)), - this, TQT_SLOT(receiveNetworkTransmission(const TQByteArray&, TQ_UINT32))); - connect (d->mMessageClient, TQT_SIGNAL(connectionBroken()), - this, TQT_SIGNAL(signalConnectionBroken())); - connect (d->mMessageClient, TQT_SIGNAL(aboutToDisconnect(TQ_UINT32)), - this, TQT_SLOT(aboutToLoseConnection(TQ_UINT32))); - connect (d->mMessageClient, TQT_SIGNAL(connectionBroken()), - this, TQT_SLOT(slotResetConnection())); - - connect (d->mMessageClient, TQT_SIGNAL(adminStatusChanged(bool)), - this, TQT_SLOT(slotAdminStatusChanged(bool))); - connect (d->mMessageClient, TQT_SIGNAL(eventClientConnected(TQ_UINT32)), - this, TQT_SIGNAL(signalClientConnected(TQ_UINT32))); - connect (d->mMessageClient, TQT_SIGNAL(eventClientDisconnected(TQ_UINT32, bool)), - this, TQT_SIGNAL(signalClientDisconnected(TQ_UINT32, bool))); - - // broacast and direct messages are treated equally on receive. - connect (d->mMessageClient, TQT_SIGNAL(forwardReceived(const TQByteArray&, TQ_UINT32, const TQValueList<TQ_UINT32>&)), - d->mMessageClient, TQT_SIGNAL(broadcastReceived(const TQByteArray&, TQ_UINT32))); - - } else { - // should be no problem but still has to be tested - kdDebug(11001) << k_funcinfo << "Client already exists!" << endl; - } - d->mMessageClient->setServer(d->mMessageServer); -} - -void KGameNetwork::setDiscoveryInfo(const TQString& type, const TQString& name) -{ - kdDebug() << k_funcinfo << type << ":" << name << endl; - d->mType = type; - d->mName = name; - tryPublish(); -} - -void KGameNetwork::tryPublish() -{ - if (d->mType.isNull() || !isOfferingConnections()) return; - if (!d->mService) d->mService = new DNSSD::PublicService(d->mName,d->mType,port()); - else { - if (d->mType!=d->mService->type()) d->mService->setType(d->mType); - if (d->mName!=d->mService->serviceName()) d->mService->setServiceName(d->mName); - } - if (!d->mService->isPublished()) d->mService->publishAsync(); -} - -void KGameNetwork::tryStopPublishing() -{ - if (d->mService) d->mService->stop(); -} - -bool KGameNetwork::offerConnections(TQ_UINT16 port) -{ - kdDebug (11001) << k_funcinfo << "on port " << port << endl; - if (!isMaster()) { - setMaster(); - } - - // Make sure this is 0 - d->mDisconnectId = 0; - - // FIXME: This debug message can be removed when the program is working correct. - if (d->mMessageServer && d->mMessageServer->isOfferingConnections()) { - kdDebug (11001) << k_funcinfo << "Already running as server! Changing the port now!" << endl; - } - - tryStopPublishing(); - kdDebug (11001) << k_funcinfo << "before Server->initNetwork" << endl; - if (!d->mMessageServer->initNetwork (port)) { - kdError (11001) << k_funcinfo << "Unable to bind to port " << port << "!" << endl; - // no need to delete - we just cannot listen to the port -// delete d->mMessageServer; -// d->mMessageServer = 0; -// d->mMessageClient->setServer((KMessageServer*)0); - return false; - } - kdDebug (11001) << k_funcinfo << "after Server->initNetwork" << endl; - tryPublish(); - return true; -} - -bool KGameNetwork::connectToServer (const TQString& host, TQ_UINT16 port) -{ - if (host.isEmpty()) { - kdError(11001) << k_funcinfo << "No hostname given" << endl; - return false; - } - - // Make sure this is 0 - d->mDisconnectId = 0; - -// if (!d->mMessageServer) { -// // FIXME: What shall we do here? Probably must stop a running game. -// kdWarning (11001) << k_funcinfo << "We are already connected to another server!" << endl; -/// } - - if (d->mMessageServer) { - // FIXME: What shall we do here? Probably must stop a running game. - kdWarning(11001) << "we are server but we are trying to connect to another server! " - << "make sure that all clients connect to that server! " - << "quitting the local server now..." << endl; - stopServerConnection(); - d->mMessageClient->setServer((KMessageIO*)0); - delete d->mMessageServer; - d->mMessageServer = 0; - } - - kdDebug(11001) << " about to set server" << endl; - d->mMessageClient->setServer(host, port); - emit signalAdminStatusChanged(false); // as we delete the connection above isAdmin() is always false now! - - // OK: We say that we already have connected, but this isn't so yet! - // If the connection cannot be established, it will look as being disconnected - // again ("slotConnectionLost" is called). - // Shall we differ between these? - kdDebug(11001) << "connected to " << host << ":" << port << endl; - return true; -} - -TQ_UINT16 KGameNetwork::port() const -{ - if (isNetwork()) { - if (isOfferingConnections()) { - return d->mMessageServer->serverPort(); - } else { - return d->mMessageClient->peerPort(); - } - } - return 0; -} - -TQString KGameNetwork::hostName() const -{ - return d->mMessageClient->peerName(); -} - -bool KGameNetwork::stopServerConnection() -{ - // We still are the Master, we just don't accept further connections! - tryStopPublishing(); - if (d->mMessageServer) { - d->mMessageServer->stopNetwork(); - return true; - } - return false; -} - -bool KGameNetwork::isOfferingConnections() const -{ return (d->mMessageServer && d->mMessageServer->isOfferingConnections()); } - -void KGameNetwork::disconnect() -{ - // TODO MH - kdDebug(11001) << k_funcinfo << endl; - stopServerConnection(); - if (d->mMessageServer) { - TQValueList <TQ_UINT32> list=d->mMessageServer->clientIDs(); - TQValueList<TQ_UINT32>::Iterator it; - for( it = list.begin(); it != list.end(); ++it ) - { - kdDebug(11001) << "Client id=" << (*it) << endl; - KMessageIO *client=d->mMessageServer->findClient(*it); - if (!client) - { - continue; - } - kdDebug(11001) << " rtti=" << client->rtti() << endl; - if (client->rtti()==2) - { - kdDebug(11001) << "DIRECT IO " << endl; - } - else - { - d->mMessageServer->removeClient(client,false); - } - } - } - else - { - kdDebug(11001) << k_funcinfo << "before client->disconnect() id="<<gameId()<< endl; - //d->mMessageClient->setServer((KMessageIO*)0); - kdDebug(11001) << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl; - d->mMessageClient->disconnect(); - - kdDebug(11001) << "++++++--------------------------------------------+++++"<<endl; - } - //setMaster(); - /* - if (d->mMessageServer) { - //delete d->mMessageServer; - //d->mMessageServer=0; - server=true; - kdDebug(11001) << " server true" << endl; - d->mMessageServer->deleteClients(); - kdDebug(11001) << " server deleteClients" << endl; - } - */ - kdDebug(11001) << k_funcinfo << "DONE" << endl; -} - -void KGameNetwork::aboutToLoseConnection(TQ_UINT32 clientID) -{ - kdDebug(11001) << "Storing client id of connection "<<clientID<<endl; - d->mDisconnectId = clientID; -} - -void KGameNetwork::slotResetConnection() -{ - kdDebug(11001) << "Resseting client disconnect id"<<endl; - d->mDisconnectId = 0; -} - -void KGameNetwork::electAdmin(TQ_UINT32 clientID) -{ - if (!isAdmin()) { - kdWarning(11001) << k_funcinfo << "only ADMIN is allowed to call this!" << endl; - return; - } - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - stream << static_cast<TQ_UINT32>( KMessageServer::RETQ_ADMIN_CHANGE ); - stream << clientID; - d->mMessageClient->sendServerMessage(buffer); -} - -void KGameNetwork::setMaxClients(int max) -{ - if (!isAdmin()) { - kdWarning(11001) << k_funcinfo << "only ADMIN is allowed to call this!" << endl; - return; - } - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - stream << static_cast<TQ_UINT32>( KMessageServer::RETQ_MAX_NUM_CLIENTS ); - stream << (TQ_INT32)max; - d->mMessageClient->sendServerMessage(buffer); -} - -void KGameNetwork::lock() -{ - if (messageClient()) { - messageClient()->lock(); - } -} - -void KGameNetwork::unlock() -{ - if (messageClient()) { - messageClient()->unlock(); - } -} - -// --------------------- send messages --------------------------- - -bool KGameNetwork::sendSystemMessage(int data, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - stream << data; - return sendSystemMessage(buffer,msgid,receiver,sender); -} - -bool KGameNetwork::sendSystemMessage(const TQString &msg, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - TQByteArray buffer; - TQDataStream stream(buffer, IO_WriteOnly); - stream << msg; - return sendSystemMessage(buffer, msgid, receiver, sender); -} - -bool KGameNetwork::sendSystemMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ return sendSystemMessage(((TQBuffer*)msg.device())->buffer(), msgid, receiver, sender); } - -bool KGameNetwork::sendSystemMessage(const TQByteArray& data, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - if (!sender) { - sender = gameId(); - } - - TQ_UINT32 receiverClient = KGameMessage::rawGameId(receiver); // KGame::gameId() - int receiverPlayer = KGameMessage::rawPlayerId(receiver); // KPlayer::id() - - KGameMessage::createHeader(stream, sender, receiver, msgid); - stream.writeRawBytes(data.data(), data.size()); - - /* - kdDebug(11001) << "transmitGameClientMessage msgid=" << msgid << " recv=" - << receiver << " sender=" << sender << " Buffersize=" - << buffer.size() << endl; - */ - - if (!d->mMessageClient) { - // No client created, this should never happen! - // Having a local game means we have our own - // KMessageServer and we are the only client. - kdWarning (11001) << k_funcinfo << "We don't have a client! Should never happen!" << endl; - return false; - } - - if (receiverClient == 0 || receiverPlayer != 0) - { - // if receiverClient == 0 this is a broadcast message. if it is != 0 but - // receiverPlayer is also != 0 we have to send broadcast anyway, because the - // KPlayer object on all clients needs to receive the message. - d->mMessageClient->sendBroadcast(buffer); - } - else - { - d->mMessageClient->sendForward(buffer, receiverClient); - } - return true; -} - -bool KGameNetwork::sendMessage(int data, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ return sendSystemMessage(data,msgid+KGameMessage::IdUser,receiver,sender); } - -bool KGameNetwork::sendMessage(const TQString &msg, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ return sendSystemMessage(msg,msgid+KGameMessage::IdUser,receiver,sender); } - -bool KGameNetwork::sendMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ return sendSystemMessage(msg, msgid+KGameMessage::IdUser, receiver, sender); } - -bool KGameNetwork::sendMessage(const TQByteArray &msg, int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) -{ return sendSystemMessage(msg, msgid+KGameMessage::IdUser, receiver, sender); } - -void KGameNetwork::sendError(int error,const TQByteArray& message, TQ_UINT32 receiver, TQ_UINT32 sender) -{ - TQByteArray buffer; - TQDataStream stream(buffer,IO_WriteOnly); - stream << (TQ_INT32) error; - stream.writeRawBytes(message.data(), message.size()); - sendSystemMessage(stream,KGameMessage::IdError,receiver,sender); -} - - -// ----------------- receive messages from the network -void KGameNetwork::receiveNetworkTransmission(const TQByteArray& receiveBuffer, TQ_UINT32 clientID) -{ - TQDataStream stream(receiveBuffer, IO_ReadOnly); - int msgid; - TQ_UINT32 sender; // the id of the KGame/KPlayer who sent the message - TQ_UINT32 receiver; // the id of the KGame/KPlayer the message is for - KGameMessage::extractHeader(stream, sender, receiver, msgid); -// kdDebug(11001) << k_funcinfo << "id=" << msgid << " sender=" << sender << " recv=" << receiver << endl; - - // No broadcast : receiver==0 - // No player isPlayer(receiver) - // Different game gameId()!=receiver - if (receiver && receiver!=gameId() && !KGameMessage::isPlayer(receiver) ) - { - // receiver=0 is broadcast or player message - kdDebug(11001) << k_funcinfo << "Message not meant for us " - << gameId() << "!=" << receiver << " rawid=" - << KGameMessage::rawGameId(receiver) << endl; - return; - } - else if (msgid==KGameMessage::IdError) - { - TQString text; - TQ_INT32 error; - stream >> error; - kdDebug(11001) << k_funcinfo << "Got IdError " << error << endl; - text = KGameError::errorText(error, stream); - kdDebug(11001) << "Error text: " << text.latin1() << endl; - emit signalNetworkErrorMessage((int)error,text); - } - else - { - networkTransmission(stream, msgid, receiver, sender, clientID); - } -} - -// -------------- slots for the signals of the client -void KGameNetwork::slotAdminStatusChanged(bool isAdmin) -{ - emit signalAdminStatusChanged(isAdmin); - -// TODO: I'm pretty sure there are a lot of things that should be done here... -} - -void KGameNetwork::Debug() -{ - kdDebug(11001) << "------------------- KNETWORKGAME -------------------------" << endl; - kdDebug(11001) << "gameId " << gameId() << endl; - kdDebug(11001) << "gameMaster " << isMaster() << endl; - kdDebug(11001) << "gameAdmin " << isAdmin() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - -/* - * vim: et sw=2 - */ diff --git a/libkdegames/kgame/kgamenetwork.h b/libkdegames/kgame/kgamenetwork.h deleted file mode 100644 index b5975ffc..00000000 --- a/libkdegames/kgame/kgamenetwork.h +++ /dev/null @@ -1,432 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMENETWORK_H_ -#define __KGAMENETWORK_H_ - -#include <tqstring.h> -#include <tqobject.h> -#include <kdemacros.h> -class KGameIO; -class KMessageClient; -class KMessageServer; - -class KGameNetworkPrivate; - -/** - * The KGameNetwork class is the KGame class with network - * support. All other features are the same but they are - * now network transparent. It is not used directly but - * only via a KGame object. So you do not really have - * to bother with this object. - * - * @short The main KDE game object - * @author Martin Heni <[email protected]> - * @version $Id$ - */ -class KDE_EXPORT KGameNetwork : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Create a KGameNetwork object - */ - KGameNetwork(int cookie=42,TQObject* parent=0); - virtual ~KGameNetwork(); - - /** - * Gives debug output of the game status - **/ - virtual void Debug(); - - /** - * @return TRUE if this is a network game - i.e. you are either MASTER or - * connected to a remote MASTER. - **/ - bool isNetwork() const; - - /** - * Is this the game MASTER (i.e. has started theKMessageServer). A - * game has always exactly one MASTER. This is either a KGame object (i.e. a - * Client) or an own MessageServer-process. A KGame object that has the - * MASTER status is always admin. - * - * You probably don't want to use this. It is a mostly internal method which - * will probably become protected. Better use isAdmin - * - * @see isAdmin - * @return Whether this client has started the KMessageServer - **/ - bool isMaster() const; - - /** - * The admin of a game is the one who initializes newly connected clients - * using negotiateNetworkGame and is allowed to configure the game. - * E.g. only the admin is allowed to use KGame::setMaxPlayers. - * - * If one KGame object in the game is MASTER then this client is the admin - * as well. isMaster and isAdmin differ only if the KMessageServer - * is running in an own process. - * @return Whether this client (KGame object) is the admin - **/ - bool isAdmin() const; - - /** - * The unique ID of this game - * - * @return int id - **/ - TQ_UINT32 gameId() const; - - /** - * Inits a network game as network MASTER. Note that if the - * KMessageServer is not yet started it will be started here (see - * setMaster). Any existing connection will be disconnected. - * - * If you already offer connections the port is changed. - * - * @param port The port on which the service is offered - * @return true if it worked - **/ - bool offerConnections (TQ_UINT16 port); - - /** - * Announces game MASTER on network using DNS-SD. Clients then can discover it using - * DNSSD::ServiceBrowser (or KGameConnectWidget) instead of manually entering - * IP address. - * @param type service type (something like _kwin4._tcp). - * It should be unique for application. - * @param name game name that will be displayed by clients. If not - * set hostname will be used. In case of name conflict -2, -3 and so on will be added to name. - * @since 3.4 - **/ - void setDiscoveryInfo(const TQString& type, const TQString& name=TQString()); - - /** - * Inits a network game as a network CLIENT - * - * @param host the host to which we want to connect - * @param port the port we want to connect to - * - * @return true if connected - **/ - bool connectToServer(const TQString& host, TQ_UINT16 port); - - /** - * @since 3.2 - * @return The port we are listening to if offerConnections was called - * or the port we are connected to if connectToServer was called. - * Otherwise 0. - **/ - TQ_UINT16 port() const; - - /** - * @since 3.2 - * @return The name of the host that we are currently connected to is - * isNetwork is TRUE and we are not the MASTER, i.e. if connectToServer - * was called. Otherwise this will return "localhost". - **/ - TQString hostName() const; - - /** - * Stops offering server connections - only for game MASTER - * @return true - **/ - bool stopServerConnection(); - - /** - * Changes the maximal connection number of the KMessageServer to max. - * -1 Means infinite connections are possible. Note that existing - * connections are not affected, so even if you set this to 0 in a running - * game no client is being disconnected. You can call this only if you are - * the ADMIN! - * - * @see KMessageServer::setMaxClients - * @param max The maximal number of connections possible. - **/ - void setMaxClients(int max); - - //AB: is this now internal only? Can we make it protected (maybe with - //friends)? sendSystemMessage AND sendMessage is very confusing to the - //user. - /** - * Sends a network message msg with a given msg id msgid to all clients. - * Use this to communicate with KGame (e.g. to add a player ot to configure - * the game - usually not necessary). - * - * For your own messages use sendMessage instead! This is mostly - * internal! - * - * @param buffer the message which will be send. See messages.txt for contents - * @param msgid an id for this message. See - * KGameMessage::GameMessageIds - * @param receiver the KGame / KPlayer this message is for. - * @param sender The KGame / KPlayer this message is from (i.e. - * you). You - * probably want to leave this 0, then KGameNetwork will create the correct - * value for you. You might want to use this if you send a message from a - * specific player. - * @return true if worked - */ - // AB: TODO: doc on how "receiver" and "sender" should be created! - bool sendSystemMessage(const TQByteArray& buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * @overload - **/ - bool sendSystemMessage(int data, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * @overload - **/ - bool sendSystemMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * @overload - **/ - bool sendSystemMessage(const TQString& msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * Sends a network message - * @param error The error code - * @param message The error message - use KGameError - * @param receiver the KGame / KPlayer this message is for. 0 For - * all - * @param sender The KGame / KPlayer this message is from (i.e. - * you). You probably want to leave this 0, then KGameNetwork will create - * the correct value for you. You might want to use this if you send a - * message from a specific player. - **/ - void sendError(int error, const TQByteArray& message, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * Are we still offer offering server connections - only for game MASTER - * @return true/false - **/ - bool isOfferingConnections() const; - - /** - * Application cookie. this idendifies the game application. It - * help to distinguish between e.g. KPoker and KWin4 - * @return the application cookie - **/ - int cookie() const; - - /** - * Send a network message msg with a given message ID msgid to all clients. - * You want to use this to send a message to the clients. - * - * Note that a message is always sent to ALL clients! This is necessary so - * that all clients always have the same data and can easily be changed from - * network to non-network without restarting the game. If you want a - * specific KGame / KPlayer to react to the message use the - * receiver and sender parameters. See KGameMessage::calsMessageId - * - * SendMessage differs from sendSystemMessage only by the msgid parameter. - * sendSystemMessage is thought as a KGame only mehtod while - * sendMessage is for public use. The msgid parameter will be - * +=KGameMessage::IdUser and in KGame::signalNetworkData msgid will - * be -= KGameMessage::IdUser again, so that one can easily distinguish - * between system and user messages. - * - * Use sendSystemMessage to comunicate with KGame (e.g. by adding a - * player) and sendMessage for your own user message. - * - * Note: a player should send messages through a KGameIO! - * - * @param buffer the message which will be send. See messages.txt for contents - * @param msgid an id for this message. See KGameMessage::GameMessageIds - * @param receiver the KGame / KPlayer this message is for. - * @param sender The KGame / KPlayer this message is from (i.e. - * you). You - * probably want to leave this 0, then KGameNetwork will create the correct - * value for you. You might want to use this if you send a message from a - * specific player. - * @return true if worked - **/ - // AB: TODO: doc on how "receiver" and "sender" should be created! - bool sendMessage(const TQByteArray& buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * This is an overloaded member function, provided for convenience. - **/ - bool sendMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * This is an overloaded member function, provided for convenience. - **/ - bool sendMessage(const TQString& msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - /** - * This is an overloaded member function, provided for convenience. - **/ - bool sendMessage(int data, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0); - - - /** - * Called by ReceiveNetworkTransmission(). Will be overwritten by - * KGame and handle the incoming message. - **/ - virtual void networkTransmission(TQDataStream&, int, TQ_UINT32, TQ_UINT32, TQ_UINT32 clientID) = 0; - - - /** - * Disconnect the current connection and establish a new local one. - **/ - void disconnect(); - - - /** - * If you are the ADMIN of the game you can give the ADMIN status away to - * another client. Use this e.g. if you want to quit the game or if you want - * another client to administrate the game (note that disconnect calls - * this automatically). - * @param clientID the ID of the new ADMIN (note: this is the _client_ID - * which has nothing to do with the player IDs. See KMessageServer) - **/ - void electAdmin(TQ_UINT32 clientID); - - /** - * Don't use this unless you really know what youre doing! You might - * experience some strange behaviour if you send your messages directly - * through the KMessageClient! - * - * @return a pointer to the KMessageClient used internally to send the - * messages. You should rather use one of the send functions! - **/ - KMessageClient* messageClient() const; - - /** - * Don't use this unless you really know what you are doing! You might - * experience some strange behaviour if you use the message server directly! - * - * @return a pointer to the message server if this is the MASTER KGame - * object. Note that it might be possible that no KGame object contains - * the KMessageServer at all! It might even run stand alone! - **/ - KMessageServer* messageServer() const; - - /** - * You should call this before doing thigs like, e.g. tqApp->processEvents(). - * Don't forget to call unlock once you are done! - * - * @see KMessageClient::lock - **/ - virtual void lock(); - - /** - * @see KMessageClient::unlock - **/ - virtual void unlock(); - -signals: - /** - * A network error occurred - * @param error the error code - * @param text the error text - */ - void signalNetworkErrorMessage(int error, TQString text); - - /** - * Our connection to the KMessageServer has broken. - * See KMessageClient::connectionBroken - **/ - void signalConnectionBroken(); - - /** - * This signal is emitted whenever the KMessageServer sends us a message that a - * new client connected. KGame uses this to call KGame::negotiateNetworkGame - * for the newly connected client if we are admin (see isAdmin) - * - * @see KMessageClient::eventClientConnected - * - * @param clientID the ID of the newly connected client - **/ - void signalClientConnected(TQ_UINT32 clientID); - - /** - * This signal is emitted whenever the KMessageServer sends us a message - * that a connection to a client was detached. The second parameter can be used - * to distinguish between network errors or removing on purpose. - * - * @see KMessageClient::eventClientDisconnected - * - * @param clientID the client that has disconnected - * @param broken true if the connection was lost because of a network error, false - * if the connection was closed by the message server admin. - */ - void signalClientDisconnected(TQ_UINT32 clientID, bool broken); - - /** - * This client gets or loses the admin status. - * @see KMessageClient::adminStatusChanged - * @param isAdmin True if this client gets the ADMIN status otherwise FALSE - **/ - void signalAdminStatusChanged(bool isAdmin); - -protected: - /** - * @internal - * Start a KMessageServer object and use it as the MASTER of the game. - * Note that you must not call this if there is already another master - * running! - **/ - void setMaster(); - -protected slots: - /** - * Called by KMessageClient::broadcastReceived() and will check if the - * message format is valid. If it is not, it will generate an error (see - * signalNetworkVersionError and signalNetworkErorrMessage). - * If it is valid, the pure virtual method networkTransmission() is called. - * (This one is overwritten in KGame.) - **/ - void receiveNetworkTransmission(const TQByteArray& a, TQ_UINT32 clientID); - - /** - * This KGame object receives or loses the admin status. - * @param isAdmin Whether we are admin or not - **/ - void slotAdminStatusChanged(bool isAdmin); - - /** - * Called when the network connection is about to terminate. Is used - * to store the network parameter like the game id - */ - void aboutToLoseConnection(TQ_UINT32 id); - - /** - * Called when the network connection is terminated. Used to clean - * up the disconnect parameter - */ - void slotResetConnection(); - - -private: - void tryPublish(); - void tryStopPublishing(); - KGameNetworkPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/kgameprocess.cpp b/libkdegames/kgame/kgameprocess.cpp deleted file mode 100644 index 9dcc66c0..00000000 --- a/libkdegames/kgame/kgameprocess.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgameprocess.h" -#include "kplayer.h" -#include "kgame.h" -#include "kgamemessage.h" -#include "kmessageio.h" - -#include <krandomsequence.h> - -#include <tqbuffer.h> -#include <tqdatastream.h> -#include <tqcstring.h> - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#define READ_BUFFER_SIZE 1024 - -// ----------------------- Process Child --------------------------- - -KGameProcess::KGameProcess() : TQObject(0,0) -{ - mTerminate=false; - // Check whether a player is set. If not create one! - rFile.open(IO_ReadOnly|IO_Raw,stdin); - wFile.open(IO_WriteOnly|IO_Raw,stdout); - mMessageIO=new KMessageFilePipe(this,&rFile,&wFile); -// mMessageClient=new KMessageClient(this); -// mMessageClient->setServer(mMessageIO); -// connect (mMessageClient, TQT_SIGNAL(broadcastReceived(const TQByteArray&, TQ_UINT32)), -// this, TQT_SLOT(receivedMessage(const TQByteArray&, TQ_UINT32))); - connect (mMessageIO, TQT_SIGNAL(received(const TQByteArray&)), - this, TQT_SLOT(receivedMessage(const TQByteArray&))); - fprintf(stderr,"KGameProcess::constructor %p %p\n",&rFile,&wFile); - - mRandom = new KRandomSequence; - mRandom->setSeed(0); -} -KGameProcess::~KGameProcess() -{ - delete mRandom; - //delete mMessageClient; - //delete mMessageServer; - delete mMessageIO; - rFile.close(); - wFile.close(); - fprintf(stderr,"KGameProcess::destructor\n"); -} - - -bool KGameProcess::exec(int argc, char *argv[]) -{ - // Get id and cookie, ... from command line - processArgs(argc,argv); - do - { - mMessageIO->exec(); - } while(!mTerminate); - return true; -} - -// You have to do this to create a message -// TQByteArray buffer; -// TQDataStream wstream(buffer,IO_WriteOnly); -// then stream data into the stream and call this function -void KGameProcess::sendSystemMessage(TQDataStream &stream,int msgid,TQ_UINT32 receiver) -{ - fprintf(stderr,"KGameProcess::sendMessage id=%d recv=%d",msgid,receiver); - TQByteArray a; - TQDataStream outstream(a,IO_WriteOnly); - - TQBuffer *device=(TQBuffer *)stream.device(); - TQByteArray data=device->buffer();; - - KGameMessage::createHeader(outstream,0,receiver,msgid); - outstream.writeRawBytes(data.data(),data.size()); - - //if (mMessageClient) mMessageClient->sendBroadcast(a); - // TODO: The fixed received 2 will cause problems. But how to address the - // proper one? -// if (mMessageClient) mMessageClient->sendForward(a,2); - if (mMessageIO) mMessageIO->send(a); -} - -void KGameProcess::sendMessage(TQDataStream &stream,int msgid,TQ_UINT32 receiver) -{ - sendSystemMessage(stream,msgid+KGameMessage::IdUser,receiver); -} - -void KGameProcess::processArgs(int argc, char *argv[]) -{ - int v=0; - if (argc>2) - { - v=atoi(argv[2]); - //kdDebug(11001) << "cookie (unused) " << v << endl; - } - if (argc>1) - { - v=atoi(argv[1]); - //kdDebug(11001) << "id (unused) " << v << endl; - } - fprintf(stderr,"processArgs \n"); - fflush(stderr); -} - -void KGameProcess::receivedMessage(const TQByteArray& receiveBuffer) -{ - TQDataStream stream(receiveBuffer, IO_ReadOnly); - int msgid; - TQ_UINT32 sender; - TQ_UINT32 receiver; - KGameMessage::extractHeader(stream, sender, receiver, msgid); - fprintf(stderr,"------ receiveNetworkTransmission(): id=%d sender=%d,recv=%d\n",msgid,sender,receiver); - switch(msgid) - { - case KGameMessage::IdTurn: - TQ_INT8 b; - stream >> b; - emit signalTurn(stream,(bool)b); - break; - case KGameMessage::IdIOAdded: - TQ_INT16 id; - stream >> id; - emit signalInit(stream,(int)id); - break; - default: - emit signalCommand(stream,msgid-KGameMessage::IdUser,receiver,sender); - break; - } -} - -#include "kgameprocess.moc" diff --git a/libkdegames/kgame/kgameprocess.h b/libkdegames/kgame/kgameprocess.h deleted file mode 100644 index b7e2d145..00000000 --- a/libkdegames/kgame/kgameprocess.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMEPROCESS_H_ -#define __KGAMEPROCESS_H_ - -#include <tqstring.h> -#include <tqobject.h> -#include <tqfile.h> - -#include "kgameproperty.h" -#include <krandomsequence.h> -#include <kdemacros.h> -class KPlayer; -class KMessageFilePipe; - -/** - * This is the process class used on the computer player - * side to communicate with its counterpart KProcessIO class. - * Using these two classes will give fully transparent communication - * via TQDataStreams. - */ -class KDE_EXPORT KGameProcess: public TQObject -{ - Q_OBJECT - TQ_OBJECT - - public: - /** - * Creates a KGameProcess class. Done only in the computer - * player. To activate the communication you have to call - * the exec function of this class which will listen - * to the communication and emit signals to notify you of - * any incoming messages. - * Note: This function will only return after you set - * setTerminate(true) in one of the received signals. - * So you can not do any computer calculation after the exec function. - * Instead you react on the signals which are emitted after a - * message is received and perform the calculations there! - * Example: - * \code - * int main(int argc ,char * argv[]) - * { - * KGameProcess proc; - * connect(&proc,TQT_SIGNAL(signalCommand(TQDataStream &,int ,int ,int )), - * this,TQT_SLOT(slotCommand(TQDataStream & ,int ,int ,int ))); - * connect(&proc,TQT_SIGNAL(signalInit(TQDataStream &,int)), - * this,TQT_SLOT(slotInit(TQDataStream & ,int ))); - * connect(&proc,TQT_SIGNAL(signalTurn(TQDataStream &,bool )), - * this,TQT_SLOT(slotTurn(TQDataStream & ,bool ))); - * return proc.exec(argc,argv); - * } - * \endcode - */ - KGameProcess(); - /** - * Destruct the process - */ - ~KGameProcess(); - - /** - * Enters the event loop of the computer process. Does only - * return on setTerminate(true)! - */ - bool exec(int argc, char *argv[]); - - /** - * Should the computer process leave its exec function? - * Activated if you setTerminate(true); - * - * @return true/false - */ - bool terminate() const {return mTerminate;} - - /** - * Set this to true if the computer process should end, ie - * leave its exec function. - * - * @param b true for exit the exec function - */ - void setTerminate(bool b) {mTerminate=b;} - - /** - * Sends a message to the corresponding KGameIO - * device. Works like the sendSystemMessage but - * for user id's - * - * @param stream the TQDataStream containing the message - * @param msgid the message id for the message - * @param receiver unused - */ - void sendMessage(TQDataStream &stream,int msgid,TQ_UINT32 receiver=0); - - /** - * Sends a system message to the corresonding KGameIO device. - * This will normally be either a performed move or a query - * (IdProcessQuery). The query option is a way to communicate - * with the KGameIO at the other side and e.g. retrieve some - * game relevant data from here. - * Exmaple for a query: - * \code - * TQByteArray buffer; - * TQDataStream out(buffer,IO_WriteOnly); - * int msgid=KGameMessage::IdProcessQuery; - * out << (int)1; - * proc.sendSystemMessage(out,msgid,0); - * \endcode - * - * @param stream the TQDataStream containing the message - * @param msgid the message id for the message - * @param receiver unused - */ - void sendSystemMessage(TQDataStream &stream,int msgid,TQ_UINT32 receiver=0); - - /** - * Returns a pointer to a KRandomSequence. You can generate - * random numbers via e.g. - * \code - * random()->getLong(100); - * \endcode - * - * @return KRandomSequence pointer - */ - KRandomSequence *random() {return mRandom;} - - protected: - /** - * processes the command line argumens to set up the computer player - * Pass the argumens exactely as given by main() - */ - void processArgs(int argc, char *argv[]); - - protected slots: - /** - * A message is received via the interprocess connection. The - * appropriate signals are called. - */ - void receivedMessage(const TQByteArray& receiveBuffer); - - signals: - /** - * The generic communication signal. You have to connect to this - * signal to generate a valid computer response onto arbitrary messages. - * All signals but IdIOAdded and IdTurn end up here! - * Example: - * \code - * void Computer::slotCommand(int &msgid,TQDataStream &in,TQDataStream &out) - * { - * TQ_INT32 data,move; - * in >> data; - * // compute move ... - * move=data*2; - * out << move; - * } - * \endcode - * - * @param inputStream the incoming data stream - * @param msgid the message id of the message which got transmitted to the computer - * @param receiver the id of the receiver - * @param sender the id of the sender - */ - void signalCommand(TQDataStream &inputStream,int msgid,int receiver,int sender); - - /** - * This signal is emmited if the computer player should perform a turn. - * Calculations can be made here and the move can then be send back with - * sendSystemMessage with the message id KGameMessage::IdPlayerInput. - * These must provide a move which complies to your other move syntax as - * e.g. produces by keyboard or mouse input. - * Additonal data which have been written into the stream from the - * ProcessIO's signal signalPrepareTurn can be retrieved from the - * stream here. - * Example: - * \code - * void slotTurn(TQDataStream &in,bool turn) - * { - * int id; - * int recv; - * TQByteArray buffer; - * TQDataStream out(buffer,IO_WriteOnly); - * if (turn) - * { - * // Create a move - the format is yours to decide - * // It arrives exactly as this in the kgame inputMove function!! - * TQ_INT8 x1,y1,pl; - * pl=-1; - * x1=proc.random()->getLong(8); - * y1=proc.random()->getLong(8); - * // Stream it - * out << pl << x1 << y1; - * id=KGameMessage::IdPlayerInput; - * proc.sendSystemMessage(out,id,0); - * } - * } - * \endcode - * - * @param stream The datastream which contains user data - * @param turn True or false whether the turn is activated or deactivated - * - */ - void signalTurn(TQDataStream &stream,bool turn); - - /** - * This signal is emmited when the process is initialized, i.e. added - * to a KPlayer. Initial initialisation can be performed here be reacting - * to the KProcessIO signal signalIOAdded and retrieving the data here - * from the stream. - * It works just as the signalTurn() but is only send when the player is - * added to the game, i.e. it needs some initialization data - * - * @param stream The datastream which contains user data - * @param userid The userId of the player. (Careful to rely on it yet) - */ - void signalInit(TQDataStream &stream,int userid); - - protected: - bool mTerminate; - KMessageFilePipe *mMessageIO; - private: - TQFile rFile; - TQFile wFile; - KRandomSequence* mRandom; -}; -#endif diff --git a/libkdegames/kgame/kgameproperty.cpp b/libkdegames/kgame/kgameproperty.cpp deleted file mode 100644 index 49a8984f..00000000 --- a/libkdegames/kgame/kgameproperty.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgameproperty.h" -#include "kgamepropertyhandler.h" -#include "kgamemessage.h" -#include "kplayer.h" -#include "kgame.h" - -#define KPLAYERHANDLER_LOAD_COOKIE 6239 - -KGamePropertyBase::KGamePropertyBase(int id, KGame* parent) -{ - init(); - registerData(id, parent); -} - -KGamePropertyBase::KGamePropertyBase(int id, KPlayer* parent) -{ - init(); - registerData(id, parent); -} - -KGamePropertyBase::KGamePropertyBase(int id, KGamePropertyHandler* owner) -{ - init(); - registerData(id, owner); -} - -KGamePropertyBase::KGamePropertyBase() -{ - init(); -} - -KGamePropertyBase::~KGamePropertyBase() -{ - unregisterData(); -} - -void KGamePropertyBase::init() -{ - mOwner = 0; - setDirty(false); - - // this is very useful and used by e.g. KGameDialog so - // it is activated by default. Big games may profit by deactivating it to get - // a better performance. - setEmittingSignal(true); - - setOptimized(false); - - //setReadOnly(false); - mFlags.bits.locked = false ; // setLocked(false); is NOT possible as it checks whether isLocked() allows to change the status - - // local is default - setPolicy(PolicyLocal); -} - -int KGamePropertyBase::registerData(int id, KGame* owner, TQString name) -{ return registerData(id, owner->dataHandler(), name); } - -int KGamePropertyBase::registerData(int id, KPlayer* owner, TQString name) -{ return registerData(id, owner->dataHandler(), name); } - -int KGamePropertyBase::registerData( KGamePropertyHandler* owner,PropertyPolicy p, TQString name) -{ return registerData(-1, owner,p, name); } - -int KGamePropertyBase::registerData(int id, KGamePropertyHandler* owner, TQString name) -{ return registerData(id, owner,PolicyUndefined, name); } - -int KGamePropertyBase::registerData(int id, KGamePropertyHandler* owner,PropertyPolicy p, TQString name) -{ -// we don't support changing the id - if (!owner) { - kdWarning(11001) << k_funcinfo << "Resetting owner=0. Sure you want to do this?" << endl; - mOwner=0; - return -1; - } - if (!mOwner) { - if (id==-1) { - id=owner->uniquePropertyId(); - } - mId = id; - mOwner = owner; - mOwner->addProperty(this, name); - if (p!=PolicyUndefined) { - setPolicy(p); - } else { - setPolicy(mOwner->policy()); - } - } - return mId; -} - -void KGamePropertyBase::unregisterData() -{ - if (!mOwner) { - return; - } - mOwner->removeProperty(this); - mOwner = 0; -} - -bool KGamePropertyBase::sendProperty() -{ - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyHeader(s, id()); - save(s); - if (mOwner) { - return mOwner->sendProperty(s); - } else { - kdError(11001) << k_funcinfo << "Cannot send because there is no receiver defined" << endl; - return false; - } -} - -bool KGamePropertyBase::sendProperty(const TQByteArray& data) -{ - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyHeader(s, id()); - s.writeRawBytes(data.data(), data.size()); - if (mOwner) { - return mOwner->sendProperty(s); - } else { - kdError(11001) << k_funcinfo << ": Cannot send because there is no receiver defined" << endl; - return false; - } -} - -bool KGamePropertyBase::lock() -{ - if (isLocked()) { - return false; - } - setLock(true); - return true; -} - -bool KGamePropertyBase::unlock(bool force) -{ - if (isLocked() && !force) { - return false; - } - setLock(false); - return true; -} - -void KGamePropertyBase::setLock(bool l) -{ - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s, IdCommand, id(), CmdLock); - - s << (TQ_INT8)l; - if (mOwner) { - mOwner->sendProperty(s); - } else { - kdError(11001) << k_funcinfo << ": Cannot send because there is no receiver defined" << endl; - return ; - } -} - -void KGamePropertyBase::emitSignal() -{ - //kdDebug(11001) << k_funcinfo << ": mOwnerP="<< mOwner << " id=" << id() << endl; - if (mOwner ) { - mOwner->emitSignal(this); - } else { - kdError(11001) << k_funcinfo << ":id="<<id()<<" Cannot emitSignal because there is no handler set" << endl; - } -} - -void KGamePropertyBase::command(TQDataStream& s, int cmd, bool isSender) -{ - switch (cmd) { - case CmdLock: - { - if (!isSender) { - TQ_INT8 locked; - s >> locked; - mFlags.bits.locked = (bool)locked ; - break; - } - } - default: // probably in derived classes - break; - } -} - diff --git a/libkdegames/kgame/kgameproperty.h b/libkdegames/kgame/kgameproperty.h deleted file mode 100644 index f02c4db0..00000000 --- a/libkdegames/kgame/kgameproperty.h +++ /dev/null @@ -1,848 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEPROPERTY_H_ -#define __KGAMEPROPERTY_H_ - -#include <tqdatastream.h> - -#include <kdebug.h> -#include <typeinfo> -#include <kdemacros.h> -class KGame; -class KPlayer; -class KGamePropertyHandler; -using namespace std; - -/** - * @short Base class of KGameProperty - * - * The KGamePropertyBase class is the base class of KGameProperty. See - * KGameProperty for further information. - * - * @author Andreas Beckermann <[email protected]> - **/ -class KDE_EXPORT KGamePropertyBase -{ -public: - enum PropertyDataIds { // these belong to KPlayer/KGame! - //KPlayer - IdGroup=1, - IdUserId=2, - IdAsyncInput=3, - IdTurn=4, - IdName=5, - - //KGame - IdGametqStatus=6, - IdMaxPlayer=7, - IdMinPlayer=8, - - // Input Grabbing - IdGrabInput=16, - IdReleaseInput=17, - - IdCommand, // Reserved for internal use - IdUser=256, - - IdAutomatic=0x7000 // Id's from here on are automatically given (16bit) - }; - - /** - * Commands for advanced properties (TQ_INT8) - **/ - enum PropertyCommandIds - { - // General - CmdLock=1, - - // Array - CmdAt=51, - CmdResize=52, - CmdFill=53, - CmdSort=54, - // List (could be the same id's actually) - CmdInsert=61, - CmdAppend=62, - CmdRemove=63, - CmdClear=64 - }; - - /** - * The policy of the property. This can be PolicyClean (setValue uses - * send), PolicyDirty (setValue uses changeValue) or - * PolicyLocal (setValue uses setLocal). - * - * A "clean" policy means that the property is always the same on every - * client. This is achieved by calling send which actually changes - * the value only when the message from the MessageServer is received. - * - * A "dirty" policy means that as soon as setValue is called the - * property is changed immediately. And additionally sent over network. - * This can sometimes lead to bugs as the other clients do not - * immediately have the same value. For more information see - * changeValue. - * - * PolicyLocal means that a KGameProperty behaves like ever - * "normal" variable. Whenever setValue is called (e.g. using "=") - * the value of the property is changes immediately without sending it - * over network. You might want to use this if you are sure that all - * clients set the property at the same time. - **/ - enum PropertyPolicy - { - PolicyUndefined = 0, - PolicyClean = 1, - PolicyDirty = 2, - PolicyLocal = 3 - }; - - - /** - * Constructs a KGamePropertyBase object and calls registerData. - * @param id The id of this property. MUST be UNITQUE! Used to send and - * receive changes in the property of the playere automatically via - * network. - * @param owner The owner of the object. Must be a KGamePropertyHandler which manages - * the changes made to this object, i.e. which will send the new data - **/ - KGamePropertyBase(int id, KGamePropertyHandler* owner); - - KGamePropertyBase(int id, KGame* parent); - KGamePropertyBase(int id, KPlayer* parent); - - /** - * Creates a KGamePropertyBase object without an owner. Remember to call - * registerData! - **/ - KGamePropertyBase(); - - virtual ~KGamePropertyBase(); - - /** - * Changes the consistency policy of a property. The - * PropertyPolicy is one of PolicyClean (defaulz), PolicyDirty or PolicyLocal. - * - * It is up to you to decide how you want to work. - **/ - void setPolicy(PropertyPolicy p) { mFlags.bits.policy = p; } - - /** - * @return The default policy of the property - **/ - PropertyPolicy policy() const { return (PropertyPolicy)mFlags.bits.policy; } - - /** - * Sets this property to emit a signal on value changed. - * As the proerties do not inehrit TQObject for optimisation - * this signal is emited via the KPlayer or KGame object - **/ - void setEmittingSignal(bool p) { mFlags.bits.emitsignal=p; } - - /** - * See also setEmittingSignal - * @return Whether this property emits a signal on value change - **/ - bool isEmittingSignal() const { return mFlags.bits.emitsignal; } - - /** - * Sets this property to try to optimize signal and network handling - * by not sending it out when the property value is not changed. - **/ - void setOptimized(bool p) { mFlags.bits.optimize = p ; } - - /** - * See also setOptimize - * @return Whether the property optimizes access (signals,network traffic) - **/ - bool isOptimized() const { return mFlags.bits.optimize; } - - /** - * @return Whether this property is "dirty". See also setDirty - **/ - bool isDirty() const { return mFlags.bits.dirty; } - - /** - * A locked property can only be changed by the player who has set the - * lock. See also setLocked - * @return Whether this property is currently locked. - **/ - bool isLocked() const { return mFlags.bits.locked; } - - /** - * A locked property can only be changed by the player who has set the - * lock. - * - * You can only call this if isLocked is false. A message is sent - * over network so that the property is locked for all players except - * you. - * - * @return returns false if the property can not be locked, i.e. it is already locked - * - **/ - bool lock(); - - /** - * A locked property can only be changed by the player who has set the - * lock. - * - * You can only call this if isLocked is false. A message is sent - * over network so that the property is locked for all players except - * you. - * - * @return returns false if the property can not be locked, i.e. it is already locked - * - **/ - bool unlock(bool force=false); - - /** - * This will read the value of this property from the stream. You MUST - * overwrite this method in order to use this class - * @param s The stream to read from - **/ - virtual void load(TQDataStream& s) = 0; - - /** - * Write the value into a stream. MUST be overwritten - **/ - virtual void save(TQDataStream& s) = 0; - - /** - * send a command to advanced properties like arrays - * @param stream The stream containing the data of the comand - * @param msgid The ID of the command - see PropertyCommandIds - * @param isSender whether this client is also the sender of the command - **/ - virtual void command(TQDataStream &stream, int msgid, bool isSender=false); - - /** - * @return The id of this property - **/ - int id() const { return mId; } - - /** - * @return a type_info of the data this property contains. This is used - * e.g. by KGameDebugDialog - **/ - virtual const type_info* typeinfo() { return &typeid(this); } - - /** - * You have to register a KGamePropertyBase before you can use it. - * - * You MUST call this before you can use KGamePropertyBase! - * - * @param id the id of this KGamePropertyBase object. The id MUST be - * unique, i.e. you cannot have two properties with the same id for one - * player, although (currently) nothing prevents you from doing so. But - * you will get strange results! - * - * @param owner The owner of this data. This will send the data - * using KPropertyHandler::sendProperty whenever you call send - * - * @param p If not 0 you can set the policy of the property here - * - * @param name if not 0 you can assign a name to this property - * - **/ - int registerData(int id, KGamePropertyHandler* owner,PropertyPolicy p, TQString name=0); - - /** - * This is an overloaded member function, provided for convenience. - * It differs from the above function only in what argument(s) it accepts. - **/ - int registerData(int id, KGamePropertyHandler* owner, TQString name=0); - - /** - * This is an overloaded member function, provided for convenience. - * It differs from the above function only in what argument(s) it accepts. - **/ - int registerData(int id, KGame* owner, TQString name=0); - - /** - * This is an overloaded member function, provided for convenience. - * It differs from the above function only in what argument(s) it accepts. - **/ - int registerData(int id, KPlayer* owner, TQString name=0); - - /** - * This is an overloaded member function, provided for convenience. - * It differs from the above function only in what argument(s) it accepts. - * In particular you can use this function to create properties which - * will have an automatic id assigned. The new id is returned. - **/ - int registerData(KGamePropertyHandler* owner,PropertyPolicy p=PolicyUndefined, TQString name=0); - - void unregisterData(); - - -protected: - /** - * A locked property can only be changed by the player who has set the - * lock. - * - * You can only call this if isLocked is false. A message is sent - * over network so that the property is locked for all players except - * you. - * Usually you use lock and unlock to access this property - * - **/ - void setLock(bool l); - - /** - * Sets the "dirty" flag of the property. If a property is "dirty" i.e. - * KGameProperty::setLocal has been called there is no guarantee - * that all clients share the same value. You have to ensure this - * yourself e.g. by calling KGameProperty::setLocal on every - * client. You can also ignore the dirty flag and continue working withe - * the property depending on your situation. - **/ - void setDirty(bool d) { mFlags.bits.dirty = d ; } - - /** - * Forward the data to the owner of this property which then sends it - * over network. save is used to store the data into a stream so - * you have to make sure that function is working properly if you - * implement your own property! - * - * Note: this sends the <em>current</em> property! - * - * Might be obsolete - KGamePropertyArray still uses it. Is this a bug - * or correct? - **/ - bool sendProperty(); - - /** - * Forward the data to the owner of this property which then sends it - * over network. save is used to store the data into a stream so - * you have to make sure that function is working properly if you - * implement your own property! - * - * This function is used by send to send the data over network. - * This does <em>not</em> send the current value but the explicitly - * given value. - * - * @return TRUE if the message could be sent successfully, otherwise - * FALSE - **/ - bool sendProperty(const TQByteArray& b); - - /** - * Causes the parent object to emit a signal on value change - **/ - void emitSignal(); - -protected: - KGamePropertyHandler* mOwner; - - // Having this as a union of the bitfield and the char - // allows us to stream this quantity easily (if we need to) - // At the moment it is not yet transmitted - union Flags { - char flag; - struct { - // unsigned char dosave : 1; // do save this property - // unsigned char delaytransmit : 1; // do not send immediately on - // change but a KPlayer:TQTimer - // sends it later on - fast - // changing variables - unsigned char emitsignal : 1; // KPlayer notifies on variable change (true) - //unsigned char readonly : 1; // whether the property can be changed (false) - unsigned char optimize : 1; // whether the property tries to optimize send/emit (false) - unsigned char dirty: 1; // whether the property dirty (setLocal() was used) - unsigned char policy : 2; // whether the property is always consistent (see PropertyPolicy) - unsigned char locked: 1; // whether the property is locked (true) - } bits; - } mFlags; - -private: - friend class KGamePropertyHandler; - void init(); - -private: - int mId; - -}; - -/** - * @short A class for network transparent games - * - * Note: The entire API documentation is obsolete! - * - * The class KGameProperty can store any form of data and will transmit it via - * network whenver you call send. This makes network transparent games - * very easy. You first have to register the data to a KGamePropertyHandler - * using KGamePropertyBase::registerData (which is called by the - * constructor). For the KGamePropertyHandler you can use - * KGame::dataHandler or KPlayer::dataHandler but you can also create your - * own data handler. - * - * There are several concepts you can follow when writing network games. These - * concepts differ completely from the way how data is transferred so you should - * decide which one to use. You can also mix these concepts for a single - * property but we do not recommend this. The concepts: - * <ul> - * <li> Always Consistent (clean) - * <li> Not Always Consistent (dirty) - * <li> A Mixture (very dirty) - * </ul> - * I repeat: we do <em>not</em> recommend the third option ("a mixture"). Unless - * you have a good reason for this you will probably introduce some hard to find - * (and to fix) bugs. - * - * @section Always consistent (clean): - * - * This "policy" is default. Whenever you create a KGameProperty it is always - * consistent. This means that consistency is the most important thing for the - * property. This is achieved by using send to change the value of the - * property. send needs a running KMessageServer and therefore - * <em>MUST</em> be plugged into a KGamePropertyHandler using either - * registerData or the constructor. The parent of the dataHandler must be able - * to send messages (see above: the message server must be running). If you use - * send to change the value of a property you won't see the effect - * immediately: The new value is first transferred to the message server which - * queues the message. As soon as <em>all</em> messages in the message server - * which are before the changed property have been transferred the message - * server delivers the new value of the KGameProperty to all clients. A - * TQTimer::singleShot is used to queue the messages inside the - * KMessageServer. - * - * This means that if you do the following: - * \code - * KGamePropertyInt myProperty(id, dataHandler()); - * myProperty.initData(0); - * myProperty = 10; - * int value = myProperty.value(); - * \endcode - * then "value" will be "0". initData is used to initialize the property - * (e.g. when the KMessageServer is not yet running or can not yet be - * reached). This is because "myProperty = 10" or "myProperty.send(10)" send a - * message to the KMessageServer which uses TQTimer::singleShot to - * queue the message. The game first has to go back into the event loop where - * the message is received. The KGamePropertyHandler receives the new value - * sets the property. So if you need the new value you need to store it in a - * different variable (see setLocal which creates one for you until the - * message is received). The KGamePropertyHandler emits a signal (unless - * you called setEmitSignal with false) when the new value is received: - * KGamePropertyHandler::signalPropertyChanged. You can use this to react - * to a changed property. - * - * This may look quite confusing but it has a <em>big</em> advantage: all - * KGameProperty objects are ensured to have the same value on all clients in - * the game at every time. This way you will save you a lot of trouble as - * debugging can be very difficult if the value of a property changes - * immediately on client A but only after one or two additianal messages - * (function calls, status changes, ...) on client B. - * - * The only disadvantage of this (clean) concept is that you cannot use a - * changed variable immediately but have to wait for the KMessageServer to - * change it. You probably want to use - * KGamePropertyHandler::signalPropertyChanged for this. - * - * @section Not Always Consistent (dirty): - * - * There are a lot of people who don't want to use the (sometimes quite complex) - * "clean" way. You can use setAlwaysConsistent to change the default - * behaviour of the KGameProperty. If a property is not always consistent - * it will use changeValue to send the property. changeValue also uses - * send to send the new value over network but it also uses - * setLocal to create a local copy of the property. This copy is created - * dynamically and is deleted again as soon as the next message from the network - * is received. To use the example above again: - * \code - * KGamePropertyInt myProperty(id, dataHandler()); - * myProperty.setAlwaysConsistent(false); - * myProperty.initData(0); - * myProperty = 10; - * int value = myProperty.value(); - * \endcode - * Now this example will "work" so value now is 10. Additionally the - * KMessageServer receives a message from the local client (just as explained - * above in "Always Consistent"). As soon as the message returns to the local - * client again the local value is deleted, as the "network value" has the same - * value as the local one. So you won't lose the ability to use the always - * consistent "clean" value of the property if you use the "dirty" way. Just use - * networkValue to access the value which is consistent among all clients. - * - * The advantage of this concept is clear: you can use a KGameProperty as - * every other variable as the changes value takes immediate effect. - * Additionally you can be sure that the value is transferred to all clients. - * You will usually not experience serious bugs just because you use the "dirty" - * way. Several events have to happen at once to get these "strange errors" - * which result in inconsistent properties (like "game running" on client A but - * "game ended/paused" on client B). But note that there is a very good reason - * for the existence of these different concepts of KGameProperty. I have - * myself experienced such a "strange error" and it took me several days to find - * the reason until I could fix it. So I personally recommend the "clean" way. - * On the other hand if you want to port a non-network game to a network game - * you will probably start with "dirty" properties as it is you will not have to - * change that much code... - * - * @section A Mixture (very dirty): - * - * You can also mix the concepts above. Note that we really don't recommend - * this. With a mixture I mean something like this: - * \code - * KGamePropertyInt myProperty(id, dataHandler()); - * myProperty.setAlwaysConsistent(false); - * myProperty.initData(0); - * myProperty = 10; - * myProperty.setAlwaysConsistent(true); - * myProperty = 20; - * \endcode - * (totally senseless example, btw) I.e. I am speaking of mixing both concepts - * for a single property. Things like - * \code - * KGamePropertyInt myProperty1(id1, dataHandler()); - * KGamePropertyInt myProperty2(id2, dataHandler()); - * myProperty1.initData(0); - * myProperty2.initData(0); - * myProperty1.setAlwaysConsistent(false); - * myProperty2.setAlwaysConsistent(true); - * myProperty1 = 10; - * myProperty2 = 20; - * \endcode - * are ok. But mixing the concepts for a single property will make it nearly - * impossible to you to debug your game. - * - * So the right thing to do(tm) is to decide in the constructor whether you want - * a "clean" or "dirty" property. - * - * Even if you have decided for one of the concepts you still can manually - * follow another concept than the "policy" of your property. So if you use an - * always consistent KGameProperty you still can manually call - * changeValue as if it was not always consistent. Note that although this is - * also kind of a "mixture" as described above this is very useful sometimes. In - * contrast to the "mixture" above you don't have the problem that you don't - * exactly know which concept you are currently following because you used the - * function of the other concept only once. - * - * @section Custom classes: - * - * If you want to use a custum class with KGameProperty you have to implement the - * operators << and >> for TQDataStream: - * \code - * class Card - * { - * public: - * int type; - * int suite; - * }; - * TQDataStream& operator<<(TQDataStream& stream, Card& card) - * { - * TQ_INT16 type = card.type; - * TQ_INT16 suite = card.suite; - * s << type; - * s << suite; - * return s; - * } - * TQDataStream& operator>>(TQDataStream& stream, Card& card) - * { - * TQ_INT16 type; - * TQ_INT16 suite; - * s >> type; - * s >> suite; - * card.type = (int)type; - * card.suite = (int)suite; - * return s; - * } - * - * class Player : KPlayer - * { - * [...] - * KGameProperty<Card> mCards; - * }; - * \endcode - * - * Note: unlike most QT classes KGameProperty objects are *not* deleted - * automatically! So if you create an object using e.g. KGameProperty<int>* data = - * new KGameProperty(id, dataHandler()) you have to put a delete data into your - * destructor! - * - * @author Andreas Beckermann <[email protected]> - **/ -template<class type> -class KGameProperty : public KGamePropertyBase -{ -public: - /** - * Constructs a KGameProperty object. A KGameProperty object will transmit - * any changes to the KMessageServer and then to all clients in the - * game (including the one that has sent the new value) - * @param id The id of this property. <em>MUST be UNITQUE</em>! Used to send and - * receive changes in the property of the playere automatically via - * network. - * @param owner The parent of the object. Must be a KGame which manages - * the changes made to this object, i.e. which will send the new data. - * Note that in contrast to most KDE/QT classes KGameProperty objects - * are <em>not</em> deleted automatically! - **/ -// TODO: ID: Very ugly - better use something like parent()->propertyId() or so which assigns a free id automatically. - KGameProperty(int id, KGamePropertyHandler* owner) : KGamePropertyBase(id, owner) { init(); } - - /** - * This constructor does nothing. You have to call - * KGamePropertyBase::registerData - * yourself before using the KGameProperty object. - **/ - KGameProperty() : KGamePropertyBase() { init(); } - - virtual ~KGameProperty() {} - - /** - * Set the value depending on the current policy (see - * setConsistent). By default KGameProperty just uses send to set - * the value of a property. This behaviour can be changed by using - * setConsistent. - * @param v The new value of the property - **/ - void setValue(type v) - { - switch (policy()) { - case PolicyClean: - send(v); - break; - case PolicyDirty: - changeValue(v); - break; - case PolicyLocal: - setLocal(v); - break; - default: // NEVER! - kdError(11001) << "Undefined Policy in property " << id() << endl; - return; - } - } - - - /** - * This function sends a new value over network. - * - * Note that the value DOES NOT change when you call this function. This - * function saves the value into a TQDataStream and calls - * sendProperty where it gets forwarded to the owner and finally the - * value is sent over network. The KMessageServer now sends the - * value to ALL clients - even the one who called this function. As soon - * as the value from the message server is received load is called - * and _then_ the value of the KGameProperty has been set. - * - * This ensures that a KGameProperty has _always_ the same value on - * _every_ client in the network. Note that this means you can NOT do - * something like - * \code - * myProperty.send(1); - * doSomething(myProperty); - * \endcode - * as myProperty has not yet been set when doSomething is being called. - * - * You are informed about a value change by a singal from the parent of - * the property which can be deactivated by setEmittingSignal because of - * performance (you probably don't have to deactivate it - except you - * want to write a real-time game like Command&Conquer with a lot of - * acitvity). See emitSignal - * - * Note that if there is no KMessageServer accessible - before - * the property has been registered to the KGamePropertyHandler (as - * it is the case e.g. before a KPlayer has been plugged into the - * KGame object) the property is *not* sent but set *locally* (see - * setLocal)! - * - * @param v The new value of the property - * @return whether the property could be sent successfully - * @see setValue setLocal changeValue value - **/ - bool send(type v) - { - if (isOptimized() && mData == v) { - return true; - } - if (isLocked()) { - return false; - } - TQByteArray b; - TQDataStream stream(b, IO_WriteOnly); - stream << v; - if (!sendProperty(b)) { - setLocal(v); - return false; - } - return true; - } - - /** - * This function sets the value of the property directly, i.e. it - * doesn't send it to the network. - * - * Int contrast to @see you change _only_ the local value when using - * this function. You do _not_ change the value of any other client. You - * probably don't want to use this if you are using a dedicated server - * (which is the only "client" which is allowed to change a value) but - * rather want to use send(). - * - * But if you use your clients as servers (i.e. all clients receive a - * players turn and then calculate the reaction of the game theirselves) - * then you probably want to use setLocal as you can do things like - * \code - * myProperty.setLocal(1); - * doSomething(myProperty); - * \endcode - * on every client. - * - * If you want to set the value locally AND send it over network you - * want to call changeValue! - * - * You can also use setPolicy to set the default policy to - * PolicyLocal. - * - * @see setValue send changeValue value - **/ - bool setLocal(type v) - { - if (isOptimized() && mData == v) { - return false; - } - if (isLocked()) { - return false; - } - mData = v; - setDirty(true); - if (isEmittingSignal()) { - emitSignal(); - } - return true; - } - - /** - * This function does both, change the local value and change the - * network value. The value is sent over network first, then changed - * locally. - * - * This function is a convenience function and just calls send - * followed by setLocal - * - * Note that emitSignal is also called twice: once after - * setLocal and once when the value from send is received - * - * @see send setLocal setValue value - **/ - void changeValue(type v) - { - send(v); - setLocal(v); - } - - /** - * Saves the object to a stream. - * @param stream The stream to save to - **/ - virtual void save(TQDataStream &stream) - { - stream << mData; - } - - /** - * @return The local value (see setLocal) if it is existing, - * otherwise the network value which is always consistent on every - * client. - **/ - const type& value() const - { - return mData; - } - - /** - * Reads from a stream and assigns the read value to this object. - * - * This function is called automatically when a new value is received - * over network (i.e. it has been sent using send on this or any - * other client) or when a game is loaded (and maybe on some other - * events). - * - * Also calls emitSignal if isEmittingSignal is TRUE. - * @param s The stream to read from - **/ - virtual void load(TQDataStream& s) - { - s >> mData; - setDirty(false); - if (isEmittingSignal()) { - emitSignal(); - } - } - - /** - * This calls setValue to change the value of the property. Note - * that depending on the policy (see setAlwaysConsistent) the - * returned value might be different from the assigned value!! - * - * So if you use setPolicy(PolicyClean): - * \code - * int a, b = 10; - * myProperty = b; - * a = myProperty.value(); - * \endcode - * Here a and b would differ! - * The value is actually set as soon as it is received from the - * KMessageServer which forwards it to ALL clients in the network. - * - * If you use a clean policy (see setPolicy) then - * the returned value is the assigned value - **/ - const type& operator=(const type& t) - { - setValue(t); - return value(); - } - - /** - * This copies the data of property to the KGameProperty object. - * - * Equivalent to setValue(property.value()); - **/ - const type& operator=(const KGameProperty& property) - { - setValue(property.value()); - return value(); - } - - /** - * Yeah, you can do it! - * \code - * int a = myGamePropertyInt; - * \endcode - * If you don't see it: you don't have to use integerData.value() - **/ - operator type() const { return value(); } - - virtual const type_info* typeinfo() { return &typeid(type); } - -private: - void init() { } - -private: - type mData; -}; - - -typedef KGameProperty<int> KGamePropertyInt; -typedef KGameProperty<unsigned int> KGamePropertyUInt; -typedef KGameProperty<TQString> KGamePropertyTQString; -typedef KGameProperty<TQ_INT8> KGamePropertyBool; - -#endif diff --git a/libkdegames/kgame/kgamepropertyarray.h b/libkdegames/kgame/kgamepropertyarray.h deleted file mode 100644 index 0bb1d1a1..00000000 --- a/libkdegames/kgame/kgamepropertyarray.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEPROPERTYARRAY_H_ -#define __KGAMEPROPERTYARRAY_H_ - -#include <tqdatastream.h> -#include <kdebug.h> - -#include "kgamemessage.h" -#include "kgameproperty.h" -#include "kgamepropertyhandler.h" - - -template<class type> -class KGamePropertyArray : public TQMemArray<type>, public KGamePropertyBase -{ -public: - KGamePropertyArray() :TQMemArray<type>(), KGamePropertyBase() - { - //kdDebug(11001) << "KGamePropertyArray init" << endl; - } - - KGamePropertyArray( int size ) - { - resize(size); - } - - KGamePropertyArray( const KGamePropertyArray<type> &a ) : TQMemArray<type>(a) - { - } - - bool resize( uint size ) - { - if (size!=TQMemArray<type>::size()) - { - bool a=true; - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdResize); - s << size ; - if (policy()==PolicyClean || policy()==PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - extractProperty(b); -// a=TQMemArray<type>::resize(size);// FIXME: return value! - } - return a; - } - else return true; - } - - void setAt(uint i,type data) - { - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdAt); - s << i ; - s << data; - if (policy()==PolicyClean || policy()==PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - extractProperty(b); - } - //kdDebug(11001) << "KGamePropertyArray setAt send COMMAND for id="<<id() << " type=" << 1 << " at(" << i<<")="<<data << endl; - } - - type at( uint i ) const - { - return TQMemArray<type>::at(i); - } - - type operator[]( int i ) const - { - return TQMemArray<type>::at(i); - } - - KGamePropertyArray<type> &operator=(const KGamePropertyArray<type> &a) - { - return assign(a); - } - - bool truncate( uint pos ) - { - return resize(pos); - } - - bool fill( const type &data, int size = -1 ) - { - bool r=true; - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdFill); - s << data; - s << size ; - if (policy()==PolicyClean || policy()==PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - extractProperty(b); -// r=TQMemArray<type>::fill(data,size);//FIXME: return value! - } - return r; - } - - KGamePropertyArray<type>& assign( const KGamePropertyArray<type>& a ) - { -// note: send() has been replaced by sendProperty so it might be broken now! - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendProperty(); - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - TQMemArray<type>::assign(a); - } - return *this; - } - KGamePropertyArray<type>& assign( const type *a, uint n ) - { - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendProperty(); - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - TQMemArray<type>::assign(a,n); - } - return *this; - } - KGamePropertyArray<type>& duplicate( const KGamePropertyArray<type>& a ) - { - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendProperty(); - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - TQMemArray<type>::duplicate(a); - } - return *this; - } - KGamePropertyArray<type>& duplicate( const type *a, uint n ) - { - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendProperty(); - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - TQMemArray<type>::duplicate(a,n); - } - return *this; - } - KGamePropertyArray<type>& setRawData( const type *a, uint n ) - { - if (policy()==PolicyClean || policy()==PolicyDirty) - { - sendProperty(); - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - TQMemArray<type>::setRawData(a,n); - } - return *this; - } - void sort() - { - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdSort); - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy()==PolicyLocal || policy()==PolicyDirty) - { - extractProperty(b); - } - } - - void load(TQDataStream& s) - { - //kdDebug(11001) << "KGamePropertyArray load " << id() << endl; - type data; - for (unsigned int i=0; i<TQMemArray<type>::size(); i++) - { - s >> data; - TQMemArray<type>::at(i)=data; - } - if (isEmittingSignal()) - { - emitSignal(); - } - } - void save(TQDataStream &s) - { - //kdDebug(11001) << "KGamePropertyArray save "<<id() << endl; - for (unsigned int i=0; i<TQMemArray<type>::size(); i++) - { - s << at(i); - } - } - - void command(TQDataStream &s,int cmd,bool) - { - KGamePropertyBase::command(s, cmd); - //kdDebug(11001) << "Array id="<<id()<<" got command ("<<cmd<<") !!!" <<endl; - switch(cmd) - { - case CmdAt: - { - uint i; - type data; - s >> i >> data; - TQMemArray<type>::at(i)=data; - //kdDebug(11001) << "CmdAt:id="<<id()<<" i="<<i<<" data="<<data <<endl; - if (isEmittingSignal()) - { - emitSignal(); - } - break; - } - case CmdResize: - { - uint size; - s >> size; - //kdDebug(11001) << "CmdResize:id="<<id()<<" oldsize="<<TQMemArray<type>::size()<<" newsize="<<size <<endl; - if (TQMemArray<type>::size() != size) - { - TQMemArray<type>::resize(size); - } - break; - } - case CmdFill: - { - int size; - type data; - s >> data >> size; - //kdDebug(11001) << "CmdFill:id="<<id()<<"size="<<size <<endl; - TQMemArray<type>::fill(data,size); - if (isEmittingSignal()) - { - emitSignal(); - } - break; - } - case CmdSort: - { - //kdDebug(11001) << "CmdSort:id="<<id()<<endl; - TQMemArray<type>::sort(); - break; - } - default: - kdError(11001) << "Error in KPropertyArray::command: Unknown command " << cmd << endl; - break; - } - } -protected: - void extractProperty(const TQByteArray& b) - { - TQDataStream s(b, IO_ReadOnly); - int cmd; - int propId; - KGameMessage::extractPropertyHeader(s, propId); - KGameMessage::extractPropertyCommand(s, propId, cmd); - command(s, cmd, true); - } - -}; - -#endif diff --git a/libkdegames/kgame/kgamepropertyhandler.cpp b/libkdegames/kgame/kgamepropertyhandler.cpp deleted file mode 100644 index 405d433e..00000000 --- a/libkdegames/kgame/kgamepropertyhandler.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgamepropertyhandler.h" -#include "kgameproperty.h" -#include "kgamemessage.h" - -#include <tqmap.h> -#include <tqptrqueue.h> - -#include <klocale.h> -#include <typeinfo> - -#define KPLAYERHANDLER_LOAD_COOKIE 6239 - -//---------------------- KGamePropertyHandler ----------------------------------- -class KGamePropertyHandlerPrivate -{ -public: - KGamePropertyHandlerPrivate() - { - } - - TQMap<int, TQString> mNameMap; - TQIntDict<KGamePropertyBase> mIdDict; - int mUniqueId; - int mId; - KGamePropertyBase::PropertyPolicy mDefaultPolicy; - bool mDefaultUserspace; - int mIndirectEmit; - TQPtrQueue<KGamePropertyBase> mSignalQueue; -}; - -KGamePropertyHandler::KGamePropertyHandler(int id, const TQObject* receiver, const char * sendf, const char *emitf, TQObject* parent) : TQObject(parent) -{ - init(); - registerHandler(id,receiver,sendf,emitf); -} - -KGamePropertyHandler::KGamePropertyHandler(TQObject* parent) : TQObject(parent) -{ - init(); -} - -KGamePropertyHandler::~KGamePropertyHandler() -{ - clear(); - delete d; -} - -void KGamePropertyHandler::init() -{ - kdDebug(11001) << k_funcinfo << ": this=" << this << endl; - d = new KGamePropertyHandlerPrivate; // for future use - is BC important to us? - d->mId = 0; - d->mUniqueId=KGamePropertyBase::IdAutomatic; - d->mDefaultPolicy=KGamePropertyBase::PolicyLocal; - d->mDefaultUserspace=true; - d->mIndirectEmit=0; -} - - -int KGamePropertyHandler::id() const -{ - return d->mId; -} - -void KGamePropertyHandler::setId(int id) -{ - d->mId = id; -} - -void KGamePropertyHandler::registerHandler(int id,const TQObject * receiver, const char * sendf, const char *emitf) -{ - setId(id); - if (receiver && sendf) { - kdDebug(11001) << "Connecting TQT_SLOT " << sendf << endl; - connect(this, TQT_SIGNAL(signalSendMessage(int, TQDataStream &, bool*)), receiver, sendf); - } - if (receiver && emitf) { - kdDebug(11001) << "Connecting TQT_SLOT " << emitf << endl; - connect(this, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase *)), receiver, emitf); - } -} - -bool KGamePropertyHandler::processMessage(TQDataStream &stream, int id, bool isSender) -{ -// kdDebug(11001) << k_funcinfo << ": id=" << id << " mId=" << d->mId << endl; - if (id != d->mId) { - return false; // Is the message meant for us? - } - KGamePropertyBase* p; - int propertyId; - KGameMessage::extractPropertyHeader(stream, propertyId); -// kdDebug(11001) << k_funcinfo << ": Got property " << propertyId << endl; - if (propertyId==KGamePropertyBase::IdCommand) { - int cmd; - KGameMessage::extractPropertyCommand(stream, propertyId, cmd); -//kdDebug(11001) << k_funcinfo << ": Got COMMAND for id= "<<propertyId <<endl; - p = d->mIdDict.find(propertyId); - if (p) { - if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) { - p->command(stream, cmd, isSender); - } - } else { - kdError(11001) << k_funcinfo << ": (cmd): property " << propertyId << " not found" << endl; - } - return true; - } - p = d->mIdDict.find(propertyId); - if (p) { - //kdDebug(11001) << k_funcinfo << ": Loading " << propertyId << endl; - if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) { - p->load(stream); - } - } else { - kdError(11001) << k_funcinfo << ": property " << propertyId << " not found" << endl; - } - return true; -} - -bool KGamePropertyHandler::removeProperty(KGamePropertyBase* data) -{ - if (!data) { - return false; - } - d->mNameMap.erase(data->id()); - return d->mIdDict.remove(data->id()); -} - -bool KGamePropertyHandler::addProperty(KGamePropertyBase* data, TQString name) -{ - //kdDebug(11001) << k_funcinfo << ": " << data->id() << endl; - if (d->mIdDict.find(data->id())) { - // this id already exists - kdError(11001) << " -> cannot add property " << data->id() << endl; - return false; - } else { - d->mIdDict.insert(data->id(), data); - // if here is a check for "is_debug" or so we can add the strings only in debug mode - // and save memory!! - if (!name.isNull()) { - d->mNameMap[data->id()] = name; - //kdDebug(11001) << k_funcinfo << ": nid="<< (data->id()) << " inserted in Map name=" << d->mNameMap[data->id()] <<endl; - //kdDebug(11001) << "Typeid=" << typeid(data).name() << endl; - //kdDebug(11001) << "Typeid call=" << data->typeinfo()->name() << endl; - } - } - return true; -} - -TQString KGamePropertyHandler::propertyName(int id) const -{ - TQString s; - if (d->mIdDict.find(id)) { - if (d->mNameMap.contains(id)) { - s = i18n("%1 (%2)").tqarg(d->mNameMap[id]).tqarg(id); - } else { - s = i18n("Unnamed - ID: %1").tqarg(id); - } - } else { - // Should _never_ happen - s = i18n("%1 unregistered").tqarg(id); - } - return s; -} - -bool KGamePropertyHandler::load(TQDataStream &stream) -{ - // Prevent direct emmiting until all is loaded - lockDirectEmit(); - uint count,i; - stream >> count; - kdDebug(11001) << k_funcinfo << ": " << count << " KGameProperty objects " << endl; - for (i = 0; i < count; i++) { - processMessage(stream, id(),false); - } - TQ_INT16 cookie; - stream >> cookie; - if (cookie == KPLAYERHANDLER_LOAD_COOKIE) { - kdDebug(11001) << " KGamePropertyHandler loaded propertly"<<endl; - } else { - kdError(11001) << "KGamePropertyHandler loading error. probably format error"<<endl; - } - // Allow direct emmiting (if no other lock still holds) - unlockDirectEmit(); - return true; -} - -bool KGamePropertyHandler::save(TQDataStream &stream) -{ - kdDebug(11001) << k_funcinfo << ": " << d->mIdDict.count() << " KGameProperty objects " << endl; - stream << (uint)d->mIdDict.count(); - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - KGamePropertyBase *base=it.current(); - if (base) { - KGameMessage::createPropertyHeader(stream, base->id()); - base->save(stream); - } - ++it; - } - stream << (TQ_INT16)KPLAYERHANDLER_LOAD_COOKIE; - return true; -} - -KGamePropertyBase::PropertyPolicy KGamePropertyHandler::policy() -{ -// kdDebug(11001) << k_funcinfo << ": " << d->mDefaultPolicy << endl; - return d->mDefaultPolicy; -} -void KGamePropertyHandler::setPolicy(KGamePropertyBase::PropertyPolicy p,bool userspace) -{ - // kdDebug(11001) << k_funcinfo << ": " << p << endl; - d->mDefaultPolicy=p; - d->mDefaultUserspace=userspace; - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - if (!userspace || it.current()->id()>=KGamePropertyBase::IdUser) { - it.current()->setPolicy((KGamePropertyBase::PropertyPolicy)p); - } - ++it; - } -} - -void KGamePropertyHandler::unlockProperties() -{ - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - it.current()->unlock(); - ++it; - } -} - -void KGamePropertyHandler::lockProperties() -{ - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - it.current()->lock(); - ++it; - } -} - -int KGamePropertyHandler::uniquePropertyId() -{ - return d->mUniqueId++; -} - -void KGamePropertyHandler::flush() -{ - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - if (it.current()->isDirty()) { - it.current()->sendProperty(); - } - ++it; - } -} - -/* Fire all property signal changed which are collected in - * the queque - **/ -void KGamePropertyHandler::lockDirectEmit() -{ - d->mIndirectEmit++; -} - -void KGamePropertyHandler::unlockDirectEmit() -{ - // If the flag is <=0 we emit the queued signals - d->mIndirectEmit--; - if (d->mIndirectEmit<=0) - { - KGamePropertyBase *prop; - while((prop=d->mSignalQueue.dequeue()) != 0) - { - // kdDebug(11001) << "emmiting signal for " << prop->id() << endl; - emit signalPropertyChanged(prop); - } - } -} - -void KGamePropertyHandler::emitSignal(KGamePropertyBase *prop) -{ - // If the indirect flag is set (load and network transmit) - // we cannot emit the signals directly as it can happend that - // a sigal causes an access to a property which is e.g. not - // yet loaded or received - - if (d->mIndirectEmit>0) - { - // Queque the signal - d->mSignalQueue.enqueue(prop); - } - else - { - // directly emit - emit signalPropertyChanged(prop); - } -} - -bool KGamePropertyHandler::sendProperty(TQDataStream &s) -{ - bool sent = false; - emit signalSendMessage(id(), s, &sent); - return sent; -} - -KGamePropertyBase *KGamePropertyHandler::find(int id) -{ - return d->mIdDict.find(id); -} - -void KGamePropertyHandler::clear() -{ - kdDebug(11001) << k_funcinfo << id() << endl; - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.toFirst()) { - KGamePropertyBase* p = it.toFirst(); - p->unregisterData(); - if (d->mIdDict.find(p->id())) { - // shouldn't happen - but if mOwner in KGamePropertyBase is NULL - // this might be possible - removeProperty(p); - } - } -} - -TQIntDict<KGamePropertyBase>& KGamePropertyHandler::dict() const -{ - return d->mIdDict; -} - -TQString KGamePropertyHandler::propertyValue(KGamePropertyBase* prop) -{ - if (!prop) { - return i18n("NULL pointer"); - } - - int id = prop->id(); - TQString name = propertyName(id); - TQString value; - - const type_info* t = prop->typeinfo(); - if (*t == typeid(int)) { - value = TQString::number(((KGamePropertyInt*)prop)->value()); - } else if (*t == typeid(unsigned int)) { - value = TQString::number(((KGamePropertyUInt *)prop)->value()); - } else if (*t == typeid(long int)) { - value = TQString::number(((KGameProperty<long int> *)prop)->value()); - } else if (*t == typeid(unsigned long int)) { - value = TQString::number(((KGameProperty<unsigned long int> *)prop)->value()); - } else if (*t == typeid(TQString)) { - value = ((KGamePropertyTQString*)prop)->value(); - } else if (*t == typeid(TQ_INT8)) { - value = ((KGamePropertyBool*)prop)->value() ? i18n("True") : i18n("False"); - } else { - emit signalRequestValue(prop, value); - } - - if (value.isNull()) { - value = i18n("Unknown"); - } - return value; -} - -void KGamePropertyHandler::Debug() -{ - kdDebug(11001) << "-----------------------------------------------------------" << endl; - kdDebug(11001) << "KGamePropertyHandler:: Debug this=" << this << endl; - - kdDebug(11001) << " Registered properties: (Policy,Lock,Emit,Optimized, Dirty)" << endl; - TQIntDictIterator<KGamePropertyBase> it(d->mIdDict); - while (it.current()) { - KGamePropertyBase *p=it.current(); - kdDebug(11001) << " "<< p->id() << ": p=" << p->policy() - << " l="<<p->isLocked() - << " e="<<p->isEmittingSignal() - << " o=" << p->isOptimized() - << " d="<<p->isDirty() - << endl; - ++it; - } - kdDebug(11001) << "-----------------------------------------------------------" << endl; -} - -#include "kgamepropertyhandler.moc" diff --git a/libkdegames/kgame/kgamepropertyhandler.h b/libkdegames/kgame/kgamepropertyhandler.h deleted file mode 100644 index c2a3429f..00000000 --- a/libkdegames/kgame/kgamepropertyhandler.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Andreas Beckermann ([email protected]) - Copyright (C) 2001 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEPROPERTYHANDLER_H_ -#define __KGAMEPROPERTYHANDLER_H_ - -#include <tqobject.h> -#include <tqintdict.h> - -#include "kgameproperty.h" -#include <kdemacros.h> - -class TQDataStream; -class KGame; -class KPlayer; -//class KGamePropertyBase; - -class KGamePropertyHandlerPrivate; // wow - what a name ;-) - -/** - * @short A collection class for KGameProperty objects - * - * The KGamePropertyHandler class is some kind of a collection class for - * KGameProperty. You usually don't have to create one yourself, as both - * KPlayer and KGame provide a handler. In most cases you do not even have - * to care about the KGamePropertHandler. KGame and KPlayer implement - * all features of KGamePropertyHandler so you will rather use it there. - * - * You have to use the KGamePropertyHandler as parent for all KGameProperty - * objects but you can also use KPlayer or KGame as parent - then - * KPlayer::dataHandler or KGame::dataHandler will be used. - * - * Every KGamePropertyHandler must have - just like every KGameProperty - - * a unique ID. This ID is provided either in the constructor or in - * registerHandler. The ID is used to assign an incoming message (e.g. a changed - * property) to the correct handler. Inside the handler the property ID is used - * to change the correct property. - * - * The constructor or registerHandler takes 3 addittional arguments: a - * receiver and two slots. The first slot is connected to - * signalSendMessage, the second to signalPropertyChanged. You must provide - * these in order to use the KGamePropertyHandler. - * - * The most important function of KGamePropertyHandler is processMessage - * which assigns an incoming value to the correct property. - * - * A KGamePropertyHandler is also used - indirectly using emitSignal - to - * emit a signal when the value of a property changes. This is done this way - * because a KGameProperty does not inherit TQObject because of memory - * advantages. Many games can have dozens or even hundreds of KGameProperty - * objects so every additional variable in KGameProperty would be - * multiplied. - * - **/ -class KDE_EXPORT KGamePropertyHandler : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Construct an unregistered KGamePropertyHandler - * - * You have to call registerHandler before you can use this - * handler! - **/ - KGamePropertyHandler(TQObject* parent = 0); - - /** - * Construct a registered handler. - * - * @see registerHandler - **/ - KGamePropertyHandler(int id, const TQObject* receiver, const char* sendf, const char* emitf, TQObject* parent = 0); - ~KGamePropertyHandler(); - - /** - * Register the handler with a parent. This is to use - * if the constructor without arguments has been chosen. - * Otherwise you need not call this. - * - * @param id The id of the message to listen for - * @param receiver The object that will receive the signals of - * KGamePropertyHandler - * @param send A slot that is being connected to signalSendMessage - * @param emit A slot that is being connected to signalPropertyChanged - **/ - void registerHandler(int id, const TQObject *receiver, const char * send, const char *emit); - - /** - * Main message process function. This has to be called by - * the parent's message event handler. If the id of the message - * agrees with the id of the handler, the message is extracted - * and processed. Otherwise false is returned. - * Example: - * \code - * if (mProperties.processMessage(stream,msgid,sender==gameId())) return ; - * \endcode - * - * @param stream The data stream containing the message - * @param id the message id of the message - * @param isSender Whether the receiver is also the sender - * @return true on message processed otherwise false - **/ - bool processMessage(TQDataStream &stream, int id, bool isSender ); - - /** - * @return the id of the handler - **/ - int id() const; - - /** - * Adds a KGameProperty property to the handler - * @param data the property - * @param name A description of the property, which will be returned by - * propertyName. This is used for debugging, e.g. in KGameDebugDialog - * @return true on success - **/ - bool addProperty(KGamePropertyBase *data, TQString name=0); - - /** - * Removes a property from the handler - * @param data the property - * @return true on success - **/ - bool removeProperty(KGamePropertyBase *data); - - /** - * returns a unique property ID starting called usually with a base of - * KGamePropertyBase::IdAutomatic. This is used internally by - * the property base to assign automtic id's. Not much need to - * call this yourself. - **/ - int uniquePropertyId(); - - - /** - * Loads properties from the datastream - * - * @param stream the datastream to load from - * @return true on success otherwise false - **/ - virtual bool load(TQDataStream &stream); - - /** - * Saves properties into the datastream - * - * @param stream the datastream to save to - * @return true on success otherwise false - **/ - virtual bool save(TQDataStream &stream); - - /** - * called by a property to send itself into the - * datastream. This call is simply forwarded to - * the parent object - **/ - bool sendProperty(TQDataStream &s); - - void sendLocked(bool l); - - /** - * called by a property to emit a signal - * This call is simply forwarded to - * the parent object - **/ - void emitSignal(KGamePropertyBase *data); - - /** - * @param id The ID of the property - * @return A name of the property which can be used for debugging. Don't - * depend on this function! It it possible not to provide a name or to - * provide the same name for multiple properties! - **/ - TQString propertyName(int id) const; - - /** - * @param id The ID of the property. See KGamePropertyBase::id - * @return The KGameProperty this ID is assigned to - **/ - KGamePropertyBase *find(int id); - - /** - * Clear the KGamePropertyHandler. Note that the properties are - * <em>not</em> deleted so if you created your KGameProperty - * objects dynamically like - * \code - * KGamePropertyInt* myProperty = new KGamePropertyInt(id, dataHandler()); - * \endcode - * you also have to delete it: - * \code - * dataHandler()->clear(); - * delete myProperty; - * \endcode - **/ - void clear(); - - /** - * Use id as new ID for this KGamePropertyHandler. This is used - * internally only. - **/ - void setId(int id);//AB: TODO: make this protected in KGamePropertyHandler!! - - /** - * Calls KGamePropertyBase::setReadOnly(false) for all properties of this - * player. See also lockProperties - **/ - void unlockProperties(); - - /** - * Set the policy for all kgame variables which are currently registerd in - * the KGame proeprty handler. See KGamePropertyBase::setPolicy - * - * @param p is the new policy for all properties of this handler - * @param userspace if userspace is true (default) only user properties are changed. - * Otherwise the system properties are also changed. - **/ - void setPolicy(KGamePropertyBase::PropertyPolicy p, bool userspace=true); - - /** - * Called by the KGame or KPlayer object or the handler itself to delay - * emmiting of signals. Lockign keeps a counter and unlock is only achieved - * when every lock is canceld by an unlock. - * While this is set signals are quequed and only emmited after this - * is reset. Its deeper meaning is to prevent inconsistencies in a game - * load or network transfer where a emit could access a property not - * yet loaded or transmitted. Calling this by yourself you better know - * what your are doing. - **/ - void lockDirectEmit(); - - /** - * Removes the lock from the emitting of property signals. Corresponds to - * the lockIndirectEmits - **/ - void unlockDirectEmit(); - - /** - * Returns the default policy for this property handler. All properties - * registered newly, will have this property. - **/ - KGamePropertyBase::PropertyPolicy policy(); - - /** - * Calls KGamePropertyBase::setReadOnly(true) for all properties of this - * handler - * - * Use with care! This will even lock the core properties, like name, - * group and myTurn!! - * - * @see unlockProperties - **/ - void lockProperties(); - - /** - * Sends all properties which are marked dirty over the network. This will - * make a forced synchornisation of the properties and mark them all not dirty. - **/ - void flush(); - - /** - * Reference to the internal dictionary - **/ - TQIntDict<KGamePropertyBase> &dict() const; - - /** - * In several situations you just want to have a TQString of a - * KGameProperty object. This is the case in the - * KGameDebugDialog where the value of all properties is displayed. This - * function will provide you with such a TQString for all the types - * used inside of all KGame classes. If you have a non-standard - * property (probably a self defined class or something like this) you - * also need to connect to signalRequestValue to make this function - * useful. - * @param property Return the value of this KGameProperty - * @return The value of a KGameProperty - **/ - TQString propertyValue(KGamePropertyBase* property); - - - /** - * Writes some debug output to the console. - **/ - void Debug(); - - -signals: - /** - * This is emitted by a property. KGamePropertyBase::emitSignal - * calls emitSignal which emits this signal. - * - * This signal is emitted whenever the property is changed. Note that - * you can switch off this behaviour using - * KGamePropertyBase::setEmittingSignal in favor of performance. Note - * that you won't experience any performance loss using signals unless - * you use dozens or hundreds of properties which change very often. - **/ - void signalPropertyChanged(KGamePropertyBase *); - - /** - * This signal is emitted when a property needs to be sent. Only the - * parent has to react to this. - * @param msgid The id of the handler - * @param sent set this to true if the property was sent successfully - - * otherwise don't touch - **/ - void signalSendMessage(int msgid, TQDataStream &, bool* sent); // AB shall we change bool* into bool& again? - - /** - * If you call propertyValue with a non-standard KGameProperty - * it is possible that the value cannot automatically be converted into a - * TQString. Then this signal is emitted and asks you to provide the - * correct value. You probably want to use something like this to achieve - * this: - * \code - * #include <typeinfo> - * void slotRequestValue(KGamePropertyBase* p, TQString& value) - * { - * if (*(p->typeinfo()) == typeid(MyType) { - * value = TQString(((KGameProperty<MyType>*)p)->value()); - * } - * } - * \endcode - * - * @param property The KGamePropertyBase the value is requested for - * @param value The value of this property. You have to set this. - **/ - void signalRequestValue(KGamePropertyBase* property, TQString& value); - -private: - void init(); - -private: - KGamePropertyHandlerPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/kgamepropertylist.h b/libkdegames/kgame/kgamepropertylist.h deleted file mode 100644 index df8eb604..00000000 --- a/libkdegames/kgame/kgamepropertylist.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KGAMEPROPERTYLIST_H_ -#define __KGAMEPROPERTYLIST_H_ - -#include <tqvaluelist.h> - -#include <kdebug.h> - -#include "kgamemessage.h" -#include "kgameproperty.h" -#include "kgamepropertyhandler.h" - -// AB: also see README.LIB! - -template<class type> -class KGamePropertyList : public TQValueList<type>, public KGamePropertyBase -{ -public: - /** - * Typedefs - */ - typedef TQValueListIterator<type> Iterator; - typedef TQValueListConstIterator<type> ConstIterator; - - KGamePropertyList() :TQValueList<type>(), KGamePropertyBase() - { - } - - KGamePropertyList( const KGamePropertyList<type> &a ) : TQValueList<type>(a) - { - } - - uint findIterator(Iterator me) - { - Iterator it; - uint cnt=0; - for( it = this->begin(); it != this->end(); ++it ) - { - if (me==it) - { - return cnt; - } - cnt++; - } - return this->count(); - } - - Iterator insert( Iterator it, const type& d ) - { - it=TQValueList<type>::insert(it,d); - - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdInsert); - int i=findIterator(it); - s << i; - s << d; - if (policy() == PolicyClean || policy() == PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy() == PolicyDirty || policy() == PolicyLocal) - { - extractProperty(b); - } - return it; - } - - void prepend( const type& d) { insert(this->begin(),d); } - - void append( const type& d ) - { - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdAppend); - s << d; - if (policy() == PolicyClean || policy() == PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy() == PolicyDirty || policy() == PolicyLocal) - { - extractProperty(b); - } - } - - Iterator erase( Iterator it ) - { - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdRemove); - int i=findIterator(it); - s << i; - if (policy() == PolicyClean || policy() == PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy() == PolicyDirty || policy() == PolicyLocal) - { - extractProperty(b); - } - //TODO: return value - is it correct for PolicyLocal|PolicyDirty? -// return TQValueList<type>::remove(it); - return it; - } - - Iterator remove( Iterator it ) - { - return erase(it); - } - - void remove( const type& d ) - { - Iterator it=find(d); - remove(it); - } - - void clear() - { - TQByteArray b; - TQDataStream s(b, IO_WriteOnly); - KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdClear); - if (policy() == PolicyClean || policy() == PolicyDirty) - { - if (mOwner) - { - mOwner->sendProperty(s); - } - } - if (policy() == PolicyDirty || policy() == PolicyLocal) - { - extractProperty(b); - } - } - - void load(TQDataStream& s) - { - kdDebug(11001) << "KGamePropertyList load " << id() << endl; - TQValueList<type>::clear(); - uint size; - type data; - s >> size; - - for (unsigned int i=0;i<size;i++) - { - s >> data; - TQValueList<type>::append(data); - } - if (isEmittingSignal()) emitSignal(); - } - - void save(TQDataStream &s) - { - kdDebug(11001) << "KGamePropertyList save "<<id() << endl; - type data; - uint size=this->count(); - s << size; - Iterator it; - for( it = this->begin(); it != this->end(); ++it ) - { - data=*it; - s << data; - } - } - - void command(TQDataStream &s,int cmd,bool) - { - KGamePropertyBase::command(s, cmd); - kdDebug(11001) << "---> LIST id="<<id()<<" got command ("<<cmd<<") !!!" <<endl; - Iterator it; - switch(cmd) - { - case CmdInsert: - { - uint i; - type data; - s >> i >> data; - it=this->at(i); - TQValueList<type>::insert(it,data); -// kdDebug(11001) << "CmdInsert:id="<<id()<<" i="<<i<<" data="<<data <<endl; - if (isEmittingSignal()) emitSignal(); - break; - } - case CmdAppend: - { - type data; - s >> data; - TQValueList<type>::append(data); -// kdDebug(11001) << "CmdAppend:id=" << id() << " data=" << data << endl; - if (isEmittingSignal()) emitSignal(); - break; - } - case CmdRemove: - { - uint i; - s >> i; - it=this->at(i); - TQValueList<type>::remove(it); - kdDebug(11001) << "CmdRemove:id="<<id()<<" i="<<i <<endl; - if (isEmittingSignal()) emitSignal(); - break; - } - case CmdClear: - { - TQValueList<type>::clear(); - kdDebug(11001) << "CmdClear:id="<<id()<<endl; - if (isEmittingSignal()) emitSignal(); - break; - } - default: - kdDebug(11001) << "Error in KPropertyList::command: Unknown command " << cmd << endl; - } - } - -protected: - void extractProperty(const TQByteArray& b) - // this is called for Policy[Dirty|Local] after putting the stuff into the - // stream - { - TQDataStream s(b, IO_ReadOnly); - int cmd; - int propId; - KGameMessage::extractPropertyHeader(s, propId); - KGameMessage::extractPropertyCommand(s, propId, cmd); - command(s, cmd, true); - } - -}; - -#endif diff --git a/libkdegames/kgame/kgamesequence.cpp b/libkdegames/kgame/kgamesequence.cpp deleted file mode 100644 index 9391ee04..00000000 --- a/libkdegames/kgame/kgamesequence.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2003 Andreas Beckermann ([email protected]) - Copyright (C) 2003 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - -#include "kgamesequence.h" -#include "kgamesequence.moc" - -#include "kplayer.h" -#include "kgame.h" - -KGameSequence::KGameSequence() : TQObject() -{ - mGame = 0; - mCurrentPlayer = 0; -} - -KGameSequence::~KGameSequence() -{ -} - -void KGameSequence::setGame(KGame* game) -{ - mGame = game; -} - -void KGameSequence::setCurrentPlayer(KPlayer* player) -{ - mCurrentPlayer = player; -} - -KPlayer *KGameSequence::nextPlayer(KPlayer *last,bool exclusive) -{ - kdDebug(11001) << "=================== NEXT PLAYER =========================="<<endl; - if (!game()) - { - kdError() << k_funcinfo << "NULL game object" << endl; - return 0; - } - unsigned int minId,nextId,lastId; - KPlayer *nextplayer, *minplayer; - if (last) - { - lastId = last->id(); - } - else - { - lastId = 0; - } - - kdDebug(11001) << "nextPlayer: lastId="<<lastId<<endl; - - // remove when this has been checked - minId = 0x7fff; // we just need a very large number...properly MAX_UINT or so would be ok... - nextId = minId; - nextplayer = 0; - minplayer = 0; - - KPlayer *player; - for (player = game()->playerList()->first(); player != 0; player=game()->playerList()->next() ) - { - // Find the first player for a cycle - if (player->id() < minId) - { - minId=player->id(); - minplayer=player; - } - if (player==last) - { - continue; - } - // Find the next player which is bigger than the current one - if (player->id() > lastId && player->id() < nextId) - { - nextId=player->id(); - nextplayer=player; - } - } - - // Cycle to the beginning - if (!nextplayer) - { - nextplayer=minplayer; - } - - kdDebug(11001) << k_funcinfo << " ##### lastId=" << lastId << " exclusive=" - << exclusive << " minId=" << minId << " nextid=" << nextId - << " count=" << game()->playerList()->count() << endl; - if (nextplayer) - { - nextplayer->setTurn(true,exclusive); - } - else - { - return 0; - } - return nextplayer; -} - -// Per default we do not do anything -int KGameSequence::checkGameOver(KPlayer*) -{ - return 0; -} -/* - * vim: et sw=2 - */ diff --git a/libkdegames/kgame/kgamesequence.h b/libkdegames/kgame/kgamesequence.h deleted file mode 100644 index 8047c642..00000000 --- a/libkdegames/kgame/kgamesequence.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2003 Andreas Beckermann ([email protected]) - Copyright (C) 2003 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMESEQUENCE_H_ -#define __KGAMESEQUENCE_H_ - -#include <tqobject.h> - -class KPlayer; -class KGame; - -/** - * This class takes care of round or move management as well of the gameover - * condition. It is especially used for round based games. For these games @ref - * nextPlayer and @ref checkGameOver are the most important methods. - * - * You can subclass KGameSequence and use @ref KGame::setGameSequence to use - * your own rules. Note that @ref KGame will take ownership and therefore will - * delete the object on destruction. - * @short Round/move management class - * @author Andreas Beckermann <[email protected]> - **/ -class KGameSequence : public TQObject -{ - Q_OBJECT - TQ_OBJECT -public: - KGameSequence(); - virtual ~KGameSequence(); - - /** - * Select the next player in a turn based game. In an asynchronous game this - * function has no meaning. Overwrite this function for your own game sequence. - * Per default it selects the next player in the playerList - */ - virtual KPlayer* nextPlayer(KPlayer *last, bool exclusive = true); - - virtual void setCurrentPlayer(KPlayer* p); - - /** - * @return The @ref KGame object this sequence is for, or NULL if none. - **/ - KGame* game() const { return mGame; } - - KPlayer* currentPlayer() const { return mCurrentPlayer; } - - /** - * Set the @ref KGame object for this sequence. This is called - * automatically by @ref KGame::setGameSequence and you should not call - * it. - **/ - void setGame(KGame* game); - - /** - * Check whether the game is over. The default implementation always - * returns 0. - * - * @param player the player who made the last move - * @return anything else but 0 is considered as game over - **/ - virtual int checkGameOver(KPlayer *player); - -private: - KGame* mGame; - KPlayer* mCurrentPlayer; -}; - -#endif - diff --git a/libkdegames/kgame/kgameversion.h b/libkdegames/kgame/kgameversion.h deleted file mode 100644 index c3147525..00000000 --- a/libkdegames/kgame/kgameversion.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2003 Andreas Beckermann ([email protected]) - Copyright (C) 2003 Martin Heni ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ -#ifndef __KGAMEVERSION_H__ -#define __KGAMEVERSION_H__ - -/** - * In this file you find a couple of defines that indicate whether a specific - * feature or function is present in this version of the KGame library. - * - * You don't need this for KDE CVS, but for games that live outside of KDE CVS - * it may be very helpful and a lot easier than writing configure scripts for - * this task. - * - * All defines are prefixed with KGAME_ to avoid conflicts. - **/ - -// KGame::savegame() didn't exist in KDE 3.0 -#define KGAME_HAVE_KGAME_SAVEGAME 1 - -// KGameNetwork::port(), KMessageIO::peerPort() and friends were added in KDE 3.2 -#define KGAME_HAVE_KGAME_PORT 1 - -// KGameNetwork::hostName(), KMessageIO::peerName() and friends were added in KDE 3.2 -#define KGAME_HAVE_KGAME_HOSTNAME 1 - -// KGameSequence class was added in KDE 3.2 -#define KGAME_HAVE_KGAMESEQUENCE 1 - -// KGame::addPlayer() needs to assign an ID to new players, otherwise network is -// broken. this is done in KDE 3.2. -#define KGAME_HAVE_FIXED_ADDPLAYER_ID 1 - -#endif - diff --git a/libkdegames/kgame/kmessageclient.cpp b/libkdegames/kgame/kmessageclient.cpp deleted file mode 100644 index 0233884a..00000000 --- a/libkdegames/kgame/kmessageclient.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 <kdebug.h> -#include <stdio.h> - -#include <tqbuffer.h> -#include <tqtimer.h> - -#include "kmessageio.h" -#include "kmessageserver.h" - -#include "kmessageclient.h" - -class KMessageClientPrivate -{ -public: - KMessageClientPrivate () - : adminID (0), connection (0) - {} - - ~KMessageClientPrivate () - { - delete connection; - } - - TQ_UINT32 adminID; - TQValueList <TQ_UINT32> clientList; - KMessageIO *connection; - - bool isLocked; - TQValueList <TQByteArray> delayedMessages; -}; - -KMessageClient::KMessageClient (TQObject *parent, const char *name) - : TQObject (parent, name) -{ - d = new KMessageClientPrivate (); - d->isLocked = false; -} - -KMessageClient::~KMessageClient () -{ - d->delayedMessages.clear(); - delete d; -} - -// -- setServer stuff - -void KMessageClient::setServer (const TQString &host, TQ_UINT16 port) -{ - setServer (new KMessageSocket (host, port)); -} - -void KMessageClient::setServer (KMessageServer *server) -{ - KMessageDirect *serverIO = new KMessageDirect (); - setServer (new KMessageDirect (serverIO)); - server->addClient (serverIO); -} - -void KMessageClient::setServer (KMessageIO *connection) -{ - if (d->connection) - { - delete d->connection; - kdDebug (11001) << k_funcinfo << ": We are changing the server!" << endl; - } - - d->connection = connection; - if (connection ) - { - connect (connection, TQT_SIGNAL (received(const TQByteArray &)), - this, TQT_SLOT (processIncomingMessage(const TQByteArray &))); - connect (connection, TQT_SIGNAL (connectionBroken()), - this, TQT_SLOT (removeBrokenConnection ())); - } -} - -// -- id stuff - -TQ_UINT32 KMessageClient::id () const -{ - return (d->connection) ? d->connection->id () : 0; -} - -bool KMessageClient::isAdmin () const -{ - return id() != 0 && id() == adminId(); -} - -TQ_UINT32 KMessageClient::adminId () const -{ - return d->adminID; -} - -const TQValueList <TQ_UINT32> &KMessageClient::clientList() const -{ - return d->clientList; -} - -bool KMessageClient::isConnected () const -{ - return d->connection && d->connection->isConnected(); -} - -bool KMessageClient::isNetwork () const -{ - return isConnected() ? d->connection->isNetwork() : false; -} - -TQ_UINT16 KMessageClient::peerPort () const -{ - return d->connection ? d->connection->peerPort() : 0; -} - -TQString KMessageClient::peerName () const -{ - return d->connection ? d->connection->peerName() : TQString::tqfromLatin1("localhost"); -} - -// --------------------- Sending messages - -void KMessageClient::sendServerMessage (const TQByteArray &msg) -{ - if (!d->connection) - { - kdWarning (11001) << k_funcinfo << ": We have no connection yet!" << endl; - return; - } - d->connection->send (msg); -} - -void KMessageClient::sendBroadcast (const TQByteArray &msg) -{ - TQByteArray sendBuffer; - TQBuffer buffer (sendBuffer); - buffer.open (IO_WriteOnly); - TQDataStream stream (&buffer); - - stream << static_cast<TQ_UINT32> ( KMessageServer::RETQ_BROADCAST ); - TQT_TQIODEVICE(&buffer)->writeBlock (msg); - sendServerMessage (sendBuffer); -} - -void KMessageClient::sendForward (const TQByteArray &msg, const TQValueList <TQ_UINT32> &clients) -{ - TQByteArray sendBuffer; - TQBuffer buffer (sendBuffer); - buffer.open (IO_WriteOnly); - TQDataStream stream (&buffer); - - stream << static_cast<TQ_UINT32>( KMessageServer::RETQ_FORWARD ) << clients; - TQT_TQIODEVICE(&buffer)->writeBlock (msg); - sendServerMessage (sendBuffer); -} - -void KMessageClient::sendForward (const TQByteArray &msg, TQ_UINT32 client) -{ - sendForward (msg, TQValueList <TQ_UINT32> () << client); -} - - -// --------------------- Receiving and processing messages - -void KMessageClient::processIncomingMessage (const TQByteArray &msg) -{ - if (d->isLocked) - { - d->delayedMessages.append(msg); - return; - } - if (d->delayedMessages.count() > 0) - { - d->delayedMessages.append (msg); - TQByteArray first = d->delayedMessages.front(); - d->delayedMessages.pop_front(); - processMessage (first); - } - else - { - processMessage(msg); - } -} - -void KMessageClient::processMessage (const TQByteArray &msg) -{ - if (d->isLocked) - { // must NOT happen, since we check in processIncomingMessage as well as in processFirstMessage - d->delayedMessages.append(msg); - return; - } - TQBuffer in_buffer (msg); - in_buffer.open (IO_ReadOnly); - TQDataStream in_stream (&in_buffer); - - - bool unknown = false; - - TQ_UINT32 messageID; - in_stream >> messageID; - switch (messageID) - { - case KMessageServer::MSG_BROADCAST: - { - TQ_UINT32 clientID; - in_stream >> clientID; - emit broadcastReceived (in_buffer.readAll(), clientID); - } - break; - - case KMessageServer::MSG_FORWARD: - { - TQ_UINT32 clientID; - TQValueList <TQ_UINT32> tqreceivers; - in_stream >> clientID >> tqreceivers; - emit forwardReceived (in_buffer.readAll(), clientID, tqreceivers); - } - break; - - case KMessageServer::ANS_CLIENT_ID: - { - bool old_admin = isAdmin(); - TQ_UINT32 clientID; - in_stream >> clientID; - d->connection->setId (clientID); - if (old_admin != isAdmin()) - emit adminStatusChanged (isAdmin()); - } - break; - - case KMessageServer::ANS_ADMIN_ID: - { - bool old_admin = isAdmin(); - in_stream >> d->adminID; - if (old_admin != isAdmin()) - emit adminStatusChanged (isAdmin()); - } - break; - - case KMessageServer::ANS_CLIENT_LIST: - { - in_stream >> d->clientList; - } - break; - - case KMessageServer::EVNT_CLIENT_CONNECTED: - { - TQ_UINT32 id; - in_stream >> id; - - if (d->clientList.contains (id)) - kdWarning (11001) << k_funcinfo << ": Adding a client that already existed!" << endl; - else - d->clientList.append (id); - - emit eventClientConnected (id); - } - break; - - case KMessageServer::EVNT_CLIENT_DISCONNECTED: - { - TQ_UINT32 id; - TQ_INT8 broken; - in_stream >> id >> broken; - - if (!d->clientList.contains (id)) - kdWarning (11001) << k_funcinfo << ": Removing a client that doesn't exist!" << endl; - else - d->clientList.remove (id); - - emit eventClientDisconnected (id, bool (broken)); - } - break; - - default: - unknown = true; - } - - if (!unknown && !in_buffer.atEnd()) - kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl; - - emit serverMessageReceived (msg, unknown); - - if (unknown) - kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl; -} - -void KMessageClient::processFirstMessage() -{ - if (d->isLocked) - { - return; - } - if (d->delayedMessages.count() == 0) - { - kdDebug(11001) << k_funcinfo << ": no messages delayed" << endl; - return; - } - TQByteArray first = d->delayedMessages.front(); - d->delayedMessages.pop_front(); - processMessage (first); -} - -void KMessageClient::removeBrokenConnection () -{ - kdDebug (11001) << k_funcinfo << ": timer single shot for removeBrokenConnection"<<this << endl; - // MH We cannot directly delete the socket. otherwise TQSocket crashes - TQTimer::singleShot( 0, this, TQT_SLOT(removeBrokenConnection2()) ); - return; -} - - -void KMessageClient::removeBrokenConnection2 () -{ - kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object"<<this << endl; - - emit aboutToDisconnect(id()); - delete d->connection; - d->connection = 0; - d->adminID = 0; - emit connectionBroken(); - kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object DONE" << endl; -} - -void KMessageClient::disconnect () -{ - kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object" << endl; - - emit aboutToDisconnect(id()); - delete d->connection; - d->connection = 0; - d->adminID = 0; - emit connectionBroken(); - kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object DONE" << endl; -} - -void KMessageClient::lock () -{ - d->isLocked = true; -} - -void KMessageClient::unlock () -{ - d->isLocked = false; - for (unsigned int i = 0; i < d->delayedMessages.count(); i++) - { - TQTimer::singleShot(0, this, TQT_SLOT(processFirstMessage())); - } -} - -unsigned int KMessageClient::delayedMessageCount() const -{ - return d->delayedMessages.count(); -} - -#include "kmessageclient.moc" diff --git a/libkdegames/kgame/kmessageclient.h b/libkdegames/kgame/kmessageclient.h deleted file mode 100644 index 8a35234d..00000000 --- a/libkdegames/kgame/kmessageclient.h +++ /dev/null @@ -1,423 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KMESSAGECLIENT_H__ -#define __KMESSAGECLIENT_H__ - -#include <tqobject.h> -#include <tqstring.h> -#include <tqvaluelist.h> - -class KMessageIO; -class KMessageServer; -class KMessageClientPrivate; - -/** - @short A client to connect to a KMessageServer - - This class implements a client that can connect to a KMessageServer object. - It can be used to exchange messages between clients. - - Usually you will connect the signals broadcastReceived and forwardReceived to - some specific slots. In these slot methods you can analyse the messages that are - sent to you from other clients. - - To send messages to other clients, use the methods sendBroadcast() (to send to all - clients) or sendForward() (to send to a list of selected clients). - - If you want to communicate with the KMessageServer object directly (on a more low - level base), use the method sendServerMessage to send a command to the server and - connect to the signal serverMessageReceived to see all the incoming messages. - In that case the messages must be of the format specified in KMessageServer. - @author Burkhard Lehner <[email protected]> -*/ -class KMessageClient : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - - /** - Constructor. - Creates an unconnected KMessageClient object. Use setServer() later to connect to a - KMessageServer object. - */ - KMessageClient (TQObject *parent = 0, const char *name = 0); - - /** - Destructor. - Disconnects from the server, if any connection was established. - */ - ~KMessageClient (); - - /** - @return The client ID of this client. Every client that is connected to a KMessageServer - has a unique ID number. - - NOTE: As long as the object is not yet connected to the server, and as long as the server - hasn't sent the client ID, this method returns 0. - */ - TQ_UINT32 id () const; - - /** - @return Whether or not this client is the server admin. - One of the clients connected to the server is the admin and can administrate the server - (set maximum number of clients, remove clients, ...). - - If you use admin commands without being the admin, these commands are simply ignored by - the server. - - NOTE: As long as you are not connected to a server, this method returns false. - */ - bool isAdmin () const; - - /** - @return The ID of the admin client on the message server. - */ - TQ_UINT32 adminId() const; - - /** - @return The list of the IDs of all the message clients connected to the message server. - */ - const TQValueList <TQ_UINT32> &clientList() const; - - /** - Connects the client to (another) server. - - Tries to connect via a TCP/IP socket to a KMessageServer object - on the given host, listening on the specified port. - - If we were already connected, the old connection is closed. - @param host The name of the host to connect to. Must be either a hostname which can - be resolved to an IP or just an IP - @param port The port to connect to - */ - void setServer (const TQString &host, TQ_UINT16 port); - - /** - Connects the client to (another) server. - - Connects to the given server, using KMessageDirect. - (The server object has to be in the same process.) - - If we were already connected, the old connection is closed. - @param server The KMessageServer to connect to - */ - void setServer (KMessageServer *server); - - /** - * Corresponds to setServer(0); but also emits the connectionBroken signal - **/ - void disconnect(); - - /** - Connects the client to (another) server. - - To use this method, you have to create a KMessageIO object with new (indeed you must - create an instance of a subclass of KMessageIO, e.g. KMessageSocket or KMessageDirect). - This object must already be connected to the new server. - - Calling this method disconnects any earlier connection, and uses the new KMessageIO - object instead. This object gets owned by the KMessageClient object, so don't delete - or manipulate it afterwards. - - With this method it is possible to change the server on the fly. But be careful that - there are no important messages from the old server not yet delivered. - - NOTE: It is very likely that we will have another client ID on the new server. The - value returned by clientID may be a little outdated until the new server tells us - our new ID. - - NOTE: The two other setServer methods are for convenience. If you use them, you don't - have to create a KMessageIO object yourself. - */ - virtual void setServer (KMessageIO *connection); - - /** - @return True, if a connection to a KMessageServer has been started, and if the - connection is ready for transferring data. (It will return false e.g. as long as - a socket connection hasn't been established, and it will also return false after - a socket connection is broken.) - */ - bool isConnected () const; - - /** - @return TRUE if isConnected() is true AND this is not a local (like - KMessageDirect) connection. - */ - bool isNetwork () const; - - /** - @return 0 if isConnected() is FALSE, otherwise the port number this client is - connected to. See also KMessageIO::peerPort and TQSocket::peerPort. - @since 3.2 - */ - TQ_UINT16 peerPort () const; - - /** - @since 3.2 - @return "localhost" if isConnected() is FALSE, otherwise the hostname this client is - connected to. See also KMessageIO::peerName() and TQSocket::peerName(). - */ - TQString peerName() const; - - /** - Sends a message to the KMessageServer. If we are not yet connected to one, nothing - happens. - - Use this method to send a low level command to the server. It has to be in the - format specified in KMessageServer. - - If you want to send messages to other clients, you should use sendBroadcast() - and sendForward(). - @param msg The message to be sent to the server. Must be in the format specified in KMessageServer. - */ - void sendServerMessage (const TQByteArray &msg); - - /** - Sends a message to all the clients connected to the server, including ourself. - The message consists of an arbitrary block of data with arbitrary length. - - All the clients will receive an exact copy of this block of data, which will be - processed in their processBroadcast() method. - @param msg The message to be sent to the clients - */ - //AB: processBroadcast doesn't exist!! is processIncomingMessage meant? - void sendBroadcast (const TQByteArray &msg); - - /** - Sends a message to all the clients in a list. - The message consists of an arbitrary block of data with arbitrary length. - - All clients will receive an exact copy of this block of data, which will be - processed in their processForward() method. - - If the list contains client IDs that are not defined, they are ignored. If - it contains an ID several times, that client will receive the message several - times. - - To send a message to the admin of the KMessageServer, you can use 0 as clientID, - instead of using the real client ID. - @param msg The message to be sent to the clients - @param clients A list of clients the message should be sent to - */ - //AB: processForward doesn't exist!! is processIncomingMessage meant? - void sendForward (const TQByteArray &msg, const TQValueList <TQ_UINT32> &clients); - - /** - Sends a message to a single client. This is a convenieance method. It calls - sendForward (const TQByteArray &msg, const TQValueList <TQ_UINT32> &clients) - with a list containing only one client ID. - - To send a message to the admin of the KMessageServer, you can use 0 as clientID, - instead of using the real client ID. - @param msg The message to be sent to the client - @param client The id of the client the message shall be sent to - */ - void sendForward (const TQByteArray &msg, TQ_UINT32 client); - - /** - Once this function is called no message will be received anymore. - processIncomingMessage() gets delayed until unlock() is called. - - Note that all messages are still received, but their delivery (like - broadcastReceived()) get delayed only. - */ - void lock(); - - /** - Deliver every message that was delayed by lock() and actually deliver - all messages that get received from now on. - */ - void unlock(); - - /** - @return The number of messages that got delayed since lock() was called - */ - unsigned int delayedMessageCount() const; - -signals: - /** - This signal is emitted when the client receives a broadcast message from the - KMessageServer, sent by another client. Connect to this signal to analyse the - received message and do the right reaction. - - senderID contains the ID of the client that sent the broadcast message. You can - use this e.g. to send a reply message to only that client. Or you can use it - to ignore broadcast messages that were sent by yourself: - - \code - void myObject::myBroadcastSlot (const TQByteArray &msg, TQ_UINT32 senderID) - { - if (senderID == ((KMessageClient *)sender())->id()) - return; - ... - } - \endcode - @param msg The message that has been sent to us - @param senderID The ID of the client which sent the message - */ - void broadcastReceived (const TQByteArray &msg, TQ_UINT32 senderID); - - /** - This signal is emitted when the client receives a forward message from the - KMessageServer, sent by another client. Connect to this signal to analyse the - received message and do the right reaction. - - senderID contains the ID of the client that sent the broadcast message. You can - use this e.g. to send a reply message to only that client. - - tqreceivers contains the list of the clients that got the message. (If this list - only contains one number, this will be your client ID, and it was exclusivly - sent to you.) - - If you don't want to distinguish between broadcast and forward messages and - treat them the same, you can connect forwardReceived signal to the - broadcastReceived signal. (Yes, that's possible! You can connect a TQt signal to - a TQt signal, and the second one can have less parameters.) - - \code - KMessageClient *client = new KMessageClient (); - connect (client, TQT_SIGNAL (forwardReceived (const TQByteArray &, TQ_UINT32, const TQValueList <TQ_UINT32>&)), - client, TQT_SIGNAL (broadcastReceived (const TQByteArray &, TQ_UINT32))); - \endcode - - Then connect the broadcast signal to your slot that analyzes the message. - @param msg The message that has been sent to us - @param senderID The ID of the client which sent the message - @param tqreceivers All clients which receive this message - */ - void forwardReceived (const TQByteArray &msg, TQ_UINT32 senderID, const TQValueList <TQ_UINT32> &tqreceivers); - - /** - This signal is emitted when the connection to the KMessageServer is broken. - Reasons for this can be: a network error, a server breakdown, or you were just kicked - from the server. - - When this signal is sent, the connection is already lost and the client is unconnected. - You can connect to another server by calling setServer() afterwards. But keep in mind that - some important messages might have vanished. - */ - void connectionBroken (); - - /** - This signal is emitted right before the client disconnects. It can be used - to this store the id of the client which is about to be lost. - */ - void aboutToDisconnect(TQ_UINT32 id); - - /** - This signal is emitted when this client becomes the admin client or when it loses - the admin client status. Connect to this signal if you have to do any initialization - or cleanup. - @param isAdmin Whether we are now admin or not - */ - void adminStatusChanged (bool isAdmin); - - /** - This signal is emitted when another client has connected - to the server. Connect to this method if that clients needs initialization. - This should usually only be done in one client, e.g. the admin client. - @param clientID The ID of the client that has newly connectd. - */ - void eventClientConnected (TQ_UINT32 clientID); - - /** - This signal is emitted when the server has lost the - connection to one of the clients (This could be because of a bad internet connection - or because the client disconnected on purpose). - @param clientID The ID of the client that has disconnected - @param broken true if it was disconnected because of a network error - */ - void eventClientDisconnected (TQ_UINT32 clientID, bool broken); - - /** - This signal is emitted on every message that came from the server. You can connect to this - signal to see the messages directly. They are in the format specified in KMessageServer. - - @param msg The message that has been sent to us - @param unknown True when KMessageClient didn't recognize the message, i.e. it contained an unknown - message ID. If you want to add additional message types to the client, connect to this signal, - and if unknown is true, analyse the message by yourself. If you recognized the message, - set unknown to false (Otherwise a debug message will be printed). - */ - //AB: maybe add a setNoEmit() so that the other signals can be deactivated? - //Could be a performance benefit (note: KMessageClient is a time critical - //class!!!) - void serverMessageReceived (const TQByteArray &msg, bool &unknown); - -protected: - /** - This slot is called from processIncomingMessage or - processFirstMessage, depending on whether the client is locked or a delayed - message is still here (see lock) - - It processes the message and analyses it. If it is a broadcast or a forward message from - another client, it emits the signal processBroadcast or processForward accordingly. - - If you want to treat additional server messages, you can overwrite this method. Don't - forget to call processIncomingMessage of your superclass! - - At the moment, the following server messages are interpreted: - - MSG_BROADCAST, MSG_FORWARD, ANS_CLIENT_ID, ANS_ADMIN_ID, ANS_CLIENT_LIST - @param msg The incoming message - */ - - virtual void processMessage (const TQByteArray& msg); - -protected slots: - /** - This slot is called from the signal KMessageIO::received whenever a message from the - KMessageServer arrives. - - It processes the message and analyses it. If it is a broadcast or a forward message from - another client, it emits the signal processBroadcast or processForward accordingly. - - If you want to treat additional server messages, you can overwrite this method. Don't - forget to call processIncomingMessage() of your superclass! - - At the moment, the following server messages are interpreted: - - MSG_BROADCAST, MSG_FORWARD, ANS_CLIENT_ID, ANS_ADMIN_ID, ANS_CLIENT_LIST - @param msg The incoming message - */ - virtual void processIncomingMessage (const TQByteArray &msg); - - /** - Called from unlock() (using TQTimer::singleShot) until all delayed - messages are delivered. - */ - void processFirstMessage(); - - /** - This slot is called from the signal KMessageIO::connectionBroken. - - It deletes the internal KMessageIO object, and resets the client to default - values. To connect again to another server, use setServer. - */ - virtual void removeBrokenConnection (); - void removeBrokenConnection2 (); - -private: - KMessageClientPrivate *d; -}; - -#endif diff --git a/libkdegames/kgame/kmessageio.cpp b/libkdegames/kgame/kmessageio.cpp deleted file mode 100644 index b35382b0..00000000 --- a/libkdegames/kgame/kmessageio.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ - -/* - KMessageIO class and subclasses KMessageSocket and KMessageDirect -*/ - -#include "kmessageio.h" -#include <tqsocket.h> -#include <kdebug.h> -#include <kprocess.h> -#include <tqfile.h> - -// ----------------------- KMessageIO ------------------------- - -KMessageIO::KMessageIO (TQObject *parent, const char *name) - : TQObject (parent, name), m_id (0) -{} - -KMessageIO::~KMessageIO () -{} - -void KMessageIO::setId (TQ_UINT32 id) -{ - m_id = id; -} - -TQ_UINT32 KMessageIO::id () -{ - return m_id; -} - -// ----------------------KMessageSocket ----------------------- - -KMessageSocket::KMessageSocket (TQString host, TQ_UINT16 port, TQObject *parent, -const char *name) - : KMessageIO (parent, name) -{ - mSocket = new TQSocket (); - mSocket->connectToHost (host, port); - initSocket (); -} - -KMessageSocket::KMessageSocket (TQHostAddress host, TQ_UINT16 port, TQObject -*parent, const char *name) - : KMessageIO (parent, name) -{ - mSocket = new TQSocket (); - mSocket->connectToHost (host.toString(), port); - initSocket (); -} - -KMessageSocket::KMessageSocket (TQSocket *socket, TQObject *parent, const char -*name) - : KMessageIO (parent, name) -{ - mSocket = socket; - initSocket (); -} - -KMessageSocket::KMessageSocket (int socketFD, TQObject *parent, const char -*name) - : KMessageIO (parent, name) -{ - mSocket = new TQSocket (); - mSocket->setSocket (socketFD); - initSocket (); -} - -KMessageSocket::~KMessageSocket () -{ - delete mSocket; -} - -bool KMessageSocket::isConnected () const -{ - return mSocket->state() == TQSocket::Connection; -} - -void KMessageSocket::send (const TQByteArray &msg) -{ - TQDataStream str (mSocket); - str << TQ_UINT8 ('M'); // magic number for begin of message - str.writeBytes (msg.data(), msg.size()); // writes the length (as TQ_UINT32) and the data -} - -void KMessageSocket::processNewData () -{ - if (isRecursive) - return; - isRecursive = true; - - TQDataStream str (mSocket); - while (mSocket->bytesAvailable() > 0) - { - if (mAwaitingHeader) - { - // Header = magic number + packet length = 5 bytes - if (mSocket->bytesAvailable() < 5) - { - isRecursive = false; - return; - } - - // Read the magic number first. If something unexpected is found, - // start over again, ignoring the data that was read up to then. - - TQ_UINT8 v; - str >> v; - if (v != 'M') - { - kdWarning(11001) << k_funcinfo << ": Received unexpected data, magic number wrong!" << endl; - continue; - } - - str >> mNextBlockLength; - mAwaitingHeader = false; - } - else - { - // Data not completely read => wait for more - if (mSocket->bytesAvailable() < (TQ_ULONG) mNextBlockLength) - { - isRecursive = false; - return; - } - - TQByteArray msg (mNextBlockLength); - str.readRawBytes (msg.data(), mNextBlockLength); - - // send the received message - emit received (msg); - - // Waiting for the header of the next message - mAwaitingHeader = true; - } - } - - isRecursive = false; -} - -void KMessageSocket::initSocket () -{ - connect (mSocket, TQT_SIGNAL (error(int)), TQT_SIGNAL (connectionBroken())); - connect (mSocket, TQT_SIGNAL (connectionClosed()), TQT_SIGNAL (connectionBroken())); - connect (mSocket, TQT_SIGNAL (readyRead()), TQT_SLOT (processNewData())); - mAwaitingHeader = true; - mNextBlockLength = 0; - isRecursive = false; -} - -TQ_UINT16 KMessageSocket::peerPort () const -{ - return mSocket->peerPort(); -} - -TQString KMessageSocket::peerName () const -{ - return mSocket->peerName(); -} - -// ----------------------KMessageDirect ----------------------- - -KMessageDirect::KMessageDirect (KMessageDirect *partner, TQObject *parent, -const char *name) - : KMessageIO (parent, name), mPartner (0) -{ - // 0 as first parameter leaves the object unconnected - if (!partner) - return; - - // Check if the other object is already connected - if (partner && partner->mPartner) - { - kdWarning(11001) << k_funcinfo << ": Object is already connected!" << endl; - return; - } - - // Connect from us to that object - mPartner = partner; - - // Connect the other object to us - partner->mPartner = this; -} - -KMessageDirect::~KMessageDirect () -{ - if (mPartner) - { - mPartner->mPartner = 0; - emit mPartner->connectionBroken(); - } -} - -bool KMessageDirect::isConnected () const -{ - return mPartner != 0; -} - -void KMessageDirect::send (const TQByteArray &msg) -{ - if (mPartner) - emit mPartner->received (msg); - else - kdError(11001) << k_funcinfo << ": Not yet connected!" << endl; -} - - -// ----------------------- KMessageProcess --------------------------- - -KMessageProcess::~KMessageProcess() -{ - kdDebug(11001) << "@@@KMessageProcess::Delete process" << endl; - if (mProcess) - { - mProcess->kill(); - delete mProcess; - mProcess=0; - // Remove not send buffers - mQueue.setAutoDelete(true); - mQueue.clear(); - // Maybe todo: delete mSendBuffer - } -} -KMessageProcess::KMessageProcess(TQObject *parent, TQString file) : KMessageIO(parent,0) -{ - // Start process - kdDebug(11001) << "@@@KMessageProcess::Start process" << endl; - mProcessName=file; - mProcess=new KProcess; - int id=0; - *mProcess << mProcessName << TQString("%1").tqarg(id); - kdDebug(11001) << "@@@KMessageProcess::Init:Id= " << id << endl; - kdDebug(11001) << "@@@KMessgeProcess::Init:Processname: " << mProcessName << endl; - connect(mProcess, TQT_SIGNAL(receivedStdout(KProcess *, char *, int )), - this, TQT_SLOT(slotReceivedStdout(KProcess *, char * , int ))); - connect(mProcess, TQT_SIGNAL(receivedStderr(KProcess *, char *, int )), - this, TQT_SLOT(slotReceivedStderr(KProcess *, char * , int ))); - connect(mProcess, TQT_SIGNAL(processExited(KProcess *)), - this, TQT_SLOT(slotProcessExited(KProcess *))); - connect(mProcess, TQT_SIGNAL(wroteStdin(KProcess *)), - this, TQT_SLOT(slotWroteStdin(KProcess *))); - mProcess->start(KProcess::NotifyOnExit,KProcess::All); - mSendBuffer=0; - mReceiveCount=0; - mReceiveBuffer.resize(1024); -} -bool KMessageProcess::isConnected() const -{ - kdDebug(11001) << "@@@KMessageProcess::Is conencted" << endl; - if (!mProcess) return false; - return mProcess->isRunning(); -} -void KMessageProcess::send(const TQByteArray &msg) -{ - kdDebug(11001) << "@@@KMessageProcess:: SEND("<<msg.size()<<") to process" << endl; - unsigned int size=msg.size()+2*sizeof(long); - - char *tmpbuffer=new char[size]; - long *p1=(long *)tmpbuffer; - long *p2=p1+1; - kdDebug(11001) << "p1="<<p1 << "p2="<< p2 << endl; - memcpy(tmpbuffer+2*sizeof(long),msg.data(),msg.size()); - *p1=0x4242aeae; - *p2=size; - - TQByteArray *buffer=new TQByteArray(); - buffer->assign(tmpbuffer,size); - // buffer->duplicate(msg); - mQueue.enqueue(buffer); - writeToProcess(); -} -void KMessageProcess::writeToProcess() -{ - // Previous send ok and item in queue - if (mSendBuffer || mQueue.isEmpty()) return ; - mSendBuffer=mQueue.dequeue(); - if (!mSendBuffer) return ; - - // write it out to the process - // kdDebug(11001) << " @@@@@@ writeToProcess::SEND to process " << mSendBuffer->size() << " BYTE " << endl; - // char *p=mSendBuffer->data(); - // for (int i=0;i<16;i++) printf("%02x ",(unsigned char)(*(p+i)));printf("\n"); - mProcess->writeStdin(mSendBuffer->data(),mSendBuffer->size()); - -} -void KMessageProcess::slotWroteStdin(KProcess * ) -{ - kdDebug(11001) << k_funcinfo << endl; - if (mSendBuffer) - { - delete mSendBuffer; - mSendBuffer=0; - } - writeToProcess(); -} - -void KMessageProcess::slotReceivedStderr(KProcess * proc, char *buffer, int buflen) -{ - int pid=0; - int len; - char *p; - char *pos; -// kdDebug(11001)<<"############# Got stderr " << buflen << " bytes" << endl; - - if (!buffer || buflen==0) return ; - if (proc) pid=proc->pid(); - - - pos=buffer; - do - { - p=(char *)memchr(pos,'\n',buflen); - if (!p) len=buflen; - else len=p-pos; - - TQByteArray a; - a.setRawData(pos,len); - TQString s(a); - kdDebug(11001) << "PID" <<pid<< ":" << s << endl; - a.resetRawData(pos,len); - if (p) pos=p+1; - buflen-=len+1; - }while(buflen>0); -} - - -void KMessageProcess::slotReceivedStdout(KProcess * , char *buffer, int buflen) -{ - kdDebug(11001) << "$$$$$$ " << k_funcinfo << ": Received " << buflen << " bytes over inter process communication" << endl; - - // TODO Make a plausibility check on buflen to avoid memory overflow - while (mReceiveCount+buflen>=mReceiveBuffer.size()) mReceiveBuffer.resize(mReceiveBuffer.size()+1024); - memcpy(mReceiveBuffer.data()+mReceiveCount,buffer,buflen); - mReceiveCount+=buflen; - - // Possbile message - while (mReceiveCount>2*sizeof(long)) - { - long *p1=(long *)mReceiveBuffer.data(); - long *p2=p1+1; - unsigned int len; - if (*p1!=0x4242aeae) - { - kdDebug(11001) << k_funcinfo << ": Cookie error...transmission failure...serious problem..." << endl; -// for (int i=0;i<mReceiveCount;i++) fprintf(stderr,"%02x ",mReceiveBuffer[i]);fprintf(stderr,"\n"); - } - len=(int)(*p2); - if (len<2*sizeof(long)) - { - kdDebug(11001) << k_funcinfo << ": Message size error" << endl; - break; - } - if (len<=mReceiveCount) - { - kdDebug(11001) << k_funcinfo << ": Got message with len " << len << endl; - - TQByteArray msg; - // msg.setRawData(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - msg.duplicate(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - emit received(msg); - // msg.resetRawData(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - // Shift buffer - if (len<mReceiveCount) - { - memmove(mReceiveBuffer.data(),mReceiveBuffer.data()+len,mReceiveCount-len); - } - mReceiveCount-=len; - } - else break; - } -} - -void KMessageProcess::slotProcessExited(KProcess * /*p*/) -{ - kdDebug(11001) << "Process exited (slot)" << endl; - emit connectionBroken(); - delete mProcess; - mProcess=0; -} - - -// ----------------------- KMessageFilePipe --------------------------- -KMessageFilePipe::KMessageFilePipe(TQObject *parent,TQFile *readfile,TQFile *writefile) : KMessageIO(parent,0) -{ - mReadFile=readfile; - mWriteFile=writefile; - mReceiveCount=0; - mReceiveBuffer.resize(1024); -} - -KMessageFilePipe::~KMessageFilePipe() -{ -} - -bool KMessageFilePipe::isConnected () const -{ - return (mReadFile!=0)&&(mWriteFile!=0); -} - -void KMessageFilePipe::send(const TQByteArray &msg) -{ - unsigned int size=msg.size()+2*sizeof(long); - - char *tmpbuffer=new char[size]; - long *p1=(long *)tmpbuffer; - long *p2=p1+1; - memcpy(tmpbuffer+2*sizeof(long),msg.data(),msg.size()); - *p1=0x4242aeae; - *p2=size; - - TQByteArray buffer; - buffer.assign(tmpbuffer,size); - mWriteFile->writeBlock(buffer); - mWriteFile->flush(); - /* - fprintf(stderr,"+++ KMessageFilePipe:: SEND(%d to parent) realsize=%d\n",msg.size(),buffer.size()); - for (int i=0;i<buffer.size();i++) fprintf(stderr,"%02x ",buffer[i]);fprintf(stderr,"\n"); - fflush(stderr); - */ -} - -void KMessageFilePipe::exec() -{ - - // According to BL: Blocking read is ok - // while(mReadFile->atEnd()) { usleep(100); } - - int ch=mReadFile->getch(); - - while (mReceiveCount>=mReceiveBuffer.size()) mReceiveBuffer.resize(mReceiveBuffer.size()+1024); - mReceiveBuffer[mReceiveCount]=(char)ch; - mReceiveCount++; - - // Change for message - if (mReceiveCount>=2*sizeof(long)) - { - long *p1=(long *)mReceiveBuffer.data(); - long *p2=p1+1; - unsigned int len; - if (*p1!=0x4242aeae) - { - fprintf(stderr,"KMessageFilePipe::exec:: Cookie error...transmission failure...serious problem...\n"); -// for (int i=0;i<16;i++) fprintf(stderr,"%02x ",mReceiveBuffer[i]);fprintf(stderr,"\n"); - } - len=(int)(*p2); - if (len==mReceiveCount) - { - //fprintf(stderr,"KMessageFilePipe::exec:: Got Message with len %d\n",len); - - TQByteArray msg; - //msg.setRawData(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - msg.duplicate(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - emit received(msg); - //msg.resetRawData(mReceiveBuffer.data()+2*sizeof(long),len-2*sizeof(long)); - mReceiveCount=0; - } - } - - - return ; - - -} - -#include "kmessageio.moc" diff --git a/libkdegames/kgame/kmessageio.h b/libkdegames/kgame/kmessageio.h deleted file mode 100644 index 326476ff..00000000 --- a/libkdegames/kgame/kmessageio.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ - -/* - KMessageIO class and subclasses KMessageSocket and KMessageDirect -*/ - -#ifndef _KMESSAGEIO_H_ -#define _KMESSAGEIO_H_ - -#include <tqcstring.h> -#include <tqhostaddress.h> -#include <tqobject.h> -#include <tqstring.h> -#include <tqptrqueue.h> -#include <tqfile.h> -#include <kdebug.h> - -class TQSocket; -class KProcess; -//class TQFile; - - -/** - This abstract base class represents one end of a message connections - between two clients. Each client has one object of a subclass of - KMessageIO. Calling /e send() on one object will emit the signal - /e received() on the other object, and vice versa. - - For each type of connection (TCP/IP socket, COM port, direct connection - within the same class) a subclass of KMessageIO must be defined that - implements the pure virtual methods /e send() and /e isConnected(), - and sends the signals. (See /e KMessageSocket for an example implementation.) - - Two subclasses are already included: /e KMessageSocket (connection using - TCP/IP sockets) and /e KMessageDirect (connection using method calls, both - sides must be within the same process). -*/ - -class KMessageIO : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * The usual TQObject constructor, does nothing else. - **/ - KMessageIO (TQObject *parent = 0, const char *name = 0); - - /** - * The usual destructor, does nothing special. - **/ - ~KMessageIO (); - - /** - * The runtime idendifcation - */ - virtual int rtti() const {return 0;} - - /** - * @return Whether this KMessageIO is a network IO or not. - **/ - //virtual bool isNetwork () const = 0; - virtual bool isNetwork () const - { - kdError(11001) << "Calling PURE virtual isNetwork...BAD" << endl; - return false; - } - - /** - This method returns the status of the object, whether it is already - (or still) connected to another KMessageIO object or not. - - This is a pure virtual method, so it has to be implemented in a subclass - of KMessageIO. - */ - //virtual bool isConnected () const = 0; - virtual bool isConnected () const - { - kdError(11001) << "Calling PURE virtual isConencted...BAD" << endl; - return false; - } - - /** - Sets the ID number of this object. This number can for example be used to - distinguish several objects in a server. - - NOTE: Sometimes it is useful to let two connected KMessageIO objects - have the same ID number. You have to do so yourself, KMessageIO doesn't - change this value on its own! - */ - void setId (TQ_UINT32 id); - - /** - Queries the ID of this object. - */ - TQ_UINT32 id (); - - /** - @since 3.2 - @return 0 in the default implementation. Reimplemented in @ref KMessageSocket. - */ - virtual TQ_UINT16 peerPort () const { return 0; } - - /** - @since 3.2 - @return "localhost" in the default implementation. Reimplemented in @ref KMessageSocket - */ - virtual TQString peerName () const { return TQString::tqfromLatin1("localhost"); } - - -signals: - /** - This signal is emitted when /e send() on the connected KMessageIO - object is called. The parameter contains the same data array in /e msg - as was used in /e send(). - */ - void received (const TQByteArray &msg); - - /** - This signal is emitted when the connection is closed. This can be caused - by a hardware error (e.g. broken internet connection) or because the other - object was killed. - - Note: Sometimes a broken connection can be undetected for a long time, - or may never be detected at all. So don't rely on this signal! - */ - void connectionBroken (); - -public slots: - - /** - This slot sends the data block in /e msg to the connected object, that will - emit /e received(). - - For a concrete class, you have to subclass /e KMessageIO and overwrite this - method. In the subclass, implement this method as an ordinary method, not - as a slot! (Otherwise another slot would be defined. It would work, but uses - more memory and time.) See /e KMessageSocket for an example implementation. - */ - virtual void send (const TQByteArray &msg) = 0; - -protected: - TQ_UINT32 m_id; -}; - - -/** - This class implements the message communication using a TCP/IP socket. The - object can connect to a server socket, or can use an already connected socket. -*/ - -class KMessageSocket : public KMessageIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - Connects to a server socket on /e host with /e port. host can be an - numerical (e.g. "192.168.0.212") or symbolic (e.g. "wave.peter.org") - IP address. You can immediately use the /e sendSystem() and - /e sendBroadcast() methods. The messages are stored and sent to the - receiver after the connection is established. - - If the connection could not be established (e.g. unknown host or no server - socket at this port), the signal /e connectionBroken is emitted. - */ - KMessageSocket (TQString host, TQ_UINT16 port, TQObject *parent = 0, - const char *name = 0); - - /** - Connects to a server socket on /e host with /e port. You can immediately - use the /e sendSystem() and /e sendBroadcast() methods. The messages are - stored and sent to the receiver after the connection is established. - - If the connection could not be established (e.g. unknown host or no server - socket at this port), the signal /e connectionBroken is emitted. - */ - KMessageSocket (TQHostAddress host, TQ_UINT16 port, TQObject *parent = 0, - const char *name = 0); - - /** - Uses /e socket to do the communication. - - The socket should already be connected, or at least be in /e connecting - state. - - Note: The /e socket object is then owned by the /e KMessageSocket object. - So don't use it otherwise any more and don't delete it. It is deleted - together with this KMessageSocket object. (Use 0 as parent for the TQSocket - object t ensure it is not deleted.) - */ - KMessageSocket (TQSocket *socket, TQObject *parent = 0, const char *name = 0); - - /** - Uses the socket specified by the socket descriptor socketFD to do the - communication. The socket must already be connected. - - This constructor can be used with a TQServerSocket within the (pure - virtual) method /e newConnection. - - Note: The socket is then owned by the /e KMessageSocket object. So don't - manipulate the socket afterwards, especially don't close it. The socket is - automatically closed when KMessageSocket is deleted. - */ - KMessageSocket (int socketFD, TQObject *parent = 0, const char *name = 0); - - /** - Destructor, closes the socket. - */ - ~KMessageSocket (); - - /** - * The runtime idendifcation - */ - virtual int rtti() const {return 1;} - - /** - @since 3.2 - @return The port that this object is connected to. See TQSocket::peerPort - */ - virtual TQ_UINT16 peerPort () const; - - /** - @since 3.2 - @return The hostname this object is connected to. See TQSocket::peerName. - */ - virtual TQString peerName () const; - - /** - @return TRUE as this is a network IO. - */ - bool isNetwork() const { return true; } - - /** - Returns true if the socket is in state /e connected. - */ - bool isConnected () const; - - /** - Overwritten slot method from KMessageIO. - - Note: It is not declared as a slot method, since the slot is already - defined in KMessageIO as a virtual method. - */ - void send (const TQByteArray &msg); - -protected slots: - virtual void processNewData (); - -protected: - void initSocket (); - TQSocket *mSocket; - bool mAwaitingHeader; - TQ_UINT32 mNextBlockLength; - - bool isRecursive; // workaround for "bug" in TQSocket, TQt 2.2.3 or older -}; - - -/** - This class implements the message communication using function calls - directly. It can only be used when both sides of the message pipe are - within the same process. The communication is very fast. - - To establish a communication, you have to create two instances of - KMessageDirect, the first one with no parameters in the constructor, - the second one with the first as parameter: - - /code - KMessageDirect *peer1, *peer2; - peer1 = new KMessageDirect (); // unconnected - peer2 = new KMessageDirect (peer1); // connect with peer1 - /endcode - - The connection is only closed when one of the instances is deleted. -*/ - -class KMessageDirect : public KMessageIO -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - Creates an object and connects it to the object given in the first - parameter. Use 0 as first parameter to create an unconnected object, - that is later connected. - - If that object is already connected, the object remains unconnected. - */ - KMessageDirect (KMessageDirect *partner = 0, TQObject *parent = 0, const char -*name = 0); - - /** - Destructor, closes the connection. - */ - ~KMessageDirect (); - - /** - * The runtime idendifcation - */ - virtual int rtti() const {return 2;} - - - /** - @return FALSE as this is no network IO. - */ - bool isNetwork() const { return false; } - - /** - Returns true, if the object is connected to another instance. - - If you use the first constructor, the object is unconnected unless another - object is created with this one as parameter. - - The connection can only be closed by deleting one of the objects. - */ - bool isConnected () const; - - /** - Overwritten slot method from KMessageIO. - - Note: It is not declared as a slot method, since the slot is already - defined in KMessageIO as a virtual method. - */ - void send (const TQByteArray &msg); - -protected: - KMessageDirect *mPartner; -}; - -class KMessageProcess : public KMessageIO -{ - Q_OBJECT - TQ_OBJECT - - public: - KMessageProcess(TQObject *parent, TQString file); - ~KMessageProcess(); - bool isConnected() const; - void send (const TQByteArray &msg); - void writeToProcess(); - - /** - @return FALSE as this is no network IO. - */ - bool isNetwork() const { return false; } - - /** - * The runtime idendifcation - */ - virtual int rtti() const {return 3;} - - - - public slots: - void slotReceivedStdout(KProcess *proc, char *buffer, int buflen); - void slotReceivedStderr(KProcess *proc, char *buffer, int buflen); - void slotProcessExited(KProcess *p); - void slotWroteStdin(KProcess *p); - - private: - TQString mProcessName; - KProcess *mProcess; - TQPtrQueue <TQByteArray> mQueue; - TQByteArray *mSendBuffer; - TQByteArray mReceiveBuffer; - unsigned int mReceiveCount; -}; - -class KMessageFilePipe : public KMessageIO -{ - Q_OBJECT - TQ_OBJECT - - public: - KMessageFilePipe(TQObject *parent,TQFile *readFile,TQFile *writeFile); - ~KMessageFilePipe(); - bool isConnected() const; - void send (const TQByteArray &msg); - void exec(); - - /** - @return FALSE as this is no network IO. - */ - bool isNetwork() const { return false; } - - /** - * The runtime idendifcation - */ - virtual int rtti() const {return 4;} - - - - private: - TQFile *mReadFile; - TQFile *mWriteFile; - TQByteArray mReceiveBuffer; - unsigned int mReceiveCount; -}; - -#endif diff --git a/libkdegames/kgame/kmessageserver.cpp b/libkdegames/kgame/kmessageserver.cpp deleted file mode 100644 index 80df9207..00000000 --- a/libkdegames/kgame/kmessageserver.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 <tqiodevice.h> -#include <tqbuffer.h> -#include <tqptrlist.h> -#include <tqptrqueue.h> -#include <tqtimer.h> -#include <tqvaluelist.h> - -#include <kdebug.h> - -#include "kmessageio.h" -#include "kmessageserver.h" - -// --------------- internal class KMessageServerSocket - -KMessageServerSocket::KMessageServerSocket (TQ_UINT16 port, TQObject *parent) - : TQServerSocket (port, 0, parent) -{ -} - -KMessageServerSocket::~KMessageServerSocket () -{ -} - -void KMessageServerSocket::newConnection (int socket) -{ - emit newClientConnected (new KMessageSocket (socket)); -} - -// ---------------- class for storing an incoming message - -class MessageBuffer -{ - public: - MessageBuffer (TQ_UINT32 clientID, const TQByteArray &messageData) - : id (clientID), data (messageData) { } - ~MessageBuffer () {} - TQ_UINT32 id; - TQByteArray data; -}; - -// ---------------- KMessageServer's private class - -class KMessageServerPrivate -{ -public: - KMessageServerPrivate() - : mMaxClients (-1), mGameId (1), mUniqueClientNumber (1), mAdminID (0), mServerSocket (0) - { - mClientList.setAutoDelete (true); - mMessageQueue.setAutoDelete (true); - } - - int mMaxClients; - int mGameId; - TQ_UINT16 mCookie; - TQ_UINT32 mUniqueClientNumber; - TQ_UINT32 mAdminID; - - KMessageServerSocket* mServerSocket; - - TQPtrList <KMessageIO> mClientList; - TQPtrQueue <MessageBuffer> mMessageQueue; - TQTimer mTimer; - bool mIsRecursive; -}; - - -// ------------------ KMessageServer - -KMessageServer::KMessageServer (TQ_UINT16 cookie,TQObject* parent) - : TQObject(parent, 0) -{ - d = new KMessageServerPrivate; - d->mIsRecursive=false; - d->mCookie=cookie; - connect (&(d->mTimer), TQT_SIGNAL (timeout()), - this, TQT_SLOT (processOneMessage())); - kdDebug(11001) << "CREATE(KMessageServer=" - << this - << ") cookie=" - << d->mCookie - << " sizeof(this)=" - << sizeof(KMessageServer) - << endl; -} - -KMessageServer::~KMessageServer() -{ - kdDebug(11001) << k_funcinfo << "this=" << this << endl; - Debug(); - stopNetwork(); - deleteClients(); - delete d; - kdDebug(11001) << k_funcinfo << " done" << endl; -} - -//------------------------------------- TCP/IP server stuff - -bool KMessageServer::initNetwork (TQ_UINT16 port) -{ - kdDebug(11001) << k_funcinfo << endl; - - if (d->mServerSocket) - { - kdDebug (11001) << k_funcinfo << ": We were already offering connections!" << endl; - delete d->mServerSocket; - } - - d->mServerSocket = new KMessageServerSocket (port); - d->mIsRecursive = false; - - if (!d->mServerSocket || !d->mServerSocket->ok()) - { - kdError(11001) << k_funcinfo << ": Serversocket::ok() == false" << endl; - delete d->mServerSocket; - d->mServerSocket=0; - return false; - } - - kdDebug (11001) << k_funcinfo << ": Now listening to port " - << d->mServerSocket->port() << endl; - connect (d->mServerSocket, TQT_SIGNAL (newClientConnected (KMessageIO*)), - this, TQT_SLOT (addClient (KMessageIO*))); - return true; -} - -TQ_UINT16 KMessageServer::serverPort () const -{ - if (d->mServerSocket) - return d->mServerSocket->port(); - else - return 0; -} - -void KMessageServer::stopNetwork() -{ - if (d->mServerSocket) - { - delete d->mServerSocket; - d->mServerSocket = 0; - } -} - -bool KMessageServer::isOfferingConnections() const -{ - return d->mServerSocket != 0; -} - -//----------------------------------------------- adding / removing clients - -void KMessageServer::addClient (KMessageIO* client) -{ - TQByteArray msg; - - // maximum number of clients reached? - if (d->mMaxClients >= 0 && d->mMaxClients <= clientCount()) - { - kdError (11001) << k_funcinfo << ": Maximum number of clients reached!" << endl; - return; - } - - // give it a unique ID - client->setId (uniqueClientNumber()); - kdDebug (11001) << k_funcinfo << ": " << client->id() << endl; - - // connect its signals - connect (client, TQT_SIGNAL (connectionBroken()), - this, TQT_SLOT (removeBrokenClient())); - connect (client, TQT_SIGNAL (received (const TQByteArray &)), - this, TQT_SLOT (getReceivedMessage (const TQByteArray &))); - - // Tell everyone about the new guest - // Note: The new client doesn't get this message! - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_CONNECTED) << client->id(); - broadcastMessage (msg); - - // add to our list - d->mClientList.append (client); - - // tell it its ID - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_ID) << client->id(); - client->send (msg); - - // Give it the complete list of client IDs - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_LIST) << clientIDs(); - client->send (msg); - - - if (clientCount() == 1) - { - // if it is the first client, it becomes the admin - setAdmin (client->id()); - } - else - { - // otherwise tell it who is the admin - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) << adminID(); - client->send (msg); - } - - emit clientConnected (client); -} - -void KMessageServer::removeClient (KMessageIO* client, bool broken) -{ - TQ_UINT32 clientID = client->id(); - if (!d->mClientList.removeRef (client)) - { - kdError(11001) << k_funcinfo << ": Deleting client that wasn't added before!" << endl; - return; - } - - // tell everyone about the removed client - TQByteArray msg; - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_DISCONNECTED) << client->id() << (TQ_INT8)broken; - broadcastMessage (msg); - - // If it was the admin, select a new admin. - if (clientID == adminID()) - { - if (!d->mClientList.isEmpty()) - setAdmin (d->mClientList.first()->id()); - else - setAdmin (0); - } -} - -void KMessageServer::deleteClients() -{ - d->mClientList.clear(); - d->mAdminID = 0; -} - -void KMessageServer::removeBrokenClient () -{ - if (!sender()->inherits ("KMessageIO")) - { - kdError (11001) << k_funcinfo << ": sender of the signal was not a KMessageIO object!" << endl; - return; - } - - KMessageIO *client = (KMessageIO *) sender(); - - emit connectionLost (client); - removeClient (client, true); -} - - -void KMessageServer::setMaxClients(int c) -{ - d->mMaxClients = c; -} - -int KMessageServer::maxClients() const -{ - return d->mMaxClients; -} - -int KMessageServer::clientCount() const -{ - return d->mClientList.count(); -} - -TQValueList <TQ_UINT32> KMessageServer::clientIDs () const -{ - TQValueList <TQ_UINT32> list; - for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter) - list.append ((*iter)->id()); - return list; -} - -KMessageIO* KMessageServer::findClient (TQ_UINT32 no) const -{ - if (no == 0) - no = d->mAdminID; - - TQPtrListIterator <KMessageIO> iter (d->mClientList); - while (*iter) - { - if ((*iter)->id() == no) - return (*iter); - ++iter; - } - return 0; -} - -TQ_UINT32 KMessageServer::adminID () const -{ - return d->mAdminID; -} - -void KMessageServer::setAdmin (TQ_UINT32 adminID) -{ - // Trying to set the the client that is already admin => nothing to do - if (adminID == d->mAdminID) - return; - - if (adminID > 0 && findClient (adminID) == 0) - { - kdWarning (11001) << "Trying to set a new admin that doesn't exist!" << endl; - return; - } - - d->mAdminID = adminID; - - TQByteArray msg; - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) << adminID; - - // Tell everyone about the new master - broadcastMessage (msg); -} - - -//------------------------------------------- ID stuff - -TQ_UINT32 KMessageServer::uniqueClientNumber() const -{ - return d->mUniqueClientNumber++; -} - -// --------------------- Messages --------------------------- - -void KMessageServer::broadcastMessage (const TQByteArray &msg) -{ - for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter) - (*iter)->send (msg); -} - -void KMessageServer::sendMessage (TQ_UINT32 id, const TQByteArray &msg) -{ - KMessageIO *client = findClient (id); - if (client) - client->send (msg); -} - -void KMessageServer::sendMessage (const TQValueList <TQ_UINT32> &ids, const TQByteArray &msg) -{ - for (TQValueListConstIterator <TQ_UINT32> iter = ids.begin(); iter != ids.end(); ++iter) - sendMessage (*iter, msg); -} - -void KMessageServer::getReceivedMessage (const TQByteArray &msg) -{ - if (!sender() || !sender()->inherits("KMessageIO")) - { - kdError (11001) << k_funcinfo << ": slot was not called from KMessageIO!" << endl; - return; - } - //kdDebug(11001) << k_funcinfo << ": size=" << msg.size() << endl; - KMessageIO *client = (KMessageIO *) sender(); - TQ_UINT32 clientID = client->id(); - - //TQByteArray *ta=new TQByteArray; - //ta->duplicate(msg); - //d->mMessageQueue.enqueue (new MessageBuffer (clientID, *ta)); - - - d->mMessageQueue.enqueue (new MessageBuffer (clientID, msg)); - if (!d->mTimer.isActive()) - d->mTimer.start(0); // AB: should be , TRUE i guess -} - -void KMessageServer::processOneMessage () -{ - // This shouldn't happen, since the timer should be stopped before. But only to be sure! - if (d->mMessageQueue.isEmpty()) - { - d->mTimer.stop(); - return; - } - if (d->mIsRecursive) - { - return; - } - d->mIsRecursive = true; - - MessageBuffer *msg_buf = d->mMessageQueue.head(); - - TQ_UINT32 clientID = msg_buf->id; - TQBuffer in_buffer (msg_buf->data); - in_buffer.open (IO_ReadOnly); - TQDataStream in_stream (&in_buffer); - - TQByteArray out_msg; - TQBuffer out_buffer (out_msg); - out_buffer.open (IO_WriteOnly); - TQDataStream out_stream (&out_buffer); - - bool unknown = false; - - TQByteArray ttt=in_buffer.buffer(); - TQ_UINT32 messageID; - in_stream >> messageID; - //kdDebug(11001) << k_funcinfo << ": got message with messageID=" << messageID << endl; - switch (messageID) - { - case RETQ_BROADCAST: - out_stream << TQ_UINT32 (MSG_BROADCAST) << clientID; - // FIXME, compiler bug? - // this should be okay, since TQBuffer is subclass of TQIODevice! : - // out_buffer.writeBlock (in_buffer.readAll()); - TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll()); - broadcastMessage (out_msg); - break; - - case RETQ_FORWARD: - { - TQValueList <TQ_UINT32> clients; - in_stream >> clients; - out_stream << TQ_UINT32 (MSG_FORWARD) << clientID << clients; - // see above! - TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll()); - sendMessage (clients, out_msg); - } - break; - - case RETQ_CLIENT_ID: - out_stream << TQ_UINT32 (ANS_CLIENT_ID) << clientID; - sendMessage (clientID, out_msg); - break; - - case RETQ_ADMIN_ID: - out_stream << TQ_UINT32 (ANS_ADMIN_ID) << d->mAdminID; - sendMessage (clientID, out_msg); - break; - - case RETQ_ADMIN_CHANGE: - if (clientID == d->mAdminID) - { - TQ_UINT32 newAdmin; - in_stream >> newAdmin; - setAdmin (newAdmin); - } - break; - - case RETQ_REMOVE_CLIENT: - if (clientID == d->mAdminID) - { - TQValueList <TQ_UINT32> client_list; - in_stream >> client_list; - for (TQValueListIterator <TQ_UINT32> iter = client_list.begin(); iter != client_list.end(); ++iter) - { - KMessageIO *client = findClient (*iter); - if (client) - removeClient (client, false); - else - kdWarning (11001) << k_funcinfo << ": removing non-existing clientID" << endl; - } - } - break; - - case RETQ_MAX_NUM_CLIENTS: - if (clientID == d->mAdminID) - { - TQ_INT32 maximum_clients; - in_stream >> maximum_clients; - setMaxClients (maximum_clients); - } - break; - - case RETQ_CLIENT_LIST: - { - out_stream << TQ_UINT32 (ANS_CLIENT_LIST) << clientIDs(); - sendMessage (clientID, out_msg); - } - break; - - default: - unknown = true; - } - - // check if all the data has been used - if (!unknown && !in_buffer.atEnd()) - kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl; - - emit messageReceived (msg_buf->data, clientID, unknown); - - if (unknown) - kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl; - - // remove the message, since we are ready with it - d->mMessageQueue.remove(); - if (d->mMessageQueue.isEmpty()) - d->mTimer.stop(); - d->mIsRecursive = false; -} - -void KMessageServer::Debug() -{ - kdDebug(11001) << "------------------ KMESSAGESERVER -----------------------" << endl; - kdDebug(11001) << "MaxClients : " << maxClients() << endl; - kdDebug(11001) << "NoOfClients : " << clientCount() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - -#include "kmessageserver.moc" diff --git a/libkdegames/kgame/kmessageserver.h b/libkdegames/kgame/kmessageserver.h deleted file mode 100644 index 9042fca2..00000000 --- a/libkdegames/kgame/kmessageserver.h +++ /dev/null @@ -1,494 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KMESSAGESERVER_H__ -#define __KMESSAGESERVER_H__ - -#include <tqobject.h> -#include <tqserversocket.h> -#include <tqstring.h> -#include <tqvaluelist.h> - -class KMessageIO; -class KMessageServerPrivate; - -/** - @short A server for message sending and broadcasting, using TCP/IP connections. - - An object of this class listens for incoming connections via TCP/IP sockets and - creates KMessageSocket objects for every established connection. It receives - messages from the "clients", analyses them and processes an appropriate - reaction. - - You can also use other KMessageIO objects with KMessageServer, not only - TCP/IP socket based ones. Use addClient to connect via an object of any - KMessageIO subclass. (For clients within the same process, you can e.g. use - KMessageDirect.) This object already has to be connected. - - The messages are always packages of an arbitrary length. The format of the messages - is given below. All the data is stored and received with TQDataStream, to be - platform independant. - - Setting up a KMessageServer can be done like this: - - \code - KMessageServer *server = new KMessageServer (); - server->initNetwork (TCP/IP-Portnumber); - \endcode - - Usually that is everything you will do. There are a lot of public methods to - administrate the object (maximum number of clients, finding clients, removing - clients, setting the admin client, ...), but this functionality can also - be done by messages from the clients. So you can administrate the object completely - on remote. - - If you want to extend the Server for your own needs (e.g. additional message types), - you can either create a subclass and overwrite the method processOneMessage. - (But don't forget to call the method of the superclass!) Or you can connect to - the signal messageReceived, and analyse the messages there. - - Every client has a unique ID, so that messages can be sent to another dedicated - client or a list of clients. - - One of the clients (the admin) has a special administration right. Some of the - administration messages can only be used with him. The admin can give the admin - status to another client. You can send a message to the admin by using clientID 0. - This is always interpreted as the admin client, independant of its real clientID. - - Here is a list of the messages the KMessageServer understands: - << means, the value is inserted into the TQByteArray using TQDataStream. The - messageIDs (RETQ_BROADCAST, ...) are of type TQ_UINT32. - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_BROADCAST ) << raw_data - - When the server receives this message, it sends the following message to - ALL connected clients (a broadcast), where the raw_data is left unchanged: - TQByteArray << static_cast <TQ_UINT32>( MSG_BROADCAST ) << clientID << raw_data - TQ_UINT32 clientID; // the ID of the client that sent the broadcast request - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_FORWARD ) << client_list << raw_data - TQValueList <TQ_UINT32> client_list; // list of tqreceivers - - When the server receives this message, it sends the following message to - the clients in client_list: - TQByteArray << static_cast<TQ_UINT32>( MSG_FORWARD ) << senderID << client_list << raw_data - TQ_UINT32 senderID; // the sender of the forward request - TQValueList <TQ_UINT32> client_list; // a copy of the receiver list - - Note: Every client receives the message as many times as he is in the client_list. - Note: Since the client_list is sent to all the clients, every client can see who else - got the message. If you want to prevent this, send a single RETQ_FORWARD - message for every receiver. - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_CLIENT_ID ) - - When the server receives this message, it sends the following message to - the asking client: - TQByteArray << static_cast<TQ_UINT32>( ANS_CLIENT_ID ) << clientID - TQ_UINT32 clientID; // The ID of the client who asked for it - - Note: This answer is also automatically sent to a new connected client, so that he - can store his ID. The ID of a client doesn't change during his lifetime, and is - unique for this KMessageServer. - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_ADMIN_ID ) - - When the server receives this message, it sends the following message to - the asking client: - TQByteArray << ANS_ADMIN_ID << adminID - TQ_UINT32 adminID; // The ID of the admin - - Note: This answer is also automatically sent to a new connected client, so that he - can see if he is the admin or not. It will also be sent to all connected clients - when a new admin is set (see RETQ_ADMIN_CHANGE). - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_ADMIN_CHANGE ) << new_admin - TQ_UINT32 new_admin; // the ID of the new admin, or 0 for no admin - - When the server receives this message, it sets the admin to the new ID. If no client - with that ID exists, nothing happens. With new_admin == 0 no client is a admin. - ONLY THE ADMIN ITSELF CAN USE THIS MESSAGE! - - Note: The server sends a ANS_ADMIN_ID message to every connected client. - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_REMOVE_CLIENT ) << client_list - TQValueList <TQ_UINT32> client_list; // The list of clients to be removed - - When the server receives this message, it removes the clients with the ids stored in - client_list, disconnecting the connection to them. - ONLY THE ADMIN CAN USE THIS MESSAGE! - - Note: If one of the clients is the admin himself, he will also be deleted. - Another client (if any left) will become the new admin. - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_MAX_NUM_CLIENTS ) << maximum_clients - TQ_INT32 maximum_clients; // The maximum of clients connected, or infinite if -1 - - When the server receives this message, it limits the number of clients to the number given, - or sets it unlimited for maximum_clients == -1. - ONLY THE ADMIN CAN USE THIS MESSAGE! - - Note: If there are already more clients, they are not affected. It only prevents new Clients - to be added. To assure this limit, remove clients afterwards (RETQ_REMOVE_CLIENT) - - - TQByteArray << static_cast<TQ_UINT32>( RETQ_CLIENT_LIST ) - - When the server receives this message, it answers by sending a list of IDs of all the clients - that are connected at the moment. So it sends the following message to the asking client: - TQByteArray << static_cast<TQ_UINT32>( ANS_CLIENT_LIST ) << clientList - TQValueList <TQ_UINT32> clientList; // The IDs of the connected clients - - Note: This message is also sent to every new connected client, so that he knows the other - clients. - - There are two more messages that are sent from the server to the every client automatically - when a new client connects or a connection to a client is lost: - - TQByteArray << static_cast<TQ_UINT32>( EVNT_CLIENT_CONNECTED ) << clientID; - TQ_UINT32 clientID; // the ID of the new connected client - - TQByteArray << static_cast<TQ_UINT32>( EVNT_CLIENT_DISCONNECTED ) << clientID; - TQ_UINT32 clientID; // the ID of the client that lost the connection - TQ_UINT8 broken; // 1 if the network connection was closed, 0 if it was disconnected - // on purpose - - - @author Andreas Beckermann <[email protected]>, Burkhard Lehner <[email protected]> - @version $Id$ -*/ -class KMessageServer : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - MessageIDs for messages from a client to the message server. - */ - enum { - RETQ_BROADCAST = 1, - RETQ_FORWARD, - RETQ_CLIENT_ID, - RETQ_ADMIN_ID, - RETQ_ADMIN_CHANGE, - RETQ_REMOVE_CLIENT, - RETQ_MAX_NUM_CLIENTS, - RETQ_CLIENT_LIST, - RETQ_MAX_REQ = 0xffff }; - - /** - * MessageIDs for messages from the message server to a client. - **/ - enum { - MSG_BROADCAST = 101, - MSG_FORWARD, - ANS_CLIENT_ID, - ANS_ADMIN_ID, - ANS_CLIENT_LIST, - EVNT_CLIENT_CONNECTED, - EVNT_CLIENT_DISCONNECTED, - EVNT_MAX_EVNT = 0xffff - }; - - /** - * Create a KGameNetwork object - **/ - KMessageServer(TQ_UINT16 cookie = 42, TQObject* parent = 0); - - ~KMessageServer(); - - /** - * Gives debug output of the game status - **/ - virtual void Debug(); - -//---------------------------------- TCP/IP server stuff - - /** - * Starts the Communication server to listen for incoming TCP/IP connections. - * - * @param port The port on which the service is offered, or 0 to let the - * system pick a free port - * @return true if it worked - */ - bool initNetwork (TQ_UINT16 port = 0); - - /** - * Returns the TCP/IP port number we are listening to for incoming connections. - * (This has to be known by other clients so that they can connect to us. It's - * especially necessary if you used 0 as port number in initNetwork(). - * @return the port number - **/ - TQ_UINT16 serverPort () const; - - /** - * Stops listening for connections. The already running connections are - * not affected. - * To listen for connections again call initNetwork again. - **/ - void stopNetwork(); - - /** - * Are we still offer offering server connections? - * @return true, if we are still listening to connections requests - **/ - bool isOfferingConnections() const; - -//---------------------------------- adding / removing clients - -public slots: - /** - * Adds a new @ref KMessageIO object to the communication server. This "client" - * gets a unique ID. - * - * This slot method is automatically called for any incoming TCP/IP - * connection. You can use it to add other types of connections, e.g. - * local connections (KMessageDirect) to the server manually. - * - * NOTE: The @ref KMessageIO object gets owned by the KMessageServer, - * so don't delete or manipulate it afterwards. It is automatically deleted - * when the connection is broken or the communication server is deleted. - * So, add a @ref KMessageIO object to just ONE KMessageServer. - **/ - void addClient (KMessageIO *); - - /** - * Removes the KMessageIO object from the client list and deletes it. - * This destroys the connection, if it already was up. - * Does NOT emit connectionLost. - * Sends an info message to the other clients, that contains the ID of - * the removed client and the value of the parameter broken. - * - * @param io the object to delete and to remove from the client list - * @param broken true if the client has lost connection - * Mostly used internally. You will probably not need this. - **/ - void removeClient (KMessageIO *io, bool broken); - - /** - Deletes all connections to the clients. - */ - void deleteClients(); - -private slots: - /** - * Removes the sender object of the signal that called this slot. It is - * automatically connected to @ref KMessageIO::connectionBroken. - * Emits @ref connectionLost (KMessageIO*), and deletes the @ref KMessageIO object. - * Don't call it directly! - **/ - void removeBrokenClient (); - -public: - /** - * sets the maximum number of clients which can connect. - * If this number is reached, no more clients can be added. - * Setting this number to -1 means unlimited number of clients. - * - * NOTE: Existing connections are not affected. - * So, clientCount > maxClients is possible, if there were already - * more clients than allowed before reducing this value. - * - * @param maxnumber the number of clients - **/ - void setMaxClients(int maxnumber); - - /** - * returns the maximum number of clients - * - * @return the number of clients - **/ - int maxClients() const; - - /** - * returns the current number of connected clients. - * - * @return the number of clients - **/ - int clientCount() const; - - /** - * returns a list of the unique IDs of all clients. - **/ - TQValueList <TQ_UINT32> clientIDs() const; - - /** - * Find the @ref KMessageIO object to the given client number. - * @param no the client number to look for, or 0 to look for the admin - * @return address of the client, or 0 if no client with that number exists - **/ - KMessageIO *findClient (TQ_UINT32 no) const; - - /** - * Returns the clientID of the admin, if there is a admin, 0 otherwise. - * - * NOTE: Most often you don't need to know that id, since you can - * use clientID 0 to specify the admin. - **/ - TQ_UINT32 adminID() const; - - /** - * Sets the admin to a new client with the given ID. - * The old admin (if existed) and the new admin will get the ANS_ADMIN message. - * If you use 0 as new adminID, no client will be admin. - **/ - void setAdmin (TQ_UINT32 adminID); - - -//------------------------------ ID stuff - - /* - * The unique ID of this game - * - * @return int id - **/ -// int gameId() const; - - /* - * Application cookie. this idendifies the game application. It - * help to distinguish between e.g. KPoker and KWin4 - * - * @return the application cookie - **/ -// int cookie() const; - -//------------------------------ Message stuff - -public: - /** - * Sends a message to all connected clients. - * The message is NOT translated in any way. This method calls - * @ref KMessageIO::send for every client added. - **/ - virtual void broadcastMessage (const TQByteArray &msg); - - /** - * Sends a message to a single client with the given ID. - * The message is NOT translated in any way. - * If no client with the given id exists, nothing is done. - * This is just a convenience method. You could also call - * @ref findClient (id)->send(msg) manually, but this method checks for - * errors. - **/ - virtual void sendMessage (TQ_UINT32 id, const TQByteArray &msg); - - /** - * Sends a message to a list of clients. Their ID is given in ids. If - * a client id is given more than once in the list, the message is also - * sent several times to that client. - * This is just a convenience method. You could also iterate over the - * list of IDs. - **/ - virtual void sendMessage (const TQValueList <TQ_UINT32> &ids, const TQByteArray &msg); - -protected slots: - /** - * This slot receives all the messages from the @ref KMessageIO::received signals. - * It stores the messages in a queue. The messages are later taken out of the queue - * by @ref getReceivedMessage. - * - * NOTE: It is important that this slot may only be called from the signal - * @ref KMessageIO::received, since the sender() object is used to find out - * the client that sent the message! - **/ - virtual void getReceivedMessage (const TQByteArray &msg); - - /** - * This slot is called whenever there are elements in the message queue. This queue - * is filled by @ref getReceivedMessage. - * This slot takes one message out of the queue and analyses processes it, - * if it recognizes it. (See message types in the description of the class.) - * After that, the signal @ref messageReceived is emitted. Connect to that signal if - * you want to process other types of messages. - **/ - virtual void processOneMessage (); - -//---------------------------- Signals - -signals: - /** - * A new client connected to the game - * @param client the client object that connected - **/ - void clientConnected (KMessageIO *client); - - /** - * A network connection got broken. Note that the client will automatically get deleted - * after this signal is emitted. The signal is not emitted when the client was removed - * regularly. - * - * @param client the client which left the game - **/ - void connectionLost (KMessageIO *client); - - /** - * This signal is always emitted when a message from a client is received. - * - * You can use this signal to extend the communication server without subclassing. - * Just connect to this signal and analyse the message, if unknown is true. - * If you recognize a message and process it, set unknown to false, otherwise - * a warning message is printed. - * - * @param data the message data - * @param clientID the ID of the KMessageIO object that received the message - * @param unknown true, if the message type is not known by the KMessageServer - **/ - void messageReceived (const TQByteArray &data, TQ_UINT32 clientID, bool &unknown); - -protected: - /** - * @return A unique number which can be used as the id of a @ref KMessageIO. It is - * incremented after every call so if you need the id twice you have to save - * it anywhere. It's currently used to initialize newly connected clints only. - **/ - TQ_UINT32 uniqueClientNumber() const; - -private: - KMessageServerPrivate* d; -}; - - -/** - Internal class of KMessageServer. Creates a server socket and waits for - connections. - - NOTE: This has to be here in the header file, because it is a subclass from - TQObject and has to go through the tqmoc. - - @short An internal class for KServerSocket - @author Burkhard Lehner <[email protected]> -*/ -class KMessageServerSocket : public TQServerSocket -{ - Q_OBJECT - TQ_OBJECT - -public: - KMessageServerSocket (TQ_UINT16 port, TQObject *parent = 0); - ~KMessageServerSocket (); - - void newConnection (int socket); - -signals: - void newClientConnected (KMessageIO *client); -}; - - - -#endif diff --git a/libkdegames/kgame/kmessageserver.png b/libkdegames/kgame/kmessageserver.png Binary files differdeleted file mode 100644 index 07fba6c5..00000000 --- a/libkdegames/kgame/kmessageserver.png +++ /dev/null diff --git a/libkdegames/kgame/kplayer.cpp b/libkdegames/kgame/kplayer.cpp deleted file mode 100644 index 965f5e83..00000000 --- a/libkdegames/kgame/kplayer.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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. -*/ -/* - $Id$ -*/ - - -#include "kgame.h" -#include "kgameio.h" -#include "kplayer.h" -#include "kgamemessage.h" -#include "kgamepropertyhandler.h" - -#include <kdebug.h> -#include <klocale.h> - -#include <tqbuffer.h> - -#include <stdio.h> -#include <assert.h> - -#define KPLAYER_LOAD_COOKIE 7285 - -class KPlayerPrivate -{ -public: - KPlayerPrivate() - { - mNetworkPlayer = 0; - } - - TQ_UINT32 mId; - bool mVirtual; // virtual player - int mPriority; // tag for replacement - - KPlayer* mNetworkPlayer; // replacement player - - KGamePropertyHandler mProperties; - -// Playerdata - KGamePropertyTQString mName; - KGamePropertyTQString mGroup; -}; - -KPlayer::KPlayer() : TQObject(0,0) -{ - init(); -} - -KPlayer::KPlayer(KGame* game) : TQObject(0, 0) -{ - init(); - game->addPlayer(this); -} - -void KPlayer::init() -{ -// note that NO KGame object exists here! so we cannot use KGameProperty::send! - kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)="<<sizeof(KPlayer) << endl; - kdDebug(11001) << "sizeof(m_Group)="<<sizeof(d->mGroup)<<endl; - d = new KPlayerPrivate; - - d->mProperties.registerHandler(KGameMessage::IdPlayerProperty, - this,TQT_SLOT(sendProperty(int, TQDataStream&, bool*)), - TQT_SLOT(emitSignal(KGamePropertyBase *))); - d->mVirtual=false; - mActive=true; - mGame=0; - d->mId=0; // "0" is always an invalid ID! - d->mPriority=0; - // I guess we cannot translate the group otherwise no - // international conenctions are possible - - mUserId.registerData(KGamePropertyBase::IdUserId, this, i18n("UserId")); - mUserId.setLocal(0); - d->mGroup.registerData(KGamePropertyBase::IdGroup, this, i18n("Group")); - d->mGroup.setLocal(i18n("default")); - d->mName.registerData(KGamePropertyBase::IdName, this, i18n("Name")); - d->mName.setLocal(i18n("default")); - - mAsyncInput.registerData(KGamePropertyBase::IdAsyncInput, this, i18n("AsyncInput")); - mAsyncInput.setLocal(false); - mMyTurn.registerData(KGamePropertyBase::IdTurn, this, i18n("myTurn")); - mMyTurn.setLocal(false); - mMyTurn.setEmittingSignal(true); - mMyTurn.setOptimized(false); -} - -KPlayer::~KPlayer() -{ - kdDebug(11001) << k_funcinfo << ": this=" << this <<", id=" << this->id() << endl; - - // Delete IODevices - KGameIO *input; - while((input=mInputList.first())) - { - delete input; - } - if (game()) - { - game()->playerDeleted(this); - } - -// note: mProperties does not use autoDelete or so - user must delete objects -// himself - d->mProperties.clear(); - delete d; -// kdDebug(11001) << k_funcinfo << " done" << endl; -} - -bool KPlayer::forwardMessage(TQDataStream &msg,int msgid,TQ_UINT32 receiver,TQ_UINT32 sender) -{ - if (!isActive()) - { - return false; - } - if (!game()) - { - return false; - } - kdDebug(11001) << k_funcinfo << ": to game sender="<<sender<<"" << "recv="<<receiver <<"msgid="<<msgid << endl; - return game()->sendSystemMessage(msg,msgid,receiver,sender); -} - -bool KPlayer::forwardInput(TQDataStream &msg,bool transmit,TQ_UINT32 sender) -{ - if (!isActive()) - { - return false; - } - if (!game()) - { - return false; - } - - kdDebug(11001) << k_funcinfo << ": to game playerInput(sender="<<sender<<")" << endl; - if (!asyncInput() && !myTurn()) - { - kdDebug(11001) << k_funcinfo << ": rejected cause it is not our turn" << endl; - return false; - } - - // AB: I hope I remember the usage correctly: - // this function is called twice (on sender side) - once with transmit = true - // where it sends the input to the comserver and once with transmit = false - // where it really looks at the input - if (transmit) - { - kdDebug(11001) << "indirect playerInput" << endl; - return game()->sendPlayerInput(msg,this,sender); - } - else - { - kdDebug(11001) << "direct playerInput" << endl; - return game()->systemPlayerInput(msg,this,sender); - } -} - -void KPlayer::setId(TQ_UINT32 newid) -{ - // Needs to be after the sendProcess - d->mId=newid; -} - - -void KPlayer::setGroup(const TQString& group) -{ d->mGroup = group; } - -const TQString& KPlayer::group() const -{ return d->mGroup.value(); } - -void KPlayer::setName(const TQString& name) -{ d->mName = name; } - -const TQString& KPlayer::name() const -{ return d->mName.value(); } - -TQ_UINT32 KPlayer::id() const -{ return d->mId; } - -KGamePropertyHandler * KPlayer::dataHandler() -{ return &d->mProperties; } - -void KPlayer::setVirtual(bool v) -{ d->mVirtual = v; } - -bool KPlayer::isVirtual() const -{ return d->mVirtual;} - -void KPlayer::setNetworkPlayer(KPlayer* p) -{ d->mNetworkPlayer = p; } - -KPlayer* KPlayer::networkPlayer() const -{ return d->mNetworkPlayer; } - -int KPlayer::networkPriority() const -{ return d->mPriority; } - -void KPlayer::setNetworkPriority(int p) -{ d->mPriority = p; } - -bool KPlayer::addGameIO(KGameIO *input) -{ - if (!input) - { - return false; - } - mInputList.append(input); - input->initIO(this); // set player and init device - return true; -} - -// input=0, remove all -bool KPlayer::removeGameIO(KGameIO *targetinput,bool deleteit) -{ - kdDebug(11001) << k_funcinfo << ": " << targetinput << " delete=" << deleteit<< endl; - bool result=true; - if (!targetinput) // delete all - { - KGameIO *input; - while((input=mInputList.first())) - { - if (input) removeGameIO(input,deleteit); - } - } - else - { -// kdDebug(11001) << "remove IO " << targetinput << endl; - if (deleteit) - { - delete targetinput; - } - else - { - targetinput->setPlayer(0); - result=mInputList.remove(targetinput); - } - } - return result; -} - -KGameIO * KPlayer::findRttiIO(int rtti) const -{ - TQPtrListIterator<KGameIO> it(mInputList); - while (it.current()) - { - if (it.current()->rtti() == rtti) - { - return it.current(); - } - ++it; - } - return 0; -} - -int KPlayer::calcIOValue() -{ - int value=0; - TQPtrListIterator<KGameIO> it(mInputList); - while (it.current()) - { - value|=it.current()->rtti(); - ++it; - } - return value; -} - -bool KPlayer::setTurn(bool b, bool exclusive) -{ - kdDebug(11001) << k_funcinfo << ": " << id() << " (" << this << ") to " << b << endl; - if (!isActive()) - { - return false; - } - - // if we get to do an exclusive turn all other players are disallowed - if (exclusive && b && game()) - { - KPlayer *player; - KGame::KGamePlayerList *list=game()->playerList(); - for ( player=list->first(); player != 0; player=list->next() ) - { - if (player==this) - { - continue; - } - player->setTurn(false,false); - } - } - - // Return if nothing changed - mMyTurn = b; - - return true; -} - -bool KPlayer::load(TQDataStream &stream) -{ - TQ_INT32 id,priority; - stream >> id >> priority; - setId(id); - setNetworkPriority(priority); - - // Load Player Data - //FIXME: maybe set all properties setEmitSignal(false) before? - d->mProperties.load(stream); - - TQ_INT16 cookie; - stream >> cookie; - if (cookie==KPLAYER_LOAD_COOKIE) - { - kdDebug(11001) << " Player loaded propertly"<<endl; - } - else - { - kdError(11001) << " Player loading error. probably format error"<<endl; - } - - // emit signalLoad(stream); - return true; -} - -bool KPlayer::save(TQDataStream &stream) -{ - stream << (TQ_INT32)id() << (TQ_INT32)networkPriority(); - - d->mProperties.save(stream); - - stream << (TQ_INT16)KPLAYER_LOAD_COOKIE; - - //emit signalSave(stream); - return true; -} - - -void KPlayer::networkTransmission(TQDataStream &stream,int msgid,TQ_UINT32 sender) -{ - //kdDebug(11001) << k_funcinfo ": msgid=" << msgid << " sender=" << sender << " we are=" << id() << endl; - // PlayerProperties processed - bool issender; - if (game()) - { - issender=sender==game()->gameId(); - } - else - { - issender=true; - } - if (d->mProperties.processMessage(stream,msgid,issender)) - { - return ; - } - switch(msgid) - { - case KGameMessage::IdPlayerInput: - { - kdDebug(11001) << k_funcinfo << ": Got player move " - << "KPlayer (virtual) forwards it to the game object" << endl; - forwardInput(stream,false); - } - break; - default: - emit signalNetworkData(msgid - KGameMessage::IdUser, - ((TQBuffer*)stream.device())->readAll(),sender,this); - kdDebug(11001) << k_funcinfo << ": " - << "User data msgid " << msgid << endl; - break; - } - -} - -KGamePropertyBase* KPlayer::findProperty(int id) const -{ - return d->mProperties.find(id); -} - -bool KPlayer::addProperty(KGamePropertyBase* data) -{ - return d->mProperties.addProperty(data); -} - -void KPlayer::sendProperty(int msgid, TQDataStream& stream, bool* sent) -{ - if (game()) - { - bool s = game()->sendPlayerProperty(msgid, stream, id()); - if (s) - { - *sent = true; - } - } -} - -void KPlayer::emitSignal(KGamePropertyBase *me) -{ - // Notify KGameIO (Process) for a new turn - if (me->id()==KGamePropertyBase::IdTurn) - { - //kdDebug(11001) << k_funcinfo << ": for KGamePropertyBase::IdTurn " << endl; - TQPtrListIterator<KGameIO> it(mInputList); - while (it.current()) - { - it.current()->notifyTurn(mMyTurn.value()); - ++it; - } - } - emit signalPropertyChanged(me,this); -} - -// --------------------- DEBUG -------------------- -void KPlayer::Debug() -{ - kdDebug(11001) << "------------------- KPLAYER -----------------------" << endl; - kdDebug(11001) << "this: " << this << endl; - kdDebug(11001) << "rtti: " << rtti() << endl; - kdDebug(11001) << "id : " << id() << endl; - kdDebug(11001) << "Name : " << name() << endl; - kdDebug(11001) << "Group: " << group() << endl; - kdDebug(11001) << "Async: " << asyncInput() << endl; - kdDebug(11001) << "myTurn: " << myTurn() << endl; - kdDebug(11001) << "Virtual: " << isVirtual() << endl; - kdDebug(11001) << "Active: " << isActive() << endl; - kdDebug(11001) << "Priority:" << networkPriority() << endl; - kdDebug(11001) << "Game : " << game() << endl; - kdDebug(11001) << "#IOs: " << mInputList.count() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - -#include "kplayer.moc" diff --git a/libkdegames/kgame/kplayer.h b/libkdegames/kgame/kplayer.h deleted file mode 100644 index 910781f3..00000000 --- a/libkdegames/kgame/kplayer.h +++ /dev/null @@ -1,472 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Martin Heni ([email protected]) - Copyright (C) 2001 Andreas Beckermann ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 __KPLAYER_H_ -#define __KPLAYER_H_ - -#include <tqstring.h> -#include <tqobject.h> -#include <tqptrlist.h> - -#include "kgameproperty.h" -#include <kdemacros.h> - -class KGame; -class KGameIO; -class KGamePropertyBase; -class KGamePropertyHandler; - -class KPlayerPrivate; - -/** - * @short Base class for a game player - * - * The KPlayer class is the central player object. It holds - * information about the player and is responsible for any - * input the player does. For this arbitrary many KGameIO - * modules can be plugged into it. Main features are: - * - Handling of IO devices - * - load/save (mostly handled by KGamePropertyHandler) - * - Turn handling (turn based, asynchronous) - * - * A KPlayer depends on a KGame object. Call KGame::addPlayer() to plug - * a KPlayer into a KGame object. Note that you cannot do much with a - * KPlayer object before it has been plugged into a KGame. This is because - * most properties of KPlayer are KGameProperty which need to send messages - * through a KGame object to be changed. - * - * A KGameIO represents the input methods of a player and you should make all - * player inputs through it. So call something like playerInput->move(4); - * instead which should call KGameIO::sendInput() to actually move. This way - * you gain a *very* big advantage: you can exchange a KGameIO whenever you - * want! You can e.g. remove the KGameIO of a local (human) player and just - * replace it by a computerIO on the fly! So from that point on all playerInputs - * are done by the computerIO instead of the human player. You also can replace - * all network players by computer players when the network connection is broken - * or a player wants to quit. - * So remember: use KGameIO whenever possible! A KPlayer should just - * contain all data of the player (KGameIO must not!) and several common - * functions which are shared by all of your KGameIOs. - * - */ -class KDE_EXPORT KPlayer : public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - typedef TQPtrList<KGameIO> KGameIOList; - - // KPlayer(KGame *,KGameIO * input=0); - /** - * Create a new player object. It will be automatically - * deleted if the game it belongs to is deleted. - */ - KPlayer(); - - /** - * Create a new player object. It will be automatically - * deleted if the game it belongs to is deleted. This constructor - * automatically adds the player to the game using KGame::addPlayer() - */ - KPlayer(KGame* game); - - virtual ~KPlayer(); - - /** - * The idendification of the player. Overwrite this in - * classes inherting KPlayer to run time identify them. - * - * @return 0 for default KPlayer. - */ - virtual int rtti() const {return 0;} - - /** - * Gives debug output of the game status - */ - void Debug(); - - // properties - /** - * Returns a list of input devices - * - * @return list of devices - */ - KGameIOList *ioList() {return &mInputList;} - - /** - * sets the game the player belongs to. This - * is usually automatically done when adding a - * player - * - * @param game the game - */ - void setGame(KGame *game) {mGame=game;} - - /** - * Query to which game the player belongs to - * - * @return the game - */ - KGame *game() const {return mGame;} - - /** - * Set whether this player can make turns/input - * all the time (true) or only when it is its - * turn (false) as it is used in turn based games - * - * @param a async=true turn based=false - */ - void setAsyncInput(bool a) {mAsyncInput = a;} - - /** - * Query whether this player does asynchronous - * input - * - * @return true/false - */ - bool asyncInput() const {return mAsyncInput.value();} - - /** - * Is this player a virtual player, ie is it - * created by mirroring a real player from another - * network game. This mirroring is done autmatically - * as soon as a network connection is build and it affects - * all players regardless what type - * - * @return true/false - */ - bool isVirtual() const; - - /** - * @internal - * Sets whether this player is virtual. This is internally - * called - * - * @param v virtual true/false - */ - void setVirtual(bool v); - - /** - * Is this player an active player. An player is usually - * inactivated if it is replaced by a network connection. - * But this could also be called manually - * - * @return true/false - */ - bool isActive() const {return mActive;} - - /** - * Set an player as active (true) or inactive (false) - * - * @param v true=active, false=inactive - */ - void setActive(bool v) {mActive=v;} - - /** - * Returns the id of the player - * - * @return the player id - */ - TQ_UINT32 id() const; - - /* Set the players id. This is done automatically by - * the game object when adding a new player! - * - * @param i the player id - */ - void setId(TQ_UINT32 i); - - /** - * Returns the user defined id of the player - * This value can be used arbitrary by you to - * have some user idendification for your player, - * e.g. 0 for a white chess player, 1 for a black - * one. This value is more reliable than the player - * id whcih can even change when you make a network - * connection. - * - * @return the user defined player id - */ - int userId() const {return mUserId.value();} - - /* Set the user defined players id. - * - * @param i the user defined player id - */ - void setUserId(int i) {mUserId = i;} - - /** - * Returns whether this player can be replaced by a network - * connection player. The name of this function can be - * improved ;-) If you do not overwrite the function to - * select what players shall play in a network the KGame - * does an automatic selection based on the networkPriority - * This is not a terrible important function at the moment. - * - * @return true/false - */ - int networkPriority() const; - - /** - * Set whether this player can be replaced by a network - * player. There are to possible games. The first type - * of game has arbitrary many players. As soon as a network - * players connects the game runs with more players (not tagged - * situation). The other type is e.g. games like chess which - * require a constant player number. In a network game situation - * you would tag one or both players of all participants. As - * soon as the connect the tagged player will then be replaced - * by the network partner and it is then controlled over the network. - * On connection loss the old situation is automatically restored. - * - * The name of this function can be improved;-) - * - * @param b should this player be tagged - */ - void setNetworkPriority(int b); - - /** - * Returns the player which got inactivated to allow - * this player to be set up via network. Mostly internal - * function - */ - KPlayer *networkPlayer() const; - - /** - * Sets this network player replacement. Internal stuff - */ - void setNetworkPlayer(KPlayer *p); - - // A name and group the player belongs to - /** - * A group the player belongs to. This - * Can be set arbitrary by you. - */ - void setGroup(const TQString& group); - - /** - * Query the group the player belongs to. - */ - virtual const TQString& group() const; - - /** - * Sets the name of the player. - * This can be chosen arbitrary. - * @param name The player's name - */ - void setName(const TQString& name); - - /** - * @return The name of the player. - */ - virtual const TQString& name() const; - - - // set devices - /** - * Adds an IO device for the player. Possible KGameIO devices - * can either be taken from the existing ones or be self written. - * Existing are e.g. Keyboard, Mouse, Computerplayer - * - * @param input the inut device - * @return true if ok - */ - bool addGameIO(KGameIO *input); - - /** - * remove (and delete) a game IO device - * - * The remove IO(s) is/are deleted by default. If - * you do not want this set the parameter deleteit to false - * - * @param input the device to be removed or 0 for all devices - * @param deleteit true (default) to delete the device otherwisse just remove it - * @return true on ok - */ - bool removeGameIO(KGameIO *input=0,bool deleteit=true); - - /** - * Finds the KGameIO devies with the given rtti code. - * E.g. find the mouse or network device - * - * @param rtti the rtti code to be searched for - * @return the KGameIO device - */ - KGameIO *findRttiIO(int rtti) const; - - /** - * Checks whether this player has a IO device of the - * given rtti type - * - * @param rtti the rtti typed to be checked for - * @return true if it exists - */ - bool hasRtti(int rtti) const {return findRttiIO(rtti)!=0;} - - // Message exchange - /** - * Forwards input to the game object..internal use only - * - * This method is used by KGameIO::sendInput(). Use that function - * instead to send player inputs! - * - * This function forwards a player input (see KGameIO classes) to the - * game object, see KGame, either to KGame::sendPlayerInput() (if - * transmit=true, ie the message has just been created) or to - * KGame::playerInput() (if player=false, ie the message *was* sent through - * KGame::sendPlayerInput). - */ - virtual bool forwardInput(TQDataStream &msg,bool transmit=true, TQ_UINT32 sender=0); - - /** - * Forwards Message to the game object..internal use only - */ - virtual bool forwardMessage(TQDataStream &msg,int msgid,TQ_UINT32 receiver=0,TQ_UINT32 sender=0); - - // Game logic - /** - * is it my turn to go - * - * @return true/false - */ - bool myTurn() const {return mMyTurn.value();} - - /** - * Sets whether this player is the next to turn. - * If exclusive is given all other players are set - * to setTurn(false) and only this player can move - * - * @param b true/false - * @param exclusive true (default)/ false - * @return should be void - */ - bool setTurn(bool b,bool exclusive=true); - - - // load/save - /** - * Load a saved player, from file OR network. By default all - * KGameProperty objects in the dataHandler of this player are loaded - * and saved when using load or save. If you need to save/load more - * you have to replace this function (and save). You will probably - * still want to call the default implementation additionally! - * - * @param stream a data stream where you can stream the player from - * - * @return true? - */ - virtual bool load(TQDataStream &stream); - - /** - * Save a player to a file OR to network. See also load - * - * @param stream a data stream to load the player from - * - * @return true? - */ - virtual bool save(TQDataStream &stream); - - /** - * Receives a message - * @param msgid The kind of the message. See messages.txt for further - * information - * @param stream The message itself - * @param sender - **/ - void networkTransmission(TQDataStream &stream,int msgid,TQ_UINT32 sender); - - /** - * Searches for a property of the player given its id. - * @param id The id of the property - * @return The property with the specified id - **/ - KGamePropertyBase* findProperty(int id) const; - - /** - * Adds a property to a player. You would add all - * your player specific game data as KGameProperty and - * they are automatically saved and exchanged over network. - * - * @param data The property to be added. Must have an unique id! - * @return false if the given id is not valid (ie another property owns - * the id) or true if the property could be added successfully - **/ - bool addProperty(KGamePropertyBase* data); - - /** - * Calculates a checksum over the IO devices. Can be used to - * restore the IO handlers. The value returned is the 'or'ed - * value of the KGameIO rtti's. - * this is itnernally used for saving and restorign a player. - */ - int calcIOValue(); - - /** - * @return the property handler - */ - KGamePropertyHandler* dataHandler(); - -signals: - /** - * The player object got a message which was targeted - * at it but has no default method to process it. This - * means probably a user message. Connecting to this signal - * allowed to process it. - */ - void signalNetworkData(int msgid, const TQByteArray& buffer, TQ_UINT32 sender, KPlayer *me); - - /** - * This signal is emmited if a player property changes its value and - * the property is set to notify this change. This is an - * important signal as you should base the actions on a reaction - * to this property changes. - */ - void signalPropertyChanged(KGamePropertyBase *property,KPlayer *me); - -protected slots: - /** - * Called by KGameProperty only! Internal function! - **/ - void sendProperty(int msgid, TQDataStream& stream, bool* sent); - /** - * Called by KGameProperty only! Internal function! - **/ - void emitSignal(KGamePropertyBase *me); - - -private: - void init(); - -private: - KGame *mGame; - bool mActive; // active player - KGameIOList mInputList; - - // GameProperty // AB: I think we can't move them to KPlayerPrivate - inline - // makes sense here - KGamePropertyBool mAsyncInput; // async input allowed - KGamePropertyBool mMyTurn; // Is it my turn to play (only useful if not async)? - KGamePropertyInt mUserId; // a user defined id - - KPlayerPrivate* d; -}; - -#endif diff --git a/libkdegames/kgame/libkdegames.html b/libkdegames/kgame/libkdegames.html deleted file mode 100644 index a715a239..00000000 --- a/libkdegames/kgame/libkdegames.html +++ /dev/null @@ -1,187 +0,0 @@ -<html> - <head> - <title>Documentation for libtdegames</title> - <meta content=""> - <style></style> - </head> - <body> - <H1>Documentation for the classes in libtdegames</H1> -<!--------------------------------------------------------------------------------> - <H3>Design Principles</H3> - The library <em>tdegames</em> contains a collection of classes that can be used - to develop games using the KDE environment very easily. There are a few - principles that were used when developing the library:<P> - - <UL> - <LI><b>usable for a big variety of games</b><br> - The class <em>KGame</em> provides many features that are needed in many games. - It can be used for board games, card games, maze games, simulation games, strategy games and - many more.<br> - It does not (yet) include special features for realtime games, but can be used there, too. - <LI><b>features one-player and multi-player games</b></br> - A game developed with this library can easily support any number of simultaneous players. - So use it for one-player games (like Tetris or KSame), for two-player games (like TicTacToe - or chess) or for games with an arbitrary number of players. - <LI><b>computer players can easily be developed</b><br> - The class <em>KPlayer</em> represents an abstract player in a game. This can be a - human player that gets the input from the mouse or the keyboard. Or it can be a computer - player that makes moves by random or with artificial intelligence. All this can be achieved - subclassing KPlayer. - <LI><b>support for network games transparently</b><br> - The class <em>KGame</em> contains lots of features for network game support. Developing - a network game using a TCP/IP connection is very easy this way. But the default - case is still the local game. So the user should not need to connect to the internet - or to select a game server to play a game. - <LI><b>support for turn based and for asynchronous games</b><br> - You can use this library for turn based games, when only one player can make a move at a time - (like most bord games or card games), but also for asynchronous games, when every player can - make a move any time (like many action games). - </UL> -<!--------------------------------------------------------------------------------> - <H3>The central game class: <em>KGame</em></H3> - - When you want to develop your own KDE game using the KDE games library, you most likely want - to use the <em>KGame</em> class. There are two possible ways to extend it to your own needs: - Create a subclass and overwrite the virtual methods, or simply create an instance of KGame - and connect to the appropriate signals.<P> - - <<more code about KGame, an easy example>> - -<!--------------------------------------------------------------------------------> - <H3>Network games and related classes</H3> - - One of the main principles in the design of <em>KGame</em> was to make network games possible - with a minimum of effort for the game developer.<P> - - A network game is a game with usually several players, that are on different computers. These - computers are usually connected to the internet, and all the moves a player does are exchanged - over this network.<P> - - The exchange of moves and other information is done using the class <em>KMessageServer</em>. - An object of this class is a server that waits for connections. Someone who wants to take part - in the game has to connect to this server - usually using an internet socket connection. He does - this by creating a <em>KMessageClient</em> object. This object connects to the message server.<P> - - The transfer of data is realised by subclasses of the abstract class <em>KMessageIO</em>. One object - of this class is created on the client side, one on the server side. Different types of networks can - be supported by creating new subclasses of KMessageIO. There are already two subclasses of KMessageIO: - <em>KMessageSocket</em> uses a internet socket connection to transfer the data from the message client - to the message server or vice versa. <em>KMessageDirect</em> can be used if both the message server and - the message client are within the same process. The data blocks are copied directly to the other side, - so the transfer is faster and needs no network bandwidth.<P> - - A typical network game situation could look like this:<P> - - <IMG SRC="kmessageserver.png"><P> - - Here, three KGame object (called message clients) are connected to the KMessageServer object. One - is in the same process, so it uses KMessageDirect. The other two use KMessageSocket, so an internet - socket connection is used. KGame doesn't talk directly to the message server, but uses a KMessageClient - object instead. One of the KMessageClient objects is the admin of the message server. This client has some - priviledges. It may e.g. kill the connection to other message clients, or limit the number of clients - that may connect.<P> - - The KGame objects are by default all equal. So the usual approach will be that every KGame object will - store the complete status of the game, and any change or move will be broadcasted to the other KGame - objects, so that they all change the status in identical ways. Sometimes it may be necessary (or just - easier to implement) that one KGame object is a <em>game server</em> (i.e. he is repsonsible for everything, - he coordinates the complete game and stores the game status), whereas the other KGame objects are - only dumb stubs that are used to contact the <em>game server</em>. You can implement both approaches - using the message server structure. If you need to elect the KGame object that shall be - the game server, you may e.g. use the one that has the KMessageClient that is the admin of the message - server. (Of course this is only a suggestion, you can use other approaches.)<P> - - The main principle when developing the message server/client structure was, that the message server - doesn't have <em>any</em> idea of the game and its rules that is played. The message server only forwards - messages from one message client to the others without interpreting or manipulating the data. So always - keep in mind that the message server is <em>not</em> a game server! It does not store any data about - the game status. It is only a server for network connections and message broadcasting, <em>not</em> - for game purposes. The reason for this principle is, that <em>any</em> game can be played using a - KMessageServer on any computer. The computer being the message server doesn't need to know anything - about the game that is played on it. So you don't have to install new versions of the game there. Only - the clients need to be game specific.<P> - - Usually you don't need to create <em>KMessageServer</em> or <em>KMessageClient</em> objects in your game, - since <em>KGame</em> does this for you. There are three different scenarios fo network games that are - all supported in <em>KGame</em>:<P> - - <b>Scenario 1: local game</b><P> - - The local game should always be the default state a game should be in. To avoid having this scenario - as a special case, <em>KGame</em> automatically creates a KMessageServer object and a KMessageClient - object. So every change and every move is sent to the message server and is returned to the KGame - object before it is processed. Since the connection between the message client and the message server - uses KMessageDirect the data transfer is very fast and wont hurt in most cases.<P> - - <IMG SRC="scenario0.png"><P> - - This is the default situation right after creating the <em>KGame</em> object.<P> - - <b>Scenario 2: network game, started by one player</b><P> - - If one user is bored of playing alone, he can open his game for connections from the outside world. - He listens to a TCP/IP socket port (i.e. a number between 0 and 65535). Other players can create - KGame objects of their own and connect to this port. They need to know the IP address of that computer - and the port number. This situation will have this structure: - - <IMG SRC="scenario1.png"><P> - - The first player has to do something like:<P> - - <PRE> - KGame *myGame = new KGame (); - // wait for connections on port 12345 - myGame->offerConnections (12345); - </PRE> - - And the other players have to do something like:<P> - - <PRE> - KGame *myGame = new KGame (); - // connect to the message server - myGame->connectToServer ("theServer.theDomain.com", 12345); - </PRE> - - This automatically removes the message server in these KGame objects and connects to the given - one instead.<P> - - <b>Scenario 3: network game, using a stand alone message server</b><P> - - Sometimes it is not possible to let the message server run on one of the players computer. If e.g. all - the players have their computer in a local network that uses masquerading to contact the internet, - other computers cannot connect to them since the computer doesn't have a IP address to the outside - world. Then the only way to play a network game is to have a standalone KMessageServer object on - another server computer (somthing like "games.kde.org" e.g.). Since the KMessageServer isn't game - specific at all, every game can be played using it. There doesn't have to be any special software - installed on that server computer, only the program creating a KMessageServer object.<P> - - This scenario has some more advantages: The message server can be a well known meeting point to - start a game. This way one could play games against other players you never knew before. Furthermore - the game is stopped brutally when the program that contains the message server in scenario 2 is - quitted. (Migration of message servers is not yet implemented, but may be in the future.) Using a - stand alone message server, the players may enter and leave the game as they want. - - <IMG SRC="scenario2.png"><P> - - To create this scenario, a special KMessageServer program has to be started on the computer - that shall be the stand alone message server:<P> - - <PRE> - % kmessageserver -port=12345 - </PRE> - - The other games that want to connect have to do this (supposed the stand alone message server - has the IP address "games.kde.org"):<P> - - <PRE> - KGame *myGame = new KGame (); - // connect to the message server - myGame->connectToServer ("games.kde.org", 12345); - </PRE> - - - - -<!--------------------------------------------------------------------------------> - </body> -</html>
\ No newline at end of file diff --git a/libkdegames/kgame/messages.txt b/libkdegames/kgame/messages.txt deleted file mode 100644 index c42d2d91..00000000 --- a/libkdegames/kgame/messages.txt +++ /dev/null @@ -1,93 +0,0 @@ -Message formats of libtdegames: -------------------------------- - -There are two different communication layers, using their own protocols: - - - the message layer (KMessageIO, KMessageServer, KMessageClient) - - This is used to send messages from one client (i.e. KGame object) - to an other one, to a group of other clients, or to all the clients - connected to the KMessageServer. The messages are arbitrary blocks - of data, of an arbitrary length. - This layer is an underlying protocol that isn't game specific at all. - You shouldn't need to know the message format of the packets. If you - want to extend the protocol, have a look into KMessageServer API - reference for a complete list of message types. - - - the game layer (KGame, KGameIO, KPlayer) - - This layer uses the message layer to send its specific message packets - between the objects of the game. - This layer contains the game specific messages (e.g. addPlayer, setupGame). - The rest of this file describes this layer. - - -Game Layer Messages: --------------------- - - Application Cookie 16 Bit - Version 8 Bit - MsgId 16 Bit - SenderId 16 Bit - ReceiverId 16 Bit - Userdata - -The format of the messages is used internally and there is usually no reason why -you have to know what it is used for. But as usually != always here are some -comments on the format. Note that KGame is under development and the content of -this file could be obsolete. Please result the sourcecode for up-to-date -information. -Application Cookie is used to identify the application. This prevents a -chess game from talking to a poker game. -Version is the version of KNetworkGame, sender and receiver must be of the same -version. - library note: this could be a limitation, as KGame should be backward - compatible. Maybe change to version must be >= KNETWORKGAME or something less - restrictive -MsgId specifies the kind of the message data (see below). -SenderId is the id of the KGame/KPlayer object which sent the message, it is -coded like this: the lower 10 bits specify a player and the upper bit -represent the game id shifted by 10 bits. So we get -Id=playerId | (gameId<<10); -ReceiverId is the id of the receiver of the message. It can be either -a player, a game or a broadcast. For a broadcast the Id is set to 0 -in the other cases the coding is as with the senderId -Userdata is the data of the user (wow ;-)) - - -MsgId UserData ---------------------------------------------------------- -IdMessage user defined - -IdSetupGame Q_INT32 isServer - Q_INT32 maxPlayers - Q_INT32 newid (id for the new game) - Q_INT32 cntR (virtual player nunmber) - Q_INT32 cntT (tagged player number) - TODO: Changed - -IdContinueSetup: TODO - -IdSendPlayer Q_INT32 omit how many tagged players for replacement - TODO: Changed - -IdGameSave Save(msg)->Load(msg) - -IdAddPlayer rtti - gameid() of the owner - player->Save(msg) -> player->Load(msg) - -IdRemovePlayer Q_INT16 playerid - -IdError Q_INT32 errorcode - QString errortext - -IdGametqStatus Q_INT32 status - -IdPlayerProperty Q_INT16 propertyId - user defined -> the property - -IdGameProperty Q_INT16 propertyId - user defined -> the property - -IdPlayerInput user defined diff --git a/libkdegames/kgame/scenario0.png b/libkdegames/kgame/scenario0.png Binary files differdeleted file mode 100644 index 4de99b52..00000000 --- a/libkdegames/kgame/scenario0.png +++ /dev/null diff --git a/libkdegames/kgame/scenario1.png b/libkdegames/kgame/scenario1.png Binary files differdeleted file mode 100644 index 74af4f6f..00000000 --- a/libkdegames/kgame/scenario1.png +++ /dev/null diff --git a/libkdegames/kgame/scenario2.png b/libkdegames/kgame/scenario2.png Binary files differdeleted file mode 100644 index 14ea0a3c..00000000 --- a/libkdegames/kgame/scenario2.png +++ /dev/null |