]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hunt/huntd/answer.c
1 /* $NetBSD: answer.c,v 1.7 2004/11/05 21:30:32 dsl Exp $ */
3 * Copyright (c) 1983-2003, Regents of the University of California.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * + Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * + Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * + Neither the name of the University of California, San Francisco nor
16 * the names of its contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
35 __RCSID("$NetBSD: answer.c,v 1.7 2004/11/05 21:30:32 dsl Exp $");
45 # define SCOREDECAY 15
47 static char Ttyname
[NAMELEN
];
55 static char name
[NAMELEN
];
57 static int enter_status
;
59 static u_long machine
;
61 static SOCKET sockstruct
;
68 socklen
= sizeof sockstruct
;
70 socklen
= sizeof sockstruct
- 1;
73 newsock
= accept(Socket
, (struct sockaddr
*) &sockstruct
, &socklen
);
79 syslog(LOG_ERR
, "accept: %m");
87 machine
= ntohl(((struct sockaddr_in
*) &sockstruct
)->sin_addr
.s_addr
);
90 machine
= gethostid();
92 version
= htonl((u_int32_t
) HUNT_VERSION
);
93 (void) write(newsock
, (char *) &version
, LONGLEN
);
94 (void) read(newsock
, (char *) &uid
, LONGLEN
);
95 uid
= ntohl((unsigned long) uid
);
96 (void) read(newsock
, name
, NAMELEN
);
97 (void) read(newsock
, &team
, 1);
98 (void) read(newsock
, (char *) &enter_status
, LONGLEN
);
99 enter_status
= ntohl((unsigned long) enter_status
);
100 (void) read(newsock
, Ttyname
, NAMELEN
);
101 (void) read(newsock
, (char *) &mode
, sizeof mode
);
105 * Turn off blocking I/O, so a slow or dead terminal won't stop
106 * the game. All subsequent reads check how many bytes they read.
108 flags
= fcntl(newsock
, F_GETFL
, 0);
110 (void) fcntl(newsock
, F_SETFL
, flags
);
113 * Make sure the name contains only printable characters
114 * since we use control characters for cursor control
115 * between driver and player processes
117 for (cp1
= cp2
= name
; *cp1
!= '\0'; cp1
++)
118 if (isprint((unsigned char)*cp1
) || *cp1
== ' ')
123 if (mode
== C_MESSAGE
) {
124 char buf
[BUFSIZ
+ 1];
128 (void) sprintf(buf
, "%s: ", name
);
130 (void) sprintf(buf
, "%s[%c]: ", name
, team
);
132 for (pp
= Player
; pp
< End_player
; pp
++) {
133 cgoto(pp
, HEIGHT
, 0);
136 while ((n
= read(newsock
, buf
, BUFSIZ
)) > 0)
137 for (pp
= Player
; pp
< End_player
; pp
++)
139 for (pp
= Player
; pp
< End_player
; pp
++) {
141 sendcom(pp
, REFRESH
);
142 sendcom(pp
, READY
, 0);
143 (void) fflush(pp
->p_output
);
145 (void) close(newsock
);
151 if (mode
== C_MONITOR
)
152 if (End_monitor
< &Monitor
[MAXMON
]) {
154 i
= pp
- Monitor
+ MAXPL
+ 3;
157 (void) write(newsock
, (char *) &socklen
,
159 (void) close(newsock
);
164 if (End_player
< &Player
[MAXPL
]) {
169 (void) write(newsock
, (char *) &socklen
,
171 (void) close(newsock
);
176 if (mode
== C_MONITOR
&& team
== ' ')
179 pp
->p_ident
= get_ident(machine
, uid
, name
, team
);
180 pp
->p_output
= fdopen(newsock
, "w");
181 pp
->p_death
[0] = '\0';
183 fdset
[i
].fd
= newsock
;
184 fdset
[i
].events
= POLLIN
;
190 if (mode
== C_MONITOR
)
194 stplayer(pp
, enter_status
);
206 memcpy(pp
->p_maze
, Maze
, sizeof Maze
);
210 (void) sprintf(Buf
, "%5.5s%c%-10.10s %c", " ", stat_char(pp
),
211 pp
->p_ident
->i_name
, pp
->p_ident
->i_team
);
212 line
= STAT_MON_ROW
+ 1 + (pp
- Monitor
);
213 for (npp
= Player
; npp
< End_player
; npp
++) {
214 cgoto(npp
, line
, STAT_NAME_COL
);
215 outstr(npp
, Buf
, STAT_NAME_LEN
);
217 for (npp
= Monitor
; npp
< End_monitor
; npp
++) {
218 cgoto(npp
, line
, STAT_NAME_COL
);
219 outstr(npp
, Buf
, STAT_NAME_LEN
);
222 sendcom(pp
, REFRESH
);
223 sendcom(pp
, READY
, 0);
224 (void) fflush(pp
->p_output
);
229 stplayer(newpp
, enter_status
)
238 for (y
= 0; y
< UBOUND
; y
++)
239 for (x
= 0; x
< WIDTH
; x
++)
240 newpp
->p_maze
[y
][x
] = Maze
[y
][x
];
241 for ( ; y
< DBOUND
; y
++) {
242 for (x
= 0; x
< LBOUND
; x
++)
243 newpp
->p_maze
[y
][x
] = Maze
[y
][x
];
244 for ( ; x
< RBOUND
; x
++)
245 newpp
->p_maze
[y
][x
] = SPACE
;
246 for ( ; x
< WIDTH
; x
++)
247 newpp
->p_maze
[y
][x
] = Maze
[y
][x
];
249 for ( ; y
< HEIGHT
; y
++)
250 for (x
= 0; x
< WIDTH
; x
++)
251 newpp
->p_maze
[y
][x
] = Maze
[y
][x
];
254 x
= rand_num(WIDTH
- 1) + 1;
255 y
= rand_num(HEIGHT
- 1) + 1;
256 } while (Maze
[y
][x
] != SPACE
);
257 newpp
->p_over
= SPACE
;
260 newpp
->p_undershot
= FALSE
;
263 if (enter_status
== Q_FLY
) {
264 newpp
->p_flying
= rand_num(20);
265 newpp
->p_flyx
= 2 * rand_num(6) - 5;
266 newpp
->p_flyy
= 2 * rand_num(6) - 5;
267 newpp
->p_face
= FLYER
;
272 newpp
->p_flying
= -1;
273 newpp
->p_face
= rand_dir();
276 newpp
->p_damcap
= MAXDAM
;
280 newpp
->p_ammo
= ISHOTS
;
284 if (enter_status
== Q_SCAN
) {
285 newpp
->p_scan
= SCANLEN
;
290 newpp
->p_cloak
= CLOAKLEN
;
295 x
= rand_num(WIDTH
- 1) + 1;
296 y
= rand_num(HEIGHT
- 1) + 1;
297 } while (Maze
[y
][x
] != SPACE
);
300 for (pp
= Monitor
; pp
< End_monitor
; pp
++)
305 x
= rand_num(WIDTH
- 1) + 1;
306 y
= rand_num(HEIGHT
- 1) + 1;
307 } while (Maze
[y
][x
] != SPACE
);
310 for (pp
= Monitor
; pp
< End_monitor
; pp
++)
314 (void) sprintf(Buf
, "%5.2f%c%-10.10s %c", newpp
->p_ident
->i_score
,
315 stat_char(newpp
), newpp
->p_ident
->i_name
,
316 newpp
->p_ident
->i_team
);
317 y
= STAT_PLAY_ROW
+ 1 + (newpp
- Player
);
318 for (pp
= Player
; pp
< End_player
; pp
++) {
322 pp
->p_ammo
+= NSHOTS
;
323 newpp
->p_ammo
+= NSHOTS
;
324 cgoto(pp
, y
, STAT_NAME_COL
);
325 outstr(pp
, Buf
, STAT_NAME_LEN
);
326 (void) sprintf(smallbuf
, "%3d", pp
->p_ammo
);
327 cgoto(pp
, STAT_AMMO_ROW
, STAT_VALUE_COL
);
328 outstr(pp
, smallbuf
, 3);
332 for (pp
= Monitor
; pp
< End_monitor
; pp
++) {
333 cgoto(pp
, y
, STAT_NAME_COL
);
334 outstr(pp
, Buf
, STAT_NAME_LEN
);
339 drawplayer(newpp
, TRUE
);
342 if (enter_status
== Q_FLY
)
343 /* Make sure that the position you enter in will be erased */
344 showexpl(newpp
->p_y
, newpp
->p_x
, FLYER
);
346 sendcom(newpp
, REFRESH
);
347 sendcom(newpp
, READY
, 0);
348 (void) fflush(newpp
->p_output
);
353 * Return a random direction
358 switch (rand_num(4)) {
374 * Get the score structure of a player
377 get_ident(machine
, uid
, name
, team
)
386 for (ip
= Scores
; ip
!= NULL
; ip
= ip
->i_next
)
387 if (ip
->i_machine
== machine
389 && ip
->i_team
== team
390 && strncmp(ip
->i_name
, name
, NAMELEN
) == 0)
394 if (ip
->i_entries
< SCOREDECAY
)
397 ip
->i_kills
= (ip
->i_kills
* (SCOREDECAY
- 1))
399 ip
->i_score
= ip
->i_kills
/ (double) ip
->i_entries
;
402 ip
= (IDENT
*) malloc(sizeof (IDENT
));
404 /* Fourth down, time to punt */
407 ip
->i_machine
= machine
;
410 strncpy(ip
->i_name
, name
, NAMELEN
);
421 ip
->i_gkills
= ip
->i_bkills
= ip
->i_deaths
= 0;
422 ip
->i_stillb
= ip
->i_saved
= 0;