put in the beginnings of my hw-master port. /NOT/ tied into the build yet

so it won't affect 0.5.3 at all.
This commit is contained in:
Bill Currie 2003-02-10 19:31:45 +00:00
parent d494be3594
commit 5ca662ae92
8 changed files with 1818 additions and 0 deletions

4
hw/Makefile.am Normal file
View file

@ -0,0 +1,4 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS= foreign
SUBDIRS= include source

5
hw/include/Makefile.am Normal file
View file

@ -0,0 +1,5 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS= foreign
EXTRA_DIST = \
defs.h

215
hw/include/defs.h Normal file
View file

@ -0,0 +1,215 @@
#include <sys/types.h>
#include <sys/timeb.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "QF/qtypes.h"
//Defines
#define MAX_ARGS 80
#define MAX_NUM_ARGVS 50
#define MAX_MASTERS 8 // max recipients for heartbeat packets
#define PORT_ANY -1
#define PORT_MASTER 26900
#define PORT_SERVER 26950
//=========================================
// out of band message id bytes
// M = master, S = server, C = client, A = any
// the second character will allways be \n if the message isn't a single
// byte long (?? not true anymore?)
#define S2C_CHALLENGE 'c'
#define S2C_CONNECTION 'j'
#define A2A_PING 'k' // respond with an A2A_ACK
#define A2A_ACK 'l' // general acknowledgement without info
#define A2A_NACK 'm' // [+ comment] general failure
#define A2A_ECHO 'e' // for echoing
#define A2C_PRINT 'n' // print a message on client
#define S2M_HEARTBEAT 'a' // + serverinfo + userlist + fraglist
#define A2C_CLIENT_COMMAND 'B' // + command line
#define S2M_SHUTDOWN 'C'
//KS:
#define A2M_LIST 'o'
#define M2A_SENDLIST 'p'
#define MAX_MSGLEN 1450 // max length of a reliable message
#define MAX_DATAGRAM 1450 // max length of unreliable message
#define MAX_UDP_PACKET (MAX_MSGLEN*2) // one more than msg + header
#define MAX_SERVERINFO_STRING 512
#define MAX_CLIENTS 32
//Typedefs
typedef struct
{
byte ip[4];
unsigned short port;
unsigned short pad;
} netadr_t;
typedef struct server_s
{
netadr_t ip;
int heartbeat;
int players;
char info[MAX_SERVERINFO_STRING];
struct server_s *next;
struct server_s *previous;
double timeout;
} server_t;
typedef struct sizebuf_s
{
qboolean allowoverflow; // if false, do a Sys_Error
qboolean overflowed; // set to true if the buffer size failed
byte *data;
int maxsize;
int cursize;
} sizebuf_t;
typedef void (*xcommand_t) (void);
typedef struct cmd_function_s
{
struct cmd_function_s *next;
char *name;
xcommand_t function;
} cmd_function_t;
//Function prototypes
//net_test.cpp
void COM_Init (void);
int COM_CheckParm (char *parm);
char *COM_Parse (char *data);
void Sys_Error (char *error, ...);
void Sys_Quit (void);
void SZ_Clear (sizebuf_t *buf);
void *SZ_GetSpace (sizebuf_t *buf, int length);
void SZ_Write (sizebuf_t *buf, void *data, int length);
char *Sys_ConsoleInput (void);
void SV_GetConsoleCommands (void);
void SV_Frame();
void SV_Shutdown();
double Sys_DoubleTime (void);
//cmds.cpp
int Cmd_Argc (void);
char *Cmd_Argv (int arg);
void Cmd_TokenizeString (char *text);
void Cmd_AddCommand (char *cmd_name, xcommand_t function);
void Cmd_Init();
void Cmd_ExecuteString (char *text);
void Cbuf_Init (void);
void Cbuf_AddText (char *text);
void Cbuf_InsertText (char *text);
void Cbuf_Execute (void);
qboolean Cmd_Exists (char *cmd_name);
void Cmd_Quit_f();
void Cmd_ServerList_f();
//net.cpp
void MSG_WriteChar (sizebuf_t *sb, int c);
void MSG_WriteByte (sizebuf_t *sb, int c);
void MSG_WriteShort (sizebuf_t *sb, int c);
void MSG_WriteLong (sizebuf_t *sb, int c);
void MSG_WriteFloat (sizebuf_t *sb, float f);
void MSG_WriteString (sizebuf_t *sb, char *s);
void MSG_BeginReading (void);
int MSG_GetReadCount(void);
int MSG_ReadChar (void);
int MSG_ReadByte (void);
int MSG_ReadShort (void);
int MSG_ReadLong (void);
float MSG_ReadFloat (void);
char *MSG_ReadString (void);
char *MSG_ReadStringLine (void);
void NET_Init (int port);
void SV_InitNet (void);
int UDP_OpenSocket (int port);
void NET_Shutdown (void);
void NET_GetLocalAddress();
char *NET_AdrToString (netadr_t a);
qboolean NET_StringToAdr (char *s, netadr_t *a);
void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s);
void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a);
void NET_SendPacket (int length, void *data, netadr_t to);
void SV_ReadPackets (void);
qboolean NET_GetPacket (void);
void SV_ConnectionlessPacket (void);
void NET_CopyAdr (netadr_t *a, netadr_t *b);
qboolean NET_CompareAdr (netadr_t a, netadr_t b);
qboolean NET_CompareAdrNoPort (netadr_t a, netadr_t b);
void SVL_Add(server_t *sv);
void SVL_Remove(server_t *sv);
void SVL_Clear();
server_t* SVL_Find(netadr_t adr);
server_t* SVL_New();
server_t* SVL_New(netadr_t adr);
void Cmd_Filter_f();
//Globals
extern cmd_function_t *cmd_functions; // possible commands to execute
extern sizebuf_t cmd_text;
extern byte cmd_text_buf[8192];
extern int cmd_argc;
extern char *cmd_argv[MAX_ARGS];
extern char *cmd_null_string;
extern char *cmd_args;
extern char com_token[1024];
extern int com_argc;
extern char **com_argv;
extern char *largv[MAX_NUM_ARGVS + 1];
extern char *argvdummy;
extern sizebuf_t net_message;
extern int net_socket;
//extern WSADATA winsockdata;
extern netadr_t net_local_adr;
extern netadr_t master_adr[MAX_MASTERS]; // address of group servers
extern int num_masters;
extern short (*BigShort) (short l);
extern short (*LittleShort) (short l);
extern int (*BigLong) (int l);
extern int (*LittleLong) (int l);
extern float (*BigFloat) (float l);
extern float (*LittleFloat) (float l);
extern netadr_t net_from;
extern int msg_readcount;
extern qboolean msg_badread;
extern server_t *sv_list;

47
hw/source/Makefile.am Normal file
View file

@ -0,0 +1,47 @@
## Process this file with automake to produce Makefile.in
#
# Makefile.am
#
# Automake-using build system for QuakeForge
#
# Copyright (C) 2000 Jeff Teunissen <deek@quakeforge.net>
#
# This Makefile 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.
#
# This program 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 this program; if not, write to:
#
# Free Software Foundation, Inc.
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
# $Id$
#
AUTOMAKE_OPTIONS= foreign
# Stuff that is common to both client and server
INCLUDES= -I$(top_srcdir)/include -I$(top_srcdir)/hw/include
SDL_LIBS = @SDL_LIBS@
bin_PROGRAMS= @QW_TARGETS@
EXTRA_PROGRAMS= hw-master
common_ldflags= -export-dynamic
hw_master_SOURCES= master.c
hw_master_LDADD= $(top_builddir)/libs/util/libQFutil.la $(NET_LIBS)
hw_master_LDFLAGS= $(common_ldflags) -static
# Kill the temp files, hopefully.
CLEANFILES = *.i *.s $(YACCLEX_CLEANFILES)

244
hw/source/cmds.c Normal file
View file

@ -0,0 +1,244 @@
#include "defs.h"
static int cmd_argc;
static char *cmd_argv[MAX_ARGS];
static char *cmd_null_string = "";
static char *cmd_args = NULL;
static cmd_function_t *cmd_functions; // possible commands to execute
int Cmd_Argc (void)
{
return cmd_argc;
}
char *Cmd_Argv (int arg)
{
if ( arg >= cmd_argc )
return cmd_null_string;
return cmd_argv[arg];
}
void Cmd_TokenizeString (char *text)
{
int i;
// clear the args from the last string
for (i=0 ; i<cmd_argc ; i++)
free (cmd_argv[i]);
cmd_argc = 0;
cmd_args = NULL;
while (1)
{
// skip whitespace up to a /n
while (*text && *text <= ' ' && *text != '\n')
{
text++;
}
if (*text == '\n')
{ // a newline seperates commands in the buffer
text++;
break;
}
if (!*text)
return;
if (cmd_argc == 1)
cmd_args = text;
text = COM_Parse (text);
if (!text)
return;
if (cmd_argc < MAX_ARGS)
{
cmd_argv[cmd_argc] = (char *)malloc (strlen(com_token)+1);
strcpy (cmd_argv[cmd_argc], com_token);
cmd_argc++;
}
}
}
void Cmd_AddCommand (char *cmd_name, xcommand_t function)
{
cmd_function_t *cmd;
// fail if the command already exists
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!strcmp (cmd_name, cmd->name))
{
printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
return;
}
}
cmd = (cmd_function_t *)malloc(sizeof(cmd_function_t));
cmd->name = cmd_name;
cmd->function = function;
cmd->next = cmd_functions;
cmd_functions = cmd;
}
void Cmd_Init()
{
Cmd_AddCommand("quit",Cmd_Quit_f);
Cmd_AddCommand("list",Cmd_ServerList_f);
Cmd_AddCommand("filter",Cmd_Filter_f);
}
void Cmd_ExecuteString (char *text)
{
cmd_function_t *cmd;
Cmd_TokenizeString (text);
// execute the command line
if (!Cmd_Argc())
return; // no tokens
// check functions
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!strcmp(cmd_argv[0],cmd->name))
{
if (cmd->function)
cmd->function ();
return;
}
}
printf("Unknown command: %s\n",cmd_argv[0]);
}
void Cbuf_Init (void)
{
cmd_text.data = cmd_text_buf;
cmd_text.maxsize = sizeof(cmd_text_buf);
}
void Cbuf_AddText (char *text)
{
int l;
l = strlen (text);
if (cmd_text.cursize + l >= cmd_text.maxsize)
{
printf ("Cbuf_AddText: overflow\n");
return;
}
SZ_Write (&cmd_text, text, strlen (text));
}
void Cbuf_InsertText (char *text)
{
char *temp;
int templen;
// copy off any commands still remaining in the exec buffer
templen = cmd_text.cursize;
if (templen)
{
temp = (char *)malloc (templen);
memcpy (temp, cmd_text.data, templen);
SZ_Clear (&cmd_text);
}
else
temp = NULL; // shut up compiler
// add the entire text of the file
Cbuf_AddText (text);
SZ_Write (&cmd_text, "\n", 1);
// add the copied off data
if (templen)
{
SZ_Write (&cmd_text, temp, templen);
free (temp);
}
}
void Cbuf_Execute (void)
{
int i;
char *text;
char line[1024];
int quotes;
while (cmd_text.cursize)
{
// find a \n or ; line break
text = (char *)cmd_text.data;
quotes = 0;
for (i=0 ; i< cmd_text.cursize ; i++)
{
if (text[i] == '"')
quotes++;
if ( !(quotes&1) && text[i] == ';')
break; // don't break if inside a quoted string
if (text[i] == '\n')
break;
}
memcpy (line, text, i);
line[i] = 0;
// delete the text from the command buffer and move remaining commands down
// this is necessary because commands (exec, alias) can insert data at the
// beginning of the text buffer
if (i == cmd_text.cursize)
cmd_text.cursize = 0;
else
{
i++;
cmd_text.cursize -= i;
memcpy (text, text+i, cmd_text.cursize);
}
// execute the command line
Cmd_ExecuteString (line);
}
}
qboolean Cmd_Exists (char *cmd_name)
{
cmd_function_t *cmd;
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!strcmp (cmd_name,cmd->name))
return true;
}
return false;
}
//Commands
void Cmd_Quit_f()
{
printf ("Shutting down.\n");
SV_Shutdown ();
Sys_Quit();
}
void Cmd_ServerList_f()
{
server_t *sv;
for(sv = sv_list;sv;sv = sv->next)
printf("%s %i players\n",NET_AdrToString(sv->ip),sv->players);
}

825
hw/source/net.c Normal file
View file

@ -0,0 +1,825 @@
#include "QF/sizebuf.h"
#include "defs.h"
byte net_message_buffer[MAX_UDP_PACKET];
sizebuf_t net_message;
int net_socket;
WSADATA winsockdata;
netadr_t net_local_adr;
netadr_t net_from;
int msg_readcount;
qboolean msg_badread;
typedef struct filter_s
{
netadr_t from;
netadr_t to;
struct filter_s *next;
struct filter_s *previous;
}filter_t;
filter_t *filter_list = NULL;
void FL_Remove(filter_t *filter)
{
if(filter->previous)
filter->previous->next = filter->next;
if(filter->next)
filter->next->previous = filter->previous;
filter->next = NULL;
filter->previous = NULL;
if(filter_list==filter)
filter_list = NULL;
}
void FL_Clear()
{
filter_t *filter;
for(filter = filter_list;filter;)
{
if(filter)
{
filter_t *next = filter->next;
FL_Remove(filter);
free(filter);
filter = NULL;
filter = next;
}
}
filter_list = NULL;
}
filter_t* FL_New()
{
filter_t *filter;
filter = (filter_t *)malloc(sizeof(filter_t));
return filter;
}
filter_t* FL_New(netadr_t adr1,netadr_t adr2)
{
filter_t *filter;
filter = FL_New();
NET_CopyAdr(&filter->from,&adr1);
NET_CopyAdr(&filter->to,&adr2);
return filter;
}
void FL_Add(filter_t *filter)
{
filter->next = filter_list;
filter->previous = NULL;
if(filter_list)
filter_list->previous = filter;
filter_list = filter;
}
filter_t* FL_Find(netadr_t adr)
{
filter_t *filter;
for(filter = filter_list;filter;filter = filter->next)
{
if(NET_CompareAdrNoPort(filter->from,adr))
return filter;
}
return NULL;
}
server_t *sv_list = NULL;
void SVL_Clear()
{
server_t *sv;
for(sv = sv_list;sv;)
{
if(sv)
{
server_t *next = sv->next;
SVL_Remove(sv);
free(sv);
sv = NULL;
sv = next;
}
}
sv_list = NULL;
}
server_t* SVL_New()
{
server_t *sv;
sv = (server_t *)malloc(sizeof(server_t));
sv->heartbeat = 0;
sv->info[0] = 0;
sv->ip.ip[0] =
sv->ip.ip[1] =
sv->ip.ip[2] =
sv->ip.ip[3] = 0;
sv->ip.pad = 0;
sv->ip.port = 0;
sv->next = NULL;
sv->previous = NULL;
sv->players = 0;
return sv;
}
server_t* SVL_New(netadr_t adr)
{
server_t *sv;
sv = SVL_New();
NET_CopyAdr(&sv->ip,&adr);
return sv;
}
void SVL_Add(server_t *sv)
{
sv->next = sv_list;
sv->previous = NULL;
if(sv_list)
sv_list->previous = sv;
sv_list = sv;
}
void SVL_Remove(server_t *sv)
{
if(sv_list==sv)
sv_list = sv->next;
if(sv->previous)
sv->previous->next = sv->next;
if(sv->next)
sv->next->previous = sv->previous;
sv->next = NULL;
sv->previous = NULL;
}
server_t* SVL_Find(netadr_t adr)
{
server_t *sv;
for(sv = sv_list;sv;sv = sv->next)
{
if(NET_CompareAdr(sv->ip,adr))
return sv;
}
return NULL;
}
// returns -1 and sets msg_badread if no more characters are available
int MSG_ReadChar (void)
{
int c;
if (msg_readcount+1 > net_message.cursize)
{
msg_badread = true;
return -1;
}
c = (signed char)net_message.data[msg_readcount];
msg_readcount++;
return c;
}
char *MSG_ReadStringLine (void)
{
static char string[2048];
int l,c;
l = 0;
do
{
c = MSG_ReadChar ();
if (c == -1 || c == 0 || c == '\n')
break;
string[l] = c;
l++;
} while (l < sizeof(string)-1);
string[l] = 0;
return string;
}
void NET_Filter()
{
netadr_t filter_adr;
int hold_port;
hold_port = net_from.port;
NET_StringToAdr("127.0.0.1:26950",&filter_adr);
if(NET_CompareAdrNoPort(net_from,filter_adr))
{
NET_StringToAdr("0.0.0.0:26950",&filter_adr);
if(!NET_CompareAdrNoPort(net_local_adr,filter_adr))
{
NET_CopyAdr(&net_from,&net_local_adr);
net_from.port = hold_port;
}
return;
}
//if no compare with filter list
filter_t *filter;
if((filter = FL_Find(net_from)))
{
NET_CopyAdr(&net_from,&filter->to);
net_from.port = hold_port;
}
}
void NET_Init (int port)
{
WORD wVersionRequested;
int r;
wVersionRequested = MAKEWORD(1, 1);
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
if (r)
Sys_Error ("Winsock initialization failed.");
//
// open the single socket to be used for all communications
//
net_socket = UDP_OpenSocket (port);
//
// init the message buffer
//
net_message.maxsize = sizeof(net_message_buffer);
net_message.data = net_message_buffer;
//
// determine my name & address
//
NET_GetLocalAddress ();
printf("UDP Initialized\n");
}
void SV_InitNet (void)
{
int port;
int p;
port = PORT_MASTER;
p = COM_CheckParm ("-port");
if (p && p < com_argc)
{
port = atoi(com_argv[p+1]);
printf ("Port: %i\n", port);
}
NET_Init (port);
//Add filters
FILE *filters;
char str[64];
if(filters = fopen("filters.ini","rt"))
{
while(fgets(str,64,filters))
{
Cbuf_AddText("filter add ");
Cbuf_AddText(str);
Cbuf_AddText("\n");
}
fclose(filters);
}
}
int UDP_OpenSocket (int port)
{
int newsocket;
struct sockaddr_in address;
unsigned long _true = true;
int i;
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
Sys_Error ("UDP_OpenSocket: socket:", strerror(errno));
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:", strerror(errno));
address.sin_family = AF_INET;
//ZOID -- check for interface binding option
if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) {
address.sin_addr.s_addr = inet_addr(com_argv[i+1]);
printf("Binding to IP Interface Address of %s\n",
inet_ntoa(address.sin_addr));
} else
address.sin_addr.s_addr = INADDR_ANY;
if (port == PORT_ANY)
address.sin_port = 0;
else
address.sin_port = htons((short)port);
if( bind (newsocket, /*(void *)*/(struct sockaddr *)&address, sizeof(address)) == -1)
Sys_Error ("UDP_OpenSocket: bind: %s", strerror(errno));
return newsocket;
}
void NET_Shutdown (void)
{
closesocket (net_socket);
WSACleanup ();
}
qboolean NET_CompareAdr (netadr_t a, netadr_t b)
{
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port)
return true;
return false;
}
qboolean NET_CompareAdrNoPort (netadr_t a, netadr_t b)
{
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
return true;
return false;
}
void NET_CopyAdr (netadr_t *a, netadr_t *b)
{
a->ip[0] = b->ip[0];
a->ip[1] = b->ip[1];
a->ip[2] = b->ip[2];
a->ip[3] = b->ip[3];
a->port = b->port;
a->pad = b->pad;
}
void NET_GetLocalAddress (void)
{
char buff[512];
struct sockaddr_in address;
int namelen;
gethostname(buff, 512);
buff[512-1] = 0;
NET_StringToAdr (buff, &net_local_adr);
namelen = sizeof(address);
if (getsockname (net_socket, (struct sockaddr *)&address, &namelen) == -1)
Sys_Error ("NET_Init: getsockname:", strerror(errno));
net_local_adr.port = address.sin_port;
printf("IP address %s\n", NET_AdrToString (net_local_adr) );
}
char *NET_AdrToString (netadr_t a)
{
static char s[64];
sprintf (s, "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port));
return s;
}
qboolean NET_StringToAdr (char *s, netadr_t *a)
{
struct hostent *h;
struct sockaddr_in sadr;
char *colon;
char copy[128];
memset (&sadr, 0, sizeof(sadr));
sadr.sin_family = AF_INET;
sadr.sin_port = 0;
strcpy (copy, s);
// strip off a trailing :port if present
for (colon = copy ; *colon ; colon++)
if (*colon == ':')
{
*colon = 0;
sadr.sin_port = htons((short)atoi(colon+1));
}
if (copy[0] >= '0' && copy[0] <= '9')
{
*(int *)&sadr.sin_addr = inet_addr(copy);
}
else
{
if ((h = gethostbyname(copy)) == 0)
return 0;
*(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0];
}
SockadrToNetadr (&sadr, a);
return true;
}
void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
{
memset (s, 0, sizeof(*s));
s->sin_family = AF_INET;
*(int *)&s->sin_addr = *(int *)&a->ip;
s->sin_port = a->port;
}
void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
{
*(int *)&a->ip = *(int *)&s->sin_addr;
a->port = s->sin_port;
}
void NET_SendPacket (int length, void *data, netadr_t to)
{
int ret;
struct sockaddr_in addr;
NetadrToSockadr (&to, &addr);
ret = sendto (net_socket, (char *)data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
if (ret == -1)
{
int err = WSAGetLastError();
// wouldblock is silent
if (err == WSAEWOULDBLOCK)
return;
printf ("NET_SendPacket ERROR: %i\n", errno);
}
}
void AnalysePacket()
{
byte c;
byte *p;
int i;
printf("%s sending packet:\n",NET_AdrToString(net_from));
p = net_message.data;
for(i = 0;i<net_message.cursize;i++,p++)
{
c = p[0];
printf(" %3i ",c);
if(i%8==7)
printf("\n");
}
printf("\n");
printf("\n");
p = net_message.data;
for(i = 0;i<net_message.cursize;i++,p++)
{
c = p[0];
if(c=='\n')
printf(" \\n ");
else if(c>=32&&c<=127)
printf(" %c ",c);
else if(c<10)
printf(" \\%1i ",c);
else if(c<100)
printf(" \\%2i ",c);
else
printf("\\%3i ",c);
if(i%8==7)
printf("\n");
}
printf("\n");
}
void Mst_SendList()
{
byte buf[MAX_DATAGRAM];
sizebuf_t msg;
msg.data = buf;
msg.maxsize = sizeof(buf);
msg.cursize = 0;
msg.allowoverflow = true;
msg.overflowed = false;
server_t *sv;
short int sv_num = 0;
//number of servers:
for(sv = sv_list;sv;sv = sv->next)
sv_num++;
MSG_WriteByte(&msg,255);
MSG_WriteByte(&msg,255);
MSG_WriteByte(&msg,255);
MSG_WriteByte(&msg,255);
MSG_WriteByte(&msg,255);
MSG_WriteByte(&msg,'d');
MSG_WriteByte(&msg,'\n');
if(sv_num>0)
for(sv = sv_list;sv;sv = sv->next)
{
MSG_WriteByte(&msg,sv->ip.ip[0]);
MSG_WriteByte(&msg,sv->ip.ip[1]);
MSG_WriteByte(&msg,sv->ip.ip[2]);
MSG_WriteByte(&msg,sv->ip.ip[3]);
MSG_WriteShort(&msg,sv->ip.port);
}
NET_SendPacket(msg.cursize,msg.data,net_from);
}
void Mst_Packet()
{
char msg;
server_t *sv;
//NET_Filter();
msg = net_message.data[1];
if(msg==A2A_PING)
{
NET_Filter();
printf("%s >> A2A_PING\n",NET_AdrToString(net_from));
if(!(sv = SVL_Find(net_from)))
{
sv = SVL_New(net_from);
SVL_Add(sv);
}
sv->timeout = Sys_DoubleTime();
}
else if(msg==S2M_HEARTBEAT)
{
NET_Filter();
printf("%s >> S2M_HEARTBEAT\n",NET_AdrToString(net_from));
if(!(sv = SVL_Find(net_from)))
{
sv = SVL_New(net_from);
SVL_Add(sv);
}
sv->timeout = Sys_DoubleTime();
}
else if(msg==S2M_SHUTDOWN)
{
NET_Filter();
printf("%s >> S2M_SHUTDOWN\n",NET_AdrToString(net_from));
if(sv = SVL_Find(net_from))
{
SVL_Remove(sv);
free(sv);
}
}
else if(msg=='c')
{
printf("%s >> ",NET_AdrToString(net_from));
printf("Gamespy server list request\n");
Mst_SendList();
}
else
{
byte *p;
p = net_message.data;
printf("%s >> ",NET_AdrToString(net_from));
printf("Pingtool server list request\n");
if(p[0]==0&&p[1]=='y')
{
Mst_SendList();
}
else
{
printf("%s >> ",NET_AdrToString(net_from));
printf("%c\n",net_message.data[1]);
AnalysePacket();
}
}
}
void SV_ReadPackets (void)
{
while (NET_GetPacket ())
{
Mst_Packet();
}
}
qboolean NET_GetPacket (void)
{
int ret;
struct sockaddr_in from;
int fromlen;
fromlen = sizeof(from);
ret = recvfrom (net_socket, (char *)net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen);
SockadrToNetadr (&from, &net_from);
if (ret == -1)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
return false;
if (err == WSAEMSGSIZE) {
printf ("Warning: Oversize packet from %s\n",
NET_AdrToString (net_from));
return false;
}
//Sys_Error ("NET_GetPacket: %s", strerror(err));
printf ("Warning: Unrecognized recvfrom error, error code = %i\n",err);
return false;
}
net_message.cursize = ret;
if (ret == sizeof(net_message_buffer) )
{
printf ("Oversize packet from %s\n", NET_AdrToString (net_from));
return false;
}
return ret;
}
void SV_ConnectionlessPacket (void)
{
printf("%s>>%s\n",NET_AdrToString(net_from),net_message.data);
}
int argv_index_add;
void Cmd_FilterAdd()
{
filter_t *filter;
netadr_t to,from;
if(Cmd_Argc()<4+argv_index_add)
{
printf("Invalid command parameters. Usage:\nfilter add x.x.x.x:port x.x.x.x:port\n\n");
return;
}
NET_StringToAdr(Cmd_Argv(2+argv_index_add),&from);
NET_StringToAdr(Cmd_Argv(3+argv_index_add),&to);
if(to.port==0)
from.port = BigShort(PORT_SERVER);
if(from.port==0)
from.port = BigShort(PORT_SERVER);
if(!(filter = FL_Find(from)))
{
printf("Added filter %s\t\t%s\n",Cmd_Argv(2+argv_index_add),Cmd_Argv(3+argv_index_add));
filter = FL_New(from,to);
FL_Add(filter);
}
else
printf("%s already defined\n\n",Cmd_Argv(2+argv_index_add));
}
void Cmd_FilterRemove()
{
filter_t *filter;
netadr_t from;
if(Cmd_Argc()<3+argv_index_add)
{
printf("Invalid command parameters. Usage:\nfilter remove x.x.x.x:port\n\n");
return;
}
NET_StringToAdr(Cmd_Argv(2+argv_index_add),&from);
if(filter = FL_Find(from))
{
printf("Removed %s\n\n",Cmd_Argv(2+argv_index_add));
FL_Remove(filter);
free(filter);
}
else
printf("Cannot find %s\n\n",Cmd_Argv(2+argv_index_add));
}
void Cmd_FilterList()
{
filter_t *filter;
for(filter = filter_list;filter;filter = filter->next)
{
printf("%s",NET_AdrToString(filter->from));
printf("\t\t%s\n",NET_AdrToString(filter->to));
}
if(filter_list==NULL)
printf("No filter\n");
printf("\n");
}
void Cmd_FilterClear()
{
printf("Removed all filters\n\n");
FL_Clear();
}
void Cmd_Filter_f()
{
argv_index_add = 0;
if(!strcmp(Cmd_Argv(1),"add"))
Cmd_FilterAdd();
else if(!strcmp(Cmd_Argv(1),"remove"))
Cmd_FilterRemove();
else if(!strcmp(Cmd_Argv(1),"clear"))
Cmd_FilterClear();
else if(Cmd_Argc()==3)
{
argv_index_add = -1;
Cmd_FilterAdd();
}
else if(Cmd_Argc()==2)
{
argv_index_add = -1;
Cmd_FilterRemove();
}
else
Cmd_FilterList();
}
void SV_WriteFilterList()
{
FILE *filters;
if(filters = fopen("filters.ini","wt"))
{
if(filter_list == NULL)
{
fclose(filters);
return;
}
filter_t *filter;
for(filter = filter_list;filter;filter = filter->next)
{
fprintf(filters,"%s",NET_AdrToString(filter->from));
fprintf(filters," %s\n",NET_AdrToString(filter->to));
}
fclose(filters);
}
}

365
hw/source/net_test.c Normal file
View file

@ -0,0 +1,365 @@
#include "defs.h"
#include <limits.h>
int sv_mode;
sizebuf_t cmd_text;
byte cmd_text_buf[8192];
char com_token[1024];
int com_argc;
char **com_argv;
static char *largv[MAX_NUM_ARGVS + 1];
static char *argvdummy = " ";
qboolean bigendien;
short (*BigShort) (short l);
short (*LittleShort) (short l);
int (*BigLong) (int l);
int (*LittleLong) (int l);
float (*BigFloat) (float l);
float (*LittleFloat) (float l);
short ShortSwap (short l)
{
byte b1,b2;
b1 = l&255;
b2 = (l>>8)&255;
return (b1<<8) + b2;
}
short ShortNoSwap (short l)
{
return l;
}
int LongSwap (int l)
{
byte b1,b2,b3,b4;
b1 = l&255;
b2 = (l>>8)&255;
b3 = (l>>16)&255;
b4 = (l>>24)&255;
return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
}
int LongNoSwap (int l)
{
return l;
}
float FloatSwap (float f)
{
union
{
float f;
byte b[4];
} dat1, dat2;
dat1.f = f;
dat2.b[0] = dat1.b[3];
dat2.b[1] = dat1.b[2];
dat2.b[2] = dat1.b[1];
dat2.b[3] = dat1.b[0];
return dat2.f;
}
float FloatNoSwap (float f)
{
return f;
}
////////////////////////////////
void COM_Init (void)
{
byte swaptest[2] = {1,0};
// set the byte swapping variables in a portable manner
if ( *(short *)swaptest == 1)
{
bigendien = false;
BigShort = ShortSwap;
LittleShort = ShortNoSwap;
BigLong = LongSwap;
LittleLong = LongNoSwap;
BigFloat = FloatSwap;
LittleFloat = FloatNoSwap;
}
else
{
bigendien = true;
BigShort = ShortNoSwap;
LittleShort = ShortSwap;
BigLong = LongNoSwap;
LittleLong = LongSwap;
BigFloat = FloatNoSwap;
LittleFloat = FloatSwap;
}
}
void COM_InitArgv (int argc, char **argv)
{
for (com_argc=0 ; (com_argc<MAX_NUM_ARGVS) && (com_argc < argc) ;
com_argc++)
{
largv[com_argc] = argv[com_argc];
}
largv[com_argc] = argvdummy;
com_argv = largv;
}
int COM_CheckParm (char *parm)
{
int i;
for (i=1 ; i<com_argc ; i++)
{
if (!com_argv[i])
continue; // NEXTSTEP sometimes clears appkit vars.
if (!strcmp (parm,com_argv[i]))
return i;
}
return 0;
}
char *COM_Parse (char *data)
{
int c;
int len;
len = 0;
com_token[0] = 0;
if (!data)
return NULL;
// skip whitespace
skipwhite:
while ( (c = *data) <= ' ')
{
if (c == 0)
return NULL; // end of file;
data++;
}
// skip // comments
if (c=='/' && data[1] == '/')
{
while (*data && *data != '\n')
data++;
goto skipwhite;
}
// handle quoted strings specially
if (c == '\"')
{
data++;
while (1)
{
c = *data++;
if (c=='\"' || !c)
{
com_token[len] = 0;
return data;
}
com_token[len] = c;
len++;
}
}
// parse a regular word
do
{
com_token[len] = c;
data++;
len++;
c = *data;
} while (c>32);
com_token[len] = 0;
return data;
}
void Sys_Error (char *error, ...)
{
va_list argptr;
char text[1024];
va_start (argptr,error);
vsprintf (text, error,argptr);
va_end (argptr);
// MessageBox(NULL, text, "Error", 0 /* MB_OK */ );
printf ("ERROR: %s\n", text);
exit (1);
}
void Sys_Quit (void)
{
exit (0);
}
void SV_WriteFilterList();
void SV_Shutdown (void)
{
NET_Shutdown ();
//write filter list
SV_WriteFilterList();
}
char *Sys_ConsoleInput (void)
{
static char text[256];
static int len;
int c;
// read a line out
while (_kbhit())
{
c = _getch();
putch (c);
if (c == '\r')
{
text[len] = 0;
putch ('\n');
len = 0;
return text;
}
if (c == 8)
{
if (len)
{
putch (' ');
putch (c);
len--;
text[len] = 0;
}
continue;
}
text[len] = c;
len++;
text[len] = 0;
if (len == sizeof(text))
len = 0;
}
return NULL;
}
void SV_GetConsoleCommands (void)
{
char *cmd;
while (1)
{
cmd = Sys_ConsoleInput ();
if (!cmd)
break;
Cbuf_AddText (cmd);
}
}
double Sys_DoubleTime (void)
{
static DWORD starttime;
static qboolean first = true;
DWORD now;
double t;
now = timeGetTime();
if (first) {
first = false;
starttime = now;
return 0.0;
}
if (now < starttime) // wrapped?
return (now / 1000.0) + (LONG_MAX - starttime / 1000.0);
if (now - starttime == 0)
return 0.0;
return (now - starttime) / 1000.0;
}
#define SV_TIMEOUT 450
void SV_TimeOut()
{
//Remove listed severs that havnt sent a heartbeat for some time
double time = Sys_DoubleTime();
server_t *sv;
server_t *next;
if(sv_list==NULL)
return;
for(sv = sv_list;sv;)
{
if(sv->timeout + SV_TIMEOUT < time)
{
next = sv->next;
printf("%s timed out\n",NET_AdrToString(sv->ip));
SVL_Remove(sv);
free(sv);
sv = next;
}
else
sv = sv->next;
}
}
void SV_Frame()
{
SV_GetConsoleCommands ();
Cbuf_Execute ();
SV_TimeOut();
SV_ReadPackets();
}
int main (int argc, char **argv)
{
COM_Init();
COM_InitArgv (argc, argv);
Cbuf_Init();
Cmd_Init ();
SV_InitNet();
printf ("Exe: "__TIME__" "__DATE__"\n");
printf("======== HW master initialized ========\n\n");
while(1)
{
SV_Frame();
}
return 0;
}

113
hw/source/vars.c Normal file
View file

@ -0,0 +1,113 @@
#include "defs.h"
#include "QF/cvar.h"
cvar_t *cvar_vars;
char *cvar_null_string = "";
qboolean Cvar_Command (void)
{
cvar_t *v;
// check variables
v = Cvar_FindVar (Cmd_Argv(0));
if (!v)
return false;
// perform a variable print or set
if (Cmd_Argc() == 1)
{
printf ("\"%s\" is \"%s\"\n", v->name, v->string);
return true;
}
Cvar_Set (v->name, Cmd_Argv(1));
return true;
}
cvar_t *Cvar_FindVar (char *var_name)
{
cvar_t *var;
for (var=cvar_vars ; var ; var=var->next)
if (!strcmp (var_name, var->name))
return var;
return NULL;
}
void Cvar_RegisterVariable (cvar_t *variable)
{
char value[512];
// first check to see if it has allready been defined
if (Cvar_FindVar (variable->name))
{
printf ("Can't register variable %s, allready defined\n", variable->name);
return;
}
// check for overlap with a command
if (Cmd_Exists (variable->name))
{
printf ("Cvar_RegisterVariable: %s is a command\n", variable->name);
return;
}
// link the variable in
variable->next = cvar_vars;
cvar_vars = variable;
// copy the value off, because future sets will Z_Free it
strcpy (value, variable->string);
variable->string = (char *)malloc (1);
// set it through the function to be consistant
Cvar_Set (variable->name, value);
}
void Cvar_Set (char *var_name, char *value)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var)
{ // there is an error in C code if this happens
printf ("Cvar_Set: variable %s not found\n", var_name);
return;
}
free (var->string); // free the old value string
var->string = (char *)malloc (strlen(value)+1);
strcpy (var->string, value);
var->value = atof (var->string);
}
void Cvar_SetValue (char *var_name, float value)
{
char val[32];
sprintf (val, "%f",value);
Cvar_Set (var_name, val);
}
char *Cvar_VariableString (char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var)
return cvar_null_string;
return var->string;
}
float Cvar_VariableValue (char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var)
return 0;
return atof (var->string);
}