mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-14 00:11:09 +00:00
8037810110
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@177 8a3a26a2-13c4-0310-b231-cf6edde360e5
627 lines
18 KiB
C
627 lines
18 KiB
C
/*
|
|
Copyright (C) 1999-2007 id Software, Inc. and contributors.
|
|
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
|
|
|
This file is part of GtkRadiant.
|
|
|
|
GtkRadiant is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
GtkRadiant is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GtkRadiant; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
//====================================================================
|
|
//
|
|
// Name: l_net.c
|
|
// Function: -
|
|
// Programmer: MrElusive
|
|
// Last update: -
|
|
// Tab size: 3
|
|
// Notes:
|
|
//====================================================================
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "l_net.h"
|
|
#include "l_net_wins.h"
|
|
|
|
#define GetMemory malloc
|
|
#define FreeMemory free
|
|
|
|
#define qtrue 1
|
|
#define qfalse 0
|
|
|
|
#ifdef _DEBUG
|
|
void WinPrint(char *str, ...)
|
|
{
|
|
va_list argptr;
|
|
char text[4096];
|
|
|
|
va_start (argptr,str);
|
|
vsprintf (text, str, argptr);
|
|
va_end (argptr);
|
|
|
|
printf(text);
|
|
}
|
|
#else
|
|
void WinPrint(char *str, ...)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_SetAddressPort(address_t *address, int port)
|
|
{
|
|
sockaddr_t addr;
|
|
|
|
WINS_StringToAddr(address->ip, &addr);
|
|
WINS_SetSocketPort(&addr, port);
|
|
strcpy(address->ip, WINS_AddrToString(&addr));
|
|
} //end of the function Net_SetAddressPort
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int Net_AddressCompare(address_t *addr1, address_t *addr2)
|
|
{
|
|
#ifdef _WIN32
|
|
return stricmp(addr1->ip, addr2->ip);
|
|
#endif
|
|
#ifdef __linux__
|
|
return strcasecmp(addr1->ip, addr2->ip);
|
|
#endif
|
|
} //end of the function Net_AddressCompare
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_SocketToAddress(socket_t *sock, address_t *address)
|
|
{
|
|
strcpy(address->ip, WINS_AddrToString(&sock->addr));
|
|
} //end of the function Net_SocketToAddress
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int Net_Send(socket_t *sock, netmessage_t *msg)
|
|
{
|
|
int size;
|
|
|
|
size = msg->size;
|
|
msg->size = 0;
|
|
NMSG_WriteLong(msg, size-4);
|
|
msg->size = size;
|
|
//WinPrint("Net_Send: message of size %d\n", sendmsg.size);
|
|
return WINS_Write(sock->socket, msg->data, msg->size, NULL);
|
|
} //end of the function Net_SendSocketReliable
|
|
//===========================================================================
|
|
// returns the number of bytes recieved
|
|
// -1 on error
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int Net_Receive(socket_t *sock, netmessage_t *msg)
|
|
{
|
|
int curread;
|
|
|
|
if (sock->remaining > 0)
|
|
{
|
|
curread = WINS_Read(sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL);
|
|
if (curread == -1)
|
|
{
|
|
WinPrint("Net_Receive: read error\n");
|
|
return -1;
|
|
} //end if
|
|
sock->remaining -= curread;
|
|
sock->msg.size += curread;
|
|
if (sock->remaining <= 0)
|
|
{
|
|
sock->remaining = 0;
|
|
memcpy(msg, &sock->msg, sizeof(netmessage_t));
|
|
sock->msg.size = 0;
|
|
return msg->size - 4;
|
|
} //end if
|
|
return 0;
|
|
} //end if
|
|
sock->msg.size = WINS_Read(sock->socket, sock->msg.data, 4, NULL);
|
|
if (sock->msg.size == 0) return 0;
|
|
if (sock->msg.size == -1)
|
|
{
|
|
WinPrint("Net_Receive: size header read error\n");
|
|
return -1;
|
|
} //end if
|
|
//WinPrint("Net_Receive: message size header %d\n", msg->size);
|
|
sock->msg.read = 0;
|
|
sock->remaining = NMSG_ReadLong(&sock->msg);
|
|
if (sock->remaining == 0) return 0;
|
|
if (sock->remaining < 0 || sock->remaining > MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("Net_Receive: invalid message size %d\n", sock->remaining);
|
|
return -1;
|
|
} //end if
|
|
//try to read the message
|
|
curread = WINS_Read(sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL);
|
|
if (curread == -1)
|
|
{
|
|
WinPrint("Net_Receive: read error\n");
|
|
return -1;
|
|
} //end if
|
|
sock->remaining -= curread;
|
|
sock->msg.size += curread;
|
|
if (sock->remaining <= 0)
|
|
{
|
|
sock->remaining = 0;
|
|
memcpy(msg, &sock->msg, sizeof(netmessage_t));
|
|
sock->msg.size = 0;
|
|
return msg->size - 4;
|
|
} //end if
|
|
//the message has not been completely read yet
|
|
#ifdef _DEBUG
|
|
printf("++timo TODO: debug the Net_Receive on big size messages\n");
|
|
#endif
|
|
return 0;
|
|
} //end of the function Net_Receive
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
socket_t *Net_AllocSocket(void)
|
|
{
|
|
socket_t *sock;
|
|
|
|
sock = (socket_t *) GetMemory(sizeof(socket_t));
|
|
memset(sock, 0, sizeof(socket_t));
|
|
return sock;
|
|
} //end of the function Net_AllocSocket
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_FreeSocket(socket_t *sock)
|
|
{
|
|
FreeMemory(sock);
|
|
} //end of the function Net_FreeSocket
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
socket_t *Net_Connect(address_t *address, int port)
|
|
{
|
|
int newsock;
|
|
socket_t *sock;
|
|
sockaddr_t sendaddr;
|
|
|
|
// see if we can resolve the host name
|
|
WINS_StringToAddr(address->ip, &sendaddr);
|
|
|
|
newsock = WINS_OpenReliableSocket(port);
|
|
if (newsock == -1) return NULL;
|
|
|
|
sock = Net_AllocSocket();
|
|
if (sock == NULL)
|
|
{
|
|
WINS_CloseSocket(newsock);
|
|
return NULL;
|
|
} //end if
|
|
sock->socket = newsock;
|
|
|
|
//connect to the host
|
|
if (WINS_Connect(newsock, &sendaddr) == -1)
|
|
{
|
|
Net_FreeSocket(sock);
|
|
WINS_CloseSocket(newsock);
|
|
WinPrint("Net_Connect: error connecting\n");
|
|
return NULL;
|
|
} //end if
|
|
|
|
memcpy(&sock->addr, &sendaddr, sizeof(sockaddr_t));
|
|
//now we can send messages
|
|
//
|
|
return sock;
|
|
} //end of the function Net_Connect
|
|
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
socket_t *Net_ListenSocket(int port)
|
|
{
|
|
int newsock;
|
|
socket_t *sock;
|
|
|
|
newsock = WINS_OpenReliableSocket(port);
|
|
if (newsock == -1) return NULL;
|
|
|
|
if (WINS_Listen(newsock) == -1)
|
|
{
|
|
WINS_CloseSocket(newsock);
|
|
return NULL;
|
|
} //end if
|
|
sock = Net_AllocSocket();
|
|
if (sock == NULL)
|
|
{
|
|
WINS_CloseSocket(newsock);
|
|
return NULL;
|
|
} //end if
|
|
sock->socket = newsock;
|
|
WINS_GetSocketAddr(newsock, &sock->addr);
|
|
WinPrint("listen socket opened at %s\n", WINS_AddrToString(&sock->addr));
|
|
//
|
|
return sock;
|
|
} //end of the function Net_ListenSocket
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
socket_t *Net_Accept(socket_t *sock)
|
|
{
|
|
int newsocket;
|
|
sockaddr_t sendaddr;
|
|
socket_t *newsock;
|
|
|
|
newsocket = WINS_Accept(sock->socket, &sendaddr);
|
|
if (newsocket == -1) return NULL;
|
|
|
|
newsock = Net_AllocSocket();
|
|
if (newsock == NULL)
|
|
{
|
|
WINS_CloseSocket(newsocket);
|
|
return NULL;
|
|
} //end if
|
|
newsock->socket = newsocket;
|
|
memcpy(&newsock->addr, &sendaddr, sizeof(sockaddr_t));
|
|
//
|
|
return newsock;
|
|
} //end of the function Net_Accept
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_Disconnect(socket_t *sock)
|
|
{
|
|
WINS_CloseSocket(sock->socket);
|
|
Net_FreeSocket(sock);
|
|
} //end of the function Net_Disconnect
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_StringToAddress(char *string, address_t *address)
|
|
{
|
|
strcpy(address->ip, string);
|
|
} //end of the function Net_StringToAddress
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_MyAddress(address_t *address)
|
|
{
|
|
strcpy(address->ip, WINS_MyAddress());
|
|
} //end of the function Net_MyAddress
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int Net_Setup(void)
|
|
{
|
|
WINS_Init();
|
|
//
|
|
WinPrint("my address is %s\n", WINS_MyAddress());
|
|
//
|
|
return qtrue;
|
|
} //end of the function Net_Setup
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void Net_Shutdown(void)
|
|
{
|
|
WINS_Shutdown();
|
|
} //end of the function Net_Shutdown
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_Clear(netmessage_t *msg)
|
|
{
|
|
msg->size = 4;
|
|
} //end of the function NMSG_Clear
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteChar (netmessage_t *msg, int c)
|
|
{
|
|
if (c < -128 || c > 127)
|
|
WinPrint("NMSG_WriteChar: range error\n");
|
|
|
|
if (msg->size >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteChar: overflow\n");
|
|
return;
|
|
} //end if
|
|
msg->data[msg->size] = c;
|
|
msg->size++;
|
|
} //end of the function NMSG_WriteChar
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteByte(netmessage_t *msg, int c)
|
|
{
|
|
if (c < -128 || c > 127)
|
|
WinPrint("NMSG_WriteByte: range error\n");
|
|
|
|
if (msg->size + 1 >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteByte: overflow\n");
|
|
return;
|
|
} //end if
|
|
msg->data[msg->size] = c;
|
|
msg->size++;
|
|
} //end of the function NMSG_WriteByte
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteShort(netmessage_t *msg, int c)
|
|
{
|
|
if (c < ((short)0x8000) || c > (short)0x7fff)
|
|
WinPrint("NMSG_WriteShort: range error");
|
|
|
|
if (msg->size + 2 >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteShort: overflow\n");
|
|
return;
|
|
} //end if
|
|
msg->data[msg->size] = c&0xff;
|
|
msg->data[msg->size+1] = c>>8;
|
|
msg->size += 2;
|
|
} //end of the function NMSG_WriteShort
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteLong(netmessage_t *msg, int c)
|
|
{
|
|
if (msg->size + 4 >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteLong: overflow\n");
|
|
return;
|
|
} //end if
|
|
msg->data[msg->size] = c&0xff;
|
|
msg->data[msg->size+1] = (c>>8)&0xff;
|
|
msg->data[msg->size+2] = (c>>16)&0xff;
|
|
msg->data[msg->size+3] = c>>24;
|
|
msg->size += 4;
|
|
} //end of the function NMSG_WriteLong
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteFloat(netmessage_t *msg, float c)
|
|
{
|
|
if (msg->size + 4 >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteLong: overflow\n");
|
|
return;
|
|
} //end if
|
|
msg->data[msg->size] = *((int *)&c)&0xff;
|
|
msg->data[msg->size+1] = (*((int *)&c)>>8)&0xff;
|
|
msg->data[msg->size+2] = (*((int *)&c)>>16)&0xff;
|
|
msg->data[msg->size+3] = *((int *)&c)>>24;
|
|
msg->size += 4;
|
|
} //end of the function NMSG_WriteFloat
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_WriteString(netmessage_t *msg, char *string)
|
|
{
|
|
if (msg->size + strlen(string) + 1 >= MAX_NETMESSAGE)
|
|
{
|
|
WinPrint("NMSG_WriteString: overflow\n");
|
|
return;
|
|
} //end if
|
|
strcpy(&msg->data[msg->size], string);
|
|
msg->size += strlen(string) + 1;
|
|
} //end of the function NMSG_WriteString
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
void NMSG_ReadStart(netmessage_t *msg)
|
|
{
|
|
msg->readoverflow = qfalse;
|
|
msg->read = 4;
|
|
} //end of the function NMSG_ReadStart
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int NMSG_ReadChar(netmessage_t *msg)
|
|
{
|
|
if (msg->size + 1 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadChar: read overflow\n");
|
|
return 0;
|
|
} //end if
|
|
msg->read++;
|
|
return msg->data[msg->read-1];
|
|
} //end of the function NMSG_ReadChar
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int NMSG_ReadByte(netmessage_t *msg)
|
|
{
|
|
if (msg->read + 1 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadByte: read overflow\n");
|
|
return 0;
|
|
} //end if
|
|
msg->read++;
|
|
return msg->data[msg->read-1];
|
|
} //end of the function NMSG_ReadByte
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int NMSG_ReadShort(netmessage_t *msg)
|
|
{
|
|
int c;
|
|
|
|
if (msg->read + 2 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadShort: read overflow\n");
|
|
return 0;
|
|
} //end if
|
|
c = (short)(msg->data[msg->read] + (msg->data[msg->read+1]<<8));
|
|
msg->read += 2;
|
|
return c;
|
|
} //end of the function NMSG_ReadShort
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
int NMSG_ReadLong(netmessage_t *msg)
|
|
{
|
|
int c;
|
|
|
|
if (msg->read + 4 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadLong: read overflow\n");
|
|
return 0;
|
|
} //end if
|
|
c = msg->data[msg->read]
|
|
+ (msg->data[msg->read+1]<<8)
|
|
+ (msg->data[msg->read+2]<<16)
|
|
+ (msg->data[msg->read+3]<<24);
|
|
msg->read += 4;
|
|
return c;
|
|
} //end of the function NMSG_ReadLong
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
float NMSG_ReadFloat(netmessage_t *msg)
|
|
{
|
|
int c;
|
|
|
|
if (msg->read + 4 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadLong: read overflow\n");
|
|
return 0;
|
|
} //end if
|
|
c = msg->data[msg->read]
|
|
+ (msg->data[msg->read+1]<<8)
|
|
+ (msg->data[msg->read+2]<<16)
|
|
+ (msg->data[msg->read+3]<<24);
|
|
msg->read += 4;
|
|
return *(float *)&c;
|
|
} //end of the function NMSG_ReadFloat
|
|
//===========================================================================
|
|
//
|
|
// Parameter: -
|
|
// Returns: -
|
|
// Changes Globals: -
|
|
//===========================================================================
|
|
char *NMSG_ReadString(netmessage_t *msg)
|
|
{
|
|
static char string[2048];
|
|
int l, c;
|
|
|
|
l = 0;
|
|
do
|
|
{
|
|
if (msg->read + 1 > msg->size)
|
|
{
|
|
msg->readoverflow = qtrue;
|
|
WinPrint("NMSG_ReadString: read overflow\n");
|
|
string[l] = 0;
|
|
return string;
|
|
} //end if
|
|
c = msg->data[msg->read];
|
|
msg->read++;
|
|
if (c == 0) break;
|
|
string[l] = c;
|
|
l++;
|
|
} while (l < sizeof(string)-1);
|
|
string[l] = 0;
|
|
return string;
|
|
} //end of the function NMSG_ReadString
|