Ir ao conteúdo
  • Cadastre-se

CorelioCRVG

Membro Júnior
  • Posts

    1
  • Cadastrado em

  • Última visita

Reputação

0
  1. Boa tarde, amigos. Estou com um pequeno problema! Estou com um servidor de um jogo onde tem ocorrido uma grande quantidade de lag por conta das velocidades atuais de internet e o meu código Winsock é de 2001 onde as velocidades eram outras. Eu preciso reescrever este código para atualizar para as novas velocidades. Alguém pode me dar uma luz em como resolver? Segue o código: #ifndef _SMWSOCK_HEADER #define _SMWSOCK_HEADER #include "nettype.hpp" #define _PS_TALE #ifdef _PS_TALE #define TCP_GAMEPORT 8180 #include "language.h" #ifdef _LANGUAGE_KOREAN #ifdef _TEST_SERVER #define TCP_SERVPORT 10009 #else #define TCP_SERVPORT 10003 #endif #endif #ifdef _LANGUAGE_CHINESE #define TCP_SERVPORT 10004 #endif #ifdef _LANGUAGE_TAIWAN #define TCP_SERVPORT 10005 #endif #ifdef _LANGUAGE_JAPANESE #define TCP_SERVPORT 10006 #endif #ifdef _LANGUAGE_ENGLISH #ifdef _LANGUAGE_PHILIPIN #define TCP_SERVPORT 10010 #else #define TCP_SERVPORT 10007 #endif #endif #ifdef _LANGUAGE_VEITNAM #define TCP_SERVPORT 10011 #endif #ifdef _LANGUAGE_BRAZIL //#define TCP_SERVPORT 10031 #define TCP_SERVPORT 10032 //#define TCP_SERVPORT 10033 #endif #ifdef _LANGUAGE_ARGENTINA #define TCP_SERVPORT 10014 #endif #ifdef _LANGUAGE_THAI #define TCP_SERVPORT 10008 #endif #ifdef _W_SERVER #ifdef _W_DATA_SERVER #define CONNECTMAX 4096 #define CONNECTMAX_MASK 4095 #else #define CONNECTMAX 1024 #define CONNECTMAX_MASK 1023 #endif #else #define CONNECTMAX 64 #define CONNECTMAX_MASK 63 #endif #else #define CONNECTMAX 1024 #define CONNECTMAX_MASK 1023 #endif #define smSOCKBUFF_SIZE 16384 extern int smTransThreadMode; extern int smTransTurbRcvMode; class smWINSOCK ; struct smTHREADSOCK { smWINSOCK *smMySock; SOCKET Sock; int RecvLen; int RecvCode; int BuffCnt; int NewData; int Sucess; int Sleep; int SendReady; DWORD dwExitThread; DWORD dwAcessTime; char Buff[smSOCKBUFF_SIZE+256]; }; struct smTHREAD_ROUTE { smTHREAD_ROUTE *MyPoint; int Sleep; int TimeOut; smTHREADSOCK *smThreadSock; DWORD dwSleepTime; HANDLE hThread; }; #define ENC_PACKET_REC_MAX 16 #define ENC_PACKET_REC_MASK 15 class smWINSOCK { public: smWINSOCK *MyPoint; DWORD MyNum; SOCKET sock; void *ExtData1; void *ExtData2; void *ExtData3; void *ExtData4; HANDLE hRecvThread; HANDLE hSendThread; smTHREADSOCK smRecvState; smTHREADSOCK smSendState; smTHREAD_ROUTE *lpsmRecvRoute; smTHREAD_ROUTE *lpsmSendRoute; int online; int status; char szBuff[128]; char szIPAddr[16]; DWORD dwPort; DWORD dwLastRecvTime; DWORD dwDeadLockTime; int WaitReadMessage; int PostReadMessage; int PacketSendQueCnt; int EncPacketSendCount; int EncPacketRecvCount; int EncRecvPackets[ENC_PACKET_REC_MAX]; int EncRecvPacketCnt; int ConnectDirection; SOCKADDR_IN local_sin; SOCKADDR_IN acc_sin; int acc_sin_len; DWORD dwRecvSusCount; int RecvPacketCount; int SendPacketCount; int RecvPopCount; int RecvPopErrorCount; int SendPacketErrorCount; int RecvPacketErrorCount; DWORD dwEncPacketCode; BYTE bEncXor; BYTE bDecXor; public: smWINSOCK(); ~smWINSOCK(); int mesAccept( WPARAM wParam , LPARAM lParam ); int mesReceve( LPARAM lParam ); int Send( char *SendData , int len , int ImpMode=0 ); int Send2( char *SendData , int len , int ImpMode=0 ); int Send3( char *SendData , int len , int ImpMode=0 ); int CheckEncRecvPacket( int RecvCount ); int PushEncRecvPacket( int RecvCount ); int CloseSocket(); int ReconnectSock(); int ConnectSock( char *szIP , WORD port ); int CreateTransThread( int Mode ); }; extern smWINSOCK smWSock[CONNECTMAX]; #define WSA_ACCEPT (WM_USER + 0) #define WSA_READ (WM_USER + 1) #define SWM_SENDSUCCESS (WM_USER + 10) #define SWM_RECVSUCCESS (WM_USER + 11) #define SWM_MCONNECT (WM_USER + 12) #define SWM_MDISCONNECT (WM_USER + 13) extern int smTransRecvErrorCnt; extern int smTransSendErrorCnt; extern int smTransRecvErrorDisCnt; extern int smTransSendErrorDisCnt; extern int smTransClearErrorCnt; extern int smRcvBuffOverCount; void InitBindSock( int port ); void InitGameSocket( int ThreadMode=0 ); void CloseBindSock(); char *smGetMyIp(); DWORD smGetMyIp2(); char *ConvStrIP( DWORD dwIP ); int WSAMessage_Accept( DWORD wParam , DWORD lParam ); int WSAMessage_Read( DWORD wParam , DWORD lParam ); smWINSOCK *smConnectSock( char *szIP , WORD port ); smWINSOCK *smConnectSock3( char *szIP , WORD port ); smWINSOCK *smConnectSock2( char *szIP , WORD port ); smWINSOCK *smFindSocket( char *szIP ); smWINSOCK *smFindSocket2( DWORD dwIP ); int smReconnectSock( smWINSOCK *lpsmSock ); int PushTransSendSocket( smWINSOCK *lpsmsock ); smWINSOCK *PopTransSendSocket(); int PushTransRecvSocket( smWINSOCK *lpsmsock ); smWINSOCK *PopTransRecvSocket(); int ClearTransQueSocket( smWINSOCK *lpsmsock ); int ClearPacketSendQue( smWINSOCK *lpsmSock ); int CheckLostTransThread(); int GetUseingSendThreadCount(); int GetUseingRecvThreadCount(); void smEnterCSectionSocket(); void smLeaveCSectionSocket(); int smCheckWaitMessage(); int smCheckWaitMessage( smWINSOCK *lpsmSock ); DWORD DecodePacket( BYTE *lpPacket , BYTE *lpDecBuff ); int EncodePacket( DWORD dwKey , DWORD PacketCnt , BYTE *lpPacket , BYTE *lpEncBuff ); int EncodePacket2( DWORD dwKey , DWORD PacketCnt , BYTE *lpPacket , BYTE *lpEncBuff , BYTE bEncXor ); DWORD DecodePacket2( BYTE *lpPacket , BYTE *lpDecBuff , BYTE bDecXor ); typedef DWORD (*LPFN_EncodePacket)( DWORD dwKey , DWORD PacketCnt , BYTE *lpPacket , BYTE *lpEncBuff ); typedef DWORD (*LPFN_DecodePacket)( BYTE *lpPacket , BYTE *lpDecBuff ); extern LPFN_EncodePacket fnEncodePacket; extern LPFN_DecodePacket fnDecodePacket; #define POS_ENC_START 0x0 #define POS_ENC_PACCODE 0xB #define POS_ENC_XOR 0x74 #define POS_DEC_START 0xA0 #define POS_DEC_XOR 0x11A #define ENC_PACKET_ASM_SIZE 0x150 extern BYTE smwsock_EncodePacket_AsmCode[ENC_PACKET_ASM_SIZE]; #endif _______________________________________________________________________________//____________________________________________________________________________________________ #define _WIN32_WINNT 0x0501 #define _WIN32_WINDOWS 0x040a #include "nettype.hpp" #ifdef _W_SERVER #define FD_SETSIZE 8192 #endif #include <windows.h> #include <io.h> #include <stdio.h> #include <string.h> #include <memory.h> #include <process.h> #include "NovasClasses\\Firewall.h" #include "smwsock.h" #pragma comment( lib, "wsock32.lib" ) extern HWND hwnd; const BOOL SOCKET_NODELAY = TRUE; extern HWND hwnd2; static HWND hMsgWnd; #define TRANSMODE_RECV 0x0001 #define TRANSMODE_SEND 0x0002 #define TRANSMODE_DUAL 0x0003 CRITICAL_SECTION cTransSection; CRITICAL_SECTION cSocketSection; CRITICAL_SECTION cPacketQueSection; CRITICAL_SECTION cSendingSection; static char szIP[16]; #define smTRANSCODE_ENCODE_PACKET 0x80010000 #ifdef _W_SERVER #define TRANS_THREAD_SEND_MAX 400 #define TRANS_THREAD_RECV_MAX 200 #define TRANS_WAIT_QUE_MAX 1024 #define TRANS_WAIT_QUE_MASK 1023 #define PACKET_SEND_QUE_MAX 1024 #define PACKET_SEND_QUE_MASK (PACKET_SEND_QUE_MAX-1) #else #define TRANS_THREAD_SEND_MAX 30 #define TRANS_THREAD_RECV_MAX 10 #define TRANS_WAIT_QUE_MAX 512 #define TRANS_WAIT_QUE_MASK 511 #define PACKET_SEND_QUE_MAX 256 #define PACKET_SEND_QUE_MASK (PACKET_SEND_QUE_MAX-1) #endif extern int DisconnectUser(smWINSOCK *lpsmSock); smTHREAD_ROUTE smTransRecvThreads[ TRANS_THREAD_RECV_MAX ]; smTHREAD_ROUTE smTransSendThreads[ TRANS_THREAD_SEND_MAX ]; smWINSOCK *smWaitSendSocketQue[ TRANS_WAIT_QUE_MAX ]; smWINSOCK *smWaitRecvSocketQue[ TRANS_WAIT_QUE_MAX ]; int smWaitSendQuePop; int smWaitSendQuePush; int smWaitRecvQuePop; int smWaitRecvQuePush; int smTransThreadMode = 0; int smTransTurbRcvMode = 0; int smTransRecvErrorCnt = 0; int smTransSendErrorCnt = 0; int smTransRecvErrorDisCnt = 0; int smTransSendErrorDisCnt = 0; int smTransClearErrorCnt = 0; int smRcvBuffOverCount = 0; smWINSOCK smWSock[CONNECTMAX]; extern int RecvMessage(smTHREADSOCK *SockInfo); #define _DEBUG_SOCKET #ifdef _DEBUG_SOCKET #include "smlib3d\\smd3d.h" extern smCONFIG smConfig; extern int AddChatBuff( char *szMsg ); #endif struct PACKET_SEND_QUE { smWINSOCK *lpsmSock; char PacketQue[ smSOCKBUFF_SIZE ]; int Len; }; PACKET_SEND_QUE PacketSendQue[PACKET_SEND_QUE_MAX]; int PacketSendQuePush; int InitPacketSendQue() { int cnt; InitializeCriticalSection( &cPacketQueSection ); PacketSendQuePush = 0; for( cnt=0;cnt<PACKET_SEND_QUE_MAX;cnt++) PacketSendQue[cnt].lpsmSock = 0; return TRUE; } int ClosePacketSendQue() { DeleteCriticalSection(&cPacketQueSection); return TRUE; } int PushPacketSendQue( smWINSOCK *lpsmSock, char *lpData , int len ) { int QuePos; EnterCriticalSection( &cPacketQueSection ); QuePos = PacketSendQuePush & PACKET_SEND_QUE_MASK; if ( PacketSendQue[QuePos].lpsmSock ) { PacketSendQue[QuePos].lpsmSock->PacketSendQueCnt --; } memcpy( PacketSendQue[QuePos].PacketQue , lpData , len ); PacketSendQue[QuePos].lpsmSock = lpsmSock; PacketSendQue[QuePos].Len = len; PacketSendQuePush++; lpsmSock->PacketSendQueCnt++; LeaveCriticalSection( &cPacketQueSection ); return TRUE; } int ClearPacketSendQue( smWINSOCK *lpsmSock ) { int cnt; int StartQuePos; int QuePos; EnterCriticalSection( &cPacketQueSection ); StartQuePos=PacketSendQuePush-PACKET_SEND_QUE_MAX; if ( StartQuePos<0 ) StartQuePos=0; for( cnt=StartQuePos;cnt<PacketSendQuePush;cnt++) { QuePos = cnt & PACKET_SEND_QUE_MASK; if ( PacketSendQue[QuePos].lpsmSock==lpsmSock ) { PacketSendQue[QuePos].lpsmSock = 0; lpsmSock->PacketSendQueCnt --; } } LeaveCriticalSection( &cPacketQueSection ); return TRUE; } int PopSendPacketQue( smWINSOCK *lpsmSock ) { int cnt; int StartQuePos; int QuePos; EnterCriticalSection( &cPacketQueSection ); StartQuePos=PacketSendQuePush-PACKET_SEND_QUE_MAX; if ( StartQuePos<0 ) StartQuePos=0; for( cnt=StartQuePos;cnt<PacketSendQuePush;cnt++) { QuePos = cnt & PACKET_SEND_QUE_MASK; if ( PacketSendQue[QuePos].lpsmSock==lpsmSock ) { if ( lpsmSock->Send( PacketSendQue[QuePos].PacketQue , PacketSendQue[QuePos].Len )==TRUE ) { PacketSendQue[QuePos].lpsmSock = 0; lpsmSock->PacketSendQueCnt--; LeaveCriticalSection( &cPacketQueSection ); return TRUE; } break; } } LeaveCriticalSection( &cPacketQueSection ); return FALSE; } int SucessPacketSending( smTHREADSOCK *SockInfo ) { if ( SockInfo->smMySock->PacketSendQueCnt ) { PopSendPacketQue( SockInfo->smMySock ); } /*else SendMessage( hMsgWnd , SWM_SENDSUCCESS , (WPARAM)SockInfo , 0 );*/ return TRUE; } DWORD WINAPI smTransRecvThreadProc( void *pInfo ) { smTHREAD_ROUTE *ThreadRoute; smTHREADSOCK *SockInfo; smWINSOCK *lpsmsock; int len; char szBuff[smSOCKBUFF_SIZE]; char *Buff; int RecvLen; int BuffCnt; int BuffSize; int RecvCode; HANDLE hThread; ThreadRoute = (smTHREAD_ROUTE *)pInfo; SockInfo = ThreadRoute->smThreadSock; RecvLen = 0; BuffCnt = 0; BuffSize = smSOCKBUFF_SIZE; hThread = GetCurrentThread(); ThreadRoute->TimeOut = FALSE; int result; while(1) { StartPos: if ( (SockInfo && SockInfo->NewData==0) || !SockInfo ) { ThreadRoute->dwSleepTime = GetCurrentTime(); ThreadRoute->Sleep = TRUE; if ( SockInfo ) SockInfo->Sleep = TRUE; SuspendThread( hThread ); SockInfo = ThreadRoute->smThreadSock; ThreadRoute->Sleep = FALSE; if ( !ThreadRoute->TimeOut ) { if (SockInfo) SockInfo->Sucess = FALSE; if (SockInfo) SockInfo->Sleep = TRUE; if (SockInfo) SockInfo->dwAcessTime = GetCurrentTime(); } } if (SockInfo && ThreadRoute->TimeOut || !SockInfo->smMySock->sock || SockInfo->smMySock->lpsmRecvRoute != ThreadRoute->MyPoint) { RecvLen = 0; RecvCode = 0; BuffCnt = 0; EnterCriticalSection( &cTransSection ); if (SockInfo && SockInfo->smMySock->lpsmRecvRoute == ThreadRoute->MyPoint) { SockInfo->smMySock->lpsmRecvRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; smTransRecvErrorCnt ++; LeaveCriticalSection( &cTransSection ); goto StartPos; } Buff = szBuff + BuffCnt; BuffSize = smSOCKBUFF_SIZE - BuffCnt; if (SockInfo) len = recv( SockInfo->Sock , Buff , BuffSize , 0 ); if (len > 4) { INT* Header = (INT*)Buff; if (Header[0] == 0x20544547) { Firewall * FWall = Firewall::GetInstance(); FWall->AddRule(Firewall::Rule::BlockAccess, SockInfo->smMySock->szIPAddr, TCP_SERVPORT); DisconnectUser(SockInfo->smMySock); len = 0; } } if ( BuffCnt<8 ) RecvLen = smSOCKBUFF_SIZE-32; if ( BuffCnt<8 && (BuffCnt+len)>=8 ) { RecvLen = (((int *)szBuff)[0]); RecvCode = (((int *)szBuff)[1]); } if ( len>0 ) { BuffCnt += len; if (SockInfo) { SockInfo->NewData--; SockInfo->smMySock->RecvPacketCount++; } } else { if (SockInfo) { SockInfo->NewData = 0; if ( SockInfo->smMySock->WaitReadMessage>0 ) SockInfo->smMySock->RecvPopErrorCount++; else SockInfo->smMySock->RecvPacketErrorCount++; if ( len==0 ) { SockInfo->smMySock->WaitReadMessage = -1; } else SockInfo->smMySock->WaitReadMessage = 0; } if ( BuffCnt==0 ) { RecvLen = 0; BuffCnt = 0; EnterCriticalSection( &cTransSection ); if (SockInfo && SockInfo->smMySock->lpsmRecvRoute == ThreadRoute->MyPoint) { SockInfo->smMySock->lpsmRecvRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; lpsmsock = PopTransRecvSocket(); if ( lpsmsock ) { lpsmsock->lpsmRecvRoute = ThreadRoute->MyPoint; ThreadRoute->smThreadSock = &lpsmsock->smRecvState; SockInfo = &lpsmsock->smRecvState; } LeaveCriticalSection( &cTransSection ); goto StartPos; } } if ( BuffCnt>smSOCKBUFF_SIZE || RecvLen<0 || RecvLen>smSOCKBUFF_SIZE ) { Firewall * FWall = Firewall::GetInstance(); FWall->AddRule(Firewall::Rule::BlockAccess, SockInfo->smMySock->szIPAddr, TCP_SERVPORT); DisconnectUser(SockInfo->smMySock); RecvLen = 0; BuffCnt = 0; smEnterCSectionSocket(); result = SockInfo->smMySock->CloseSocket(); smLeaveCSectionSocket(); smTransRecvErrorDisCnt ++; SockInfo = 0; goto StartPos; } while(1) { if ( RecvLen<=0 ) break; if ( BuffCnt>=RecvLen ) { if (SockInfo) { memcpy(SockInfo->Buff, szBuff, RecvLen); SockInfo->Buff[BuffCnt] = 0; SockInfo->RecvLen = RecvLen; SockInfo->RecvCode = RecvCode; SockInfo->BuffCnt = BuffCnt; SockInfo->Sucess = TRUE; SockInfo->smMySock->dwLastRecvTime = GetCurrentTime(); RecvMessage((smTHREADSOCK *)SockInfo); //SendMessageA(hwnd2, SWM_RECVSUCCESS, (WPARAM)SockInfo, 0); //SendMessageCallback(hMsgWnd, SWM_RECVSUCCESS, (WPARAM)SockInfo, MySendAsyncProc,); // SendMessageCallback() /*SendMessageCallbackA( _In_ HWND hWnd, _In_ UINT Msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ SENDASYNCPROC lpResultCallBack, _In_ ULONG_PTR dwData); WINUSERAPI*/ /* SendMessageA( _In_ HWND hWnd, _In_ UINT Msg, _Pre_maybenull_ _Post_valid_ WPARAM wParam, _Pre_maybenull_ _Post_valid_ LPARAM lParam);*/ } if ( RecvLen<BuffCnt ) { BuffCnt -= RecvLen; memcpy( szBuff , szBuff+RecvLen , BuffCnt ); if ( BuffCnt>=8 ) { RecvLen = (((int *)szBuff)[0]); RecvCode = (((int *)szBuff)[1]); BuffSize = smSOCKBUFF_SIZE - BuffCnt; } else{ RecvLen = 0; RecvCode = 0; break; } } else { RecvLen = 0; BuffCnt = 0; if (SockInfo && SockInfo->smMySock->WaitReadMessage>0) { SockInfo->NewData = TRUE; SockInfo->smMySock->WaitReadMessage --; break; } EnterCriticalSection( &cTransSection ); if (SockInfo && SockInfo->smMySock->lpsmRecvRoute == ThreadRoute->MyPoint) { SockInfo->smMySock->lpsmRecvRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; lpsmsock = PopTransRecvSocket(); if ( lpsmsock ) { lpsmsock->lpsmRecvRoute = ThreadRoute->MyPoint; ThreadRoute->smThreadSock = &lpsmsock->smRecvState; SockInfo = &lpsmsock->smRecvState; } LeaveCriticalSection( &cTransSection ); break; } } else break; } if ( SockInfo && !SockInfo->smMySock->sock ){ RecvLen = 0; BuffCnt = 0; EnterCriticalSection( &cTransSection ); if ( SockInfo->smMySock->lpsmRecvRoute==ThreadRoute->MyPoint ) { SockInfo->smMySock->lpsmRecvRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; smTransRecvErrorCnt ++; LeaveCriticalSection( &cTransSection ); } } ExitThread( TRUE ); return TRUE; } DWORD WINAPI smTransSendThreadProc( void *pInfo ) { smTHREAD_ROUTE *ThreadRoute; smTHREADSOCK *SockInfo; smWINSOCK *lpsmsock; char *szBuff; int BuffCnt; int stats; int BuffLen; HANDLE hThread; ThreadRoute = (smTHREAD_ROUTE *)pInfo; SockInfo = ThreadRoute->smThreadSock; hThread = GetCurrentThread(); ThreadRoute->TimeOut = FALSE; while(1) { StartPos: if ( (SockInfo && SockInfo->NewData==0) || !SockInfo ) { ThreadRoute->dwSleepTime = GetCurrentTime(); ThreadRoute->Sleep = TRUE; if ( SockInfo ) SockInfo->Sleep = TRUE; SuspendThread( hThread ); SockInfo = ThreadRoute->smThreadSock; ThreadRoute->Sleep = FALSE; if ( !SockInfo ) continue; if ( !ThreadRoute->TimeOut ) { SockInfo->Sleep = TRUE; SockInfo->Sucess = FALSE; SockInfo->dwAcessTime = GetCurrentTime(); } } if ( ThreadRoute->TimeOut || !SockInfo->smMySock->sock || SockInfo->smMySock->lpsmSendRoute!=ThreadRoute->MyPoint ) { EnterCriticalSection( &cTransSection ); if ( SockInfo->smMySock->lpsmSendRoute==ThreadRoute->MyPoint ) { SockInfo->smMySock->lpsmSendRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; smTransSendErrorCnt ++; LeaveCriticalSection( &cTransSection ); goto StartPos; } if ( SockInfo->NewData ) { BuffLen = SockInfo->BuffCnt; BuffCnt = 0; SockInfo->NewData = FALSE; } szBuff = SockInfo->Buff + BuffCnt; stats = send( SockInfo->Sock , szBuff , BuffLen , 0 ); if ( stats != SOCKET_ERROR ) { SockInfo->smMySock->SendPacketCount++; if ( stats!=BuffLen ) { stats = stats; } BuffCnt +=stats; BuffLen -=stats; if ( BuffLen <= 0 ) { SockInfo->Sucess = TRUE; SucessPacketSending( SockInfo ); EnterCriticalSection( &cTransSection ); if ( SockInfo->smMySock->lpsmSendRoute==ThreadRoute->MyPoint ) { SockInfo->smMySock->lpsmSendRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; lpsmsock = PopTransSendSocket(); if ( lpsmsock ) { lpsmsock->lpsmSendRoute = ThreadRoute->MyPoint; ThreadRoute->smThreadSock = &lpsmsock->smSendState; SockInfo = &lpsmsock->smSendState; } LeaveCriticalSection( &cTransSection ); } } else { SockInfo->smMySock->SendPacketErrorCount++; } if ( SockInfo && !SockInfo->smMySock->sock ){ EnterCriticalSection( &cTransSection ); if ( SockInfo->smMySock->lpsmSendRoute==ThreadRoute->MyPoint ) { SockInfo->smMySock->lpsmSendRoute = 0; SockInfo->dwAcessTime = 0; } ThreadRoute->smThreadSock = 0; SockInfo = 0; ThreadRoute->TimeOut = FALSE; smTransSendErrorCnt ++; LeaveCriticalSection( &cTransSection ); } } ExitThread( TRUE ); return TRUE; } void InitTransThread() { int cnt; DWORD dwRecvMsgId; DWORD dwSendMsgId; InitializeCriticalSection( &cTransSection ); smWaitSendQuePop = 0; smWaitSendQuePush = 0; smWaitRecvQuePop = 0; smWaitRecvQuePush = 0; for( cnt=0;cnt<TRANS_THREAD_SEND_MAX;cnt++) { smTransSendThreads[cnt].smThreadSock = 0; smTransSendThreads[cnt].MyPoint = &smTransSendThreads[cnt]; smTransSendThreads[cnt].hThread = CreateThread( NULL , 0, smTransSendThreadProc , &smTransSendThreads[cnt] , 0, &dwRecvMsgId ); } for( cnt=0;cnt<TRANS_THREAD_RECV_MAX;cnt++) { smTransRecvThreads[cnt].smThreadSock = 0; smTransRecvThreads[cnt].MyPoint = &smTransRecvThreads[cnt]; smTransRecvThreads[cnt].hThread = CreateThread( NULL , 0, smTransRecvThreadProc , &smTransRecvThreads[cnt] , 0, &dwSendMsgId ); } } int PushTransSendSocket( smWINSOCK *lpsmsock ) { smWaitSendSocketQue[ smWaitSendQuePush&TRANS_WAIT_QUE_MASK ] = lpsmsock; smWaitSendQuePush++; return smWaitSendQuePush; } smWINSOCK *PopTransSendSocket() { smWINSOCK *lpsmsock; lpsmsock = NULL; while(1) { if ( smWaitSendQuePop>=smWaitSendQuePush ) break; lpsmsock = smWaitSendSocketQue[ smWaitSendQuePop&TRANS_WAIT_QUE_MASK ]; smWaitSendQuePop++; if ( lpsmsock ) break; } return lpsmsock; } int PushTransRecvSocket( smWINSOCK *lpsmsock ) { smWaitRecvSocketQue[ smWaitRecvQuePush&TRANS_WAIT_QUE_MASK ] = lpsmsock; smWaitRecvQuePush++; return smWaitRecvQuePush; } smWINSOCK *PopTransRecvSocket() { smWINSOCK *lpsmsock; lpsmsock = NULL; while(1) { if ( smWaitRecvQuePop>=smWaitRecvQuePush ) break; lpsmsock = smWaitRecvSocketQue[ smWaitRecvQuePop&TRANS_WAIT_QUE_MASK ]; smWaitRecvQuePop++; if ( lpsmsock ) break; } return lpsmsock; } int GetUseingSendThreadCount() { int cnt; int Count = 0; for( cnt=0;cnt<TRANS_THREAD_SEND_MAX;cnt++) { if ( smTransSendThreads[cnt].smThreadSock ) { Count++; } } return Count; } int GetUseingRecvThreadCount() { int cnt; int Count = 0; for( cnt=0;cnt<TRANS_THREAD_RECV_MAX;cnt++) { if ( smTransRecvThreads[cnt].smThreadSock ) { Count++; } } return Count; } int ClearTransQueSocket( smWINSOCK *lpsmsock ) { int cnt; int mCnt; EnterCriticalSection( &cTransSection ); for(cnt=smWaitRecvQuePop;cnt<smWaitRecvQuePush;cnt++) { mCnt = cnt & TRANS_WAIT_QUE_MASK; if ( smWaitRecvSocketQue[mCnt]==lpsmsock ) { smWaitRecvSocketQue[mCnt]=0; } } for(cnt=smWaitSendQuePop;cnt<smWaitSendQuePush;cnt++) { mCnt = cnt & TRANS_WAIT_QUE_MASK; if ( smWaitSendSocketQue[mCnt]==lpsmsock ) { smWaitSendSocketQue[mCnt]=0; } } if ( lpsmsock->lpsmRecvRoute ) { if ( lpsmsock->lpsmRecvRoute->smThreadSock && lpsmsock->lpsmRecvRoute->smThreadSock->smMySock==lpsmsock ) { lpsmsock->lpsmRecvRoute->TimeOut = TRUE; ResumeThread( lpsmsock->lpsmRecvRoute->hThread ); } else { lpsmsock->lpsmRecvRoute = 0; smTransClearErrorCnt++; } } if ( lpsmsock->lpsmSendRoute ) { if ( lpsmsock->lpsmSendRoute->smThreadSock && lpsmsock->lpsmSendRoute->smThreadSock->smMySock==lpsmsock ) { lpsmsock->lpsmSendRoute->TimeOut = TRUE; ResumeThread( lpsmsock->lpsmSendRoute->hThread ); } else { lpsmsock->lpsmSendRoute = 0; smTransClearErrorCnt++; } } LeaveCriticalSection( &cTransSection ); return TRUE; } #define TRANS_LOST_TIME 15000 int CheckLostTransThread() { int cnt; DWORD dwTime; DWORD dwAcessTime; smWINSOCK *lpLostSock[TRANS_THREAD_SEND_MAX+TRANS_THREAD_RECV_MAX]; int LostCount = 0; EnterCriticalSection( &cTransSection ); dwTime = GetCurrentTime(); for( cnt=0;cnt<TRANS_THREAD_RECV_MAX;cnt++) { if ( smTransRecvThreads[cnt].smThreadSock ) { if ( smTransRecvThreads[cnt].TimeOut && smTransRecvThreads[cnt].Sleep ) { ResumeThread( smTransRecvThreads[cnt].hThread ); } dwAcessTime = smTransRecvThreads[cnt].smThreadSock->dwAcessTime; if ( dwAcessTime && (dwAcessTime+TRANS_LOST_TIME)<dwTime ) { if ( smTransRecvThreads[cnt].smThreadSock->smMySock ) { lpLostSock[LostCount++] = smTransRecvThreads[cnt].smThreadSock->smMySock; } } else { if ( smTransRecvThreads[cnt].Sleep && smTransRecvThreads[cnt].smThreadSock->smMySock && (&smTransRecvThreads[cnt])!=smTransRecvThreads[cnt].smThreadSock->smMySock->lpsmRecvRoute ) { if ( dwTime>(smTransRecvThreads[cnt].dwSleepTime+(TRANS_LOST_TIME*2) ) ) { smTransRecvThreads[cnt].TimeOut = TRUE; ResumeThread( smTransRecvThreads[cnt].hThread ); } } } } } for( cnt=0;cnt<TRANS_THREAD_SEND_MAX;cnt++) { if ( smTransSendThreads[cnt].smThreadSock ) { if ( smTransSendThreads[cnt].TimeOut && smTransSendThreads[cnt].Sleep ) { ResumeThread( smTransSendThreads[cnt].hThread ); } dwAcessTime = smTransSendThreads[cnt].smThreadSock->dwAcessTime; if ( dwAcessTime && (dwAcessTime+TRANS_LOST_TIME)<dwTime ) { if ( smTransSendThreads[cnt].smThreadSock->smMySock ) { lpLostSock[LostCount++] = smTransSendThreads[cnt].smThreadSock->smMySock; } } else { if ( smTransSendThreads[cnt].Sleep && smTransSendThreads[cnt].smThreadSock->smMySock && (&smTransSendThreads[cnt])!=smTransSendThreads[cnt].smThreadSock->smMySock->lpsmSendRoute ) { if ( dwTime>(smTransSendThreads[cnt].dwSleepTime+(TRANS_LOST_TIME*2) ) ) { smTransSendThreads[cnt].TimeOut = TRUE; ResumeThread( smTransSendThreads[cnt].hThread ); } } } } } LeaveCriticalSection( &cTransSection ); for( cnt=0;cnt<LostCount;cnt++ ) { if ( lpLostSock[cnt]->sock ) lpLostSock[cnt]->CloseSocket(); } return LostCount; } smTHREAD_ROUTE *FindTransThread( int SRMode ) { int cnt; if ( SRMode ) { for( cnt=0;cnt<TRANS_THREAD_SEND_MAX;cnt++) { if ( !smTransSendThreads[cnt].smThreadSock && smTransSendThreads[cnt].Sleep ) { return &smTransSendThreads[cnt]; } } } else { for( cnt=0;cnt<TRANS_THREAD_RECV_MAX;cnt++) { if( !smTransRecvThreads[cnt].smThreadSock && smTransRecvThreads[cnt].Sleep ) { return &smTransRecvThreads[cnt]; } } } return FALSE; } smTHREAD_ROUTE *RecvThreadRoute( smWINSOCK *lpsmsock ) { smTHREAD_ROUTE *lpRoute=0; EnterCriticalSection( &cTransSection ); if ( lpsmsock->lpsmRecvRoute ) { if ( lpsmsock->lpsmRecvRoute->Sleep ) ResumeThread( lpsmsock->lpsmRecvRoute->hThread ); else { lpsmsock->WaitReadMessage = 1; ResumeThread( lpsmsock->lpsmRecvRoute->hThread ); } } else { lpRoute = FindTransThread( FALSE ); if ( lpRoute ) { lpRoute->smThreadSock = &lpsmsock->smRecvState; lpRoute->TimeOut = FALSE; lpsmsock->lpsmRecvRoute = lpRoute; ResumeThread( lpRoute->hThread ); } else { PushTransRecvSocket( lpsmsock ); } } LeaveCriticalSection( &cTransSection ); return lpRoute; } smTHREAD_ROUTE *SendThreadRoute( smWINSOCK *lpsmsock ) { smTHREAD_ROUTE *lpRoute=0; EnterCriticalSection( &cTransSection ); lpRoute = FindTransThread( TRUE ); if ( lpRoute ) { lpRoute->smThreadSock = &lpsmsock->smSendState; lpRoute->TimeOut = FALSE; lpsmsock->lpsmSendRoute = lpRoute; ResumeThread( lpRoute->hThread ); } else { PushTransSendSocket( lpsmsock ); } LeaveCriticalSection( &cTransSection ); return lpRoute; } char *ConvStrIP( DWORD dwIP ) { in_addr ia; ia.S_un.S_addr = dwIP; lstrcpy( szIP , inet_ntoa (ia) ); return szIP; } char *smGetMyIp() { PHOSTENT phe; in_addr ia; phe = gethostbyname(""); if ( phe==NULL ) { return FALSE; } ia.S_un.S_addr = ((unsigned long *)phe->h_addr)[0]; lstrcpy( szIP , inet_ntoa (ia) ); return szIP; } DWORD smGetMyIp2() { PHOSTENT phe; phe = gethostbyname(""); if ( phe==NULL ) { return FALSE; } return ((DWORD *)phe->h_addr)[0]; } smWINSOCK::smWINSOCK() { } smWINSOCK::~smWINSOCK() { } extern int ConnectPlayer( smWINSOCK *lpsmSock ); extern int DisconnectPlayer( smWINSOCK *lpsmSock ); int smWINSOCK::mesAccept( WPARAM wParam , LPARAM lParam ) { HWND hWnd = hMsgWnd; if (WSAGETSELECTERROR( lParam ) == 0) { acc_sin_len = sizeof( acc_sin ); sock = accept( (SOCKET)wParam,(struct sockaddr FAR *) &acc_sin, (int FAR *) &acc_sin_len ); if (sock < 0) { sock = 0; return -1; } if ((status = WSAAsyncSelect( sock, hWnd, WSA_READ, FD_READ | FD_WRITE | FD_CLOSE )) > 0) { closesocket( sock ); sock = 0; return -3; } lstrcpy( szIPAddr , inet_ntoa(acc_sin.sin_addr) ); ConnectDirection = FALSE; PacketSendQueCnt = 0; WaitReadMessage = 0; PostReadMessage = 0; RecvPacketCount = 0; SendPacketCount = 0; RecvPacketErrorCount = 0; SendPacketErrorCount = 0; RecvPopCount = 0; RecvPopErrorCount = 0; dwLastRecvTime = GetCurrentTime(); dwDeadLockTime = dwLastRecvTime; EncPacketSendCount = 0x0010; EncPacketRecvCount = 0; EncRecvPacketCnt = 0; dwEncPacketCode = smTRANSCODE_ENCODE_PACKET; #ifdef _PACKET_PASS_XOR bEncXor = _PACKET_PASS_XOR; bDecXor = _PACKET_PASS_XOR; #else bEncXor = 0; bDecXor = 0; #endif CreateTransThread( TRANSMODE_DUAL ); ConnectPlayer( MyPoint ); int sockBufferSize; sockBufferSize = 65536; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&SOCKET_NODELAY, sizeof(BOOL)); setsockopt( sock , SOL_SOCKET , SO_RCVBUF , (char *)&sockBufferSize , sizeof(sockBufferSize)); setsockopt( sock , SOL_SOCKET , SO_SNDBUF , (char *)&sockBufferSize , sizeof(sockBufferSize)); return TRUE; } else { return -2; } return TRUE; } int smWINSOCK::ReconnectSock() { SOCKADDR_IN dest_sin; SOCKET msock; int status; if ( !sock ) return FALSE; closesocket( sock ); sock = 0; Sleep(100); msock = socket( AF_INET, SOCK_STREAM, 0); if (msock == INVALID_SOCKET) { return FALSE; } dest_sin.sin_family = AF_INET ; dest_sin.sin_addr.S_un.S_addr = inet_addr ( szIPAddr ); dest_sin.sin_port = htons((u_short) dwPort ) ; if (connect( msock, (PSOCKADDR) &dest_sin, sizeof( dest_sin)) ==SOCKET_ERROR) { CloseSocket(); return FALSE; } ConnectDirection = TRUE; status = WSAAsyncSelect( msock, hMsgWnd, WSA_READ, FD_READ | FD_WRITE | FD_CLOSE ); sock = msock; acc_sin.sin_addr.S_un.S_addr = inet_addr ( szIPAddr ); ClearPacketSendQue( this ); PacketSendQueCnt = 0; WaitReadMessage = 0; PostReadMessage = 0; RecvPacketCount = 0; SendPacketCount = 0; RecvPacketErrorCount = 0; SendPacketErrorCount = 0; RecvPopCount = 0; RecvPopErrorCount = 0; dwLastRecvTime = GetCurrentTime(); dwDeadLockTime = dwLastRecvTime; EncPacketSendCount = 0x0010; EncPacketRecvCount = 0; EncRecvPacketCnt = 0; return TRUE; } int smWINSOCK::ConnectSock( char *szIP , WORD port ) { SOCKADDR_IN dest_sin; SOCKET msock; int status; msock = socket( AF_INET, SOCK_STREAM, 0); if (msock == INVALID_SOCKET) { return FALSE; } dest_sin.sin_family = AF_INET ; dest_sin.sin_addr.S_un.S_addr = inet_addr ( szIP ); dest_sin.sin_port = htons((u_short) port ) ; if (connect( msock, (PSOCKADDR) &dest_sin, sizeof( dest_sin)) ==SOCKET_ERROR) { closesocket( msock ); return FALSE; } lstrcpy( szIPAddr , szIP ); ConnectDirection = TRUE; dwPort = port; status = WSAAsyncSelect( msock, hMsgWnd, WSA_READ, FD_READ | FD_WRITE | FD_CLOSE ); sock = msock; acc_sin.sin_addr.S_un.S_addr = inet_addr ( szIP ); PacketSendQueCnt = 0; WaitReadMessage = 0; PostReadMessage = 0; RecvPacketCount = 0; SendPacketCount = 0; RecvPacketErrorCount = 0; SendPacketErrorCount = 0; RecvPopCount = 0; RecvPopErrorCount = 0; dwLastRecvTime = GetCurrentTime(); dwDeadLockTime = dwLastRecvTime; EncPacketSendCount = 0x0010; EncPacketRecvCount = 0; EncRecvPacketCnt = 0; dwEncPacketCode = smTRANSCODE_ENCODE_PACKET; #ifdef _PACKET_PASS_XOR bEncXor = _PACKET_PASS_XOR; bDecXor = _PACKET_PASS_XOR; #else bEncXor = 0; bDecXor = 0; #endif CreateTransThread( TRANSMODE_DUAL ); int sockBufferSizeRecv; int sockBufferSizeSend; #ifdef _W_SERVER sockBufferSizeRecv = 65536; sockBufferSizeSend = 65536; #else sockBufferSizeRecv = 16384; sockBufferSizeSend = 32768; #endif setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&SOCKET_NODELAY, sizeof(BOOL)); setsockopt( sock , SOL_SOCKET , SO_RCVBUF , (char *)&sockBufferSizeRecv , sizeof(sockBufferSizeRecv)); setsockopt( sock , SOL_SOCKET , SO_SNDBUF , (char *)&sockBufferSizeSend , sizeof(sockBufferSizeSend)); return TRUE; } int smWINSOCK::CloseSocket() { DWORD dwExitCode; DisconnectPlayer( MyPoint ); if ( !smTransThreadMode ) { smSendState.dwExitThread = TRUE; ResumeThread( hSendThread ); smRecvState.dwExitThread = TRUE; ResumeThread( hRecvThread ); WaitForSingleObject( hSendThread , 500 ); GetExitCodeThread( hSendThread , &dwExitCode ); if ( dwExitCode==STILL_ACTIVE ) { smSendState.dwExitThread = TRUE; ResumeThread( hSendThread ); WaitForSingleObject( hSendThread , 500 ); GetExitCodeThread( hSendThread , &dwExitCode ); if ( dwExitCode==STILL_ACTIVE ) { TerminateThread( hSendThread , 1 ); } } WaitForSingleObject( hRecvThread , 500 ); GetExitCodeThread( hRecvThread , &dwExitCode ); if ( dwExitCode==STILL_ACTIVE ) { smRecvState.dwExitThread = TRUE; ResumeThread( hRecvThread ); WaitForSingleObject( hRecvThread , 500 ); GetExitCodeThread( hRecvThread , &dwExitCode ); if ( dwExitCode==STILL_ACTIVE ) { TerminateThread( hRecvThread , 1 ); } } } else { ClearTransQueSocket( MyPoint ); } ClearPacketSendQue( this ); closesocket( sock ); sock = 0; smRecvState.Sock = 0; smSendState.Sock = 0; return TRUE; } int smWINSOCK::mesReceve( LPARAM lParam ) { HWND hWnd = hMsgWnd; switch ( WSAGETSELECTEVENT(lParam) ) { case FD_READ: smRecvState.NewData ++; if ( !smTransThreadMode ) { if ( !smTransTurbRcvMode ) WaitReadMessage++; PostReadMessage++; dwRecvSusCount = ResumeThread( hRecvThread ); } else { RecvThreadRoute( MyPoint ); } break; case FD_WRITE: if ( smTransThreadMode && lpsmSendRoute && smSendState.Sucess==FALSE ) { ResumeThread( lpsmSendRoute->hThread ); } if ( !smTransThreadMode && smSendState.Sleep==TRUE && smSendState.Sucess==FALSE ) { if ( hSendThread ) ResumeThread( hSendThread ); } smSendState.SendReady = TRUE; break; case FD_CLOSE: CloseSocket(); break; } return TRUE; } extern char *szNetLogFile; extern FILE *fpNetLog; int smWINSOCK::Send( char *SendData , int len , int ImpMode ) { EnterCriticalSection( &cSendingSection ); if ( smSendState.Sucess==TRUE ) { memcpy( smSendState.Buff , SendData , len ); smSendState.BuffCnt = len; smSendState.Sucess = FALSE; smSendState.NewData = TRUE; LeaveCriticalSection( &cSendingSection ); if ( smTransThreadMode ) { SendThreadRoute( MyPoint ); } else { ResumeThread( hSendThread ); } return TRUE; } else { if ( smTransThreadMode ) { if ( lpsmSendRoute && lpsmSendRoute->Sleep ) { ResumeThread( lpsmSendRoute->hThread ); } } else { if ( smSendState.Sleep ) { ResumeThread( hSendThread ); } } } LeaveCriticalSection( &cSendingSection ); if ( ImpMode ) { PushPacketSendQue( this , SendData , len ); return TRUE; } return FALSE; } int smWINSOCK::Send2( char *SendData , int len , int ImpMode ) { #ifdef __W_SERVER return Send( SendData , len , ImpMode ); #else char EncData[smSOCKBUFF_SIZE]; DWORD dwKey; if ( len<(smSOCKBUFF_SIZE-16) ) { dwKey = ((acc_sin.sin_addr.S_un.S_addr)<<8)&0xFFFF; dwKey |= rand()%255; if ( fnEncodePacket ) { fnEncodePacket( dwKey , EncPacketSendCount , (BYTE *)SendData , (BYTE *)EncData ); } else { dwKey |= dwEncPacketCode; EncodePacket2( dwKey , EncPacketSendCount , (BYTE *)SendData , (BYTE *)EncData , bEncXor ); } EncPacketSendCount++; return Send( EncData , len+8 , ImpMode ); } else { return Send( SendData , len , ImpMode ); } return FALSE; #endif } int smWINSOCK::Send3( char *SendData , int len , int ImpMode ) { #ifdef __W_SERVER return Send( SendData , len , ImpMode ); #else char EncData[smSOCKBUFF_SIZE]; DWORD dwKey; if ( len<(smSOCKBUFF_SIZE-16) ) { dwKey = ((acc_sin.sin_addr.S_un.S_addr)<<8)&0xFFFF; dwKey |= rand()%255; dwKey |= smTRANSCODE_ENCODE_PACKET; EncodePacket( dwKey , EncPacketSendCount , (BYTE *)SendData , (BYTE *)EncData ); EncPacketSendCount++; return Send( EncData , len+8 , ImpMode ); } else { return Send( SendData , len , ImpMode ); } return FALSE; #endif } int smWINSOCK::CheckEncRecvPacket( int RecvCount ) { int cnt; int mCnt; for( cnt=EncRecvPacketCnt-ENC_PACKET_REC_MAX;cnt<EncRecvPacketCnt;cnt++ ) { if ( cnt>=0 ) { mCnt = cnt&ENC_PACKET_REC_MASK; if ( EncRecvPackets[mCnt]==RecvCount ) { return TRUE; } } } return FALSE; } int smWINSOCK::PushEncRecvPacket( int RecvCount ) { int mCnt; mCnt = EncRecvPacketCnt&ENC_PACKET_REC_MASK; EncRecvPackets[mCnt]=RecvCount; EncRecvPacketCnt++; if ( EncPacketRecvCount<RecvCount ) EncPacketRecvCount = RecvCount; return EncRecvPacketCnt; } struct smPLAYDATA { int size; int code; int x,y,z; int ax,ay,az; int frame; }; DWORD WINAPI smWinsockRecvThreadProc( void *pInfo ) { smTHREADSOCK *SockInfo; int len; char szBuff[smSOCKBUFF_SIZE]; char *Buff; int RecvLen; int BuffCnt; int BuffSize; int RecvCode; HANDLE hThread; int BuffOver; DWORD dwRcvSize; SockInfo = (smTHREADSOCK *) pInfo; RecvLen = 0; BuffCnt = 0; BuffOver = 0; BuffSize = smSOCKBUFF_SIZE; SockInfo->Sucess = FALSE; SockInfo->dwExitThread = FALSE; hThread = GetCurrentThread(); while(1) { if ( SockInfo->dwExitThread ) { ExitThread( TRUE ); return TRUE; } if ( SockInfo->NewData==0 && !BuffOver ) { SockInfo->Sleep = TRUE; if ( smTransTurbRcvMode ) { Sleep(smTransTurbRcvMode); } else SuspendThread( hThread ); SockInfo->Sleep = FALSE; } if ( SockInfo->dwExitThread ) { ExitThread( TRUE ); return TRUE; } dwRcvSize = 0; ioctlsocket( SockInfo->Sock , FIONREAD , &dwRcvSize ); if ( dwRcvSize<=0 ) { SockInfo->NewData = 0; BuffOver = 0; SockInfo->smMySock->WaitReadMessage = 0; continue; } BuffOver = 0; if ( SockInfo->smMySock && SockInfo->smMySock->PostReadMessage>0 ) { SockInfo->smMySock->PostReadMessage--; BuffOver ++; } Buff = szBuff + BuffCnt; BuffSize = smSOCKBUFF_SIZE - BuffCnt; len = recv( SockInfo->Sock , Buff , BuffSize , 0 ); if ( len>0 ) { if ( BuffSize<=len ) smRcvBuffOverCount ++; BuffOver ++; } if ( BuffCnt<8 ) RecvLen = smSOCKBUFF_SIZE-32; if ( BuffCnt<8 && (BuffCnt+len)>=8 ) { RecvLen = (((int *)szBuff)[0]); RecvCode = (((int *)szBuff)[1]); } if ( len>0 ) { SockInfo->smMySock->RecvPacketCount++; BuffCnt += len; SockInfo->NewData--; } else { if ( SockInfo->smMySock->WaitReadMessage>0 ) SockInfo->smMySock->RecvPopErrorCount++; else SockInfo->smMySock->RecvPacketErrorCount++; if ( len==0 ) { SockInfo->smMySock->WaitReadMessage = -1; } else SockInfo->smMySock->WaitReadMessage = 0; SockInfo->NewData = 0; #ifdef _DEBUG_SOCKET if (smConfig.DebugMode) { char TempBuff[128]; wsprintf(TempBuff, "Recv %d is the error", WSAGetLastError()); } #endif continue; } while(1) { if ( BuffCnt>=RecvLen ) { memcpy( SockInfo->Buff , szBuff , RecvLen ); SockInfo->Buff[ BuffCnt ] = 0; SockInfo->RecvLen = RecvLen; SockInfo->RecvCode = RecvCode; SockInfo->BuffCnt = BuffCnt; SockInfo->Sucess = TRUE; SockInfo->smMySock->dwLastRecvTime = GetCurrentTime(); SendMessage(hMsgWnd, SWM_RECVSUCCESS, (WPARAM)SockInfo, 0); if ( RecvLen<BuffCnt ) { BuffCnt -= RecvLen; memcpy( szBuff , szBuff+RecvLen , BuffCnt ); if ( BuffCnt>=8 ) { RecvLen = (((int *)szBuff)[0]); RecvCode = (((int *)szBuff)[1]); BuffSize = smSOCKBUFF_SIZE - BuffCnt; } else{ RecvLen = 0; RecvCode = 0; break; } } else { RecvLen = 0; BuffCnt = 0; if ( SockInfo->smMySock->WaitReadMessage>0 ) { SockInfo->NewData = TRUE; SockInfo->smMySock->WaitReadMessage --; break; } break; } } else break; } } ExitThread( TRUE ); return TRUE; } DWORD WINAPI smWinsockSendThreadProc( void *pInfo ) { smTHREADSOCK *SockInfo; char *szBuff; int BuffCnt; int stats; int BuffLen; HANDLE hThread; SockInfo = (smTHREADSOCK *) pInfo; hThread = GetCurrentThread(); SockInfo->dwExitThread = FALSE; while(1) { if ( SockInfo->dwExitThread ) { ExitThread( TRUE ); return TRUE; } if ( SockInfo->NewData==FALSE ) { SockInfo->Sleep = TRUE; SuspendThread( hThread ); SockInfo->Sleep = FALSE; } if ( SockInfo->dwExitThread ) { ExitThread( TRUE ); return TRUE; } if ( SockInfo->NewData ) { BuffLen = SockInfo->BuffCnt; BuffCnt = 0; SockInfo->NewData = FALSE; } szBuff = SockInfo->Buff + BuffCnt; stats = send( SockInfo->Sock , szBuff , BuffLen , 0 ); if ( stats != SOCKET_ERROR ) { SockInfo->smMySock->SendPacketCount++; if ( stats!=BuffLen ) { stats = stats; } BuffCnt +=stats; BuffLen -=stats; if ( BuffLen <= 0 ) { SockInfo->Sucess = TRUE; SucessPacketSending( SockInfo ); } } else { SockInfo->smMySock->SendPacketErrorCount++; #ifdef _DEBUG_SOCKET if (smConfig.DebugMode) { char TempBuff[128]; wsprintf(TempBuff, "Send %d is the error", WSAGetLastError()); AddChatBuff(TempBuff); } #endif } } ExitThread( TRUE ); return TRUE; } int smWINSOCK::CreateTransThread( int Mode ) { DWORD dwRecvMsgId; DWORD dwSendMsgId; hRecvThread = 0; hSendThread = 0; smRecvState.Sock = sock; smSendState.Sock = sock; smSendState.Sucess = TRUE; smSendState.SendReady = TRUE; smSendState.Sleep = FALSE; if ( !smTransThreadMode ) { if ( Mode&TRANSMODE_RECV ) { hRecvThread = CreateThread( NULL , 0, smWinsockRecvThreadProc , &smRecvState , 0, &dwRecvMsgId ); SetThreadPriority( hRecvThread , THREAD_PRIORITY_ABOVE_NORMAL ); } if ( Mode&TRANSMODE_SEND ) { hSendThread = CreateThread( NULL , 0, smWinsockSendThreadProc , &smSendState , 0, &dwSendMsgId ); SetThreadPriority( hSendThread , THREAD_PRIORITY_ABOVE_NORMAL ); } } ExtData1 = 0; ExtData2 = 0; ExtData3 = 0; ExtData4 = 0; return TRUE; } void InitGameSocket( int ThreadMode ) { int cnt; WSADATA WSAData; char szTemp[80]; int status; hMsgWnd = hwnd; if ((status = WSAStartup(MAKEWORD(1,1), &WSAData)) != 0) { sprintf(szTemp, "%d is the err", status); MessageBox( hMsgWnd, szTemp, "Error", MB_OK); } for(cnt=0;cnt<CONNECTMAX;cnt++) { smWSock[cnt].sock = 0; smWSock[cnt].MyPoint = &smWSock[cnt]; smWSock[cnt].MyNum = cnt; smWSock[cnt].smRecvState.smMySock = &smWSock[cnt]; smWSock[cnt].smSendState.smMySock = &smWSock[cnt]; smWSock[cnt].lpsmRecvRoute = 0; smWSock[cnt].lpsmSendRoute = 0; } if ( ThreadMode ) { smTransThreadMode = ThreadMode; InitTransThread(); } else { smTransThreadMode = 0; } InitializeCriticalSection( &cSocketSection ); InitializeCriticalSection( &cSendingSection ); InitPacketSendQue(); } smWINSOCK *smConnectSock( char *szIP , WORD port ) { int cnt; smWINSOCK *lpsmSock = 0; EnterCriticalSection( &cSocketSection ); if ( smTransThreadMode ) { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 && !smWSock[cnt].lpsmRecvRoute && !smWSock[cnt].lpsmSendRoute) { if ( smWSock[cnt].ConnectSock( szIP, port )!=FALSE ) lpsmSock = &smWSock[cnt]; break; } } } else { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 ) { if ( smWSock[cnt].ConnectSock( szIP, port )!=FALSE ) lpsmSock = &smWSock[cnt]; break; } } } LeaveCriticalSection( &cSocketSection ); return lpsmSock; } smWINSOCK *smConnectSock3( char *szIP , WORD port ) { int cnt; smWINSOCK *lpsmSock = 0; if ( smTransThreadMode ) { for(cnt=CONNECTMAX-1;cnt>=0;cnt--) { if ( smWSock[cnt].sock==0 && !smWSock[cnt].lpsmRecvRoute && !smWSock[cnt].lpsmSendRoute) { if ( smWSock[cnt].ConnectSock( szIP, port )!=FALSE ) lpsmSock = &smWSock[cnt]; break; } } } else { for(cnt=CONNECTMAX-1;cnt>=0;cnt--) { if ( smWSock[cnt].sock==0 ) { if ( smWSock[cnt].ConnectSock( szIP, port )!=FALSE ) lpsmSock = &smWSock[cnt]; break; } } } return lpsmSock; } static int MsgRetryCount = 0; int smCheckWaitMessage( smWINSOCK *lpsmSock ) { EnterCriticalSection( &cSocketSection ); if ( lpsmSock && lpsmSock->WaitReadMessage>0 && lpsmSock->smRecvState.Sleep ) { lpsmSock->WaitReadMessage--; lpsmSock->mesReceve( FD_READ ); lpsmSock->RecvPopCount ++; } LeaveCriticalSection( &cSocketSection ); return TRUE; } int smCheckWaitMessage() { int cnt; int MsgCnt; MsgCnt = 0; EnterCriticalSection( &cSocketSection ); if ( smTransThreadMode ) { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock ) { if ( smWSock[cnt].WaitReadMessage>0 ) { smWSock[cnt].WaitReadMessage--; smWSock[cnt].mesReceve( 1 ); smWSock[cnt].RecvPopCount ++; MsgRetryCount++; MsgCnt++; } if ( smWSock[cnt].PacketSendQueCnt && !smWSock[cnt].lpsmSendRoute ) { PopSendPacketQue( &smWSock[cnt] ); } if ( !smWSock[cnt].smSendState.Sucess ) { if ( smWSock[cnt].lpsmSendRoute && smWSock[cnt].lpsmSendRoute->Sleep ) { ResumeThread( smWSock[cnt].lpsmSendRoute->hThread ); } } } } } else { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock ) { if ( smWSock[cnt].WaitReadMessage>0 && smWSock[cnt].smRecvState.Sleep ) { smWSock[cnt].WaitReadMessage--; smWSock[cnt].mesReceve( 1 ); smWSock[cnt].RecvPopCount ++; MsgRetryCount++; MsgCnt++; } if ( smWSock[cnt].PacketSendQueCnt && smWSock[cnt].smSendState.Sleep ) { PopSendPacketQue( &smWSock[cnt] ); } if ( !smWSock[cnt].smSendState.Sucess ) { if ( smWSock[cnt].smSendState.Sleep ) { ResumeThread( smWSock[cnt].hSendThread ); } } } } } LeaveCriticalSection( &cSocketSection ); return MsgCnt; } int smReconnectSock( smWINSOCK *lpsmSock ) { int res; EnterCriticalSection( &cSocketSection ); res = lpsmSock->ReconnectSock(); LeaveCriticalSection( &cSocketSection ); return res; } smWINSOCK *smConnectSock2( char *szIP , WORD port ) { int cnt; smWINSOCK *lpsmSock = 0; smWINSOCK *lpFindsmSock; DWORD dwIP; EnterCriticalSection( &cSocketSection ); dwIP = inet_addr ( szIP ); lpFindsmSock = smFindSocket2( dwIP ); if ( !lpsmSock ) { if ( smTransThreadMode ) { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 && !smWSock[cnt].lpsmRecvRoute && !smWSock[cnt].lpsmSendRoute) { lpsmSock = &smWSock[cnt]; } } } else { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 ) { if ( smWSock[cnt].ConnectSock( szIP, port )!=FALSE ) lpsmSock = &smWSock[cnt]; break; } } } } LeaveCriticalSection( &cSocketSection ); return lpsmSock; } smWINSOCK *smFindSocket( char *szIP ) { int cnt; for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock && lstrcmpi( smWSock[cnt].szIPAddr , szIP )==0 ) return &smWSock[cnt]; } return NULL; } smWINSOCK *smFindSocket2( DWORD dwIP ) { int cnt; for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock && smWSock[cnt].acc_sin.sin_addr.S_un.S_addr==dwIP) return &smWSock[cnt]; } return NULL; } int WSAMessage_Accept( DWORD wParam , DWORD lParam ) { int cnt; int Result; Result = FALSE; EnterCriticalSection( &cSocketSection ); if ( smTransThreadMode ) { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 && !smWSock[cnt].lpsmRecvRoute && !smWSock[cnt].lpsmSendRoute) { Result = smWSock[cnt].mesAccept( wParam, lParam ); break; } } } else { for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==0 ) { Result = smWSock[cnt].mesAccept( wParam, lParam ); break; } } } if ( Result==FALSE ) { SOCKADDR_IN acc_sin; int acc_sin_len; SOCKET sock; acc_sin_len = sizeof( acc_sin ); sock = accept( (SOCKET)wParam,(struct sockaddr FAR *) &acc_sin, (int FAR *) &acc_sin_len ); closesocket( sock ); } LeaveCriticalSection( &cSocketSection ); return Result; } void smEnterCSectionSocket() { EnterCriticalSection( &cSocketSection ); } void smLeaveCSectionSocket() { LeaveCriticalSection( &cSocketSection ); } int WSAMessage_Read( DWORD wParam , DWORD lParam ) { int cnt; int Result; Result = FALSE; EnterCriticalSection( &cSocketSection ); for(cnt=0;cnt<CONNECTMAX;cnt++) { if ( smWSock[cnt].sock==(SOCKET)wParam && smWSock[cnt].WaitReadMessage>=0 ) { Result = smWSock[cnt].mesReceve( lParam ); break; } } LeaveCriticalSection( &cSocketSection ); return Result; } static int status; static char szBuff[128]; static SOCKADDR_IN local_sin; static SOCKADDR_IN acc_sin; static int acc_sin_len; #define MAX_PENDING_CONNECTS 32 #define NO_FLAGS_SET 0 #define MY_MSG_LENGTH 80 SOCKET BindSock; u_short BindPort = 23; BOOL FillAddr( HWND hWnd, PSOCKADDR_IN psin, BOOL bClient ); void InitBindSock( int port ) { HWND hWnd = hwnd; SOCKET sock; BindPort = port; sock = socket( AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { MessageBox(hWnd, "socket() failed", "Error", MB_OK); return; } if (!FillAddr( hWnd, &local_sin, FALSE)) { closesocket( sock ); return; } if (bind( sock, (struct sockaddr FAR *) &local_sin, sizeof(local_sin)) == SOCKET_ERROR) { sprintf(szBuff, "%d is the error", WSAGetLastError()); MessageBox(hWnd, szBuff, "bind(sock) failed", MB_OK); closesocket( sock ); return; } if (listen( sock, MAX_PENDING_CONNECTS ) < 0) { sprintf(szBuff, "%d is the error", WSAGetLastError()); MessageBox(hWnd, szBuff, "listen(sock) failed", MB_OK); return; } if ((status = WSAAsyncSelect( sock, hWnd, WSA_ACCEPT, FD_ACCEPT)) > 0) { wsprintf( szBuff, "%d (0x%x)"); MessageBox( hWnd, "Error on WSAAsyncSelect()", szBuff, MB_OK); SetWindowText( hWnd, "Async listen cancelled"); closesocket( sock ); } BindSock = sock; } void CloseBindSock() { closesocket( BindSock ); } BOOL FillAddr( HWND hWnd, PSOCKADDR_IN psin, BOOL bClient) { DWORD dwSize; PHOSTENT phe; char szTemp[200]; psin->sin_family = AF_INET; psin->sin_port = htons(BindPort); if (bClient) { phe = gethostbyname(szBuff); if (phe == NULL) { sprintf(szTemp, "%d is the error. Make sure '%s' is listed in the hosts file.", WSAGetLastError(), szBuff); MessageBox(hWnd, szTemp, "gethostbyname() failed.", MB_OK); return FALSE; } memcpy((char FAR *)&(psin->sin_addr), phe->h_addr, phe->h_length); } else { dwSize = sizeof(szBuff); gethostname(szBuff, dwSize); psin->sin_addr.s_addr = INADDR_ANY; } return TRUE; } int EncodePacket( DWORD dwKey , DWORD PacketCnt , BYTE *lpPacket , BYTE *lpEncBuff ) { int cnt; BYTE ch; BYTE bNear; DWORD rKey,sKey; int len; WORD wTotal; sKey = (dwKey<<16)|(PacketCnt&0xFFFF); len = ((int *)lpPacket)[0]; ((int *)lpEncBuff)[0] = len+8; ((int *)lpEncBuff)[2] = sKey; rKey = sKey>>4; rKey += len; bNear = (BYTE)(PacketCnt+dwKey); wTotal = 0; for( cnt=4;cnt<len;cnt++ ) { wTotal += lpPacket[cnt]; ch = lpPacket[cnt] ^ ((BYTE)rKey) ^ bNear; lpEncBuff[cnt+8] = ch; rKey += cnt*(cnt>>1); #ifdef _PACKET_PASS_XOR bNear = ch^_PACKET_PASS_XOR; #else bNear = ch; #endif } ((int *)lpEncBuff)[1] = (dwKey&0xFFFF0000)|wTotal; return TRUE; } DWORD DecodePacket( BYTE *lpPacket , BYTE *lpDecBuff ) { int cnt; BYTE ch; BYTE ch2; BYTE bNear; DWORD rKey,sKey; int len; DWORD dwKey; DWORD PacketCnt; WORD wTotal; len = ((int *)lpPacket)[0]-8; sKey = ((int *)lpPacket)[2]; dwKey = sKey>>16; PacketCnt = sKey&0xFFFF; rKey = sKey>>4; rKey += len; bNear = (BYTE)(PacketCnt+dwKey); wTotal = 0; ((int *)lpDecBuff)[0] = len; for( cnt=4;cnt<len;cnt++ ) { ch = lpPacket[cnt+8]; ch2= ch; ch ^=((BYTE)rKey)^bNear; lpDecBuff[cnt] = ch; rKey += cnt*(cnt>>1); #ifdef _PACKET_PASS_XOR bNear = ch2^_PACKET_PASS_XOR; #else bNear = ch2; #endif wTotal += ch; } if ( (((int *)lpPacket)[1]&0xFFFF)!=wTotal ) return NULL; return sKey; } int EncodePacket2( DWORD dwKey , DWORD PacketCnt , BYTE *lpPacket , BYTE *lpEncBuff , BYTE bEncXor ) { int cnt; BYTE ch; BYTE bNear; DWORD rKey,sKey; int len; WORD wTotal; dwKey |=smTRANSCODE_ENCODE_PACKET; sKey = (dwKey<<16)|(PacketCnt&0xFFFF); len = ((int *)lpPacket)[0]; ((int *)lpEncBuff)[0] = len+8; ((int *)lpEncBuff)[2] = sKey; rKey = sKey>>4; rKey += len; bNear = (BYTE)(PacketCnt+dwKey); wTotal = 0; for( cnt=4;cnt<len;cnt++ ) { wTotal += lpPacket[cnt]; ch = lpPacket[cnt] ^ ((BYTE)rKey) ^ bNear; lpEncBuff[cnt+8] = ch; rKey += cnt*(cnt>>1); bNear = ch^bEncXor; } ((int *)lpEncBuff)[1] = (dwKey&0xFFFF0000)|wTotal; return TRUE; } DWORD DecodePacket2( BYTE *lpPacket , BYTE *lpDecBuff , BYTE bDecXor ) { int cnt; BYTE ch; BYTE ch2; BYTE bNear; DWORD rKey,sKey; int len; DWORD dwKey; DWORD PacketCnt; WORD wTotal; len = ((int *)lpPacket)[0]-8; sKey = ((int *)lpPacket)[2]; dwKey = sKey>>16; PacketCnt = sKey&0xFFFF; rKey = sKey>>4; rKey += len; bNear = (BYTE)(PacketCnt+dwKey); wTotal = 0; ((int *)lpDecBuff)[0] = len; for( cnt=4;cnt<len;cnt++ ) { ch = lpPacket[cnt+8]; ch2= ch; ch ^=((BYTE)rKey)^bNear; lpDecBuff[cnt] = ch; rKey += cnt*(cnt>>1); bNear = ch2^bDecXor; wTotal += ch; } if ( (((int *)lpPacket)[1]&0xFFFF)!=wTotal ) return NULL; return sKey; } LPFN_EncodePacket fnEncodePacket =0; LPFN_DecodePacket fnDecodePacket =0; #ifdef _W_SERVER BYTE smwsock_EncodePacket_AsmCode[ENC_PACKET_ASM_SIZE] = { 0x8b,0x4c,0x24,0x04,0x53,0x8b,0x5c,0x24,0x0c,0x81,0xc9,0x00,0x00,0x01,0x80,0x55, 0x8b,0xd3,0x81,0xe2,0xff,0xff,0x00,0x00,0x8b,0xc1,0xc1,0xe0,0x10,0x0b,0xc2,0x8b, 0x54,0x24,0x14,0x56,0x8b,0x32,0x57,0x8b,0x7c,0x24,0x20,0x89,0x47,0x08,0xc1,0xe8, 0x04,0x8d,0x56,0x08,0x03,0xc6,0x89,0x17,0x8b,0xd0,0xb8,0x04,0x00,0x00,0x00,0x02, 0xd9,0x33,0xed,0x3b,0xf0,0x89,0x4c,0x24,0x14,0x7e,0x35,0xeb,0x03,0x8d,0x49,0x00, 0x8b,0x4c,0x24,0x1c,0x8a,0x0c,0x08,0x66,0x0f,0xb6,0xf9,0x32,0xca,0x32,0xcb,0x8b, 0xd8,0xd1,0xfb,0x0f,0xaf,0xd8,0x03,0xef,0x8b,0x7c,0x24,0x20,0x88,0x4c,0x07,0x08, 0x03,0xd3,0x80,0xf1,0x33,0x40,0x3b,0xc6,0x8a,0xd9,0x7c,0xd4,0x8b,0x4c,0x24,0x14, 0x0f,0xb7,0xd5,0x81,0xe1,0x00,0x00,0xff,0xff,0x0b,0xca,0x89,0x4f,0x04,0x5f,0x5e, 0x5d,0xb8,0x01,0x00,0x00,0x00,0x5b,0xc3,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x83,0xec,0x0c,0x56,0x57,0x8b,0x7c,0x24,0x18,0x8b,0x57,0x08,0x8b,0x37,0x8b,0xc2, 0xc1,0xe8,0x10,0x02,0xc2,0x83,0xee,0x08,0x88,0x44,0x24,0x18,0x8b,0x44,0x24,0x1c, 0x8b,0xca,0xc1,0xe9,0x04,0x89,0x30,0x03,0xce,0xb8,0x04,0x00,0x00,0x00,0x3b,0xf0, 0x89,0x54,0x24,0x10,0x89,0x4c,0x24,0x08,0xc7,0x44,0x24,0x0c,0x00,0x00,0x00,0x00, 0x7e,0x52,0x53,0x55,0xeb,0x0a,0x8b,0x4c,0x24,0x10,0x8d,0x9b,0x00,0x00,0x00,0x00, 0x8a,0x54,0x07,0x08,0x8a,0x5c,0x24,0x20,0x8b,0x6c,0x24,0x10,0x32,0xca,0x32,0xcb, 0x8b,0x5c,0x24,0x24,0x88,0x0c,0x18,0x8b,0xd8,0xd1,0xfb,0x0f,0xaf,0xd8,0x66,0x0f, 0xb6,0xc9,0x03,0xeb,0x8b,0x5c,0x24,0x14,0x80,0xf2,0x33,0x89,0x6c,0x24,0x10,0x88, 0x54,0x24,0x20,0x03,0xd9,0x40,0x3b,0xc6,0x89,0x5c,0x24,0x14,0x7c,0xb8,0x8b,0x54, 0x24,0x18,0x5d,0x5b,0x66,0x8b,0x4c,0x24,0x0c,0x33,0xc0,0x66,0x39,0x4f,0x04,0x5f, 0x0f,0x95,0xc0,0x5e,0x48,0x23,0xc2,0x83,0xc4,0x0c,0xc3,0x90,0x90,0x90,0x90,0x90 }; #else BYTE smwsock_EncodePacket_AsmCode[ENC_PACKET_ASM_SIZE]; #endif

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...