2007-01-15 12:09:25 -08:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
|
|
|
|
Warzone 2100 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.
|
|
|
|
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
/*
|
|
|
|
* Netplay.c
|
|
|
|
*
|
|
|
|
* Alex Lee sep97-> june98
|
|
|
|
*/
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// includes
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
#include <time.h> // for stats
|
2007-06-28 10:47:08 -07:00
|
|
|
#include <SDL/SDL_thread.h>
|
|
|
|
#include <SDL/SDL_net.h>
|
2006-06-16 12:10:23 -07:00
|
|
|
#include <physfs.h>
|
2006-11-06 06:40:07 -08:00
|
|
|
#include <string.h>
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "netplay.h"
|
2006-04-08 12:32:29 -07:00
|
|
|
#include "netlog.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
char* master_server = "warzone2100.kicks-ass.org";
|
|
|
|
#define MASTER_SERVER_PORT 9998
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
#define WARZONE_NET_PORT 9999
|
|
|
|
#define MAX_CONNECTED_PLAYERS 8
|
|
|
|
#define MAX_TMP_SOCKETS 16
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
#define NET_READ_TIMEOUT 0
|
2007-06-28 10:47:08 -07:00
|
|
|
#define NET_BUFFER_SIZE 1024
|
|
|
|
|
|
|
|
#define MSG_JOIN 90
|
|
|
|
#define MSG_ACCEPTED 91
|
|
|
|
#define MSG_PLAYER_INFO 92
|
|
|
|
#define MSG_PLAYER_DATA 93
|
|
|
|
#define MSG_PLAYER_JOINED 94
|
|
|
|
#define MSG_PLAYER_LEFT 95
|
|
|
|
#define MSG_GAME_FLAGS 96
|
|
|
|
|
|
|
|
//#define NET_DEBUG
|
|
|
|
|
|
|
|
static BOOL allow_joining = FALSE;
|
|
|
|
|
2006-09-13 14:14:47 -07:00
|
|
|
static void NETallowJoining(void);
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL MultiPlayerJoin(UDWORD dpid);
|
|
|
|
BOOL MultiPlayerLeave(UDWORD dpid);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-02-18 10:54:37 -08:00
|
|
|
// Variables
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
NETPLAY NetPlay;
|
|
|
|
static GAMESTRUCT game;
|
|
|
|
|
|
|
|
void NETsetMessageSize(NETMSG* pMsg, unsigned int size) {
|
|
|
|
unsigned int tmp = 8 - (size % 8);
|
|
|
|
|
|
|
|
if (tmp == 8) {
|
|
|
|
pMsg->size = size;
|
|
|
|
pMsg->paddedBytes = 0;
|
|
|
|
} else {
|
|
|
|
pMsg->size = size + tmp;
|
|
|
|
pMsg->paddedBytes = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// *********** Socket with buffer that read NETMSGs ******************
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
TCPsocket socket;
|
|
|
|
char* buffer;
|
|
|
|
unsigned int buffer_start;
|
|
|
|
unsigned int bytes;
|
|
|
|
} NETBUFSOCKET;
|
|
|
|
|
2006-09-13 14:14:47 -07:00
|
|
|
static NETBUFSOCKET* NET_createBufferedSocket(void) {
|
2007-06-28 10:47:08 -07:00
|
|
|
NETBUFSOCKET* bs = (NETBUFSOCKET*)malloc(sizeof(NETBUFSOCKET));
|
|
|
|
|
|
|
|
bs->socket = NULL;
|
|
|
|
bs->buffer = NULL;
|
|
|
|
bs->buffer_start = 0;
|
|
|
|
bs->bytes = 0;
|
|
|
|
|
|
|
|
return bs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NET_destroyBufferedSocket(NETBUFSOCKET* bs) {
|
|
|
|
free(bs->buffer);
|
|
|
|
free(bs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NET_initBufferedSocket(NETBUFSOCKET* bs, TCPsocket s) {
|
|
|
|
bs->socket = s;
|
|
|
|
if (bs->buffer == NULL) {
|
|
|
|
bs->buffer = (char*)malloc(NET_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
bs->buffer_start = 0;
|
|
|
|
bs->bytes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL NET_fillBuffer(NETBUFSOCKET* bs, SDLNet_SocketSet socket_set)
|
|
|
|
{
|
|
|
|
int size;
|
|
|
|
char* bufstart = bs->buffer + bs->buffer_start + bs->bytes;
|
|
|
|
const int bufsize = NET_BUFFER_SIZE - bs->buffer_start - bs->bytes;
|
|
|
|
|
|
|
|
|
|
|
|
if (bs->buffer_start != 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SDLNet_SocketReady(bs->socket) <= 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size = SDLNet_TCP_Recv(bs->socket, bufstart, bufsize);
|
|
|
|
|
|
|
|
if (size > 0) {
|
|
|
|
bs->bytes += size;
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
if (socket_set != NULL) {
|
|
|
|
SDLNet_TCP_DelSocket(socket_set, bs->socket);
|
|
|
|
}
|
|
|
|
SDLNet_TCP_Close(bs->socket);
|
|
|
|
bs->socket = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL NET_recvMessage(NETBUFSOCKET* bs, NETMSG* pMsg)
|
|
|
|
{
|
|
|
|
unsigned int size;
|
|
|
|
const NETMSG* message = (NETMSG*)(bs->buffer + bs->buffer_start);
|
|
|
|
const unsigned int headersize = sizeof(message->size)
|
|
|
|
+ sizeof(message->type)
|
|
|
|
+ sizeof(message->paddedBytes)
|
|
|
|
+ sizeof(message->destination);
|
|
|
|
|
|
|
|
if (headersize > bs->bytes) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = message->size + headersize;
|
|
|
|
|
|
|
|
if (size > bs->bytes) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETrecvMessage: received message of type %i and size %i.\n", message->type, message->size );
|
2005-12-02 13:45:42 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
memcpy(pMsg, message, size);
|
|
|
|
bs->buffer_start += size;
|
|
|
|
bs->bytes -= size;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (bs->buffer_start != 0) {
|
|
|
|
static char* tmp_buffer = NULL;
|
|
|
|
char* buffer_start = bs->buffer + bs->buffer_start;
|
|
|
|
char* tmp;
|
|
|
|
|
|
|
|
//printf("Moving data in buffer\n");
|
|
|
|
|
|
|
|
// Create tmp buffer if necessary
|
|
|
|
if (tmp_buffer == NULL) {
|
|
|
|
//printf("Creating tmp buffer\n");
|
|
|
|
tmp_buffer = (char*)malloc(NET_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move remaining contents into tmp buffer
|
|
|
|
memcpy(tmp_buffer, buffer_start, bs->bytes);
|
|
|
|
|
|
|
|
// swap tmp buffer with buffer
|
|
|
|
tmp = bs->buffer;
|
|
|
|
bs->buffer = tmp_buffer;
|
|
|
|
tmp_buffer = tmp;
|
|
|
|
|
|
|
|
// Now data is in the beginning of the buffer
|
|
|
|
bs->buffer_start = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static TCPsocket tcp_socket = NULL;
|
|
|
|
static NETBUFSOCKET* bsocket = NULL;
|
|
|
|
static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL };
|
|
|
|
static SDLNet_SocketSet socket_set = NULL;
|
|
|
|
static BOOL is_server = FALSE;
|
|
|
|
|
|
|
|
static TCPsocket tmp_socket[MAX_TMP_SOCKETS] = { 0 };
|
|
|
|
static SDLNet_SocketSet tmp_socket_set = NULL;
|
|
|
|
|
|
|
|
static NETMSG message;
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
static char* hostname;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct { // data regarding the last one second or so.
|
|
|
|
UDWORD bytesRecvd;
|
|
|
|
UDWORD bytesSent; // number of bytes sent in about 1 sec.
|
2006-02-18 10:54:37 -08:00
|
|
|
UDWORD packetsSent;
|
2007-06-28 10:47:08 -07:00
|
|
|
UDWORD packetsRecvd;
|
|
|
|
} NETSTATS;
|
|
|
|
|
|
|
|
static NETSTATS nStats = { 0 };
|
|
|
|
|
|
|
|
#define PLAYER_HOST 1
|
|
|
|
#define PLAYER_SPECTATOR 2
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Players stuff
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
BOOL allocated;
|
|
|
|
unsigned int id;
|
|
|
|
char name[StringSize];
|
|
|
|
unsigned int flags;
|
|
|
|
} NET_PLAYER;
|
|
|
|
|
|
|
|
static NET_PLAYER players[MAX_CONNECTED_PLAYERS];
|
|
|
|
|
2006-09-13 14:14:47 -07:00
|
|
|
static void NET_InitPlayers(void) {
|
2007-06-28 10:47:08 -07:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_CONNECTED_PLAYERS; ++i) {
|
|
|
|
players[i].allocated = FALSE;
|
|
|
|
players[i].id = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NETBroadcastPlayerInfo(int dpid) {
|
|
|
|
message.type = MSG_PLAYER_INFO;
|
|
|
|
NETsetMessageSize(&message, sizeof(NET_PLAYER));
|
|
|
|
memcpy(message.body, &players[dpid], sizeof(NET_PLAYER));
|
|
|
|
NETbcast(&message, TRUE);
|
|
|
|
}
|
|
|
|
|
2007-01-04 09:03:32 -08:00
|
|
|
unsigned int NET_CreatePlayer(const char* name, unsigned int flags) {
|
2007-06-28 10:47:08 -07:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 1; i < MAX_CONNECTED_PLAYERS; ++i) {
|
|
|
|
if (players[i].allocated == FALSE) {
|
|
|
|
players[i].allocated = TRUE;
|
|
|
|
strcpy(players[i].name, name);
|
|
|
|
players[i].flags = flags;
|
|
|
|
NETBroadcastPlayerInfo(i);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NET_DestroyPlayer(unsigned int id) {
|
|
|
|
players[id].allocated = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// count players. call with null to enumerate the game already joined.
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETplayerInfo(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
unsigned int i;
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
NetPlay.playercount = 0; // reset player counter
|
|
|
|
|
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
NetPlay.playercount = 1;
|
|
|
|
NetPlay.players[0].bHost = TRUE;
|
|
|
|
NetPlay.players[0].bSpectator = FALSE;
|
|
|
|
NetPlay.players[0].dpid = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(NetPlay.players, 0, (sizeof(PLAYER)*MaxNumberOfPlayers)); // reset player info
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_CONNECTED_PLAYERS; ++i) {
|
|
|
|
if (players[i].allocated == TRUE) {
|
|
|
|
NetPlay.players[NetPlay.playercount].dpid = i;
|
|
|
|
strcpy(NetPlay.players[NetPlay.playercount].name, players[i].name);
|
|
|
|
if (players[i].flags & PLAYER_HOST) {
|
|
|
|
NetPlay.players[NetPlay.playercount].bHost = TRUE;
|
|
|
|
} else {
|
|
|
|
NetPlay.players[NetPlay.playercount].bHost = FALSE;
|
|
|
|
}
|
|
|
|
if (players[i].flags & PLAYER_SPECTATOR) {
|
|
|
|
NetPlay.players[NetPlay.playercount].bSpectator = TRUE;
|
|
|
|
} else {
|
|
|
|
NetPlay.players[NetPlay.playercount].bSpectator = FALSE;
|
|
|
|
}
|
|
|
|
NetPlay.playercount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NetPlay.playercount;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// rename the local player
|
|
|
|
// dont call this a lot, since it uses a guaranteed msg.
|
|
|
|
BOOL NETchangePlayerName(UDWORD dpid, char *newName)
|
|
|
|
{
|
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
strcpy(NetPlay.players[0].name, newName);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(players[dpid].name, newName);
|
|
|
|
|
|
|
|
NETBroadcastPlayerInfo(dpid);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
unsigned int size;
|
|
|
|
void* data;
|
|
|
|
unsigned int buffer_size;
|
|
|
|
} NET_PLAYER_DATA;
|
|
|
|
|
|
|
|
static NET_PLAYER_DATA local_player_data[MAX_CONNECTED_PLAYERS] = { { 0 } };
|
|
|
|
static NET_PLAYER_DATA global_player_data[MAX_CONNECTED_PLAYERS] = { { 0 } };
|
|
|
|
|
|
|
|
void resize_local_player_data(unsigned int i, unsigned int size) {
|
|
|
|
if (local_player_data[i].buffer_size < size) {
|
|
|
|
if (local_player_data[i].data != NULL) {
|
|
|
|
free(local_player_data[i].data);
|
|
|
|
}
|
|
|
|
local_player_data[i].data = malloc(size);
|
|
|
|
local_player_data[i].buffer_size = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize_global_player_data(unsigned int i, unsigned int size) {
|
|
|
|
if (global_player_data[i].buffer_size < size) {
|
|
|
|
if (global_player_data[i].data != NULL) {
|
|
|
|
free(global_player_data[i].data);
|
|
|
|
}
|
|
|
|
global_player_data[i].data = malloc(size);
|
|
|
|
global_player_data[i].buffer_size = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-11-04 15:16:51 -08:00
|
|
|
BOOL NETgetLocalPlayerData(UDWORD dpid, void *pData, SDWORD *pSize)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
memcpy(pData, local_player_data[dpid].data, local_player_data[dpid].size);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-11-04 15:16:51 -08:00
|
|
|
BOOL NETgetGlobalPlayerData(UDWORD dpid, void *pData, SDWORD *pSize)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if(!NetPlay.bComms)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
memcpy(pData, local_player_data[dpid].data, local_player_data[dpid].size);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(pData, global_player_data[dpid].data, global_player_data[dpid].size);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-11-04 15:16:51 -08:00
|
|
|
BOOL NETsetLocalPlayerData(UDWORD dpid,void *pData, SDWORD size)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
local_player_data[dpid].size = size;
|
|
|
|
resize_local_player_data(dpid, size);
|
|
|
|
memcpy(local_player_data[dpid].data, pData, size);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-11-04 15:16:51 -08:00
|
|
|
BOOL NETsetGlobalPlayerData(UDWORD dpid, void *pData, SDWORD size)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if(!NetPlay.bComms)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
local_player_data[dpid].size = size;
|
|
|
|
resize_local_player_data(dpid, size);
|
|
|
|
memcpy(local_player_data[dpid].data, pData, size);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
global_player_data[dpid].size = size;
|
|
|
|
resize_global_player_data(dpid, size);
|
|
|
|
memcpy(global_player_data[dpid].data, pData, size);
|
|
|
|
|
|
|
|
{ // broadcast player data
|
|
|
|
unsigned int* p_dpid = (unsigned int*)(message.body);
|
|
|
|
|
|
|
|
message.type = MSG_PLAYER_DATA;
|
|
|
|
NETsetMessageSize(&message, sizeof(unsigned int)+size);
|
|
|
|
*p_dpid = dpid;
|
|
|
|
memcpy(message.body+sizeof(unsigned int), pData, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
NETBroadcastPlayerInfo(dpid);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////////////
|
|
|
|
// Game flags stuff...
|
|
|
|
|
2006-11-04 15:16:51 -08:00
|
|
|
SDWORD NetGameFlags[4];
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// return one of the four user flags in the current sessiondescription.
|
2006-11-04 15:16:51 -08:00
|
|
|
SDWORD NETgetGameFlags(UDWORD flag)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
if (flag < 1 || flag > 4) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return NetGameFlags[flag-1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set a game flag
|
2006-11-04 15:16:51 -08:00
|
|
|
BOOL NETsetGameFlags(UDWORD flag, SDWORD value)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
if(!NetPlay.bComms) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag < 1 || flag > 4) {
|
|
|
|
return NetGameFlags[flag-1] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
message.type = MSG_GAME_FLAGS;
|
|
|
|
NETsetMessageSize(&message, sizeof(NetGameFlags));
|
|
|
|
memcpy(message.body, NetGameFlags, sizeof(NetGameFlags));
|
|
|
|
NETbcast(&message, TRUE);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// setup stuff
|
|
|
|
BOOL NETinit(BOOL bFirstCall)
|
|
|
|
{
|
|
|
|
UDWORD i;
|
2006-06-03 16:46:03 -07:00
|
|
|
debug( LOG_NET, "NETinit" );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// NEThashFile("warzonedebug.exe");
|
|
|
|
|
|
|
|
if(bFirstCall)
|
|
|
|
{
|
2006-08-22 07:28:49 -07:00
|
|
|
debug( LOG_NEVER, "NETPLAY: Init called, MORNIN'\n" );
|
2006-02-18 10:54:37 -08:00
|
|
|
|
|
|
|
NetPlay.bLobbyLaunched = FALSE; // clean up
|
|
|
|
NetPlay.dpidPlayer = 0;
|
2007-06-28 10:47:08 -07:00
|
|
|
NetPlay.bHost = 0;
|
|
|
|
NetPlay.bComms = TRUE;
|
|
|
|
|
|
|
|
NetPlay.bEncryptAllPackets = FALSE;
|
|
|
|
NETsetKey(0x2fe8f810, 0xb72a5, 0x114d0, 0x2a7); // j-random key to get us started
|
|
|
|
|
|
|
|
NetPlay.bAllowCaptureRecord = FALSE;
|
|
|
|
NetPlay.bAllowCapturePlay = FALSE;
|
|
|
|
NetPlay.bCaptureInUse = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0;i<MaxNumberOfPlayers;i++)
|
|
|
|
{
|
|
|
|
memset(&NetPlay.players[i], 0, sizeof(PLAYER));
|
|
|
|
memset(&NetPlay.games[i], 0, sizeof(GAMESTRUCT));
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
//GAME_GUID = g;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
NETuseNetwork(TRUE);
|
|
|
|
NETstartLogging();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SDLNet_Init() == -1) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "SDLNet_Init: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// SHUTDOWN THE CONNECTION.
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL NETshutdown(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-06-03 16:46:03 -07:00
|
|
|
unsigned int i;
|
2006-02-18 10:54:37 -08:00
|
|
|
debug( LOG_NET, "NETshutdown" );
|
|
|
|
|
|
|
|
for( i = 0; i < MAX_CONNECTED_PLAYERS; i++ )
|
|
|
|
{
|
|
|
|
if( local_player_data[i].data != NULL )
|
|
|
|
{
|
|
|
|
free( local_player_data[i].data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NETstopLogging();
|
2007-06-28 10:47:08 -07:00
|
|
|
SDLNet_Quit();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
//close the open game..
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL NETclose(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETclose\n" );
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
NEThaltJoining();
|
2007-06-28 10:47:08 -07:00
|
|
|
is_server=FALSE;
|
|
|
|
|
|
|
|
if(bsocket) {
|
|
|
|
NET_destroyBufferedSocket(bsocket);
|
|
|
|
bsocket=NULL;
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
for(i=0;i<MAX_CONNECTED_PLAYERS;i++) {
|
|
|
|
if(connected_bsocket[i]) {
|
|
|
|
NET_destroyBufferedSocket(connected_bsocket[i]);
|
|
|
|
connected_bsocket[i]=NULL;
|
|
|
|
}
|
|
|
|
NET_DestroyPlayer(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tmp_socket_set) {
|
|
|
|
SDLNet_FreeSocketSet(tmp_socket_set);
|
|
|
|
tmp_socket_set=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=0;i<MAX_TMP_SOCKETS;i++) {
|
|
|
|
if(tmp_socket[i]) {
|
|
|
|
SDLNet_TCP_Close(tmp_socket[i]);
|
|
|
|
tmp_socket[i]=NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(socket_set) {
|
|
|
|
SDLNet_FreeSocketSet(socket_set);
|
|
|
|
socket_set=NULL;
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(tcp_socket) {
|
|
|
|
SDLNet_TCP_Close(tcp_socket);
|
|
|
|
tcp_socket=NULL;
|
|
|
|
}
|
2006-11-26 05:45:04 -08:00
|
|
|
return FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Send and Recv functions
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// return bytes of data sent recently.
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetBytesSent(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD lastsec=0;
|
|
|
|
static UDWORD timy=0;
|
|
|
|
|
2006-02-18 10:54:37 -08:00
|
|
|
if( (UDWORD)clock() > (timy+CLOCKS_PER_SEC) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
timy = clock();
|
|
|
|
lastsec = nStats.bytesSent;
|
|
|
|
nStats.bytesSent = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return lastsec;
|
|
|
|
}
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetRecentBytesSent(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return nStats.bytesSent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetBytesRecvd(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD lastsec=0;
|
|
|
|
static UDWORD timy=0;
|
2006-02-18 10:54:37 -08:00
|
|
|
if( (UDWORD)clock() > (timy+CLOCKS_PER_SEC) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
timy = clock();
|
|
|
|
lastsec = nStats.bytesRecvd;
|
|
|
|
nStats.bytesRecvd = 0;
|
|
|
|
}
|
|
|
|
return lastsec;
|
|
|
|
}
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetRecentBytesRecvd(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return nStats.bytesRecvd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return number of packets sent last sec.
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetPacketsSent(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD lastsec=0;
|
|
|
|
static UDWORD timy=0;
|
|
|
|
|
2006-02-18 10:54:37 -08:00
|
|
|
if( (UDWORD)clock() > (timy+CLOCKS_PER_SEC) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
timy = clock();
|
|
|
|
lastsec = nStats.packetsSent;
|
|
|
|
nStats.packetsSent = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return lastsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetRecentPacketsSent(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return nStats.packetsSent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetPacketsRecvd(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD lastsec=0;
|
|
|
|
static UDWORD timy=0;
|
2006-02-18 10:54:37 -08:00
|
|
|
if( (UDWORD)clock() > (timy+CLOCKS_PER_SEC) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
timy = clock();
|
|
|
|
lastsec = nStats.packetsRecvd;
|
|
|
|
nStats.packetsRecvd = 0;
|
|
|
|
}
|
|
|
|
return lastsec;
|
|
|
|
}
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
UDWORD NETgetRecentPacketsRecvd(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return nStats.packetsRecvd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Send a message to a player, option to guarantee message
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL NETsend(NETMSG *msg, UDWORD player, BOOL guarantee)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-01-04 12:24:26 -08:00
|
|
|
int size;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETsend\n" );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (player >= MAX_CONNECTED_PLAYERS) return FALSE;
|
|
|
|
//printf("Sending message %i to %i\n", msg->type, msg->destination);
|
|
|
|
msg->destination = player;
|
|
|
|
|
|
|
|
if ( NetPlay.bEncryptAllPackets
|
|
|
|
&& (msg->type!=AUDIOMSG)
|
|
|
|
&& (msg->type!=FILEMSG)) {
|
|
|
|
NETmanglePacket(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//printf("NETsend %i\n", msg->type);
|
|
|
|
|
|
|
|
size = msg->size + sizeof(msg->size) + sizeof(msg->type) + sizeof(msg->paddedBytes) + sizeof(msg->destination);
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
if ( player < MAX_CONNECTED_PLAYERS
|
|
|
|
&& connected_bsocket[player] != NULL
|
|
|
|
&& connected_bsocket[player]->socket != NULL
|
|
|
|
&& SDLNet_TCP_Send(connected_bsocket[player]->socket,
|
|
|
|
msg, size) == size) {
|
|
|
|
nStats.bytesSent += size;
|
|
|
|
nStats.packetsSent += 1;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( tcp_socket
|
|
|
|
&& SDLNet_TCP_Send(tcp_socket, msg, size) == size) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// broadcast a message to all players.
|
|
|
|
BOOL NETbcast(NETMSG *msg, BOOL guarantee)
|
2006-02-18 10:54:37 -08:00
|
|
|
{
|
2007-01-04 12:24:26 -08:00
|
|
|
int size;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-10-02 10:58:10 -07:00
|
|
|
debug( LOG_NET, "NETbcast\n");
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
msg->destination = NET_ALL_PLAYERS;
|
|
|
|
|
|
|
|
if ( NetPlay.bEncryptAllPackets
|
|
|
|
&& (msg->type!=AUDIOMSG)
|
|
|
|
&& (msg->type!=FILEMSG)) {
|
|
|
|
NETmanglePacket(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
size = msg->size + sizeof(msg->size) + sizeof(msg->type) + sizeof(msg->paddedBytes) + sizeof(msg->destination);
|
|
|
|
|
|
|
|
//printf("NETbcast %i\n", msg->type);
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_CONNECTED_PLAYERS; ++i) {
|
|
|
|
if ( connected_bsocket[i] != NULL
|
|
|
|
&& connected_bsocket[i]->socket != NULL) {
|
|
|
|
SDLNet_TCP_Send(connected_bsocket[i]->socket, msg, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if ( tcp_socket == NULL
|
|
|
|
|| SDLNet_TCP_Send(tcp_socket, msg, size) < size) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nStats.bytesSent += size;
|
|
|
|
nStats.packetsSent += 1;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Check if a message is a system message
|
|
|
|
BOOL NETprocessSystemMessage(NETMSG * pMsg)
|
|
|
|
{
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETprocessSystemMessage\n" );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
switch (pMsg->type) {
|
|
|
|
case MSG_PLAYER_INFO: {
|
|
|
|
NET_PLAYER* pi = (NET_PLAYER*)(pMsg->body);
|
|
|
|
int dpid = pi->id;
|
|
|
|
|
|
|
|
//printf("Receiving info for player %i\n", dpid);
|
|
|
|
|
|
|
|
memcpy(&players[dpid], pi, sizeof(NET_PLAYER));
|
|
|
|
NETplayerInfo();
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
NETBroadcastPlayerInfo(dpid);
|
|
|
|
}
|
|
|
|
|
|
|
|
//printf("Just received and processed MSG_PLAYER_INFO\n");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case MSG_PLAYER_DATA: {
|
|
|
|
unsigned int* pdpid = (unsigned int*)(pMsg->body);
|
|
|
|
int dpid = *pdpid;
|
|
|
|
unsigned int size = pMsg->size - sizeof(unsigned int);
|
|
|
|
|
|
|
|
//printf("Receiving DATA for player %i\n", dpid);
|
|
|
|
|
|
|
|
global_player_data[dpid].size = size;
|
|
|
|
resize_global_player_data(dpid, size);
|
|
|
|
memcpy(global_player_data[dpid].data, pMsg->body+sizeof(unsigned int), size);
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
NETbcast(pMsg, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
//printf("Just received and processed MSG_PLAYER_DATA\n");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case MSG_PLAYER_JOINED: {
|
|
|
|
unsigned int* pdpid = (unsigned int*)(pMsg->body);
|
|
|
|
int dpid = *pdpid;
|
|
|
|
|
|
|
|
MultiPlayerJoin(dpid);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case MSG_PLAYER_LEFT: {
|
|
|
|
unsigned int* pdpid = (unsigned int*)(pMsg->body);
|
|
|
|
int dpid = *pdpid;
|
|
|
|
|
|
|
|
NET_DestroyPlayer(dpid);
|
|
|
|
MultiPlayerLeave(dpid);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case MSG_GAME_FLAGS: {
|
|
|
|
//printf("Receiving game flags\n");
|
|
|
|
|
|
|
|
memcpy(NetGameFlags, pMsg->body, sizeof(NetGameFlags));
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
NETbcast(pMsg, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
//printf("Just received and processed MSG_GAME_FLAGS\n");
|
|
|
|
} break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// receive a message over the current connection
|
|
|
|
|
|
|
|
BOOL NETrecv(NETMSG * pMsg)
|
|
|
|
{
|
|
|
|
static unsigned int current = 0;
|
|
|
|
BOOL received;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
if (!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
return FALSE;
|
2006-02-18 10:54:37 -08:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
NETallowJoining();
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
receive_message:
|
|
|
|
received = FALSE;
|
|
|
|
//printf("Receiving something\n");
|
|
|
|
|
|
|
|
if (is_server) {
|
|
|
|
if (connected_bsocket[current] == NULL) return FALSE;
|
|
|
|
|
|
|
|
received = NET_recvMessage(connected_bsocket[current], pMsg);
|
|
|
|
|
|
|
|
if (received == FALSE) {
|
|
|
|
unsigned int i = current + 1;
|
|
|
|
|
|
|
|
if ( socket_set == NULL
|
|
|
|
|| SDLNet_CheckSockets(socket_set, NET_READ_TIMEOUT) <= 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
for (;;) {
|
|
|
|
if (connected_bsocket[i]->socket == NULL) {
|
|
|
|
} else if (NET_fillBuffer(connected_bsocket[i], socket_set)) {
|
|
|
|
received = NET_recvMessage(connected_bsocket[i], pMsg);
|
|
|
|
current = i;
|
|
|
|
break;
|
|
|
|
} else if (connected_bsocket[i]->socket == NULL) {
|
|
|
|
unsigned int* message_dpid = (unsigned int*)(message.body);
|
|
|
|
|
|
|
|
game.desc.dwCurrentPlayers--;
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
message.type = MSG_PLAYER_LEFT;
|
|
|
|
NETsetMessageSize(&message, 4);
|
|
|
|
*message_dpid = i;
|
|
|
|
NETbcast(&message, TRUE);
|
|
|
|
|
|
|
|
NET_DestroyPlayer(i);
|
|
|
|
MultiPlayerLeave(i);
|
|
|
|
}
|
|
|
|
if (++i == MAX_CONNECTED_PLAYERS) {
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
if (i == current+1) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (bsocket == NULL) {
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
received = NET_recvMessage(bsocket, pMsg);
|
|
|
|
|
|
|
|
if (received == FALSE) {
|
|
|
|
if ( socket_set != NULL
|
|
|
|
&& SDLNet_CheckSockets(socket_set, NET_READ_TIMEOUT) > 0
|
|
|
|
&& NET_fillBuffer(bsocket, socket_set)) {
|
|
|
|
received = NET_recvMessage(bsocket, pMsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (received == FALSE) {
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
size = pMsg->size + sizeof(pMsg->size) + sizeof(pMsg->type)
|
|
|
|
+ sizeof(pMsg->paddedBytes) + sizeof(pMsg->destination);
|
|
|
|
if (is_server == FALSE) {
|
|
|
|
} else if (pMsg->destination == NET_ALL_PLAYERS) {
|
|
|
|
unsigned int j;
|
|
|
|
|
|
|
|
for (j = 0; j < MAX_CONNECTED_PLAYERS; ++j) {
|
|
|
|
if ( j != current
|
|
|
|
&& connected_bsocket[j] != NULL
|
|
|
|
&& connected_bsocket[j]->socket != NULL) {
|
|
|
|
SDLNet_TCP_Send(connected_bsocket[j]->socket,
|
|
|
|
pMsg, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (pMsg->destination != NetPlay.dpidPlayer) {
|
|
|
|
if ( pMsg->destination < MAX_CONNECTED_PLAYERS
|
|
|
|
&& connected_bsocket[pMsg->destination] != NULL
|
|
|
|
&& connected_bsocket[pMsg->destination]->socket != NULL) {
|
2006-11-03 17:11:26 -08:00
|
|
|
//printf("Reflecting message to UDWORD %i\n", pMsg->destination);
|
2007-06-28 10:47:08 -07:00
|
|
|
SDLNet_TCP_Send(connected_bsocket[pMsg->destination]->socket,
|
|
|
|
pMsg, size);
|
|
|
|
} else {
|
2006-11-03 17:11:26 -08:00
|
|
|
//printf("Cannot reflect message %i to UDWORD %i\n", pMsg->type, pMsg->destination);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
goto receive_message;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (pMsg->type>=ENCRYPTFLAG)
|
|
|
|
&& (pMsg->type!=AUDIOMSG)
|
|
|
|
&& (pMsg->type!=FILEMSG)) {
|
|
|
|
NETunmanglePacket(pMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//printf("Received message : type = %i, size = %i, size = %i.\n", pMsg->type, pMsg->size, size);
|
|
|
|
|
|
|
|
nStats.bytesRecvd += size;
|
|
|
|
nStats.packetsRecvd += 1;
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
} while (NETprocessSystemMessage(pMsg) == TRUE);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Protocol functions
|
|
|
|
|
2006-09-13 02:09:05 -07:00
|
|
|
BOOL NETsetupTCPIP(void ** addr, char * machine)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETsetupTCPIP\n" );
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if ( hostname != NULL
|
|
|
|
&& hostname != master_server) {
|
|
|
|
free(hostname);
|
|
|
|
}
|
|
|
|
if ( machine != NULL
|
|
|
|
&& machine[0] != '\0') {
|
|
|
|
hostname = strdup(machine);
|
|
|
|
} else {
|
|
|
|
hostname = master_server;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// select a current protocol. Call with a connection returned by findprotocol.
|
2006-09-13 02:09:05 -07:00
|
|
|
BOOL NETselectProtocol(void * lpConnection)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// call with true to enumerate available protocols.
|
|
|
|
BOOL NETfindProtocol(BOOL Lob)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// File Transfer programs.
|
|
|
|
// uses guaranteed messages to send files between clients.
|
|
|
|
|
|
|
|
// send file. it returns % of file sent. when 100 it's complete. call until it returns 100.
|
|
|
|
|
2006-11-03 17:11:26 -08:00
|
|
|
UBYTE NETsendFile(BOOL newFile, const char *fileName, UDWORD player)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-06-16 12:10:23 -07:00
|
|
|
static PHYSFS_sint64 fileSize,currPos;
|
|
|
|
static PHYSFS_file *pFileHandle;
|
|
|
|
PHYSFS_sint64 bytesRead;
|
2007-06-28 10:47:08 -07:00
|
|
|
UBYTE inBuff[2048];
|
|
|
|
NETMSG msg;
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(newFile) //force it true for now -Q
|
|
|
|
{
|
|
|
|
// open the file.
|
2006-06-16 12:10:23 -07:00
|
|
|
pFileHandle = PHYSFS_openRead(fileName); // check file exists
|
2007-06-28 10:47:08 -07:00
|
|
|
if (pFileHandle == NULL)
|
|
|
|
{
|
2006-06-16 12:10:23 -07:00
|
|
|
debug( LOG_WZ, "NETsendFile: Failed\n" );
|
2007-06-28 10:47:08 -07:00
|
|
|
return 0; // failed
|
|
|
|
}
|
|
|
|
// get the file's size.
|
|
|
|
fileSize = 0;
|
|
|
|
currPos =0;
|
|
|
|
do
|
|
|
|
{
|
2006-06-16 12:10:23 -07:00
|
|
|
bytesRead = PHYSFS_read( pFileHandle, &inBuff, 1, sizeof(inBuff) );
|
2007-06-28 10:47:08 -07:00
|
|
|
fileSize += bytesRead;
|
|
|
|
} while(bytesRead != 0);
|
|
|
|
|
2006-06-16 12:10:23 -07:00
|
|
|
PHYSFS_seek(pFileHandle, 0 );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
// read some bytes.
|
2006-06-16 12:10:23 -07:00
|
|
|
bytesRead = PHYSFS_read(pFileHandle, &inBuff, sizeof(inBuff), 1 );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// form a message
|
|
|
|
NetAdd(msg,0,fileSize); // total bytes in this file.
|
2006-02-18 10:54:37 -08:00
|
|
|
NetAdd(msg,4,bytesRead); // bytes in this packet
|
2007-06-28 10:47:08 -07:00
|
|
|
NetAdd(msg,8,currPos); // start byte
|
|
|
|
msg.body[12]=strlen(fileName);
|
|
|
|
msg.size = 13;
|
|
|
|
NetAddSt(msg,msg.size,fileName);
|
|
|
|
msg.size += strlen(fileName);
|
2006-02-18 10:54:37 -08:00
|
|
|
memcpy(&(msg.body[msg.size]),&inBuff,bytesRead);
|
2007-06-28 10:47:08 -07:00
|
|
|
msg.size += bytesRead;
|
|
|
|
msg.type = FILEMSG;
|
|
|
|
msg.paddedBytes = 0;
|
|
|
|
if(player==0)
|
|
|
|
{
|
|
|
|
NETbcast(&msg,TRUE); // send it.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NETsend(&msg,player,TRUE);
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
currPos += bytesRead; // update position!
|
|
|
|
if(currPos == fileSize)
|
|
|
|
{
|
2006-06-16 12:10:23 -07:00
|
|
|
PHYSFS_close(pFileHandle);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return (currPos*100)/fileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// recv file. it returns % of the file so far recvd.
|
|
|
|
UBYTE NETrecvFile(NETMSG *pMsg)
|
|
|
|
{
|
2006-02-18 10:54:37 -08:00
|
|
|
UDWORD pos, fileSize, currPos, bytesRead;
|
2006-07-21 12:38:55 -07:00
|
|
|
char fileName[256];
|
2007-06-28 10:47:08 -07:00
|
|
|
unsigned int len;
|
2006-06-16 12:10:23 -07:00
|
|
|
static PHYSFS_file *pFileHandle;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//read incoming bytes.
|
|
|
|
NetGet(pMsg,0,fileSize);
|
|
|
|
NetGet(pMsg,4,bytesRead);
|
|
|
|
NetGet(pMsg,8,currPos);
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
// read filename
|
|
|
|
len = (unsigned int)(pMsg->body[12]);
|
|
|
|
memcpy(fileName,&(pMsg->body[13]),len);
|
|
|
|
fileName[len] = '\0'; // terminate string.
|
|
|
|
pos = 13+len;
|
|
|
|
//printf("NETrecvFile: Creating new file %s\n", fileName);
|
|
|
|
|
|
|
|
if(currPos == 0) // first packet!
|
|
|
|
{
|
|
|
|
//printf("NETrecvFile: Creating new file %s\n", fileName);
|
2006-06-16 12:10:23 -07:00
|
|
|
pFileHandle = PHYSFS_openWrite(fileName); // create a new file.
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
//write packet to the file.
|
2006-06-16 12:10:23 -07:00
|
|
|
PHYSFS_write( pFileHandle, &(pMsg->body[pos]), bytesRead, 1 );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(currPos+bytesRead == fileSize) // last packet
|
|
|
|
{
|
2006-06-16 12:10:23 -07:00
|
|
|
PHYSFS_close(pFileHandle);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//return the percent count.
|
|
|
|
return ((currPos+bytesRead)*100) / fileSize;
|
|
|
|
}
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
void NETregisterServer(int state) {
|
|
|
|
static TCPsocket rs_socket = NULL;
|
2006-02-28 22:12:28 -08:00
|
|
|
static int registered = 0;
|
|
|
|
static int server_not_there = 0;
|
2005-12-02 13:45:42 -08:00
|
|
|
IPaddress ip;
|
|
|
|
|
2006-02-28 22:12:28 -08:00
|
|
|
if (server_not_there) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state != registered) {
|
2005-12-02 13:45:42 -08:00
|
|
|
switch(state) {
|
|
|
|
case 1: {
|
|
|
|
if(SDLNet_ResolveHost(&ip, master_server, MASTER_SERVER_PORT) == -1) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "NETregisterServer: couldn't resolve master server (%s): %s\n", master_server, SDLNet_GetError() );
|
2006-02-28 22:12:28 -08:00
|
|
|
server_not_there = 1;
|
2005-12-02 13:45:42 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!rs_socket) rs_socket = SDLNet_TCP_Open(&ip);
|
|
|
|
if(rs_socket == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "NETregisterServer: Cannot connect to master server (%s): %s\n", master_server, SDLNet_GetError() );
|
2006-02-28 22:12:28 -08:00
|
|
|
server_not_there = 1;
|
2005-12-02 13:45:42 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDLNet_TCP_Send(rs_socket, "addg", 5);
|
|
|
|
SDLNet_TCP_Send(rs_socket, &game, sizeof(GAMESTRUCT));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
SDLNet_TCP_Close(rs_socket);
|
|
|
|
rs_socket=NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
registered=state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Host a game with a given name and player name. & 4 user game flags
|
|
|
|
|
2006-09-13 14:14:47 -07:00
|
|
|
static void NETallowJoining(void) {
|
2007-06-28 10:47:08 -07:00
|
|
|
unsigned int i;
|
2005-12-02 13:45:42 -08:00
|
|
|
UDWORD numgames=1; // always 1 on normal server
|
|
|
|
char buffer[5];
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if (allow_joining == FALSE) return;
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
NETregisterServer(1);
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if (tmp_socket_set == NULL) {
|
|
|
|
tmp_socket_set = SDLNet_AllocSocketSet(MAX_TMP_SOCKETS+1);
|
|
|
|
if (tmp_socket_set == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "Couldn't create socket set: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
SDLNet_TCP_AddSocket(tmp_socket_set, tcp_socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SDLNet_CheckSockets(tmp_socket_set, NET_READ_TIMEOUT) > 0) {
|
|
|
|
if (SDLNet_SocketReady(tcp_socket)) {
|
|
|
|
for (i = 0; i < MAX_TMP_SOCKETS; ++i) {
|
|
|
|
if (tmp_socket[i] == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmp_socket[i] = SDLNet_TCP_Accept(tcp_socket);
|
|
|
|
SDLNet_TCP_AddSocket(tmp_socket_set, tmp_socket[i]);
|
2005-12-02 13:45:42 -08:00
|
|
|
if (SDLNet_CheckSockets(tmp_socket_set, 1000) > 0
|
|
|
|
&& SDLNet_SocketReady(tmp_socket)
|
|
|
|
&& SDLNet_TCP_Recv(tmp_socket[i], buffer, 5)) {
|
|
|
|
if(strcmp(buffer, "list")==0) {
|
|
|
|
SDLNet_TCP_Send(tmp_socket[i], &numgames, sizeof(UDWORD));
|
|
|
|
SDLNet_TCP_Send(tmp_socket[i], &game, sizeof(GAMESTRUCT));
|
|
|
|
} else if(strcmp(buffer, "join")==0) {
|
|
|
|
SDLNet_TCP_Send(tmp_socket[i], &game, sizeof(GAMESTRUCT));
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
for(i = 0; i < MAX_TMP_SOCKETS; ++i) {
|
|
|
|
if ( tmp_socket[i] != NULL
|
|
|
|
&& SDLNet_SocketReady(tmp_socket[i]) > 0) {
|
|
|
|
int size = SDLNet_TCP_Recv(tmp_socket[i], &message, sizeof(NETMSG));
|
|
|
|
|
|
|
|
if (size <= 0) {
|
|
|
|
// socket probably disconnected.
|
|
|
|
SDLNet_TCP_DelSocket(tmp_socket_set, tmp_socket[i]);
|
|
|
|
SDLNet_TCP_Close(tmp_socket[i]);
|
|
|
|
tmp_socket[i] = NULL;
|
|
|
|
} else if (message.type == MSG_JOIN) {
|
|
|
|
int j;
|
|
|
|
|
|
|
|
char* name = message.body;
|
2007-01-04 09:03:32 -08:00
|
|
|
unsigned int dpid = NET_CreatePlayer(name, 0);
|
2007-06-28 10:47:08 -07:00
|
|
|
unsigned int* message_dpid = (unsigned int*)(message.body);
|
|
|
|
|
|
|
|
SDLNet_TCP_DelSocket(tmp_socket_set, tmp_socket[i]);
|
|
|
|
NET_initBufferedSocket(connected_bsocket[dpid], tmp_socket[i]);
|
|
|
|
SDLNet_TCP_AddSocket(socket_set, connected_bsocket[dpid]->socket);
|
|
|
|
tmp_socket[i] = NULL;
|
|
|
|
|
|
|
|
//printf("Creating player %i\n", dpid);
|
|
|
|
game.desc.dwCurrentPlayers++;
|
|
|
|
|
|
|
|
message.type = MSG_ACCEPTED;
|
|
|
|
NETsetMessageSize(&message, 4);
|
|
|
|
*message_dpid = dpid;
|
|
|
|
NETsend(&message, dpid, TRUE);
|
|
|
|
|
|
|
|
MultiPlayerJoin(dpid);
|
|
|
|
message.type = MSG_PLAYER_JOINED;
|
|
|
|
NETsetMessageSize(&message, 4);
|
|
|
|
|
|
|
|
// Send info about players to newcomer.
|
|
|
|
for (j = 0; j < MAX_CONNECTED_PLAYERS; ++j) {
|
|
|
|
if ( players[j].allocated
|
|
|
|
&& dpid != players[j].id) {
|
|
|
|
*message_dpid = players[j].id;
|
|
|
|
NETsend(&message, dpid, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send info about newcomer to all players.
|
|
|
|
*message_dpid = dpid;
|
|
|
|
NETbcast(&message, TRUE);
|
|
|
|
|
|
|
|
for (j = 0; j < MAX_CONNECTED_PLAYERS; ++j) {
|
|
|
|
NETBroadcastPlayerInfo(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL NEThostGame(const char* SessionName, const char* PlayerName,
|
2006-11-04 15:16:51 -08:00
|
|
|
SDWORD one, SDWORD two, SDWORD three, SDWORD four,
|
2007-06-28 10:47:08 -07:00
|
|
|
UDWORD plyrs) // # of players.
|
|
|
|
{
|
|
|
|
IPaddress ip;
|
|
|
|
unsigned int i;
|
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NEThostGame\n" );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
NetPlay.dpidPlayer = 1;
|
|
|
|
NetPlay.bHost = TRUE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(SDLNet_ResolveHost(&ip, NULL, WARZONE_NET_PORT) == -1) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "NEThostGame: couldn't resolve master self: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if(!tcp_socket) tcp_socket = SDLNet_TCP_Open(&ip);
|
2007-06-28 10:47:08 -07:00
|
|
|
if(tcp_socket == NULL) {
|
|
|
|
printf("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if(!socket_set) socket_set = SDLNet_AllocSocketSet(MAX_CONNECTED_PLAYERS);
|
2007-06-28 10:47:08 -07:00
|
|
|
if (socket_set == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "Couldn't create socket set: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
for (i = 0; i < MAX_CONNECTED_PLAYERS; ++i) {
|
|
|
|
connected_bsocket[i] = NET_createBufferedSocket();
|
|
|
|
}
|
|
|
|
|
|
|
|
is_server = TRUE;
|
|
|
|
|
|
|
|
strcpy(game.name, SessionName);
|
|
|
|
memset(&game.desc, 0, sizeof(SESSIONDESC));
|
|
|
|
game.desc.dwSize = sizeof(SESSIONDESC);
|
|
|
|
//game.desc.guidApplication = GAME_GUID;
|
2005-12-02 13:45:42 -08:00
|
|
|
strcpy(game.desc.host, "");
|
2007-06-28 10:47:08 -07:00
|
|
|
game.desc.dwCurrentPlayers = 1;
|
|
|
|
game.desc.dwMaxPlayers = plyrs;
|
|
|
|
game.desc.dwFlags = 0;
|
|
|
|
game.desc.dwUser1 = one;
|
|
|
|
game.desc.dwUser2 = two;
|
|
|
|
game.desc.dwUser3 = three;
|
|
|
|
game.desc.dwUser4 = four;
|
|
|
|
|
|
|
|
NET_InitPlayers();
|
|
|
|
NetPlay.dpidPlayer = NET_CreatePlayer(PlayerName, PLAYER_HOST);
|
|
|
|
NetPlay.bHost = TRUE;
|
|
|
|
NetPlay.bSpectator = FALSE;
|
|
|
|
|
|
|
|
MultiPlayerJoin(NetPlay.dpidPlayer);
|
|
|
|
|
|
|
|
allow_joining = TRUE;
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
NETregisterServer(0);
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Stop the dplay interface from accepting more players.
|
2006-09-13 02:09:05 -07:00
|
|
|
BOOL NEThaltJoining(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NEThaltJoining\n" );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
allow_joining = FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
2006-02-18 10:54:37 -08:00
|
|
|
// find games on open connection, option to do this asynchronously
|
2007-06-28 10:47:08 -07:00
|
|
|
// since it can sometimes take a while.
|
|
|
|
BOOL NETfindGame(BOOL async) /// may (not) want to use async here...
|
|
|
|
{
|
2005-12-02 13:45:42 -08:00
|
|
|
static UDWORD gamecount = 0, gamesavailable;
|
2007-06-28 10:47:08 -07:00
|
|
|
IPaddress ip;
|
|
|
|
char buffer[sizeof(GAMESTRUCT)*2];
|
|
|
|
GAMESTRUCT* tmpgame = (GAMESTRUCT*)buffer;
|
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETfindGame\n" );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
gamecount = 0;
|
|
|
|
NetPlay.games[0].desc.dwSize = 0;
|
|
|
|
NetPlay.games[0].desc.dwCurrentPlayers = 0;
|
|
|
|
NetPlay.games[0].desc.dwMaxPlayers = 0;
|
|
|
|
|
|
|
|
if(!NetPlay.bComms)
|
|
|
|
{
|
|
|
|
NetPlay.dpidPlayer = 1;
|
|
|
|
NetPlay.bHost = TRUE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if (SDLNet_ResolveHost(&ip, hostname, (hostname == master_server) ? MASTER_SERVER_PORT
|
|
|
|
: WARZONE_NET_PORT) == -1) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "NETfindGame: couldn't resolve hostname (%s): %s\n", hostname, SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tcp_socket != NULL) {
|
|
|
|
SDLNet_TCP_Close(tcp_socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
tcp_socket = SDLNet_TCP_Open(&ip);
|
|
|
|
if (tcp_socket == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "SDLNet_TCP_Open: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
socket_set = SDLNet_AllocSocketSet(1);
|
|
|
|
if (socket_set == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "Couldn't create socket set: %s\n", SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
SDLNet_TCP_AddSocket(socket_set, tcp_socket);
|
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
SDLNet_TCP_Send(tcp_socket, "list", 5);
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( SDLNet_CheckSockets(socket_set, 1000) > 0
|
|
|
|
&& SDLNet_SocketReady(tcp_socket)
|
2005-12-02 13:45:42 -08:00
|
|
|
&& SDLNet_TCP_Recv(tcp_socket, buffer, sizeof(int))) {
|
|
|
|
gamesavailable=(UDWORD)buffer[0];
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "receiving info of %d game(s)\n", gamesavailable );
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
do {
|
|
|
|
if ( SDLNet_CheckSockets(socket_set, 1000) > 0
|
|
|
|
&& SDLNet_SocketReady(tcp_socket)
|
|
|
|
&& SDLNet_TCP_Recv(tcp_socket, buffer, sizeof(GAMESTRUCT)) == sizeof(GAMESTRUCT)
|
|
|
|
&& tmpgame->desc.dwSize == sizeof(SESSIONDESC)) {
|
|
|
|
strcpy(NetPlay.games[gamecount].name, tmpgame->name);
|
|
|
|
NetPlay.games[gamecount].desc.dwSize = tmpgame->desc.dwSize;
|
|
|
|
NetPlay.games[gamecount].desc.dwCurrentPlayers = tmpgame->desc.dwCurrentPlayers;
|
|
|
|
NetPlay.games[gamecount].desc.dwMaxPlayers = tmpgame->desc.dwMaxPlayers;
|
|
|
|
if (tmpgame->desc.host[0] == '\0') {
|
|
|
|
unsigned char* address = (unsigned char*)(&(ip.host));
|
|
|
|
|
|
|
|
sprintf(NetPlay.games[gamecount].desc.host,
|
|
|
|
"%i.%i.%i.%i",
|
|
|
|
(int)(address[0]),
|
|
|
|
(int)(address[1]),
|
|
|
|
(int)(address[2]),
|
|
|
|
(int)(address[3]));
|
|
|
|
} else {
|
|
|
|
strcpy(NetPlay.games[gamecount].desc.host, tmpgame->desc.host);
|
|
|
|
}
|
|
|
|
//printf("Received info for host %s\n", NetPlay.games[gamecount].desc.host);
|
|
|
|
gamecount++;
|
|
|
|
}
|
|
|
|
} while (gamecount<gamesavailable);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// ////////////////////////////////////////////////////////////////////////
|
|
|
|
// Functions used to setup and join games.
|
2006-11-03 17:11:26 -08:00
|
|
|
BOOL NETjoinGame(UDWORD gameNumber, const char* playername)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
char* name;
|
2005-12-02 13:45:42 -08:00
|
|
|
IPaddress ip;
|
|
|
|
char buffer[sizeof(GAMESTRUCT)*2];
|
|
|
|
GAMESTRUCT* tmpgame = (GAMESTRUCT*)buffer;
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_NET, "NETjoinGame gameNumber=%d\n", gameNumber );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
NETclose(); // just to be sure :)
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if (hostname != master_server) {
|
|
|
|
free(hostname);
|
|
|
|
}
|
|
|
|
hostname = strdup(NetPlay.games[gameNumber].desc.host);
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if(SDLNet_ResolveHost(&ip, hostname, WARZONE_NET_PORT) == -1) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "NETjoinGame: couldn't resolve hostname (%s): %s\n", hostname, SDLNet_GetError() );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if (tcp_socket != NULL) {
|
|
|
|
SDLNet_TCP_Close(tcp_socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
tcp_socket = SDLNet_TCP_Open(&ip);
|
|
|
|
if (tcp_socket == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "SDLNet_TCP_Open: %s\n", SDLNet_GetError() );
|
2005-12-02 13:45:42 -08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
socket_set = SDLNet_AllocSocketSet(1);
|
|
|
|
if (socket_set == NULL) {
|
2006-08-23 08:27:20 -07:00
|
|
|
debug( LOG_ERROR, "Couldn't create socket set: %s\n", SDLNet_GetError() );
|
2005-12-02 13:45:42 -08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
SDLNet_TCP_AddSocket(socket_set, tcp_socket);
|
|
|
|
|
|
|
|
|
|
|
|
SDLNet_TCP_Send(tcp_socket, "join", 5);
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2005-12-02 13:45:42 -08:00
|
|
|
if ( SDLNet_CheckSockets(socket_set, 1000) > 0
|
|
|
|
&& SDLNet_SocketReady(tcp_socket)
|
|
|
|
&& SDLNet_TCP_Recv(tcp_socket, buffer, sizeof(GAMESTRUCT)*2) == sizeof(GAMESTRUCT)
|
|
|
|
&& tmpgame->desc.dwSize == sizeof(SESSIONDESC)) {
|
|
|
|
strcpy(NetPlay.games[gameNumber].name, tmpgame->name);
|
|
|
|
NetPlay.games[gameNumber].desc.dwSize = tmpgame->desc.dwSize;
|
|
|
|
NetPlay.games[gameNumber].desc.dwCurrentPlayers = tmpgame->desc.dwCurrentPlayers;
|
|
|
|
NetPlay.games[gameNumber].desc.dwMaxPlayers = tmpgame->desc.dwMaxPlayers;
|
|
|
|
strcpy(NetPlay.games[gameNumber].desc.host, tmpgame->desc.host);
|
|
|
|
if (tmpgame->desc.host[0] == '\0') {
|
|
|
|
unsigned char* address = (unsigned char*)(&(ip.host));
|
|
|
|
|
|
|
|
sprintf(NetPlay.games[gameNumber].desc.host,
|
|
|
|
"%i.%i.%i.%i",
|
|
|
|
(int)(address[0]),
|
|
|
|
(int)(address[1]),
|
|
|
|
(int)(address[2]),
|
|
|
|
(int)(address[3]));
|
|
|
|
} else {
|
|
|
|
strcpy(NetPlay.games[gameNumber].desc.host, tmpgame->desc.host);
|
|
|
|
}
|
|
|
|
//printf("JoinGame: Received info for host %s\n", NetPlay.games[gameNumber].desc.host);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
bsocket = NET_createBufferedSocket();
|
|
|
|
NET_initBufferedSocket(bsocket, tcp_socket);
|
|
|
|
|
|
|
|
message.type = MSG_JOIN;
|
|
|
|
NETsetMessageSize(&message, 64);
|
|
|
|
name = message.body;
|
2006-02-18 10:54:37 -08:00
|
|
|
strcpy(name, playername);
|
2007-06-28 10:47:08 -07:00
|
|
|
NETsend(&message, 1, TRUE);
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
NETrecv(&message);
|
|
|
|
|
|
|
|
if (message.type == MSG_ACCEPTED) {
|
|
|
|
unsigned int* message_dpid = (unsigned int*)(message.body);
|
|
|
|
|
|
|
|
NetPlay.dpidPlayer = *message_dpid;
|
2005-12-02 13:45:42 -08:00
|
|
|
//printf("I'm player %i\n", NetPlay.dpidPlayer);
|
2007-06-28 10:47:08 -07:00
|
|
|
NetPlay.bHost = FALSE;
|
|
|
|
NetPlay.bSpectator = FALSE;
|
|
|
|
|
|
|
|
players[NetPlay.dpidPlayer].allocated = TRUE;
|
|
|
|
players[NetPlay.dpidPlayer].id = NetPlay.dpidPlayer;
|
|
|
|
strcpy(players[NetPlay.dpidPlayer].name, playername);
|
|
|
|
players[NetPlay.dpidPlayer].flags = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|