mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-21 18:14:19 +00:00
177 lines
3.5 KiB
C++
177 lines
3.5 KiB
C++
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||
|
#include <base/system.h>
|
||
|
#include "config.h"
|
||
|
#include "network.h"
|
||
|
|
||
|
void CConsoleNetConnection::Reset()
|
||
|
{
|
||
|
m_State = NET_CONNSTATE_OFFLINE;
|
||
|
mem_zero(&m_PeerAddr, sizeof(m_PeerAddr));
|
||
|
m_aErrorString[0] = 0;
|
||
|
|
||
|
m_aBuffer[0] = 0;
|
||
|
m_pBufferPos = 0;
|
||
|
m_Timeout = 0;
|
||
|
}
|
||
|
|
||
|
void CConsoleNetConnection::Init(NETSOCKET Socket, const NETADDR *pAddr)
|
||
|
{
|
||
|
Reset();
|
||
|
|
||
|
m_Socket = Socket;
|
||
|
net_tcp_set_non_blocking(m_Socket);
|
||
|
|
||
|
m_LastRecvTime = time_get();
|
||
|
|
||
|
m_PeerAddr = *pAddr;
|
||
|
m_State = NET_CONNSTATE_ONLINE;
|
||
|
}
|
||
|
|
||
|
void CConsoleNetConnection::Init(NETSOCKET Socket)
|
||
|
{
|
||
|
Reset();
|
||
|
|
||
|
m_Socket = Socket;
|
||
|
net_tcp_set_non_blocking(m_Socket);
|
||
|
|
||
|
m_LastRecvTime = time_get();
|
||
|
}
|
||
|
|
||
|
int CConsoleNetConnection::Connect(const NETADDR *pAddr)
|
||
|
{
|
||
|
if(State() != NET_CONNSTATE_OFFLINE)
|
||
|
return -1;
|
||
|
|
||
|
// init connection
|
||
|
Reset();
|
||
|
m_PeerAddr = *pAddr;
|
||
|
net_tcp_connect(m_Socket, pAddr);
|
||
|
m_State = NET_CONNSTATE_ONLINE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CConsoleNetConnection::Disconnect(const char *pReason)
|
||
|
{
|
||
|
if(State() == NET_CONNSTATE_OFFLINE)
|
||
|
return;
|
||
|
|
||
|
if(pReason)
|
||
|
{
|
||
|
char aBuf[sizeof(pReason) + 4];
|
||
|
str_format(aBuf, sizeof(aBuf), "%s", pReason);
|
||
|
Send(aBuf);
|
||
|
}
|
||
|
|
||
|
net_tcp_close(m_Socket);
|
||
|
|
||
|
Reset();
|
||
|
}
|
||
|
|
||
|
int CConsoleNetConnection::Update()
|
||
|
{
|
||
|
if(m_Timeout && time_get() > m_LastRecvTime + m_Timeout * time_freq())
|
||
|
{
|
||
|
m_State = NET_CONNSTATE_ERROR;
|
||
|
str_copy(m_aErrorString, "timeout", sizeof(m_aErrorString));
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if(State() == NET_CONNSTATE_ONLINE)
|
||
|
{
|
||
|
char aBuf[NET_MAX_PACKETSIZE];
|
||
|
|
||
|
int Bytes = net_tcp_recv(m_Socket, aBuf, sizeof(aBuf) - 1);
|
||
|
|
||
|
if(Bytes > 0)
|
||
|
{
|
||
|
aBuf[Bytes - 1] = 0;
|
||
|
|
||
|
if(!m_pBufferPos)
|
||
|
m_aBuffer[0] = 0;
|
||
|
else if(m_pBufferPos != m_aBuffer)
|
||
|
mem_move(m_pBufferPos, m_aBuffer, str_length(m_pBufferPos) + 1); // +1 for the \0
|
||
|
m_pBufferPos = m_aBuffer;
|
||
|
|
||
|
str_append(m_aBuffer, aBuf, sizeof(m_aBuffer));
|
||
|
|
||
|
m_LastRecvTime = time_get();
|
||
|
}
|
||
|
else if(Bytes < 0)
|
||
|
{
|
||
|
if(net_would_block()) // no data received
|
||
|
return 0;
|
||
|
|
||
|
m_State = NET_CONNSTATE_ERROR; // error
|
||
|
str_copy(m_aErrorString, "connection failure", sizeof(m_aErrorString));
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_State = NET_CONNSTATE_ERROR;
|
||
|
str_copy(m_aErrorString, "remote end closed the connection", sizeof(m_aErrorString));
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CConsoleNetConnection::Recv(char *pLine, int MaxLength)
|
||
|
{
|
||
|
if(State() == NET_CONNSTATE_ONLINE)
|
||
|
{
|
||
|
if(m_pBufferPos && *m_pBufferPos)
|
||
|
{
|
||
|
char *pResult = m_pBufferPos;
|
||
|
|
||
|
while(*m_pBufferPos && *m_pBufferPos != '\r' && *m_pBufferPos != '\n')
|
||
|
m_pBufferPos++;
|
||
|
|
||
|
if(*m_pBufferPos) // haven't reached the end of the buffer?
|
||
|
{
|
||
|
if(*m_pBufferPos == '\r' && *(m_pBufferPos + 1) == '\n')
|
||
|
{
|
||
|
*m_pBufferPos = 0;
|
||
|
m_pBufferPos += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*m_pBufferPos = 0;
|
||
|
m_pBufferPos++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pBufferPos = 0;
|
||
|
}
|
||
|
|
||
|
str_copy(pLine, pResult, MaxLength);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CConsoleNetConnection::Send(const char *pLine)
|
||
|
{
|
||
|
if(State() != NET_CONNSTATE_ONLINE)
|
||
|
return -1;
|
||
|
|
||
|
int Length = str_length(pLine);
|
||
|
char aBuf[1024];
|
||
|
str_copy(aBuf, pLine, sizeof(aBuf) - 2);
|
||
|
aBuf[Length + 1] = '\n';
|
||
|
aBuf[Length + 2] = '\0';
|
||
|
|
||
|
if(net_tcp_send(m_Socket, aBuf, Length + 2) < 0)
|
||
|
{
|
||
|
m_State = NET_CONNSTATE_ERROR;
|
||
|
str_copy(m_aErrorString, "Failed to send packet", sizeof(m_aErrorString));
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|