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