|
Odamex
Setting the Standard in Multiplayer Doom
|
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