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