123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- EQ2Emulator: Everquest II Server Emulator
- Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
- This file is part of EQ2Emulator.
- EQ2Emulator 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 3 of the License, or
- (at your option) any later version.
- EQ2Emulator 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 EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef _EQPROTOCOL_H
- #define _EQPROTOCOL_H
- #include <string>
- #include <vector>
- #include <deque>
- #include <map>
- #include <set>
- #ifndef WIN32
- #include <netinet/in.h>
- #endif
- #include "EQPacket.h"
- #include "Mutex.h"
- #include "opcodemgr.h"
- #include "misc.h"
- #include "Condition.h"
- #include "Crypto.h"
- #include "zlib.h"
- #include "timer.h"
- using namespace std;
- typedef enum {
- ESTABLISHED,
- CLOSING,
- CLOSED
- } EQStreamState;
- #define FLAG_COMPRESSED 0x01
- #define FLAG_ENCODED 0x04
- #define RATEBASE 1048576 // 1 MB
- #define DECAYBASE 78642 // RATEBASE/10
- #pragma pack(1)
- struct SessionRequest {
- uint32 UnknownA;
- uint32 Session;
- uint32 MaxLength;
- };
- struct SessionResponse {
- uint32 Session;
- uint32 Key;
- uint8 UnknownA;
- uint8 Format;
- uint8 UnknownB;
- uint32 MaxLength;
- uint32 UnknownD;
- };
- //Deltas are in ms, representing round trip times
- struct ClientSessionStats {
- /*000*/ uint16 RequestID;
- /*002*/ uint32 last_local_delta;
- /*006*/ uint32 average_delta;
- /*010*/ uint32 low_delta;
- /*014*/ uint32 high_delta;
- /*018*/ uint32 last_remote_delta;
- /*022*/ uint64 packets_sent;
- /*030*/ uint64 packets_recieved;
- /*038*/
- };
- struct ServerSessionStats {
- uint16 RequestID;
- uint32 current_time;
- uint32 unknown1;
- uint32 received_packets;
- uint32 unknown2;
- uint32 sent_packets;
- uint32 unknown3;
- uint32 sent_packets2;
- uint32 unknown4;
- uint32 received_packets2;
- };
-
- #pragma pack()
- class OpcodeManager;
- extern OpcodeManager *EQNetworkOpcodeManager;
- class EQStreamFactory;
- typedef enum {
- UnknownStream=0,
- LoginStream,
- WorldStream,
- ZoneStream,
- ChatOrMailStream,
- ChatStream,
- MailStream,
- EQ2Stream,
- } EQStreamType;
- class EQStream {
- protected:
- uint32 received_packets;
- uint32 sent_packets;
- uint32 remote_ip;
- uint16 remote_port;
- uint8 buffer[8192];
- unsigned char *oversize_buffer;
- uint32 oversize_offset,oversize_length;
- uint8 app_opcode_size;
- EQStreamType StreamType;
- bool compressed,encoded;
- //uint32 buffer_len;
- uint32 Session, Key;
- uint16 NextInSeq;
- uint16 NextOutSeq;
- uint32 MaxLen;
- uint16 MaxSends;
- int8 timeout_delays;
- uint8 active_users; //how many things are actively using this
- Mutex MInUse;
- EQStreamState State;
- Mutex MState;
- uint32 LastPacket;
- Mutex MVarlock;
- EQApplicationPacket* CombinedAppPacket;
- Mutex MCombinedAppPacket;
- long LastSeqSent;
- Mutex MLastSeqSent;
- void SetLastSeqSent(uint32);
- // Ack sequence tracking.
- long MaxAckReceived,NextAckToSend,LastAckSent;
- long GetMaxAckReceived();
- long GetNextAckToSend();
- long GetLastAckSent();
- void SetMaxAckReceived(uint32 seq);
- void SetNextAckToSend(uint32);
- void SetLastAckSent(uint32);
- Mutex MAcks;
- // Packets waiting to be sent
- deque<EQProtocolPacket *> NonSequencedQueue;
- deque<EQProtocolPacket *> SequencedQueue;
- map<uint16, EQProtocolPacket *> OutOfOrderpackets;
- Mutex MOutboundQueue;
- // Packes waiting to be processed
- deque<EQApplicationPacket *> InboundQueue;
- Mutex MInboundQueue;
- static uint16 MaxWindowSize;
- sint32 BytesWritten;
- Mutex MRate;
- sint32 RateThreshold;
- sint32 DecayRate;
- EQStreamFactory *Factory;
- public:
- Mutex MCombineQueueLock;
- bool CheckCombineQueue();
- deque<EQ2Packet*> combine_queue;
- Timer* combine_timer;
- Crypto* crypto;
- int8 EQ2_Compress(EQ2Packet* app, int8 offset = 3);
- z_stream stream;
- uchar* stream_buffer;
- int32 stream_buffer_size;
- bool eq2_compressed;
- int8 compressed_offset;
- int16 client_version;
- int16 GetClientVersion(){ return client_version; }
- void SetClientVersion(int16 version){ client_version = version; }
- EQStream() { init(); remote_ip = 0; remote_port = 0; State = CLOSED; StreamType = UnknownStream; compressed = true;
- encoded = false; app_opcode_size = 2;}
- EQStream(sockaddr_in addr);
- virtual ~EQStream() {
- RemoveData();
- safe_delete(crypto);
- safe_delete(combine_timer);
- safe_delete(resend_que_timer);
- safe_delete_array(oversize_buffer);
- deque<EQ2Packet*>::iterator cmb;
- MCombineQueueLock.lock();
- for (cmb = combine_queue.begin(); cmb != combine_queue.end(); cmb++){
- safe_delete(*cmb);
- }
- MCombineQueueLock.unlock();
- deflateEnd(&stream);
- map<int16, EQProtocolPacket*>::iterator oop;
- for (oop = OutOfOrderpackets.begin(); oop != OutOfOrderpackets.end(); oop++){
- safe_delete(oop->second);
- }
- }
- inline void SetFactory(EQStreamFactory *f) { Factory=f; }
- void init();
- void SetMaxLen(uint32 length) { MaxLen=length; }
- int8 getTimeoutDelays(){ return timeout_delays; }
- void addTimeoutDelay(){ timeout_delays++; }
- void EQ2QueuePacket(EQ2Packet* app, bool attempted_combine = false);
- void PreparePacket(EQ2Packet* app, int8 offset = 0);
- void UnPreparePacket(EQ2Packet* app);
- void EncryptPacket(EQ2Packet* app, int8 compress_offset, int8 offset);
- void FlushCombinedPacket();
- void SendPacket(EQApplicationPacket *p);
- void QueuePacket(EQProtocolPacket *p);
- void SendPacket(EQProtocolPacket *p);
- vector<EQProtocolPacket *> convert(EQApplicationPacket *p);
- void NonSequencedPush(EQProtocolPacket *p);
- void SequencedPush(EQProtocolPacket *p);
- Mutex MResendQue;
- Mutex MCompressData;
- deque<EQProtocolPacket*>resend_que;
- void CheckResend(int eq_fd);
- void Write(int eq_fd);
- void WritePacket(int fd,EQProtocolPacket *p);
- void EncryptPacket(uchar* data, int16 size);
- uint32 GetKey() { return Key; }
- void SetKey(uint32 k) { Key=k; }
- void SetSession(uint32 s) { Session=s; }
- void SetLastPacketTime(uint32 t) {LastPacket=t;}
- void Process(const unsigned char *data, const uint32 length);
- void ProcessPacket(EQProtocolPacket *p);
- bool HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset = 2, int16 length = 0);
- EQProtocolPacket * ProcessEncryptedPacket(EQProtocolPacket *p);
- EQProtocolPacket * ProcessEncryptedData(uchar* data, int32 size, int16 opcode);
- virtual void DispatchPacket(EQApplicationPacket *p) { p->DumpRaw(); }
- void SendSessionResponse();
- void SendSessionRequest();
- void SendDisconnect(bool setstate = true);
- void SendAck(uint16 seq);
- void SendOutOfOrderAck(uint16 seq);
- bool CheckTimeout(uint32 now, uint32 timeout=30) { return (LastPacket && (now-LastPacket) > timeout); }
- bool Stale(uint32 now, uint32 timeout=30) { return (LastPacket && (now-LastPacket) > timeout); }
- void InboundQueuePush(EQApplicationPacket *p);
- EQApplicationPacket *PopPacket(); // InboundQueuePop
- void InboundQueueClear();
- void OutboundQueueClear();
- bool HasOutgoingData();
- void SendKeyRequest();
- int16 processRSAKey(EQProtocolPacket *p);
- void RemoveData() { InboundQueueClear(); OutboundQueueClear(); if (CombinedAppPacket) delete CombinedAppPacket; }
- //
- inline bool IsInUse() { bool flag; MInUse.lock(); flag=(active_users>0); MInUse.unlock(); return flag; }
- inline void PutInUse() { MInUse.lock(); active_users++; MInUse.unlock(); }
- inline void ReleaseFromUse() { MInUse.lock(); if(active_users > 0) active_users--; MInUse.unlock(); }
-
- inline EQStreamState GetState() { return State; }
- inline void SetState(EQStreamState state) { State=state; }
- inline uint32 GetRemoteIP() { return remote_ip; }
- inline uint32 GetrIP() { return remote_ip; }
- inline uint16 GetRemotePort() { return remote_port; }
- inline uint16 GetrPort() { return remote_port; }
-
- static EQProtocolPacket *Read(int eq_fd, sockaddr_in *from);
- static sint8 CompareSequence(uint16 expected_seq , uint16 seq);
- void Close() { SendDisconnect(); }
- bool CheckActive() { return GetState()==ESTABLISHED; }
- bool CheckClosed() { return GetState()==CLOSED; }
- void SetOpcodeSize(uint8 s) { app_opcode_size = s; }
- void SetStreamType(EQStreamType t);
- inline const EQStreamType GetStreamType() const { return StreamType; }
- void Decay();
- void AdjustRates(uint32 average_delta);
- Timer* resend_que_timer;
- };
- #endif
|