Odamex
Setting the Standard in Multiplayer Doom
odalaunch/src/net_packet.h
Go to the documentation of this file.
00001 // Emacs style mode select   -*- C++ -*- 
00002 //-----------------------------------------------------------------------------
00003 //
00004 // $Id: net_packet.h 2042 2010-12-13 21:20:42Z russellrice $
00005 //
00006 // Copyright (C) 2006-2010 by The Odamex Team.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // DESCRIPTION:  
00019 //      Launcher packet structure file
00020 //  AUTHOR:     Russell Rice (russell at odamex dot net)
00021 //
00022 //-----------------------------------------------------------------------------
00023 
00024 
00025 #ifndef NET_PACKET_H
00026 #define NET_PACKET_H
00027 
00028 #include <wx/mstream.h>
00029 #include <wx/datstrm.h>
00030 #include <wx/log.h>
00031 
00032 #include <vector>
00033 
00034 #include "net_io.h"
00035 
00036 // Default server port
00037 #define DEF_SERVERPORT 10666
00038 
00039 #define MASTER_CHALLENGE    777123
00040 #define MASTER_RESPONSE     777123
00041 #define SERVER_CHALLENGE    0xAD011002
00042 
00043 #define ASSEMBLEVERSION(MAJOR,MINOR,PATCH) ((MAJOR) * 256 + (MINOR)(PATCH))
00044 #define DISECTVERSION(V,MAJOR,MINOR,PATCH) \
00045         { \
00046             MAJOR = (V / 256); \
00047             MINOR = ((V % 256) / 10); \
00048             PATCH = ((V % 256) % 10); \
00049         }
00050 
00051 #define VERSIONMAJOR(V) (V / 256)
00052 #define VERSIONMINOR(V) ((V % 256) / 10)
00053 #define VERSIONPATCH(V) ((V % 256) % 10)
00054 
00055 #define VERSION (0*256+51)
00056 #define PROTOCOL_VERSION 2
00057 
00058 #define TAG_ID 0xAD0
00059 
00060 struct Cvar_t
00061 {
00062     wxString Name;
00063     wxString Value;
00064 };
00065 
00066 struct Wad_t
00067 {
00068     wxString Name;
00069     wxString Hash;
00070 };
00071 
00072 struct Team_t
00073 {
00074     wxString Name;
00075     wxUint32 Colour;
00076     wxInt16 Score;
00077 };
00078 
00079 struct Player_t
00080 {
00081     wxString Name;
00082     wxInt16 Frags;
00083     wxUint16 Ping;
00084     wxUint8 Team;
00085     wxUint16 Kills;
00086     wxUint16 Deaths;
00087     wxUint16 Time;
00088     bool Spectator;
00089 };
00090 
00091 enum GameType_t
00092 {
00093      GT_Cooperative = 0
00094     ,GT_Deathmatch
00095     ,GT_TeamDeathmatch
00096     ,GT_CaptureTheFlag
00097     ,GT_Max
00098 };
00099 
00100 struct ServerInfo_t
00101 {
00102     wxUint32 Response; // Launcher specific: Server response
00103     wxUint8 VersionMajor; // Launcher specific: Version fields
00104     wxUint8 VersionMinor;
00105     wxUint8 VersionPatch;
00106     wxUint32 VersionProtocol;
00107     wxUint32 VersionRealProtocol;
00108     wxUint32 VersionRevision;
00109     wxUint32 PTime;
00110     wxString Name; // Launcher specific: Server name
00111     wxUint8 MaxClients; // Launcher specific: Maximum clients
00112     wxUint8 MaxPlayers; // Launcher specific: Maximum players
00113     GameType_t GameType; // Launcher specific: Game type
00114     wxUint16 ScoreLimit; // Launcher specific: Score limit
00115     std::vector<Cvar_t> Cvars;
00116     wxString PasswordHash;
00117     wxString CurrentMap;
00118     wxUint16 TimeLeft;
00119     std::vector<Team_t> Teams;
00120     std::vector<wxString> Patches;
00121     std::vector<Wad_t> Wads;
00122     std::vector<Player_t> Players;
00123 };
00124 
00125 class ServerBase  // [Russell] - Defines an abstract class for all packets
00126 {
00127     protected:      
00128         BufferedSocket Socket;
00129         
00130         // Magic numbers
00131         wxUint32 challenge;
00132         wxUint32 response;
00133            
00134         // The time in milliseconds a packet was received
00135         wxUint32 Ping;
00136     public:
00137         // Constructor
00138         ServerBase() 
00139         {
00140             Ping = 0;
00141             challenge = 0;
00142             response = 0;
00143         }
00144         
00145         // Destructor
00146         virtual ~ServerBase()
00147         {
00148         }
00149         
00150         // Parse a packet, the parameter is the packet
00151         virtual wxInt32 Parse() { return -1; }
00152         
00153         // Query the server
00154         wxInt32 Query(wxInt32 Timeout);
00155         
00156                 void SetAddress(const wxString &Address, const wxInt16 &Port) 
00157                 { 
00158                     Socket.SetRemoteAddress(Address, Port);
00159         }
00160         
00161                 wxString GetAddress() const { return Socket.GetRemoteAddress(); }
00162                 wxUint32 GetPing() const { return Ping; }
00163 };
00164 
00165 class MasterServer : public ServerBase  // [Russell] - A master server packet
00166 {
00167     private:
00168         // Address format structure
00169         typedef struct
00170         {
00171             wxString    ip;
00172             wxUint16    port;
00173             bool        custom;
00174         } addr_t;
00175 
00176         std::vector<addr_t> addresses;
00177         std::vector<addr_t> masteraddresses;
00178     public:
00179         MasterServer() 
00180         { 
00181             challenge = MASTER_CHALLENGE;
00182             response = MASTER_CHALLENGE;
00183         }
00184         
00185         virtual ~MasterServer() 
00186         { 
00187 
00188         }
00189         
00190                 size_t GetServerCount() { return addresses.size(); }
00191                       
00192         bool GetServerAddress(const size_t &Index, 
00193                               wxString &Address, 
00194                               wxUint16 &Port)
00195         {
00196             if (Index < addresses.size())
00197             {
00198                 Address = addresses[Index].ip;
00199                 Port = addresses[Index].port;
00200                 
00201                 return addresses[Index].custom;
00202             }
00203             
00204             return false;
00205         }
00206         
00207         void AddMaster(const wxString &Address, const wxUint16 &Port)
00208         {
00209             addr_t Master = { Address, Port, true };
00210             
00211             if ((Master.ip != _T("")) && (Master.port != 0))
00212                 masteraddresses.push_back(Master);
00213         }
00214         
00215         void QueryMasters(const wxUint32 &Timeout)
00216         {           
00217             DeleteAllNormalServers();
00218             
00219             for (size_t i = 0; i < masteraddresses.size(); ++i)
00220             {
00221                 Socket.SetRemoteAddress(masteraddresses[i].ip, masteraddresses[i].port);
00222                 
00223                 Query(Timeout);
00224             }
00225         }
00226         
00227         size_t GetMasterCount() { return masteraddresses.size(); }
00228         
00229         void DeleteAllNormalServers()
00230         {
00231             size_t i = 0;
00232             
00233             // don't delete our custom servers!
00234             while (i < addresses.size())
00235             {       
00236                 if (addresses[i].custom == false)
00237                 {
00238                     addresses.erase(addresses.begin() + i);
00239                     continue;
00240                 }
00241                 
00242                 ++i;
00243             }            
00244         }
00245         
00246         void AddCustomServer(const wxString &Address, const wxUint16 &Port)
00247         {
00248             addr_t cs;
00249                     
00250             cs.ip = Address;
00251             cs.port = Port;
00252             cs.custom = true;
00253             
00254             // Don't add the same address more than once.
00255             for (wxUint32 i = 0; i < addresses.size(); ++i)
00256             {
00257                 if (addresses[i].ip == cs.ip && 
00258                     addresses[i].port == cs.port &&
00259                     addresses[i].custom == cs.custom)
00260                 {
00261                     return;
00262                 }
00263             }
00264             
00265             addresses.push_back(cs);
00266         }
00267                
00268         bool DeleteCustomServer(const size_t &Index)
00269         {
00270             if (Index < addresses.size())
00271             {
00272                 if (addresses[Index].custom)
00273                 {
00274                     addresses.erase(addresses.begin() + Index);
00275                     
00276                     return true;
00277                 }
00278                 else
00279                     return false;
00280             }
00281             
00282             return false;
00283         }
00284 
00285         void DeleteAllCustomServers()
00286         {
00287             size_t i = 0;
00288             
00289             while (i < addresses.size())
00290             {       
00291                 if (DeleteCustomServer(i))
00292                     continue;
00293                 
00294                 ++i;
00295             }       
00296         }
00297         
00298         wxInt32 Parse();
00299 };
00300 
00301 class Server : public ServerBase  // [Russell] - A single server
00302 {           
00303    
00304     public:
00305         ServerInfo_t Info;
00306         
00307         Server();
00308         
00309         void ResetData();
00310         
00311         virtual  ~Server();
00312         
00313         wxInt32 Query(wxInt32 Timeout);
00314         
00315         void ReadInformation(const wxUint8 &VersionMajor, 
00316                              const wxUint8 &VersionMinor,
00317                              const wxUint8 &VersionPatch,
00318                              const wxUint32 &ProtocolVersion);
00319         
00320         wxInt32 TranslateResponse(const wxUint16 &TagId, 
00321                                   const wxUint8 &TagApplication,
00322                                   const wxUint8 &TagQRId,
00323                                   const wxUint16 &TagPacketType);
00324 
00325         bool GotResponse() const { return m_ValidResponse; }
00326 
00327         wxInt32 Parse();
00328     
00329     protected:
00330         bool m_ValidResponse;
00331 };
00332 
00333 #endif // NETPACKET_H
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends