Odamex
Setting the Standard in Multiplayer Doom
ag-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 2164 2011-05-07 20:10:55Z hypereye $
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 //
00021 // AUTHORS: 
00022 //  Russell Rice (russell at odamex dot net)
00023 //  Michael Wood (mwoodj at huntsvegas dot org)
00024 //
00025 //-----------------------------------------------------------------------------
00026 
00027 
00028 #ifndef NET_PACKET_H
00029 #define NET_PACKET_H
00030 
00031 #include <string>
00032 #include <vector>
00033 
00034 #include <agar/core.h> // For AG_Mutex
00035 #include <agar/config/ag_debug.h> // Determine if Agar is compiled for debugging
00036 
00037 #include "net_io.h"
00038 #include "typedefs.h"
00039 
00040 #define ASSEMBLEVERSION(MAJOR,MINOR,PATCH) ((MAJOR) * 256 + (MINOR)(PATCH))
00041 #define DISECTVERSION(V,MAJOR,MINOR,PATCH) \
00042 { \
00043         MAJOR = (V / 256); \
00044         MINOR = ((V % 256) / 10); \
00045         PATCH = ((V % 256) % 10); \
00046 }
00047 
00048 #define VERSIONMAJOR(V) (V / 256)
00049 #define VERSIONMINOR(V) ((V % 256) / 10)
00050 #define VERSIONPATCH(V) ((V % 256) % 10)
00051 
00052 #define VERSION (0*256+51)
00053 #define PROTOCOL_VERSION 1
00054 
00055 #define TAG_ID 0xAD0
00056 
00063 namespace agOdalaunch {
00064 
00065 const uint32_t MASTER_CHALLENGE = 777123;
00066 const uint32_t MASTER_RESPONSE  = 777123;
00067 const uint32_t SERVER_CHALLENGE = 0xAD011002;
00068 
00069 struct Cvar_t
00070 {
00071         std::string Name;
00072         std::string Value;
00073 };
00074 
00075 struct Wad_t
00076 {
00077         std::string Name;
00078         std::string Hash;
00079 };
00080 
00081 struct Team_t
00082 {
00083         std::string Name;
00084         uint32_t    Colour;
00085         int16_t     Score;
00086 };
00087 
00088 struct Player_t
00089 {
00090         std::string Name;
00091         int16_t     Frags;
00092         uint16_t    Ping;
00093         uint8_t     Team;
00094         uint16_t    Kills;
00095         uint16_t    Deaths;
00096         uint16_t    Time;
00097         bool        Spectator;
00098 };
00099 
00100 enum GameType_t
00101 {
00102         GT_Cooperative = 0
00103         ,GT_Deathmatch
00104         ,GT_TeamDeathmatch
00105         ,GT_CaptureTheFlag
00106         ,GT_Max
00107 };
00108 
00109 struct ServerInfo_t
00110 {
00111         uint32_t                 Response; // Launcher specific: Server response
00112         uint8_t                  VersionMajor; // Launcher specific: Version fields
00113         uint8_t                  VersionMinor;
00114         uint8_t                  VersionPatch;
00115         uint32_t                 VersionRevision;
00116         uint32_t                 VersionProtocol;
00117         std::string              Name; // Launcher specific: Server name
00118         uint8_t                  MaxClients; // Launcher specific: Maximum clients
00119         uint8_t                  MaxPlayers; // Launcher specific: Maximum players
00120         GameType_t               GameType; // Launcher specific: Game type
00121         uint16_t                 ScoreLimit; // Launcher specific: Score limit
00122         std::vector<Cvar_t>      Cvars;
00123         std::string              PasswordHash;
00124         std::string              CurrentMap;
00125         uint16_t                 TimeLeft;
00126         std::vector<Team_t>      Teams;
00127         std::vector<std::string> Patches;
00128         std::vector<Wad_t>       Wads;
00129         std::vector<Player_t>    Players;
00130 };
00131 
00132 class ServerBase  // [Russell] - Defines an abstract class for all packets
00133 {
00134 protected:      
00135         BufferedSocket Socket;
00136 
00137         // Magic numbers
00138         uint32_t challenge;
00139         uint32_t response;
00140 
00141         // The time in milliseconds a packet was received
00142         uint32_t Ping;
00143 
00144         AG_Mutex m_Mutex;
00145 public:
00146         // Constructor
00147         ServerBase() 
00148         {
00149                 Ping = 0;
00150                 challenge = 0;
00151                 response = 0;
00152 
00153                 AG_MutexInit(&m_Mutex);
00154         }
00155 
00156         // Destructor
00157         virtual ~ServerBase()
00158         {
00159         }
00160 
00161         // Parse a packet, the parameter is the packet
00162         virtual int32_t Parse() { return -1; }
00163 
00164         // Query the server
00165         int32_t Query(int32_t Timeout);
00166 
00167         void SetAddress(const std::string &Address, const int16_t &Port) 
00168         { 
00169                 Socket.SetRemoteAddress(Address, Port);
00170         }
00171 
00172         std::string GetAddress() const { return Socket.GetRemoteAddress(); }
00173         uint32_t GetPing() const { return Ping; }
00174 
00175 #ifdef AG_DEBUG
00176         // These funtions will cause termination on error when AG_DEBUG is enabled
00177         int GetLock() { AG_MutexLock(&m_Mutex); return 0; }
00178         int TryLock() { AG_MutexTrylock(&m_Mutex); return 0; }
00179         int Unlock() { AG_MutexUnlock(&m_Mutex); return 0; }
00180 #else
00181         int GetLock() { return AG_MutexLock(&m_Mutex); }
00182         int TryLock() { return AG_MutexTrylock(&m_Mutex); }
00183         int Unlock() { return AG_MutexUnlock(&m_Mutex); }
00184 #endif
00185 };
00186 
00187 class MasterServer : public ServerBase  // [Russell] - A master server packet
00188 {
00189 private:
00190         // Address format structure
00191         typedef struct
00192         {
00193                 std::string ip;
00194                 uint16_t    port;
00195                 bool        custom;
00196         } addr_t;
00197 
00198         std::vector<addr_t> addresses;
00199         std::vector<addr_t> masteraddresses;
00200 public:
00201         MasterServer() 
00202         { 
00203                 challenge = MASTER_CHALLENGE;
00204                 response = MASTER_CHALLENGE;
00205         }
00206 
00207         virtual ~MasterServer() 
00208         { 
00209 
00210         }
00211 
00212         size_t GetServerCount() { return addresses.size(); }
00213 
00214         bool GetServerAddress(const size_t &Index, 
00215                         std::string &Address, 
00216                         uint16_t &Port)
00217         {
00218                 if (Index < addresses.size())
00219                 {
00220                         Address = addresses[Index].ip;
00221                         Port = addresses[Index].port;
00222 
00223                         return addresses[Index].custom;
00224                 }
00225 
00226                 return false;
00227         }
00228 
00229         void AddMaster(const std::string &Address, const uint16_t &Port)
00230         {
00231                 addr_t Master = { Address, Port, true };
00232 
00233                 if ((Master.ip.size()) && (Master.port != 0))
00234                         masteraddresses.push_back(Master);
00235         }
00236 
00237         void QueryMasters(const uint32_t &Timeout)
00238         {           
00239                 DeleteAllNormalServers();
00240 
00241                 for (size_t i = 0; i < masteraddresses.size(); ++i)
00242                 {
00243                         Socket.SetRemoteAddress(masteraddresses[i].ip, masteraddresses[i].port);
00244 
00245                         Query(Timeout);
00246                 }
00247         }
00248 
00249         size_t GetMasterCount() { return masteraddresses.size(); }
00250 
00251         void DeleteAllNormalServers()
00252         {
00253                 size_t i = 0;
00254 
00255                 // don't delete our custom servers!
00256                 while (i < addresses.size())
00257                 {       
00258                         if (addresses[i].custom == false)
00259                         {
00260                                 addresses.erase(addresses.begin() + i);
00261                                 continue;
00262                         }
00263 
00264                         ++i;
00265                 }            
00266         }
00267 
00268         void AddCustomServer(const std::string &Address, const uint16_t &Port)
00269         {
00270                 addr_t cs;
00271 
00272                 cs.ip = Address;
00273                 cs.port = Port;
00274                 cs.custom = true;
00275 
00276                 // Don't add the same address more than once.
00277                 for (uint32_t i = 0; i < addresses.size(); ++i)
00278                 {
00279                         if (addresses[i].ip == cs.ip && 
00280                                         addresses[i].port == cs.port &&
00281                                         addresses[i].custom == cs.custom)
00282                         {
00283                                 return;
00284                         }
00285                 }
00286 
00287                 addresses.push_back(cs);
00288         }
00289 
00290         bool DeleteCustomServer(const size_t &Index)
00291         {
00292                 if (Index < addresses.size())
00293                 {
00294                         if (addresses[Index].custom)
00295                         {
00296                                 addresses.erase(addresses.begin() + Index);
00297 
00298                                 return true;
00299                         }
00300                         else
00301                                 return false;
00302                 }
00303 
00304                 return false;
00305         }
00306 
00307         void DeleteAllCustomServers()
00308         {
00309                 size_t i = 0;
00310 
00311                 while (i < addresses.size())
00312                 {       
00313                         if (DeleteCustomServer(i))
00314                                 continue;
00315 
00316                         ++i;
00317                 }       
00318         }
00319 
00320         int32_t Parse();
00321 };
00322 
00323 class Server : public ServerBase  // [Russell] - A single server
00324 {           
00325 public:
00326         ServerInfo_t Info;
00327 
00328         Server();
00329 
00330         void ResetData();
00331 
00332         virtual  ~Server();
00333 
00334         int32_t Query(int32_t Timeout);
00335 
00336         void ReadInformation(const uint8_t &VersionMajor, 
00337                         const uint8_t &VersionMinor,
00338                         const uint8_t &VersionPatch,
00339                         const uint32_t &ProtocolVersion);
00340 
00341         int32_t TranslateResponse(const uint16_t &TagId, 
00342                         const uint8_t &TagApplication,
00343                         const uint8_t &TagQRId,
00344                         const uint16_t &TagPacketType);
00345 
00346         bool GotResponse() const { return m_ValidResponse; }
00347 
00348         int32_t Parse();
00349 
00350 protected:
00351         bool m_ValidResponse;
00352 };
00353 
00354 } // namespace
00355 
00356 #endif // NETPACKET_H
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends