]> git.pond.sub.org Git - empserver/blob - src/lib/subs/pr.c
Update copyright notice.
[empserver] / src / lib / subs / pr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2004, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  pr.c: Use to do output to a player
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1986, 1989 
32  *     Steve McClure, 1998-2000
33  */
34 /*
35  * The pr routine historically arranged for nonbuffered i/o
36  * because stdio didn't used to automatically flush stdout before
37  * it read something from stdin.  Now pr() prepends an "output id"
38  * in front of each line of text, informing the user interface
39  * what sort of item it is seeing; prompt, noecho prompt,
40  * more input data, etc.
41  */
42
43 #include <string.h>
44 #include <fcntl.h>
45 #include <ctype.h>
46 #include <stdarg.h>
47 #include "proto.h"
48 #include "misc.h"
49 #include "player.h"
50 #include "nat.h"
51 #include "empio.h"
52 #include "file.h"
53 #include "com.h"
54 #include "news.h"
55 #include "tel.h"
56 #include "server.h"
57 #include "prototypes.h"
58
59 static void outid(struct player *pl, int n);
60
61 /*VARARGS*/
62 void
63 pr(s_char *format, ...)
64 {
65     s_char buf[4096];
66     va_list ap;
67
68     va_start(ap, format);
69     (void)vsprintf(buf, format, ap);
70     va_end(ap);
71     pr_player(player, C_DATA, buf);
72 }
73
74 void
75 prnf(s_char *buf)
76 {
77     pr_player(player, C_DATA, buf);
78 }
79
80 /*VARARGS*/
81 void
82 pr_id(struct player *p, int id, s_char *format, ...)
83 {
84     s_char buf[4096];
85     va_list ap;
86
87     if (p->curid >= 0) {
88         io_puts(p->iop, "\n");
89         p->curid = -1;
90     }
91     va_start(ap, format);
92     (void)vsprintf(buf, format, ap);
93     va_end(ap);
94     pr_player(p, id, buf);
95 }
96
97 void
98 pr_flash(struct player *pl, s_char *format, ...)
99 {
100     s_char buf[4096];
101     va_list ap;
102
103     if (pl->state != PS_PLAYING)
104         return;
105     va_start(ap, format);
106     (void)vsprintf(buf, format, ap);
107     va_end(ap);
108     pr_player(pl, C_FLASH, buf);
109     io_output(pl->iop, IO_NOWAIT);
110 }
111
112 void
113 pr_inform(struct player *pl, s_char *format, ...)
114 {
115     s_char buf[4096];
116     va_list ap;
117
118     if (pl->state != PS_PLAYING)
119         return;
120     va_start(ap, format);
121     (void)vsprintf(buf, format, ap);
122     va_end(ap);
123     pr_player(pl, C_INFORM, buf);
124     io_output(pl->iop, IO_NOWAIT);
125 }
126
127 void
128 pr_wall(s_char *format, ...)
129 {
130     s_char buf[4096];
131     struct player *p;
132     va_list ap;
133
134     va_start(ap, format);
135     (void)vsprintf(buf, format, ap);
136     va_end(ap);
137     for (p = player_next(0); p; p = player_next(p)) {
138         if (p->state != PS_PLAYING)
139             continue;
140         pr_player(p, C_FLASH, buf);
141         io_output(p->iop, IO_NOWAIT);
142     }
143 }
144
145 void
146 pr_player(struct player *pl, int id, s_char *buf)
147 {
148     register s_char *p;
149     register s_char *bp;
150     register int len;
151
152     bp = buf;
153     while (*bp != '\0') {
154         if (pl->curid != -1 && pl->curid != id) {
155             io_puts(pl->iop, "\n");
156             pl->curid = -1;
157         }
158         if (pl->curid == -1) {
159             outid(pl, id);
160         }
161         p = strchr(bp, '\n');
162         if (p != 0) {
163             len = (p - bp) + 1;
164             if (pl->command && (pl->command->c_flags & C_MOD))
165                 io_write(pl->iop, bp, len, IO_NOWAIT);
166             else
167                 io_write(pl->iop, bp, len, IO_WAIT);
168             bp += len;
169             pl->curid = -1;
170         } else {
171             len = io_puts(pl->iop, bp);
172             bp += len;
173         }
174     }
175 }
176
177 /*
178  * highlighted characters have hex 80 or'ed in
179  * with them to designate their highlightedness
180  */
181 void
182 pr_hilite(s_char *buf)
183 {
184     register s_char *bp;
185     register s_char c;
186     s_char *p;
187
188     p = (s_char *)malloc(strlen(buf) + 1);
189     strcpy(p, buf);
190     for (bp = p; 0 != (c = *bp); bp++)
191         if (isprint(c))
192             *bp |= 0x80;
193     pr(p);
194     free(p);
195 }
196
197 /*
198  * output hex code + space
199  */
200 static void
201 outid(struct player *pl, int n)
202 {
203     s_char c;
204     s_char buf[3];
205
206     if (n > C_LAST) {
207         logerror("outid: %d not valid code\n", n);
208         return;
209     }
210     if (n >= 10)
211         c = 'a' - 10 + n;
212     else
213         c = '0' + n;
214     buf[0] = c;
215     buf[1] = ' ';
216     buf[2] = '\0';
217     io_puts(pl->iop, buf);
218     pl->curid = n;
219 }
220
221 void
222 prredir(s_char *redir)
223 {
224     pr_id(player, *redir == '>' ? C_REDIR : C_PIPE, "%s\n", redir);
225 }
226
227 void
228 prexec(s_char *file)
229 {
230     pr_id(player, C_EXECUTE, "%s\n", file);
231 }
232
233 void
234 prprompt(int min, int btu)
235 {
236     pr_id(player, C_PROMPT, "%d %d\n", min, btu);
237 }
238
239 void
240 showvers(int vers)
241 {
242     pr_id(player, C_INIT, "%d\n", vers);
243 }
244
245 int
246 prmptrd(s_char *prompt, s_char *str, int size)
247 {
248     int r;
249
250     pr_id(player, C_FLUSH, "%s\n", prompt);
251     if ((r = recvclient(str, size)) < 0)
252         return r;
253     time(&player->curup);
254     if (*str == 0)
255         return 1;
256     return strlen(str);
257 }
258
259 void
260 prdate(void)
261 {
262     time_t now;
263
264     (void)time(&now);
265     pr(ctime(&now));
266 }
267
268 /*
269  * print x,y formatting as country
270  */
271 void
272 prxy(s_char *format, coord x, coord y, natid country)
273 {
274     s_char buf[255];
275     struct natstr *np;
276
277     np = getnatp(country);
278     sprintf(buf, format, xrel(np, x), yrel(np, y));
279     pr(buf);
280 }
281
282 /*VARARGS*/
283 void
284 PR(int cn, s_char *format, ...)
285 {
286     /* XXX should really do this on a per-nation basis */
287     static s_char longline[MAXNOC][512];
288     int newline;
289     va_list ap;
290     s_char buf[1024];
291
292     va_start(ap, format);
293     (void)vsprintf(buf, format, ap);
294     va_end(ap);
295     newline = strrchr(buf, '\n') ? 1 : 0;
296     strcat(longline[cn], buf);
297     if (newline) {
298         if (update_pending || (cn && cn != player->cnum))
299             typed_wu(0, cn, longline[cn], TEL_BULLETIN);
300         else
301             pr_player(player, C_DATA, longline[cn]);
302         longline[cn][0] = '\0';
303     }
304 }
305
306 void
307 PRdate(natid cn)
308 {
309     time_t now;
310
311     (void)time(&now);
312     PR(cn, ctime(&now));
313 }
314
315 void
316 pr_beep(void)
317 {
318     struct natstr *np = getnatp(player->cnum);
319
320     if (np->nat_flags & NF_BEEP)
321         pr("\07");
322 }
323
324 void
325 mpr(int cn, s_char *format, ...)
326 {
327     s_char buf[4096];
328     va_list ap;
329
330     va_start(ap, format);
331     (void)vsprintf(buf, format, ap);
332     va_end(ap);
333     if (cn) {
334         if (update_pending || cn != player->cnum)
335             typed_wu(0, cn, buf, TEL_BULLETIN);
336         else
337             pr_player(player, C_DATA, buf);
338     }
339 }