DragonNest/Common/NetworkLib/SpinBuffer.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

364 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "../Protocol/DNPacket.h"
#include "SocketContext.h"
#include "SpinBuffer.h"
#include "DnServerDef.h"
#include "DnServerPacketCash.h"
#include "Log.h"
#if defined(_SERVER)
//==================================================================================================================================================//
// Class ScopeSpinBufferSwitch
//==================================================================================================================================================//
ScopeSpinBufferSwitch::ScopeSpinBufferSwitch( CSpinBuffer* pSpinBuffer )
: m_pSpinBuffer( pSpinBuffer ), m_pBuffer( NULL ), m_uiSize( 0 ), m_uiBufferIndex( 0 )
{
m_uiBufferIndex = m_pSpinBuffer->Switch( m_pBuffer, m_uiSize );
}
ScopeSpinBufferSwitch::~ScopeSpinBufferSwitch()
{
if( m_uiBufferIndex != UINT_MAX )
m_pSpinBuffer->SwitchClear( m_uiBufferIndex );
}
//==================================================================================================================================================//
// Class CSpinBuffer
//==================================================================================================================================================//
CSpinBuffer::CSpinBuffer( const UINT uiAccessThreadCount, const UINT uiSize )
: m_uiActiveBufferIndex(0), m_uiMaxBufferCount(0)
{
_ASSERT( uiAccessThreadCount );
m_uiMaxBufferCount = uiAccessThreadCount+1;
m_vBufferSize.reserve( m_uiMaxBufferCount );
m_vBufferOffset.reserve( m_uiMaxBufferCount );
m_vBuffer.reserve( m_uiMaxBufferCount );
for( UINT i=0 ; i<m_uiMaxBufferCount ; ++i )
{
m_vBuffer.push_back( new (std::nothrow) char[uiSize] );
m_vBufferOffset.push_back( 0 );
m_vBufferSize.push_back( uiSize );
if( i )
m_qBuffer.push( i );
}
}
CSpinBuffer::~CSpinBuffer()
{
for( UINT i=0 ; i<m_uiMaxBufferCount ; ++i )
{
if( m_vBuffer[i] )
delete[] m_vBuffer[i];
}
}
void CSpinBuffer::Clear()
{
ScopeLock<CSyncLock> Lock( m_Lock );
for( UINT i=0 ; i<m_uiMaxBufferCount ; ++i )
m_vBufferOffset[i] = 0;
}
// [ReturnValue] ReturnBuffer BufferIndex
UINT CSpinBuffer::Switch( char*& pReturnBuffer, UINT& uiReturnSize )
{
ScopeLock<CSyncLock> Lock( m_Lock );
_ASSERT( !m_qBuffer.empty() );
UINT uiReturnBufferIndex = m_uiActiveBufferIndex;
pReturnBuffer = m_vBuffer[m_uiActiveBufferIndex];
uiReturnSize = m_vBufferOffset[m_uiActiveBufferIndex];
if( uiReturnSize == 0 )
return UINT_MAX;
m_uiActiveBufferIndex = m_qBuffer.front();
m_qBuffer.pop();
m_vBufferOffset[m_uiActiveBufferIndex] = 0;
return uiReturnBufferIndex;
}
void CSpinBuffer::SwitchClear( const UINT uiBufferIndex )
{
ScopeLock<CSyncLock> Lock( m_Lock );
m_qBuffer.push( uiBufferIndex );
}
int CSpinBuffer::Resize( const UINT32 uiSize )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
_ASSERT( m_vBufferSize[m_uiActiveBufferIndex] < uiSize );
char* pResizeBuffer = new (std::nothrow) char[uiSize];
if( pResizeBuffer == NULL )
return -1;
if( m_vBufferOffset[m_uiActiveBufferIndex] )
memcpy( pResizeBuffer, m_vBuffer[m_uiActiveBufferIndex], m_vBufferOffset[m_uiActiveBufferIndex] );
delete[] m_vBuffer[m_uiActiveBufferIndex];
m_vBuffer[m_uiActiveBufferIndex] = pResizeBuffer;
m_vBufferSize[m_uiActiveBufferIndex] = uiSize;
return 0;
}
int CSpinBuffer::RawPush( const void* pSrc, const UINT uiLen )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
if( m_vBufferOffset[m_uiActiveBufferIndex] + uiLen > m_vBufferSize[m_uiActiveBufferIndex] )
{
if( Resize( m_vBufferSize[m_uiActiveBufferIndex]*2 ) < 0 )
return -1;
// Buffer Resize <20>ص<EFBFBD> <20><><EFBFBD>ڶ<EFBFBD><DAB6>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ѵ<EFBFBD>.
// Buffer <20><> <20>ٽ<EFBFBD> Resize <20>ص<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߻<EFBFBD><DFBB><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
if( m_vBufferOffset[m_uiActiveBufferIndex] + uiLen > m_vBufferSize[m_uiActiveBufferIndex] )
{
g_Log.Log(LogType::_ERROR, L"[RawPush] Offset:%u, uiLen:%u, Max:%u\r\n", m_vBufferOffset[m_uiActiveBufferIndex], uiLen, m_vBufferSize[m_uiActiveBufferIndex]);
return -1;
}
}
char* pBuffer = m_vBuffer[m_uiActiveBufferIndex] + m_vBufferOffset[m_uiActiveBufferIndex];
memcpy( pBuffer, pSrc, uiLen );
m_vBufferOffset[m_uiActiveBufferIndex] += uiLen;
return 0;
}
//==================================================================================================================================================//
// Class CTcpRecvSpinBuffer
//==================================================================================================================================================//
CTcpRecvSpinBuffer::CTcpRecvSpinBuffer( const UINT uiAccessThreadCount, const UINT uiSize )
: CSpinBuffer( uiAccessThreadCount, uiSize )
{
}
CTcpRecvSpinBuffer::~CTcpRecvSpinBuffer()
{
}
int CTcpRecvSpinBuffer::Push( CSocketContext *pSocketContext )
{
ScopeLock<CSyncLock> Lock( m_Lock );
int iPushCount = 0;
const char* pRecvBuffer = pSocketContext->m_RecvIO.buffer;
UINT uiRecvBufferLen = pSocketContext->m_RecvIO.Len;
while( uiRecvBufferLen )
{
UINT uiPacketLen = 0;
if (pSocketContext->m_dwKeyParam == CONNECTIONKEY_AUTH)
uiPacketLen = GetCompleteAuthPacketLength( pRecvBuffer, uiRecvBufferLen );
else if (pSocketContext->m_dwKeyParam == CONNECTIONKEY_BILLING)
uiPacketLen = GetCompleteBillingPacketLength( pRecvBuffer, uiRecvBufferLen );
#if defined(_TW)
else if (pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_AUTHLOGIN || pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_AUTHLOGOUT ||
pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_QUERY || pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_SHOPITEM ||
pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_COUPON || pSocketContext->m_dwKeyParam == CONNECTIONKEY_TW_COUPON_ROLLBACK)
uiPacketLen = GetCompleteAuthPacketLength_TW( pRecvBuffer, uiRecvBufferLen );
#elif defined(_TH)
else if (pSocketContext->m_dwKeyParam == CONNECTIONKEY_TH_AUTH || pSocketContext->m_dwKeyParam == CONNECTIONKEY_TH_QUERY || pSocketContext->m_dwKeyParam == CONNECTIONKEY_TH_SHOPITEM)
uiPacketLen = GetCompleteAuthPacketLength_TH_Auth(pRecvBuffer, uiRecvBufferLen);
else if (pSocketContext->m_dwKeyParam == CONNECTIONKEY_TH_OTP)
uiPacketLen = GetCompleteAuthPacketLength_TH_OTP(pRecvBuffer, uiRecvBufferLen);
#endif // #if defined(_TW)
else
uiPacketLen = GetCompletePacketLength( pRecvBuffer, uiRecvBufferLen );
if( uiPacketLen <= 0 )
break;
if( RawPush( pRecvBuffer, uiPacketLen ) < 0 )
return -1;
pRecvBuffer += uiPacketLen;
uiRecvBufferLen -= uiPacketLen;
++iPushCount;
}
if( iPushCount > 0 )
{
pSocketContext->m_RecvIO.Len = uiRecvBufferLen;
if( uiRecvBufferLen )
memmove( &pSocketContext->m_RecvIO.buffer, pRecvBuffer, uiRecvBufferLen );
}
return iPushCount;
}
int CTcpRecvSpinBuffer::Push( const DNTPacket& Packet )
{
ScopeLock<CSyncLock> Lock( m_Lock );
return RawPush( &Packet, Packet.iLen );
}
int CTcpRecvSpinBuffer::Push( const DNEncryptPacketSeq& Packet )
{
ScopeLock<CSyncLock> Lock( m_Lock );
return RawPush( &Packet, Packet.nLen );
}
UINT CTcpRecvSpinBuffer::GetCompletePacketLength( const void* pBuffer, const UINT uiLen ) const
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
// iLen + cMainCmd + cSubCmd
static const UINT uiTcpPacketHeaderSize = sizeof(USHORT)+sizeof(UCHAR)+sizeof(UCHAR);
if( uiLen < uiTcpPacketHeaderSize )
return 0;
const DNTPacket* pPacket = static_cast<const DNTPacket*>(pBuffer);
return (pPacket->iLen <= uiLen) ? pPacket->iLen : 0;
}
UINT CTcpRecvSpinBuffer::GetCompleteAuthPacketLength( const void* pBuffer, const UINT uiLen ) const
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
// Header + Length
static const UINT uiTcpPacketHeaderSize = sizeof(BYTE) + sizeof(USHORT);
if( uiLen < uiTcpPacketHeaderSize )
return 0;
const TAuthHeader* pPacket = static_cast<const TAuthHeader*>(pBuffer);
USHORT wLength = SWAP16(pPacket->wLength) + uiTcpPacketHeaderSize;
return (wLength <= uiLen) ? wLength : 0;
}
UINT CTcpRecvSpinBuffer::GetCompleteBillingPacketLength( const void* pBuffer, const UINT uiLen ) const
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
// Header + Length
static const UINT uiTcpPacketHeaderSize = sizeof(BYTE) + sizeof(UINT);
if( uiLen < uiTcpPacketHeaderSize )
return 0;
const TBillingHeader* pPacket = static_cast<const TBillingHeader*>(pBuffer);
UINT nLength = SWAP32(pPacket->nLength) + uiTcpPacketHeaderSize;
return (nLength <= uiLen) ? nLength : 0;
}
#if defined(_TW)
UINT CTcpRecvSpinBuffer::GetCompleteAuthPacketLength_TW( const void* pBuffer, const UINT uiLen ) const
{
// GASH <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '\r\n' <20><> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ
UINT nLength = 0;
for (INT iIndex = 0 ; (static_cast<int>(uiLen) - 1) > iIndex ; ++iIndex) {
if ('\r' == static_cast<const char*>(pBuffer)[iIndex] && '\n' == static_cast<const char*>(pBuffer)[iIndex + 1]) {
nLength = iIndex + 2;
break;
}
}
return (nLength <= uiLen) ? nLength : 0;
}
#elif defined(_TH)
UINT CTcpRecvSpinBuffer::GetCompleteAuthPacketLength_TH_Auth( const char* pBuffer, const UINT uiLen ) const
{
UINT nLength = 0;
for (INT iIndex = 0 ; (static_cast<int>(uiLen)) > iIndex ; ++iIndex) {
if (';' == pBuffer[iIndex]) {
nLength = iIndex + 1;
break;
}
}
return (nLength <= uiLen) ? nLength : 0;
}
UINT CTcpRecvSpinBuffer::GetCompleteAuthPacketLength_TH_OTP( const void* pBuffer, const UINT uiLen ) const
{
return uiLen;
}
#endif // #if defined(_TH)
//==================================================================================================================================================//
// Class CCompPacketBuffer
//==================================================================================================================================================//
CCompPacketBuffer::CCompPacketBuffer( const UINT uiAccessThreadCount, const UINT uiSize )
: CSpinBuffer( uiAccessThreadCount, uiSize )
{
}
CCompPacketBuffer::~CCompPacketBuffer()
{
}
int CCompPacketBuffer::Push( const DNTCompPacket& Packet )
{
ScopeLock<CSyncLock> Lock(m_Lock);
return RawPush(&Packet, Packet.header.nLen);
}
UINT CCompPacketBuffer::GetLeftBufferSize()
{
ScopeLock<CSyncLock> Lock(m_Lock);
return m_vBufferSize[m_uiActiveBufferIndex] - m_vBufferOffset[m_uiActiveBufferIndex];
}
//==================================================================================================================================================//
// Class CRawSpinBuffer
//==================================================================================================================================================//
CRawSpinBuffer::CRawSpinBuffer( const UINT uiAccessThreadCount, const UINT uiSize )
: CSpinBuffer( uiAccessThreadCount, uiSize ), m_bIsLock( false )
{
}
CRawSpinBuffer::~CRawSpinBuffer()
{
}
int CRawSpinBuffer::Push( const void* pSrc, const UINT uiLen )
{
_ASSERT( m_bIsLock == true );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LOCK <20>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD> <20><>
if( RawPush( pSrc, uiLen ) < 0 )
return -1;
return uiLen;
}
void CRawSpinBuffer::Lock()
{
m_Lock.Lock();
m_bIsLock = true;
}
void CRawSpinBuffer::UnLock()
{
m_Lock.UnLock();
m_bIsLock = false;
}
UINT CRawSpinBuffer::GetCompletePacketLength( const void* pBuffer, const UINT uiLen ) const
{
return uiLen;
}
#endif // #if defined(_SERVER)