Home | History | Annotate | Download | only in WinQuake
      1 /*
      2 Copyright (C) 1996-1997 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 // net_loop.c
     21 
     22 #include "quakedef.h"
     23 #include "net_loop.h"
     24 
     25 qboolean	localconnectpending = false;
     26 qsocket_t	*loop_client = NULL;
     27 qsocket_t	*loop_server = NULL;
     28 
     29 int Loop_Init (void)
     30 {
     31 	if (cls.state == ca_dedicated)
     32 		return -1;
     33 	return 0;
     34 }
     35 
     36 
     37 void Loop_Shutdown (void)
     38 {
     39 }
     40 
     41 
     42 void Loop_Listen (qboolean state)
     43 {
     44 }
     45 
     46 
     47 void Loop_SearchForHosts (qboolean xmit)
     48 {
     49 	if (!sv.active)
     50 		return;
     51 
     52 	hostCacheCount = 1;
     53 	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
     54 		Q_strcpy(hostcache[0].name, "local");
     55 	else
     56 		Q_strcpy(hostcache[0].name, hostname.string);
     57 	Q_strcpy(hostcache[0].map, sv.name);
     58 	hostcache[0].users = net_activeconnections;
     59 	hostcache[0].maxusers = svs.maxclients;
     60 	hostcache[0].driver = net_driverlevel;
     61 	Q_strcpy(hostcache[0].cname, "local");
     62 }
     63 
     64 
     65 qsocket_t *Loop_Connect (const char *host)
     66 {
     67 	if (Q_strcmp(host,"local") != 0)
     68 		return NULL;
     69 
     70 	localconnectpending = true;
     71 
     72 	if (!loop_client)
     73 	{
     74 		if ((loop_client = NET_NewQSocket ()) == NULL)
     75 		{
     76 			Con_Printf("Loop_Connect: no qsocket available\n");
     77 			return NULL;
     78 		}
     79 		Q_strcpy (loop_client->address, "localhost");
     80 	}
     81 	loop_client->receiveMessageLength = 0;
     82 	loop_client->sendMessageLength = 0;
     83 	loop_client->canSend = true;
     84 
     85 	if (!loop_server)
     86 	{
     87 		if ((loop_server = NET_NewQSocket ()) == NULL)
     88 		{
     89 			Con_Printf("Loop_Connect: no qsocket available\n");
     90 			return NULL;
     91 		}
     92 		Q_strcpy (loop_server->address, "LOCAL");
     93 	}
     94 	loop_server->receiveMessageLength = 0;
     95 	loop_server->sendMessageLength = 0;
     96 	loop_server->canSend = true;
     97 
     98 	loop_client->driverdata = (void *)loop_server;
     99 	loop_server->driverdata = (void *)loop_client;
    100 
    101 	return loop_client;
    102 }
    103 
    104 
    105 qsocket_t *Loop_CheckNewConnections (void)
    106 {
    107 	if (!localconnectpending)
    108 		return NULL;
    109 
    110 	localconnectpending = false;
    111 	loop_server->sendMessageLength = 0;
    112 	loop_server->receiveMessageLength = 0;
    113 	loop_server->canSend = true;
    114 	loop_client->sendMessageLength = 0;
    115 	loop_client->receiveMessageLength = 0;
    116 	loop_client->canSend = true;
    117 	return loop_server;
    118 }
    119 
    120 
    121 static int IntAlign(int value)
    122 {
    123 	return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1));
    124 }
    125 
    126 
    127 int Loop_GetMessage (qsocket_t *sock)
    128 {
    129 	int		ret;
    130 	int		length;
    131 
    132 	if (sock->receiveMessageLength == 0)
    133 		return 0;
    134 
    135 	ret = sock->receiveMessage[0];
    136 	length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8);
    137 	// alignment byte skipped here
    138 	SZ_Clear (&net_message);
    139 	SZ_Write (&net_message, &sock->receiveMessage[4], length);
    140 
    141 	length = IntAlign(length + 4);
    142 	sock->receiveMessageLength -= length;
    143 
    144 	if (sock->receiveMessageLength)
    145 		Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength);
    146 
    147 	if (sock->driverdata && ret == 1)
    148 		((qsocket_t *)sock->driverdata)->canSend = true;
    149 
    150 	return ret;
    151 }
    152 
    153 
    154 int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data)
    155 {
    156 	byte *buffer;
    157 	int  *bufferLength;
    158 
    159 	if (!sock->driverdata)
    160 		return -1;
    161 
    162 	bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength;
    163 
    164 	if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE)
    165 		Sys_Error("Loop_SendMessage: overflow\n");
    166 
    167 	buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength;
    168 
    169 	// message type
    170 	*buffer++ = 1;
    171 
    172 	// length
    173 	*buffer++ = data->cursize & 0xff;
    174 	*buffer++ = data->cursize >> 8;
    175 
    176 	// align
    177 	buffer++;
    178 
    179 	// message
    180 	Q_memcpy(buffer, data->data, data->cursize);
    181 	*bufferLength = IntAlign(*bufferLength + data->cursize + 4);
    182 
    183 	sock->canSend = false;
    184 	return 1;
    185 }
    186 
    187 
    188 int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
    189 {
    190 	byte *buffer;
    191 	int  *bufferLength;
    192 
    193 	if (!sock->driverdata)
    194 		return -1;
    195 
    196 	bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength;
    197 
    198 	if ((*bufferLength + data->cursize + sizeof(byte) + sizeof(short)) > NET_MAXMESSAGE)
    199 		return 0;
    200 
    201 	buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength;
    202 
    203 	// message type
    204 	*buffer++ = 2;
    205 
    206 	// length
    207 	*buffer++ = data->cursize & 0xff;
    208 	*buffer++ = data->cursize >> 8;
    209 
    210 	// align
    211 	buffer++;
    212 
    213 	// message
    214 	Q_memcpy(buffer, data->data, data->cursize);
    215 	*bufferLength = IntAlign(*bufferLength + data->cursize + 4);
    216 	return 1;
    217 }
    218 
    219 
    220 qboolean Loop_CanSendMessage (qsocket_t *sock)
    221 {
    222 	if (!sock->driverdata)
    223 		return false;
    224 	return sock->canSend;
    225 }
    226 
    227 
    228 qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock)
    229 {
    230 	return true;
    231 }
    232 
    233 
    234 void Loop_Close (qsocket_t *sock)
    235 {
    236 	if (sock->driverdata)
    237 		((qsocket_t *)sock->driverdata)->driverdata = NULL;
    238 	sock->receiveMessageLength = 0;
    239 	sock->sendMessageLength = 0;
    240 	sock->canSend = true;
    241 	if (sock == loop_client)
    242 		loop_client = NULL;
    243 	else
    244 		loop_server = NULL;
    245 }
    246