EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
EVETCPConnection.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24 */
25 
26 #include "eve-common.h"
27 
28 #include "marshal/EVEMarshal.h"
29 #include "marshal/EVEUnmarshal.h"
31 
32 /*************************************************************************/
33 /* EVETCPConnection */
34 /*************************************************************************/
35 const uint32 EVETCPConnection::TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
36 const uint32 EVETCPConnection::PACKET_SIZE_LIMIT = 1024 * 1024; // 1 megabyte
37 
39 : TCPConnection(),
40  mTimeoutTimer( TIMEOUT_MS )
41 {
42 }
43 
45 : TCPConnection( sock, rIP, rPort ),
46  mTimeoutTimer( TIMEOUT_MS )
47 {
48 }
49 
50 void EVETCPConnection::QueueRep( const PyRep* rep, bool compress/*true*/ )
51 {
52  Buffer* pBuffer = new Buffer();
53 
54  // make room for length
55  const Buffer::iterator<uint32> bufLen = pBuffer->end<uint32>();
56  pBuffer->ResizeAt( bufLen, 1 );
57 
58  if (PACKET_SIZE_LIMIT < pBuffer->size()) {
59  sLog.Error( "Network", "Packet length %u exceeds hardcoded packet length limit %lu.", pBuffer->size(), PACKET_SIZE_LIMIT );
60  SafeDelete( pBuffer );
61  return;
62  }
63 
64  bool success(false);
65  if (compress)
66  success = MarshalDeflate(rep, *pBuffer);
67  else
68  success = MarshalDeflate(rep, *pBuffer, PACKET_SIZE_LIMIT);
69 
70  if (success) {
71  // if (is_log_enabled(DEBUG__DEBUG))
72  // DumpBuffer( pBuffer, PACKET_OUTBOUND );
73  // write length
74  *bufLen = ( pBuffer->size() - sizeof( uint32 ) );
75  Send( &pBuffer );
76  } else {
77  sLog.Error( "Network", "Failed to marshal new packet." );
78  }
79 
80  PySafeDecRef(rep);
81  SafeDelete( pBuffer );
82 }
83 
85 {
86  PyRep* res(nullptr);
87 
88  MutexLock lock( mMInQueue );
89  Buffer* packet = mInQueue.PopPacket();
90 
91  if (packet != nullptr) {
92  if ( PACKET_SIZE_LIMIT < packet->size() ) {
93  sLog.Error( "Network", "Packet length %lu exceeds hardcoded packet length limit %u.", packet->size(), PACKET_SIZE_LIMIT );
94  } else {
95  // if (is_log_enabled(DEBUG__DEBUG))
96  // DumpBuffer( packet, PACKET_INBOUND );
97  res = InflateUnmarshal( *packet );
98  }
99  }
100 
101  SafeDelete( packet );
102  return res;
103 }
104 
106 {
107  if (errbuf != nullptr)
108  errbuf[0] = 0;
109 
110  MutexLock lock( mMInQueue );
111 
112  // put bytes into packetizer
114  // process packetizer
115  mInQueue.Process();
117 
118  return true;
119 }
120 
121 bool EVETCPConnection::RecvData( char* errbuf )
122 {
123  if( !TCPConnection::RecvData( errbuf ) )
124  return false;
125 
126  if( mTimeoutTimer.Check() ) {
127  if (errbuf != nullptr)
128  snprintf( errbuf, TCPCONN_ERRBUF_SIZE, "Connection timeout" );
129  return false;
130  }
131 
132  return true;
133 }
134 
136 {
139  MutexLock lock( mMInQueue );
141 }
142 
144 {
145  /*
146  FILE *logpacket;
147  char timestamp[16];
148  time_t rawtime = time(0);
149  tm *now = localtime(&rawtime);
150  strftime(timestamp,16,"%y%m%d_%H%M%S",now);
151 
152  logpacket = fopen(strcat("c:\\logs\\",strcat(timestamp,".txt")), "w");
153  Buffer:: size_type index;
154  for(index=0; index<= packet->size(); index++)
155  {
156  fputs(packet->Get(index), logpacket);
157  }
158  */
159 
160  FILE *logpacket;
161  char timestamp[16];
162  time_t rawtime = time(0);
163  tm *now = localtime(&rawtime);
164  strftime(timestamp,16,"%y%m%d_%H%M%S",now);
165 
166  std::string path = EVEMU_ROOT "/packet_log/";
167  path += timestamp;
168  if(packet_direction == PACKET_INBOUND)
169  path += "_client_";
170  else
171  path += "_server_";
172  path += ".txt";
173  logpacket = fopen(path.c_str(), "w");
174 
175  Buffer::iterator<uint8> cur = buf->begin<uint8>();
176  for (; cur != buf->end<uint8>(); ++cur) {
177  uint8 test = *cur;
178  fputc(test, logpacket);
179  }
180  fclose(logpacket);
181 }
182 
183 
Base Python wire object.
Definition: PyRep.h:66
Simple wrapper for sockets.
Definition: Socket.h:34
void ResizeAt(const_iterator< T > index, size_type requiredCount, const uint8 &fill=0)
Resizes buffer.
Definition: Buffer.h:688
unsigned __int8 uint8
Definition: eve-compat.h:46
bool MarshalDeflate(const PyRep *rep, Buffer &into, const uint32 deflationLimit)
Definition: EVEMarshal.cpp:44
static const uint32 PACKET_SIZE_LIMIT
Hardcoded limit of packet size (NetClient.dll).
PyRep * InflateUnmarshal(const Buffer &data)
Turns possibly inflated marshal stream into Python object.
packet_direction
Dumps buffer to file.
void ClearBuffers()
Clears send and receive buffers.
A lock for a Lockable object.
Definition: Lock.h:70
bool RecvData(char *errbuf=0)
Receives data and puts them into receive queue.
virtual bool RecvData(char *errbuf=0)
Receives data and puts them into receive queue.
virtual void ClearBuffers()
Clears send and receive buffers.
void QueueRep(const PyRep *rep, bool compress=true)
Queues given PyRep into send queue.
static const uint32 TIMEOUT_MS
Time (in milliseconds) after which the connection is dropped if no data were received.
PyRep * PopRep()
Pops PyRep from receive queue.
bool Send(Buffer **data)
Enqueues data to be sent.
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
static const uint32 TCPCONN_ERRBUF_SIZE
Definition: TCPConnection.h:34
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
bool ProcessReceivedData(char *errbuf=0)
Processes received data.
iterator< T > begin()
Definition: Buffer.h:381
Generic class for buffers.
Definition: Buffer.h:40
void DumpBuffer(Buffer *buf, packet_direction packet_direction)
StreamPacketizer mInQueue
Received data queue.
Buffer * mRecvBuf
#define snprintf
Definition: eve-compat.h:184
bool Check(bool reset=true)
Definition: timer.cpp:62
Generic class for TCP connections.
Definition: TCPConnection.h:45
unsigned __int32 uint32
Definition: eve-compat.h:50
EVETCPConnection()
Creates empty EVE connection.
void InputData(const Buffer &data)
Timer mTimeoutTimer
Timer used to implement timeout.
size_type size() const
Definition: Buffer.h:610
Mutex mMInQueue
Mutex to protect received data queue.
#define PySafeDecRef(op)
Definition: PyRep.h:61
unsigned __int16 uint16
Definition: eve-compat.h:48
Buffer's iterator.
Definition: Buffer.h:232
iterator< T > end()
Definition: Buffer.h:387
void Start(uint32 setTimerTime=0, bool changeResetTimer=true)
Definition: timer.cpp:81