forked from metin2/server
198 lines
4.6 KiB
C++
198 lines
4.6 KiB
C++
#include "stdafx.h"
|
|
#include "Peer.h"
|
|
#include "ItemIDRangeManager.h"
|
|
|
|
CPeer::CPeer()
|
|
{
|
|
m_state = 0;
|
|
m_bChannel = 0;
|
|
m_dwHandle = 0;
|
|
m_dwUserCount = 0;
|
|
m_wListenPort = 0;
|
|
m_wP2PPort = 0;
|
|
|
|
memset(m_alMaps, 0, sizeof(m_alMaps));
|
|
|
|
m_itemRange.dwMin = m_itemRange.dwMax = m_itemRange.dwUsableItemIDMin = 0;
|
|
m_itemSpareRange.dwMin = m_itemSpareRange.dwMax = m_itemSpareRange.dwUsableItemIDMin = 0;
|
|
}
|
|
|
|
CPeer::~CPeer()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void CPeer::OnAccept()
|
|
{
|
|
m_state = STATE_PLAYING;
|
|
|
|
static DWORD current_handle = 0;
|
|
m_dwHandle = ++current_handle;
|
|
|
|
sys_log(0, "Connection accepted. (host: %s handle: %u fd: %d)", m_host, m_dwHandle, m_fd);
|
|
}
|
|
|
|
void CPeer::OnConnect()
|
|
{
|
|
sys_log(0, "Connection established. (host: %s handle: %u fd: %d)", m_host, m_dwHandle, m_fd);
|
|
m_state = STATE_PLAYING;
|
|
}
|
|
|
|
void CPeer::OnClose()
|
|
{
|
|
m_state = STATE_CLOSE;
|
|
|
|
sys_log(0, "Connection closed. (host: %s)", m_host);
|
|
sys_log(0, "ItemIDRange: returned. %u ~ %u", m_itemRange.dwMin, m_itemRange.dwMax);
|
|
|
|
CItemIDRangeManager::instance().UpdateRange(m_itemRange.dwMin, m_itemRange.dwMax);
|
|
|
|
m_itemRange.dwMin = 0;
|
|
m_itemRange.dwMax = 0;
|
|
m_itemRange.dwUsableItemIDMin = 0;
|
|
}
|
|
|
|
DWORD CPeer::GetHandle()
|
|
{
|
|
return m_dwHandle;
|
|
}
|
|
|
|
DWORD CPeer::GetUserCount()
|
|
{
|
|
return m_dwUserCount;
|
|
}
|
|
|
|
void CPeer::SetUserCount(DWORD dwCount)
|
|
{
|
|
m_dwUserCount = dwCount;
|
|
}
|
|
|
|
bool CPeer::PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWORD & dwLength, const char ** data)
|
|
{
|
|
if (GetRecvLength() < iBytesProceed + 9)
|
|
return false;
|
|
|
|
const char * buf = (const char *) GetRecvBuffer();
|
|
buf += iBytesProceed;
|
|
|
|
header = *(buf++);
|
|
|
|
dwHandle = *((DWORD *) buf);
|
|
buf += sizeof(DWORD);
|
|
|
|
dwLength = *((DWORD *) buf);
|
|
buf += sizeof(DWORD);
|
|
|
|
//sys_log(0, "%d header %d handle %u length %u", GetRecvLength(), header, dwHandle, dwLength);
|
|
if (iBytesProceed + dwLength + 9 > (DWORD) GetRecvLength())
|
|
{
|
|
sys_log(0, "PeekPacket: not enough buffer size: len %u, recv %d",
|
|
9+dwLength, GetRecvLength()-iBytesProceed);
|
|
return false;
|
|
}
|
|
|
|
*data = buf;
|
|
iBytesProceed += dwLength + 9;
|
|
return true;
|
|
}
|
|
|
|
void CPeer::EncodeHeader(BYTE header, DWORD dwHandle, DWORD dwSize)
|
|
{
|
|
HEADER h;
|
|
|
|
sys_log(1, "EncodeHeader %u handle %u size %u", header, dwHandle, dwSize);
|
|
|
|
h.bHeader = header;
|
|
h.dwHandle = dwHandle;
|
|
h.dwSize = dwSize;
|
|
|
|
Encode(&h, sizeof(HEADER));
|
|
}
|
|
|
|
void CPeer::EncodeReturn(BYTE header, DWORD dwHandle)
|
|
{
|
|
EncodeHeader(header, dwHandle, 0);
|
|
}
|
|
|
|
int CPeer::Send()
|
|
{
|
|
if (m_state == STATE_CLOSE)
|
|
return -1;
|
|
|
|
return (CPeerBase::Send());
|
|
}
|
|
|
|
void CPeer::SetP2PPort(WORD wPort)
|
|
{
|
|
m_wP2PPort = wPort;
|
|
}
|
|
|
|
void CPeer::SetMaps(long * pl)
|
|
{
|
|
thecore_memcpy(m_alMaps, pl, sizeof(m_alMaps));
|
|
}
|
|
|
|
void CPeer::SendSpareItemIDRange()
|
|
{
|
|
if (m_itemSpareRange.dwMin == 0 || m_itemSpareRange.dwMax == 0 || m_itemSpareRange.dwUsableItemIDMin == 0)
|
|
{
|
|
EncodeHeader(HEADER_DG_ACK_SPARE_ITEM_ID_RANGE, 0, sizeof(TItemIDRangeTable));
|
|
Encode(&m_itemSpareRange, sizeof(TItemIDRangeTable));
|
|
}
|
|
else
|
|
{
|
|
SetItemIDRange(m_itemSpareRange);
|
|
|
|
if (SetSpareItemIDRange(CItemIDRangeManager::instance().GetRange()) == false)
|
|
{
|
|
sys_log(0, "ItemIDRange: spare range set error");
|
|
m_itemSpareRange.dwMin = m_itemSpareRange.dwMax = m_itemSpareRange.dwUsableItemIDMin = 0;
|
|
}
|
|
|
|
EncodeHeader(HEADER_DG_ACK_SPARE_ITEM_ID_RANGE, 0, sizeof(TItemIDRangeTable));
|
|
Encode(&m_itemSpareRange, sizeof(TItemIDRangeTable));
|
|
}
|
|
}
|
|
|
|
bool CPeer::SetItemIDRange(TItemIDRangeTable itemRange)
|
|
{
|
|
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
|
|
|
|
m_itemRange = itemRange;
|
|
sys_log(0, "ItemIDRange: SET %s %u ~ %u start: %u", GetPublicIP(), m_itemRange.dwMin, m_itemRange.dwMax, m_itemRange.dwUsableItemIDMin);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPeer::SetSpareItemIDRange(TItemIDRangeTable itemRange)
|
|
{
|
|
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
|
|
|
|
m_itemSpareRange = itemRange;
|
|
sys_log(0, "ItemIDRange: SPARE SET %s %u ~ %u start: %u", GetPublicIP(), m_itemSpareRange.dwMin, m_itemSpareRange.dwMax,
|
|
m_itemSpareRange.dwUsableItemIDMin);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPeer::CheckItemIDRangeCollision(TItemIDRangeTable itemRange)
|
|
{
|
|
if (m_itemRange.dwMin < itemRange.dwMax && m_itemRange.dwMax > itemRange.dwMin)
|
|
{
|
|
sys_err("ItemIDRange: Collision!! this %u ~ %u check %u ~ %u",
|
|
m_itemRange.dwMin, m_itemRange.dwMax, itemRange.dwMin, itemRange.dwMax);
|
|
return false;
|
|
}
|
|
|
|
if (m_itemSpareRange.dwMin < itemRange.dwMax && m_itemSpareRange.dwMax > itemRange.dwMin)
|
|
{
|
|
sys_err("ItemIDRange: Collision with spare range this %u ~ %u check %u ~ %u",
|
|
m_itemSpareRange.dwMin, m_itemSpareRange.dwMax, itemRange.dwMin, itemRange.dwMax);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|