Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison pped/interface.c @ 2:2719a89505ba
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:01 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:4d6502ffaa5e | 2:2719a89505ba |
---|---|
1 /* | |
2 * interface.c | |
3 */ | |
4 | |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8 #include <signal.h> | |
9 #include <termios.h> | |
10 #include <sys/ioctl.h> | |
11 #include <time.h> | |
12 #include <struct.h> | |
13 #include <curses.h> | |
14 #include "common.h" | |
15 #include "db.h" | |
16 #include "interface.h" | |
17 #include "intfdesc.h" | |
18 #include "file.h" | |
19 #include "data.h" | |
20 | |
21 | |
22 static char *shrt_royal_names[] = { | |
23 "", | |
24 "Wes", | |
25 "Cen", | |
26 "Pra", | |
27 "Emp" | |
28 }; | |
29 | |
30 static char *royal_names[] = { | |
31 "none", | |
32 "Wesley", | |
33 "Centurion", | |
34 "Praetor", | |
35 "Emperor" | |
36 }; | |
37 | |
38 static char *shrt_rank_names[] = { | |
39 "Recr", "Spec", "Cadt", "Mids", "EnJr", "Ensi", "LtJr", | |
40 "Lieu", "LtCm", "Cmdr", "HiCm", "Capt", "FlCp", "Comd", | |
41 "Adml", "RAdm", "Moff", "GrMo" | |
42 }; | |
43 | |
44 static char *rank_names[] = { | |
45 "Recruit", "Specialist", "Cadet", "Midshipman", | |
46 "Ensn. Jr.", "Ensign", "Lt. Jnr. Gr.", "Lieutenant", | |
47 "Lt. Cmdr.", "Commander", "High Cmdr.", "Captain", | |
48 "Fleet Capt.", "Commodore", "Admiral", "Rear Adml.", | |
49 "Moff", "Grand Moff" | |
50 }; | |
51 | |
52 void getTTYinfo() | |
53 { | |
54 struct winsize ws; | |
55 char *name, bp[1024], area[1024], *ap = area; | |
56 | |
57 #ifdef SYSV | |
58 signal(SIGWINCH, getTTYinfo); | |
59 #endif | |
60 | |
61 /* determine # of lines */ | |
62 ioctl(0, TIOCGWINSZ, &ws); | |
63 numLines = ws.ws_row; | |
64 | |
65 /* find terminal sequence to clear the screen */ | |
66 if(name = getenv("TERM")) | |
67 if(tgetent(bp, name) > 0) | |
68 clrStr = tgetstr("cl", &ap); | |
69 } | |
70 | |
71 void cls() | |
72 { | |
73 printf("%s", clrStr); fflush(stdout); | |
74 } | |
75 | |
76 void Interface() | |
77 { | |
78 struct plnode *p, *pn; | |
79 int lines, top, i, num; | |
80 char buf[18], *c; | |
81 | |
82 top = 0; | |
83 for(;;) { | |
84 lines = numLines - 4; | |
85 if(lines < 5) err_fatal("not enough tty lines!"); | |
86 | |
87 cls(); | |
88 printf("\ | |
89 C # Rnk Ryl Name C # Rnk Ryl Name\n"); | |
90 printf("\ | |
91 - --- ---- ---- ----------------- - --- ---- ---- -----------------\n"); | |
92 | |
93 for(i = 0; i < lines; i++) { | |
94 if(top + i > numDBentries - 1) { | |
95 printf("\n"); | |
96 continue; | |
97 } | |
98 p = GetNode(top + i); | |
99 if(!p) { | |
100 printf("\n"); | |
101 continue; | |
102 } | |
103 strncpy(buf, p->player.name, 16); | |
104 strcat(buf, "_"); | |
105 printf(" %c%4d %-4s %-4s %-17.17s ", | |
106 p->status ? '*':' ', top + i, | |
107 shrt_rank_names[p->player.stats.st_rank], | |
108 shrt_royal_names[p->player.stats.st_royal], | |
109 Strip(buf)); | |
110 | |
111 if(top + i + lines > numDBentries - 1) { | |
112 printf("\n"); | |
113 continue; | |
114 } | |
115 p = GetNode(top + i + lines); | |
116 if(!p) { | |
117 printf("\n"); | |
118 continue; | |
119 } | |
120 strncpy(buf, p->player.name, 16); | |
121 strcat(buf, "_"); | |
122 printf(" %c%4d %-4s %-4s %s\n", | |
123 p->status ? '*':' ', top + i + lines, | |
124 shrt_rank_names[p->player.stats.st_rank], | |
125 shrt_royal_names[p->player.stats.st_royal], | |
126 Strip(buf)); | |
127 } | |
128 printf("\nIndex: Command (? for help) -->"); fflush(stdout); | |
129 if(fgets(buf, 18, stdin) == NULL) | |
130 continue; | |
131 | |
132 switch(buf[0]) { | |
133 case '\n': | |
134 case 'n': | |
135 top += (lines * 2); | |
136 if(top >= numDBentries) | |
137 top = 0; | |
138 break; | |
139 case 'p': | |
140 if(!top) { | |
141 if(numDBentries - 2 * lines > 0) | |
142 top = numDBentries - 2 * lines; | |
143 else | |
144 top = 0; | |
145 } else { | |
146 top -= (lines * 2); | |
147 if(top < 0) top = 0; | |
148 } | |
149 break; | |
150 case 'Q': | |
151 GoAway(CheckChanged()); | |
152 break; | |
153 case 's': | |
154 DoSave(1); | |
155 break; | |
156 case 'e': | |
157 printf("Enter player name to edit -->"); | |
158 fflush(stdout); | |
159 if(fgets(buf, 18, stdin) == NULL) | |
160 break; | |
161 if(c = strrchr(buf, '\n')) | |
162 *c = (char)0; | |
163 num = GetByName(buf); | |
164 if(num < 0) { | |
165 Report("Couldn't find any players by that name."); | |
166 break; | |
167 } | |
168 Edit(num); | |
169 break; | |
170 case '?': | |
171 Report("\n\ | |
172 [num] : Edit player [num]\n\ | |
173 e : Edit player (by name)\n\ | |
174 n : Next page\n\ | |
175 [ret] : Next page\n\ | |
176 p : Previous page\n\ | |
177 s : Save to file\n\ | |
178 Q : Quit pped\n"); | |
179 break; | |
180 default: | |
181 i = sscanf(buf, "%d", &num); | |
182 if(!i || (num < 0) || (num >= numDBentries)) | |
183 break; | |
184 Edit(num); | |
185 } | |
186 } | |
187 } | |
188 | |
189 void Edit(int pnum) | |
190 { | |
191 struct plnode *p, player; | |
192 char buf[18], txt[80]; | |
193 int i, num, lines, top; | |
194 | |
195 p = GetNode(pnum); | |
196 if(!p) return; | |
197 player = *p; | |
198 player.status = 0; | |
199 | |
200 top = 0; | |
201 | |
202 for(;;) { | |
203 lines = numLines - 2; | |
204 cls(); | |
205 Display(&player, top, top+lines); | |
206 | |
207 printf("\nEdit: Command (? for help) -->"); fflush(stdout); | |
208 if(fgets(buf, 18, stdin) == NULL) | |
209 continue; | |
210 | |
211 switch(buf[0]) { | |
212 case '?': /* help */ | |
213 Report("\n\ | |
214 n : Next page\n\ | |
215 p : Previous page\n\ | |
216 [num] : Change value [num]\n\ | |
217 s : Save and return to index\n\ | |
218 w : Save\n\ | |
219 [ret] : Return to index, don't save\n\ | |
220 x : Same as [ret]\n\ | |
221 D : Delete this entry and return to index\n\ | |
222 r : Revert (undo changes since last save)\n\ | |
223 Q : Quit pped\n"); | |
224 break; | |
225 | |
226 case 'n': /* page forward */ | |
227 top += lines; | |
228 if(top > NUMDESC + 1) top = 0; | |
229 continue; | |
230 | |
231 case 'p': /* page backward */ | |
232 top -= lines; | |
233 if(top < 0) top = 0; | |
234 continue; | |
235 | |
236 case 'D': /* delete (and exit) */ | |
237 sprintf(txt, "delete entry for player %s", p->player.name); | |
238 if(Verify(txt)) { | |
239 DeleteNode(pnum); | |
240 Report("Player deleted."); | |
241 return; | |
242 } else { | |
243 Report("Canceled."); | |
244 } | |
245 break; | |
246 | |
247 case 'Q': /* quit */ | |
248 GoAway(player.status || CheckChanged()); | |
249 break; | |
250 | |
251 case 's': /* save and exit */ | |
252 if(player.status) { | |
253 *p = player; | |
254 player.status = 0; | |
255 Report("Player saved."); | |
256 } | |
257 return; | |
258 break; | |
259 | |
260 case 'w': /* save */ | |
261 if(player.status) { | |
262 *p = player; | |
263 player.status = 0; | |
264 Report("Player saved."); | |
265 } else { | |
266 Report("No changes to save."); | |
267 } | |
268 break; | |
269 | |
270 case 'r': /* revert */ | |
271 if(player.status) { | |
272 sprintf(txt, "undo changes for player %s?", p->player.name); | |
273 if(Verify(txt)) { | |
274 player = *p; | |
275 player.status = 0; | |
276 Report("Changes discarded."); | |
277 } else { | |
278 Report("Canceled."); | |
279 } | |
280 } else { | |
281 Report("No changes to undo."); | |
282 } | |
283 break; | |
284 | |
285 case 0x1B: /* (escape) exit, no changes */ | |
286 case '\n': | |
287 case 'x': | |
288 if(player.status) | |
289 if(!Verify("exit? There are unsaved changes.")) | |
290 break; | |
291 return; | |
292 | |
293 default: | |
294 i = sscanf(buf, "%d", &num); | |
295 if(!i || (num < 0) || (num >= NUMDESC)) | |
296 break; | |
297 Change(num, &player); | |
298 } | |
299 } | |
300 } | |
301 | |
302 int Verify(char *str) | |
303 { | |
304 char buffer[18]; | |
305 | |
306 for(;;) { | |
307 printf("Verify %s (y/n) -->", str); fflush(stdout); | |
308 if(fgets(buffer, 18, stdin) == NULL) | |
309 continue; | |
310 switch(buffer[0]) { | |
311 case 'Y': | |
312 case 'y': | |
313 return 1; | |
314 case 'N': | |
315 case 'n': | |
316 return 0; | |
317 } | |
318 } | |
319 } | |
320 | |
321 void Report(char *str) | |
322 { | |
323 char buffer[18]; | |
324 | |
325 printf("%s\n", str); | |
326 printf("Press return to continue -->"); fflush(stdout); | |
327 | |
328 fgets(buffer, 18, stdin); | |
329 } | |
330 | |
331 void Change(int num, struct plnode *p) | |
332 { | |
333 struct inter_desc *it; | |
334 void *ptr; | |
335 char str16[16], *c; | |
336 char buffer[80]; | |
337 int intnum, i, col; | |
338 float floatnum; | |
339 | |
340 if(num < 0 || num >= NUMDESC) return; | |
341 it = &idesc_tab[num]; | |
342 | |
343 ptr = (void *)((int)(&p->player) + it->offset); | |
344 | |
345 switch(it->type) { | |
346 case DT_CHAR16: | |
347 printf("Current value for %s: \"%s\"\n", it->name, (char *)ptr); | |
348 printf("Enter new value -->"); fflush(stdout); | |
349 str16[0] = 0; | |
350 fgets(str16, 16, stdin); | |
351 if(c = strrchr(str16, '\n')) | |
352 *c = (char)0; | |
353 | |
354 sprintf(buffer, "\"%s\" as new value for %s.", str16, it->name); | |
355 if(Verify(buffer)) { | |
356 if(strncmp((char *)ptr, str16, 16)) { | |
357 strncpy((char *)ptr, str16, 16); | |
358 p->status = 1; /* something changed */ | |
359 } | |
360 } | |
361 break; | |
362 | |
363 case DT_INT: | |
364 case DT_TICKS: | |
365 printf("Current value for %s: %d\n", it->name, *((int *)ptr)); | |
366 printf("Enter new value -->"); fflush(stdout); | |
367 fgets(buffer, 30, stdin); | |
368 intnum = atoi(buffer); | |
369 sprintf(buffer, "%d as new value for %s.", intnum, it->name); | |
370 if(Verify(buffer)) { | |
371 if(intnum != *((int *)ptr)) { | |
372 *((int *)ptr) = intnum; | |
373 p->status = 1; | |
374 } | |
375 } | |
376 break; | |
377 | |
378 case DT_FLOAT: | |
379 printf("Current value for %s: %f\n", it->name, *((float *)ptr)); | |
380 printf("Enter new value -->"); fflush(stdout); | |
381 fgets(buffer, 30, stdin); | |
382 floatnum = (float)atof(buffer); | |
383 sprintf(buffer, "%f as new value for %s.", floatnum, it->name); | |
384 if(Verify(buffer)) { | |
385 if(floatnum != *((float *)ptr)) { | |
386 *((float *)ptr) = floatnum; | |
387 p->status = 1; | |
388 } | |
389 } | |
390 break; | |
391 | |
392 case DT_RANK: | |
393 for(i = 0, col = 0; i < NUMRANKS; i++) { | |
394 printf(" %2d: %-7s ", i, shrt_rank_names[i]); | |
395 if(++col == 4) { | |
396 printf("\n"); | |
397 col = 0; | |
398 } | |
399 } | |
400 printf("\nCurrent value for %s: %d (%s)\n", it->name, | |
401 *((int *)ptr), rank_names[*((int *)ptr)]); | |
402 printf("Enter new value -->"); fflush(stdout); | |
403 fgets(buffer, 30, stdin); | |
404 intnum = atoi(buffer); | |
405 sprintf(buffer, "%d (%s) as new value for %s.", intnum, | |
406 rank_names[intnum], it->name); | |
407 if(Verify(buffer)) { | |
408 if(intnum != *((int *)ptr)) { | |
409 *((int *)ptr) = intnum; | |
410 p->status = 1; | |
411 } | |
412 } | |
413 break; | |
414 | |
415 case DT_ROYAL: | |
416 for(i = 0; i < NUMROYALRANKS; i++) | |
417 printf(" %2d: %s\n", i, royal_names[i]); | |
418 | |
419 printf("Current value for %s: %d (%s)\n", it->name, | |
420 *((int *)ptr), royal_names[*((int *)ptr)]); | |
421 printf("Enter new value -->"); fflush(stdout); | |
422 fgets(buffer, 30, stdin); | |
423 intnum = atoi(buffer); | |
424 sprintf(buffer, "%d (%s) as new value for %s.", intnum, | |
425 royal_names[intnum], it->name); | |
426 if(Verify(buffer)) { | |
427 if(intnum != *((int *)ptr)) { | |
428 *((int *)ptr) = intnum; | |
429 p->status = 1; | |
430 } | |
431 } | |
432 break; | |
433 default: | |
434 Report("Error in case statement in Change()"); | |
435 break; | |
436 } | |
437 } | |
438 | |
439 void Display(struct plnode *n, int from, int to) | |
440 { | |
441 int i, hour, dt = 0; | |
442 char c; | |
443 void *ptr; | |
444 struct inter_desc *it; | |
445 struct tm *stm; | |
446 time_t tt; | |
447 | |
448 if(to > NUMDESC) { | |
449 to = NUMDESC; | |
450 dt = 1; | |
451 } | |
452 | |
453 for(i = from; i < to; i++) { | |
454 it = &idesc_tab[i]; | |
455 ptr = (void *)((int)(&n->player) + it->offset); | |
456 | |
457 switch(it->type) { | |
458 case DT_CHAR16: | |
459 printf(" (%2d) %16s : \"%s\"\n", i, it->name, (char *)ptr); | |
460 break; | |
461 case DT_INT: | |
462 printf(" (%2d) %16s : %d\n", i, it->name, *((int *)ptr)); | |
463 break; | |
464 case DT_FLOAT: | |
465 printf(" (%2d) %16s : %.2f\n", i, it->name, *((float *)ptr)); | |
466 break; | |
467 case DT_TICKS: | |
468 printf(" (%2d) %16s : %d (%.2f hours)\n", | |
469 i, it->name, *((int *)ptr), (*((int *)ptr))/36000.0); | |
470 break; | |
471 case DT_RANK: | |
472 printf(" (%2d) %16s : %d (%s)\n", i, it->name, *((int *)ptr), | |
473 rank_names[*((int *)ptr)]); | |
474 break; | |
475 case DT_ROYAL: | |
476 printf(" (%2d) %16s : %d (%s)\n", i, it->name, *((int *)ptr), | |
477 royal_names[*((int *)ptr)]); | |
478 break; | |
479 default: | |
480 printf("Yikes! Unknown it->type in Display()\n"); | |
481 break; | |
482 } | |
483 } | |
484 if(dt) { | |
485 tt = n->player.stats.st_lastlogin; | |
486 stm = localtime(&tt); | |
487 hour = stm->tm_hour; | |
488 c = 'A'; | |
489 if(!hour) { | |
490 hour = 12; | |
491 } else if(hour > 12) { | |
492 hour -= 12; | |
493 c = 'P'; | |
494 } | |
495 printf(" Last login: %2d:%02d %cM %02d/%02d/%d\n", | |
496 hour, stm->tm_min, c, stm->tm_mon+1, stm->tm_mday, stm->tm_year); | |
497 } | |
498 } | |
499 | |
500 int CheckChanged() | |
501 { | |
502 struct plnode *p; | |
503 | |
504 if(dbDirty) return(1); | |
505 | |
506 p = firstEnt; | |
507 while(p) { | |
508 if(p->status) return(1); | |
509 p = p->next; | |
510 } | |
511 return(0); | |
512 } | |
513 | |
514 void ClearChanged() | |
515 { | |
516 struct plnode *p; | |
517 | |
518 dbDirty = 0; | |
519 | |
520 p = firstEnt; | |
521 while(p) { | |
522 p->status = 0; | |
523 p = p->next; | |
524 } | |
525 } | |
526 | |
527 /* Strip: convert non-printable control chars to ^L notation */ | |
528 char *Strip(char *str) | |
529 { | |
530 static char buff[36], *o; | |
531 | |
532 o = buff; | |
533 while(*str) { | |
534 *str &= 0x7f; | |
535 if((int)*str < (int)' ') { | |
536 *o++ = '^'; | |
537 *o++ = *str + (char)64; | |
538 } else if ((int)*str == 127) { | |
539 *o++ = '^'; | |
540 *o++ = '?'; | |
541 } else { | |
542 *o++ = *str; | |
543 } | |
544 str++; | |
545 } | |
546 *o = 0; | |
547 return(buff); | |
548 } | |
549 |