/* ************************************************************************* ArmageTron -- Just another Tron Lightcycle Game in 3D. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) ************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *************************************************************************** */ #ifndef ArmageTron_ServerInfo_H #define ArmageTron_ServerInfo_H #include "tString.h" #include "tLinkedList.h" #include "tArray.h" #include "nNetwork.h" #include //class std::ostream; //class std::istream; class nServerInfo; class tPath; typedef nServerInfo* (sn_ServerInfoCreator)(); class nServerInfo: public tListItem { int pollID; protected: // information only for the master server unsigned int transactionNr; // a running number assigned to every server that connects to the master // technical information; filled in by querying the master server/broadcasting on the LAN tString connectionName; // the internet name of the server ("192.168.10.10", "atron.dyndns.org") unsigned int port; // the network port the server listens on // encryption information (from the master server, too) int method; // encryption method identifier tArray key; // the public key for encrypting important messages to the server (i.e. the session key) // advanced information; optained by directly querying the server. bool advancedInfoSet; // did we already get the info? bool advancedInfoSetEver; // did we already get the info during this query run? int queried; // how often did we already query for it this turn? nTimeRolling timeQuerySent; // the time the info query message was sent REAL ping; // the ping time nVersion version_; // currently supported protocol versions tString release_; // release version bool login2_; // flag indicating whether the second version of the logic can be tried int timesNotAnswered; // number of times the server did not answer to information queries recently // human information tString name; // the human name of the server ("Z-Man's Armagetron Server"); int users; // number of users online int maxUsers_; // maximum number of users allowed tString userNames_; // names of the connected users tString userNamesOneLine_;// names of the connected users in one line tString options_; // description of non-default options tString url_; // url asociated with the server REAL score; // score based on ping and number of users (and game mode...) public: nServerInfo(); virtual ~nServerInfo(); nServerInfo* Prev(); virtual void CalcScore(); // calculates the score from other data // read/write all the information a normal server will broadcast // virtual void NetWrite(nMessage &m); virtual void NetRead (nMessage &m); // the same for the information the master server is responsible for virtual void MasterNetWrite(nMessage &m); // virtual void MasterNetRead (nMessage &m); virtual void Save(std::ostream &s); virtual void Load(std::istream &s); static nServerInfo *GetFirstServer(); // get the first (best) server static void Sort(); // sort the servers by score static void CalcScoreAll(); // calculate the score for all servers static void DeleteAll(bool autosave=true); // delete all server infos nConnectError Connect(); // connect to this server virtual void Alive(); // called whenever the server gave a signal of life // used to transfer small server information (adress, port, public key) // from the master server or response to a broadcast to the client static void GetSmallServerInfo(nMessage &m); // used to transfer the rest of the server info (name, number of players, // etc) from the server directly to the client static void GetBigServerInfo(nMessage &m); // request small server information from master server/broadcast static void GiveSmallServerInfo(nMessage &m); // request big server information from master server/broadcast static void GiveBigServerInfo(nMessage &m); // used to transfer the extra erver info (players, settings // etc) from the server directly to the client // static void GetExtraServerInfo(nMessage &m); // request extra server information from master server/broadcast //static void GiveExtraServerInfo(nMessage &m); // set the function that creates new server infos (so the server infos // generated by calls from the master server can be of a derived class). // returns the old function, so you can resore it later. static sn_ServerInfoCreator* SetCreator(sn_ServerInfoCreator* creator); static void Save(); // save/load all server infos static void Save(const tPath& path, const char *filename); // save/load all server infos static void Load(const tPath& path, const char *filename); static nServerInfo* GetDefaultMaster(); // get THE master server static void GetFromMaster(nServerInfo *masterInfo=NULL); // get all the basic infos from the master server static void TellMasterAboutMe(nServerInfo *masterInfo=NULL); // dedicated server: tell master server about my existence static void GetFromLAN(unsigned int pollBeginPort=4534, unsigned int pollEndPort=4544); // get all the basic infos from a LAN broadcast static void GetFromLANContinuously(unsigned int pollBeginPort=4534, unsigned int pollEndPort=4544); // get all the basic infos from a LAN broadcast; return immediately, servers will accumulate later static void GetFromLANContinuouslyStop(); // stop accepting servers from the LAN static void StartQueryAll(); // start querying the advanced info of each of the servers in our list static bool DoQueryAll(int simultaneous=10); // continue querying the advanced info of each of the servers in our list; return value: do we need to go on with this? void QueryServer(); // start to get advanced info from this server itself static void RunMaster(); // run a master server static void GetSenderData(const nMessage &m,tString& name, int& port); // information query bool Reachable() const; bool Polling() const; unsigned int TransactionNr() const {return transactionNr;} const tString& ConnectionName() const {return connectionName;} unsigned int Port() const {return port;} unsigned int Method() const {return method;} const tArray&Key() const {return key;} REAL Ping() const {return ping;} const nVersion& Version() const {return version_;} int TimesNotAnswered() const {return timesNotAnswered;} const tString& Name() const {return name;} int Users() const {return users;} int MaxUsers() const {return maxUsers_;} const tString& UserNames() const { return userNames_; } const tString& UserNamesOneLine() const { return userNamesOneLine_; } const tString& Options() const { return options_; } const tString& Url() const { return url_; } REAL Score() const {return score;} enum Compat { Compat_Ok, Compat_Downgrade, Compat_Upgrade }; Compat Compatibility() const; }; class nServerInfoAdmin { friend class nServerInfo; public: protected: nServerInfoAdmin(); virtual ~nServerInfoAdmin(); private: virtual tString GetUsers() const = 0; virtual tString GetOptions() const = 0; virtual tString GetUrl() const = 0; static nServerInfoAdmin* GetAdmin(); }; #endif