mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
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:
parent
d494be3594
commit
5ca662ae92
8 changed files with 1818 additions and 0 deletions
4
hw/Makefile.am
Normal file
4
hw/Makefile.am
Normal 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
5
hw/include/Makefile.am
Normal 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
215
hw/include/defs.h
Normal 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
47
hw/source/Makefile.am
Normal 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
244
hw/source/cmds.c
Normal 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
825
hw/source/net.c
Normal 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
365
hw/source/net_test.c
Normal 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
113
hw/source/vars.c
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue