Galactic Bloodshed
tele.cc
Go to the documentation of this file.
1 // Copyright 2014 The Galactic Bloodshed Authors. All rights reserved.
2 // Use of this source code is governed by a license that can be
3 // found in the COPYING file.
4 
5 #include "gb/tele.h"
6 
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 
11 #include <climits>
12 #include <cstdio>
13 #include <cstring>
14 #include <ctime>
15 
16 #include "gb/GB_server.h"
17 #include "gb/buffers.h"
18 #include "gb/files.h"
19 #include "gb/files_shl.h"
20 #include "gb/races.h"
21 #include "gb/tweakables.h"
22 #include "gb/vars.h"
23 
24 static long tm;
25 static FILE *teleg_read_fd;
26 static char telegram_file[PATHLEN];
27 static struct stat telestat;
28 
29 static struct tm *current_tm; /* for watching for next update */
30 
31 /*
32  * purge:
33  *
34  * arguments: none
35  *
36  * called by: process_commands
37  *
38  * description: Used to purge the News files.
39  *
40  */
41 void purge() {
42  fclose(fopen(DECLARATIONFL, "w+"));
43  newslength[0] = 0;
44  fclose(fopen(COMBATFL, "w+"));
45  newslength[1] = 0;
46  fclose(fopen(ANNOUNCEFL, "w+"));
47  newslength[2] = 0;
48  fclose(fopen(TRANSFERFL, "w+"));
49  newslength[3] = 0;
50 }
51 
52 /*
53  * post:
54  *
55  * arguments: msg The actual message type Type of message. Valid types are
56  * DECLARATION, TRANSFER, COMBAT and ANNOUNCE.
57  *
58  * called by: fire, name, declare, dock, land, dissolve, doship, doturn
59  *
60  * description: does the acutal posting of messages to the news files
61  *
62  */
63 void post(const char *origmsg, int type) {
64  const char *telefl;
65 
66  switch (type) {
67  case DECLARATION:
68  telefl = DECLARATIONFL;
69  break;
70  case TRANSFER:
71  telefl = TRANSFERFL;
72  break;
73  case COMBAT:
74  telefl = COMBATFL;
75  break;
76  case ANNOUNCE:
77  telefl = ANNOUNCEFL;
78  break;
79  default:
80  return;
81  }
82 
83  char *fixmsg = strdupa(origmsg);
84  char *p;
85  /* look for special symbols */
86  for (p = fixmsg; *p; p++) {
87  if (*p == ';')
88  *p = '\n';
89  else if (*p == '|')
90  *p = '\t';
91  }
92 
93  FILE *news_fd;
94  if ((news_fd = fopen(telefl, "a")) == nullptr) {
95  return;
96  }
97  tm = time(nullptr);
98  current_tm = localtime(&tm);
99  char *outbuf;
100  asprintf(&outbuf, "%2d/%2d %02d:%02d:%02d %s", current_tm->tm_mon + 1,
101  current_tm->tm_mday, current_tm->tm_hour, current_tm->tm_min,
102  current_tm->tm_sec, fixmsg);
103  fprintf(news_fd, "%s", outbuf);
104  fclose(news_fd);
105  newslength[type] += strlen(outbuf);
106  free(outbuf);
107 }
108 
109 /*
110  * push_telegram_race:
111  *
112  * arguments: recpient msg
113  *
114  * called by:
115  *
116  * description: Sends a message to everyone in the race
117  *
118  */
119 void push_telegram_race(const player_t recipient, const std::string &msg) {
120  racetype *Race;
121  int j;
122 
123  Race = races[recipient - 1];
124  for (j = 0; j <= MAXGOVERNORS; j++)
125  if (Race->governor[j].active) push_telegram(recipient, j, msg);
126 }
127 
128 /*
129  * push_telegram:
130  *
131  * arguments: recpient gov msg
132  *
133  * called by:
134  *
135  * description: Sends a message to everyone from person to person
136  *
137  */
138 void push_telegram(const player_t recipient, const governor_t gov,
139  const std::string &msg) {
140  char telefl[100];
141  FILE *telegram_fd;
142 
143  bzero((char *)telefl, sizeof(telefl));
144  sprintf(telefl, "%s.%d.%d", TELEGRAMFL, recipient, gov);
145 
146  if ((telegram_fd = fopen(telefl, "a")) == nullptr)
147  if ((telegram_fd = fopen(telefl, "w+")) == nullptr) {
148  perror("tele");
149  return;
150  }
151  tm = time(nullptr);
152  current_tm = localtime(&tm);
153 
154  fprintf(telegram_fd, "%2d/%2d %02d:%02d:%02d %s\n", current_tm->tm_mon + 1,
155  current_tm->tm_mday, current_tm->tm_hour, current_tm->tm_min,
156  current_tm->tm_sec, msg.c_str());
157  fclose(telegram_fd);
158 }
159 /*
160  * * read_teleg.c -- (try to) read telegrams * the first byte in
161  * each telegram is the sending player #, or 254 * to denote
162  * autoreport. then the time sent, then the message itself, * terminated
163  * by TELEG_DELIM.
164  */
165 /*
166  * teleg_read:
167  *
168  * arguments: Playernum Governor
169  *
170  * called by: process_commands
171  *
172  * description: Read the telegrams for the player. The first byte in each
173  * telegram is the sending player number or 254 to denote an autoreport.
174  * Then the time send, then the message, then terminated by TELEG_DELIM
175  */
176 void teleg_read(GameObj &g) {
177  player_t Playernum = g.player;
178  governor_t Governor = g.governor;
179  char *p;
180 
181  bzero((char *)telegram_file, sizeof(telegram_file));
182  sprintf(telegram_file, "%s.%d.%d", TELEGRAMFL, Playernum, Governor);
183 
184  if ((teleg_read_fd = fopen(telegram_file, "r")) != nullptr) {
185  g.out << "Telegrams:";
186  stat(telegram_file, &telestat);
187  if (telestat.st_size > 0) {
188  g.out << "\n";
189  while (fgets(buf, sizeof buf, teleg_read_fd)) {
190  for (p = buf; *p; p++)
191  if (*p == '\n') {
192  *p = '\0';
193  break;
194  }
195  strcat(buf, "\n");
196  notify(Playernum, Governor, buf);
197  }
198  } else {
199  g.out << " None.\n";
200  }
201 
202  fclose(teleg_read_fd);
203  teleg_read_fd = fopen(telegram_file, "w+"); /* trunc file */
204  fclose(teleg_read_fd);
205  } else {
206  sprintf(buf, "\nTelegram file %s non-existent.\n", telegram_file);
207  notify(Playernum, Governor, buf);
208  return;
209  }
210 }
211 /*
212  * news_read:
213  *
214  * arguments: Playernum Governor Type
215  *
216  * description: Read the news file
217  *
218  */
219 void news_read(int Playernum, int Governor, int type) {
220  char *p;
221  racetype *Race;
222 
223  bzero((char *)telegram_file, sizeof(telegram_file));
224  switch (type) {
225  case DECLARATION:
226  sprintf(telegram_file, "%s", DECLARATIONFL);
227  break;
228  case TRANSFER:
229  sprintf(telegram_file, "%s", TRANSFERFL);
230  break;
231  case COMBAT:
232  sprintf(telegram_file, "%s", COMBATFL);
233  break;
234  case ANNOUNCE:
235  sprintf(telegram_file, "%s", ANNOUNCEFL);
236  break;
237  default:
238  return;
239  }
240 
241  if ((teleg_read_fd = fopen(telegram_file, "r")) != nullptr) {
242  Race = races[Playernum - 1];
243  if (Race->governor[Governor].newspos[type] > newslength[type])
244  Race->governor[Governor].newspos[type] = 0;
245 
246  fseek(teleg_read_fd, Race->governor[Governor].newspos[type] & LONG_MAX,
247  SEEK_SET);
248  while (fgets(buf, sizeof buf, teleg_read_fd)) {
249  for (p = buf; *p; p++)
250  if (*p == '\n') {
251  *p = '\0';
252  break;
253  }
254  strcat(buf, "\n");
255  notify(Playernum, Governor, buf);
256  }
257 
258  fclose(teleg_read_fd);
259  Race->governor[Governor].newspos[type] = newslength[type];
260  putrace(Race);
261  } else {
262  sprintf(buf, "\nNews file %s non-existent.\n", telegram_file);
263  notify(Playernum, Governor, buf);
264  return;
265  }
266 }
267 
268 /**
269  * \brief Check for telegrams and notify the player if there is any.
270  * \arg g Game object
271  */
272 void check_for_telegrams(GameObj &g) {
273  std::string filename = std::string(TELEGRAMFL) + '.' +
274  std::to_string(g.player) + '.' +
275  std::to_string(g.governor);
276  struct stat sbuf;
277  std::memset(&sbuf, 0, sizeof(sbuf));
278  stat(filename.c_str(), &sbuf);
279  if (sbuf.st_size != 0) {
280  g.out << "You have telegram(s) waiting. Use 'read' to read them.\n";
281  }
282 }
void teleg_read(GameObj &g)
Definition: tele.cc:176
#define TRANSFERFL
Definition: files.h:39
void post(const char *origmsg, int type)
Definition: tele.cc:63
#define MAXGOVERNORS
Definition: tweakables.h:312
void push_telegram_race(const player_t recipient, const std::string &msg)
Definition: tele.cc:119
#define TRANSFER
Definition: files.h:18
static struct tm * current_tm
Definition: tele.cc:29
#define PATHLEN
Definition: files.h:14
#define ANNOUNCEFL
Definition: files.h:41
#define ANNOUNCE
Definition: files.h:20
void news_read(int Playernum, int Governor, int type)
Definition: tele.cc:219
void check_for_telegrams(GameObj &g)
Check for telegrams and notify the player if there is any.
Definition: tele.cc:272
#define COMBATFL
Definition: files.h:40
#define DECLARATION
Definition: files.h:17
static FILE * teleg_read_fd
Definition: tele.cc:25
void push_telegram(const player_t recipient, const governor_t gov, const std::string &msg)
Definition: tele.cc:138
void purge()
Definition: tele.cc:41
static char telegram_file[PATHLEN]
Definition: tele.cc:26
#define COMBAT
Definition: files.h:19
static long tm
Definition: tele.cc:24
#define TELEGRAMFL
Definition: files.h:35
void putrace(Race *r)
Definition: files_shl.cc:808
static struct stat telestat
Definition: tele.cc:27
#define DECLARATIONFL
Definition: files.h:38