Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 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 (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 | }><> |