• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Loop_Init(void)29 int Loop_Init (void)
30 {
31 	if (cls.state == ca_dedicated)
32 		return -1;
33 	return 0;
34 }
35 
36 
Loop_Shutdown(void)37 void Loop_Shutdown (void)
38 {
39 }
40 
41 
Loop_Listen(qboolean state)42 void Loop_Listen (qboolean state)
43 {
44 }
45 
46 
Loop_SearchForHosts(qboolean xmit)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 
Loop_Connect(const char * host)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 
Loop_CheckNewConnections(void)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 
IntAlign(int value)121 static int IntAlign(int value)
122 {
123 	return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1));
124 }
125 
126 
Loop_GetMessage(qsocket_t * sock)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 
Loop_SendMessage(qsocket_t * sock,sizebuf_t * data)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 
Loop_SendUnreliableMessage(qsocket_t * sock,sizebuf_t * data)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 
Loop_CanSendMessage(qsocket_t * sock)220 qboolean Loop_CanSendMessage (qsocket_t *sock)
221 {
222 	if (!sock->driverdata)
223 		return false;
224 	return sock->canSend;
225 }
226 
227 
Loop_CanSendUnreliableMessage(qsocket_t * sock)228 qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock)
229 {
230 	return true;
231 }
232 
233 
Loop_Close(qsocket_t * sock)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