Show
Ignore:
Timestamp:
11/19/08 13:22:12 (17 years ago)
Author:
yumileroy
Message:

[svn] * Added ACE for Linux and Windows (Thanks Derex for Linux part and partial Windows part)
* Updated to 6721 and 676
* Fixed TrinityScript? logo
* Version updated to 0.2.6721.676

Original author: Neo2003
Date: 2008-10-04 06:17:19-05:00

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/WorldSocket.h

    r2 r6  
    1 /* 
     1/*  
    22 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> 
    33 * 
     
    1717 */ 
    1818 
    19 /// \addtogroup u2w 
    20 /// @{ 
    21 /// \file 
    22  
    23 #ifndef __WORLDSOCKET_H 
    24 #define __WORLDSOCKET_H 
    25  
    26 #include "sockets/TcpSocket.h" 
    27 #include "Auth/AuthCrypt.h" 
    28  
    29 enum ResponseCodes 
     19/** \addtogroup u2w User to World Communication 
     20 * @{ 
     21 * \file WorldSocket.h 
     22 * \author Derex <derex101@gmail.com> 
     23 */ 
     24 
     25#ifndef _WORLDSOCKET_H 
     26#define _WORLDSOCKET_H 
     27 
     28#include <ace/Basic_Types.h> 
     29#include <ace/Synch_Traits.h> 
     30#include <ace/Svc_Handler.h> 
     31#include <ace/SOCK_Stream.h> 
     32#include <ace/SOCK_Acceptor.h> 
     33#include <ace/Acceptor.h> 
     34#include <ace/Thread_Mutex.h> 
     35#include <ace/Guard_T.h> 
     36#include <ace/Unbounded_Queue.h> 
     37#include <ace/Message_Block.h> 
     38 
     39#if !defined (ACE_LACKS_PRAGMA_ONCE) 
     40#pragma once 
     41#endif /* ACE_LACKS_PRAGMA_ONCE */ 
     42 
     43#include "Common.h" 
     44#include "Auth/AuthCrypt.h"  
     45 
     46class ACE_Message_Block; 
     47class WorldPacket; 
     48class WorldSession; 
     49 
     50/// Handler that can communicate over stream sockets. 
     51typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> WorldHandler; 
     52 
     53/** 
     54 * WorldSocket. 
     55 *  
     56 * This class is responsible for the comunication with  
     57 * remote clients. 
     58 * Most methods return -1 on failure.  
     59 * The class uses refferece counting. 
     60 * 
     61 * For output the class uses one buffer (64K usually) and  
     62 * a queue where it stores packet if there is no place on  
     63 * the queue. The reason this is done, is because the server  
     64 * does realy a lot of small-size writes to it, and it doesn't  
     65 * scale well to allocate memory for every. When something is  
     66 * writen to the output buffer the socket is not immideately  
     67 * activated for output (again for the same reason), there  
     68 * is 10ms celling (thats why there is Update() method).  
     69 * This concept is simmilar to TCP_CORK, but TCP_CORK  
     70 * usses 200ms celling. As result overhead generated by  
     71 * sending packets from "producer" threads is minimal,  
     72 * and doing a lot of writes with small size is tollerated. 
     73 *  
     74 * The calls to Upate () method are managed by WorldSocketMgr 
     75 * and ReactorRunnable. 
     76 *  
     77 * For input ,the class uses one 1024 bytes buffer on stack  
     78 * to which it does recv() calls. And then recieved data is  
     79 * distributed where its needed. 1024 matches pritey well the  
     80 * traffic generated by client for now. 
     81 *   
     82 * The input/output do speculative reads/writes (AKA it tryes  
     83 * to read all data avaible in the kernel buffer or tryes to  
     84 * write everything avaible in userspace buffer),  
     85 * which is ok for using with Level and Edge Trigered IO  
     86 * notification. 
     87 *  
     88 */ 
     89class WorldSocket : protected WorldHandler 
    3090{ 
    31     RESPONSE_SUCCESS                                       = 0x00, 
    32     RESPONSE_FAILURE                                       = 0x01, 
    33     RESPONSE_CANCELLED                                     = 0x02, 
    34     RESPONSE_DISCONNECTED                                  = 0x03, 
    35     RESPONSE_FAILED_TO_CONNECT                             = 0x04, 
    36     RESPONSE_CONNECTED                                     = 0x05, 
    37     RESPONSE_VERSION_MISMATCH                              = 0x06, 
    38  
    39     CSTATUS_CONNECTING                                     = 0x07, 
    40     CSTATUS_NEGOTIATING_SECURITY                           = 0x08, 
    41     CSTATUS_NEGOTIATION_COMPLETE                           = 0x09, 
    42     CSTATUS_NEGOTIATION_FAILED                             = 0x0A, 
    43     CSTATUS_AUTHENTICATING                                 = 0x0B, 
    44  
    45     AUTH_OK                                                = 0x0C, 
    46     AUTH_FAILED                                            = 0x0D, 
    47     AUTH_REJECT                                            = 0x0E, 
    48     AUTH_BAD_SERVER_PROOF                                  = 0x0F, 
    49     AUTH_UNAVAILABLE                                       = 0x10, 
    50     AUTH_SYSTEM_ERROR                                      = 0x11, 
    51     AUTH_BILLING_ERROR                                     = 0x12, 
    52     AUTH_BILLING_EXPIRED                                   = 0x13, 
    53     AUTH_VERSION_MISMATCH                                  = 0x14, 
    54     AUTH_UNKNOWN_ACCOUNT                                   = 0x15, 
    55     AUTH_INCORRECT_PASSWORD                                = 0x16, 
    56     AUTH_SESSION_EXPIRED                                   = 0x17, 
    57     AUTH_SERVER_SHUTTING_DOWN                              = 0x18, 
    58     AUTH_ALREADY_LOGGING_IN                                = 0x19, 
    59     AUTH_LOGIN_SERVER_NOT_FOUND                            = 0x1A, 
    60     AUTH_WAIT_QUEUE                                        = 0x1B, 
    61     AUTH_BANNED                                            = 0x1C, 
    62     AUTH_ALREADY_ONLINE                                    = 0x1D, 
    63     AUTH_NO_TIME                                           = 0x1E, 
    64     AUTH_DB_BUSY                                           = 0x1F, 
    65     AUTH_SUSPENDED                                         = 0x20, 
    66     AUTH_PARENTAL_CONTROL                                  = 0x21, 
    67     AUTH_LOCKED_ENFORCED                                   = 0x22, 
    68  
    69     REALM_LIST_IN_PROGRESS                                 = 0x23, 
    70     REALM_LIST_SUCCESS                                     = 0x24, 
    71     REALM_LIST_FAILED                                      = 0x25, 
    72     REALM_LIST_INVALID                                     = 0x26, 
    73     REALM_LIST_REALM_NOT_FOUND                             = 0x27, 
    74  
    75     ACCOUNT_CREATE_IN_PROGRESS                             = 0x28, 
    76     ACCOUNT_CREATE_SUCCESS                                 = 0x29, 
    77     ACCOUNT_CREATE_FAILED                                  = 0x2A, 
    78  
    79     CHAR_LIST_RETRIEVING                                   = 0x2B, 
    80     CHAR_LIST_RETRIEVED                                    = 0x2C, 
    81     CHAR_LIST_FAILED                                       = 0x2D, 
    82  
    83     CHAR_CREATE_IN_PROGRESS                                = 0x2E, 
    84     CHAR_CREATE_SUCCESS                                    = 0x2F, 
    85     CHAR_CREATE_ERROR                                      = 0x30, 
    86     CHAR_CREATE_FAILED                                     = 0x31, 
    87     CHAR_CREATE_NAME_IN_USE                                = 0x32, 
    88     CHAR_CREATE_DISABLED                                   = 0x33, 
    89     CHAR_CREATE_PVP_TEAMS_VIOLATION                        = 0x34, 
    90     CHAR_CREATE_SERVER_LIMIT                               = 0x35, 
    91     CHAR_CREATE_ACCOUNT_LIMIT                              = 0x36, 
    92     CHAR_CREATE_SERVER_QUEUE                               = 0x37, 
    93     CHAR_CREATE_ONLY_EXISTING                              = 0x38, 
    94     CHAR_CREATE_EXPANSION                                  = 0x39, 
    95  
    96     CHAR_DELETE_IN_PROGRESS                                = 0x3A, 
    97     CHAR_DELETE_SUCCESS                                    = 0x3B, 
    98     CHAR_DELETE_FAILED                                     = 0x3C, 
    99     CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER                 = 0x3D, 
    100     CHAR_DELETE_FAILED_GUILD_LEADER                        = 0x3E, 
    101     CHAR_DELETE_FAILED_ARENA_CAPTAIN                       = 0x3F, 
    102  
    103     CHAR_LOGIN_IN_PROGRESS                                 = 0x40, 
    104     CHAR_LOGIN_SUCCESS                                     = 0x41, 
    105     CHAR_LOGIN_NO_WORLD                                    = 0x42, 
    106     CHAR_LOGIN_DUPLICATE_CHARACTER                         = 0x43, 
    107     CHAR_LOGIN_NO_INSTANCES                                = 0x44, 
    108     CHAR_LOGIN_FAILED                                      = 0x45, 
    109     CHAR_LOGIN_DISABLED                                    = 0x46, 
    110     CHAR_LOGIN_NO_CHARACTER                                = 0x47, 
    111     CHAR_LOGIN_LOCKED_FOR_TRANSFER                         = 0x48, 
    112     CHAR_LOGIN_LOCKED_BY_BILLING                           = 0x49, 
    113  
    114     CHAR_NAME_SUCCESS                                      = 0x4A, 
    115     CHAR_NAME_FAILURE                                      = 0x4B, 
    116     CHAR_NAME_NO_NAME                                      = 0x4C, 
    117     CHAR_NAME_TOO_SHORT                                    = 0x4D, 
    118     CHAR_NAME_TOO_LONG                                     = 0x4E, 
    119     CHAR_NAME_INVALID_CHARACTER                            = 0x4F, 
    120     CHAR_NAME_MIXED_LANGUAGES                              = 0x50, 
    121     CHAR_NAME_PROFANE                                      = 0x51, 
    122     CHAR_NAME_RESERVED                                     = 0x52, 
    123     CHAR_NAME_INVALID_APOSTROPHE                           = 0x53, 
    124     CHAR_NAME_MULTIPLE_APOSTROPHES                         = 0x54, 
    125     CHAR_NAME_THREE_CONSECUTIVE                            = 0x55, 
    126     CHAR_NAME_INVALID_SPACE                                = 0x56, 
    127     CHAR_NAME_CONSECUTIVE_SPACES                           = 0x57, 
    128     CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS        = 0x58, 
    129     CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59, 
    130     CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME            = 0x5A, 
     91public: 
     92  /// Declare some friends 
     93  friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >; 
     94  friend class WorldSocketMgr; 
     95  friend class ReactorRunnable; 
     96 
     97  /// Declare the acceptor for this class 
     98  typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor; 
     99 
     100  /// Mutex type used for various syncronizations. 
     101  typedef ACE_Thread_Mutex LockType; 
     102  typedef ACE_Guard<LockType> GuardType; 
     103 
     104  /// Queue for storing packets for which there is no space. 
     105  typedef ACE_Unbounded_Queue< WorldPacket* > PacketQueueT; 
     106 
     107  /// Check if socket is closed. 
     108  bool IsClosed (void) const; 
     109 
     110  /// Close the socket. 
     111  void CloseSocket (void); 
     112 
     113  /// Get address of connected peer. 
     114  const std::string& GetRemoteAddress (void) const; 
     115 
     116  /// Send A packet on the socket, this function is reentrant. 
     117  /// @param pct packet to send 
     118  /// @return -1 of failure 
     119  int SendPacket (const WorldPacket& pct); 
     120 
     121  /// Add refference to this object. 
     122  long AddReference (void); 
     123 
     124  /// Remove refference to this object. 
     125  long RemoveReference (void); 
     126 
     127protected: 
     128  /// things called by ACE framework. 
     129  WorldSocket (void); 
     130  virtual ~WorldSocket (void); 
     131 
     132  /// Called on open ,the void* is the acceptor. 
     133  virtual int open (void *); 
     134 
     135  /// Called on failures inside of the acceptor, don't call from your code. 
     136  virtual int close (int); 
     137 
     138  /// Called when we can read from the socket. 
     139  virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); 
     140 
     141  /// Called when the socket can write. 
     142  virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE); 
     143 
     144  /// Called when connection is closed or error happens. 
     145  virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, 
     146                            ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 
     147 
     148  /// Called by WorldSocketMgr/ReactorRunnable. 
     149  int Update (void); 
     150 
     151private: 
     152  /// Helper functions for processing incoming data. 
     153  int handle_input_header (void); 
     154  int handle_input_payload (void); 
     155  int handle_input_missing_data (void); 
     156 
     157  /// Help functions to mark/unmark the socket for output. 
     158  /// @param g the guard is for m_OutBufferLock, the function will release it 
     159  int cancel_wakeup_output (GuardType& g); 
     160  int schedule_wakeup_output (GuardType& g); 
     161 
     162  /// process one incoming packet. 
     163  /// @param new_pct received packet ,note that you need to delete it.  
     164  int ProcessIncoming (WorldPacket* new_pct); 
     165 
     166  /// Called by ProcessIncoming() on CMSG_AUTH_SESSION. 
     167  int HandleAuthSession (WorldPacket& recvPacket); 
     168 
     169  /// Called by ProcessIncoming() on CMSG_PING. 
     170  int HandlePing (WorldPacket& recvPacket); 
     171 
     172  /// Try to write WorldPacket to m_OutBuffer ,return -1 if no space 
     173  /// Need to be called with m_OutBufferLock lock held 
     174  int iSendPacket (const WorldPacket& pct); 
     175 
     176  /// Flush m_PacketQueue if there are packets in it 
     177  /// Need to be called with m_OutBufferLock lock held 
     178  /// @return true if it wrote to the buffer ( AKA you need  
     179  /// to mark the socket for output ). 
     180  bool iFlushPacketQueue (); 
     181 
     182private: 
     183  /// Time in which the last ping was received 
     184  ACE_Time_Value m_LastPingTime; 
     185   
     186  /// Keep track of overspeed pings ,to prevent ping flood. 
     187  uint32 m_OverSpeedPings; 
     188 
     189  /// Address of the remote peer 
     190  std::string m_Address; 
     191 
     192  /// Class used for managing encryption of the headers 
     193  AuthCrypt m_Crypt; 
     194 
     195  /// Mutex lock to protect m_Session 
     196  LockType m_SessionLock; 
     197 
     198  /// Session to which recieved packets are routed 
     199  WorldSession* m_Session; 
     200 
     201  /// here are stored the fragmens of the recieved data 
     202  WorldPacket* m_RecvWPct; 
     203 
     204  /// This block actually refers to m_RecvWPct contents, 
     205  /// which alows easy and safe writing to it.  
     206  /// It wont free memory when its deleted. m_RecvWPct takes care of freeing. 
     207  ACE_Message_Block m_RecvPct; 
     208 
     209  /// Fragment of the recieved header. 
     210  ACE_Message_Block m_Header; 
     211 
     212  /// Mutex for protecting otuput related data. 
     213  LockType m_OutBufferLock; 
     214 
     215  /// Buffer used for writing output. 
     216  ACE_Message_Block *m_OutBuffer; 
     217 
     218  /// Size of the m_OutBuffer. 
     219  size_t m_OutBufferSize; 
     220 
     221  /// Here are stored packets for which there was no space on m_OutBuffer, 
     222  /// this alows not-to kick player if its buffer is overflowed. 
     223  PacketQueueT m_PacketQueue; 
     224 
     225  /// True if the socket is registered with the reactor for output 
     226  bool m_OutActive; 
     227 
     228  uint32 m_Seed; 
    131229}; 
    132230 
    133 class WorldPacket; 
    134 class SocketHandler; 
    135 class WorldSession; 
    136  
    137 /// Handle connection with the client software 
    138 class WorldSocket : public TcpSocket 
    139 { 
    140     public: 
    141         WorldSocket(ISocketHandler&); 
    142         ~WorldSocket(); 
    143  
    144         void SendPacket(WorldPacket const* packet); 
    145         void CloseSocket(); 
    146  
    147         void OnAccept(); 
    148         void OnRead(); 
    149         void OnDelete(); 
    150  
    151         void Update(time_t diff); 
    152         // Player Queue 
    153         void SendAuthWaitQue(uint32 position); 
    154  
    155         WorldSession* GetSession() const { return _session; } 
    156     protected: 
    157         void SendSinglePacket(); 
    158  
    159     protected: 
    160         void _HandleAuthSession(WorldPacket& recvPacket); 
    161         void _HandlePing(WorldPacket& recvPacket); 
    162  
    163     private: 
    164         AuthCrypt _crypt; 
    165         uint32 _seed; 
    166         uint32 _cmd; 
    167         uint16 _remaining; 
    168         WorldSession* _session; 
    169  
    170         ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _sendQueue; 
    171  
    172         uint32 m_LastPingMSTime; 
    173         uint32 m_OverSpeedPings; 
    174  
    175         // internal checks 
    176         void SizeError(WorldPacket const& packet, uint32 size) const; 
    177 }; 
    178 #endif 
     231#endif  /* _WORLDSOCKET_H */ 
     232 
    179233/// @}