1 /* Pioneers - Implementation of the excellent Settlers of Catan board game.
2 * Go buy a copy.
3 *
4 * Copyright (C) 1999 Dave Cole
5 * Copyright (C) 2003 Bas Wijnen <shevek@fmf.nl>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "config.h"
23 #include <stdio.h>
24 #include <time.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include "log.h"
29 #include "driver.h"
30
31 static gboolean debug_enabled = FALSE;
32
33 /* The default function to use to write messages, when nothing else has been
34 * specified.
35 */
36 #define LOG_FUNC_DEFAULT log_message_string_console
37
log_set_func(LogFunc func)38 void log_set_func(LogFunc func)
39 {
40 if (func != NULL)
41 driver->log_write = func;
42 else
43 driver->log_write = LOG_FUNC_DEFAULT;
44 }
45
log_set_func_default(void)46 void log_set_func_default(void)
47 {
48 driver->log_write = LOG_FUNC_DEFAULT;
49 }
50
log_message_string_console(gint msg_type,const gchar * text)51 void log_message_string_console(gint msg_type, const gchar * text)
52 {
53 const gchar *prefix = NULL;
54
55 switch (msg_type) {
56 case MSG_ERROR:
57 /* Log prefix */
58 prefix = _("*ERROR* ");
59 break;
60 case MSG_INFO:
61 /* Log prefix for info message */
62 prefix = "- ";
63 break;
64 case MSG_CHAT:
65 /* Log prefix */
66 prefix = _("Chat: ");
67 break;
68 case MSG_RESOURCE:
69 /* Log prefix */
70 prefix = _("Resource: ");
71 break;
72 case MSG_BUILD:
73 /* Log prefix */
74 prefix = _("Build: ");
75 break;
76 case MSG_DICE:
77 /* Log prefix */
78 prefix = _("Dice: ");
79 break;
80 case MSG_STEAL:
81 /* Log prefix */
82 prefix = _("Steal: ");
83 break;
84 case MSG_TRADE:
85 /* Log prefix */
86 prefix = _("Trade: ");
87 break;
88 case MSG_DEVCARD:
89 /* Log prefix */
90 prefix = _("Development: ");
91 break;
92 case MSG_LARGESTARMY:
93 /* Log prefix */
94 prefix = _("Army: ");
95 break;
96 case MSG_LONGESTROAD:
97 /* Log prefix */
98 prefix = _("Road: ");
99 break;
100 case MSG_BEEP:
101 /* Log prefix */
102 prefix = _("*BEEP* ");
103 break;
104 case MSG_TIMESTAMP:
105 break; /* No prefix */
106 case MSG_PLAYER1:
107 /* Log prefix */
108 prefix = _("Player 1: ");
109 break;
110 case MSG_PLAYER2:
111 /* Log prefix */
112 prefix = _("Player 2: ");
113 break;
114 case MSG_PLAYER3:
115 /* Log prefix */
116 prefix = _("Player 3: ");
117 break;
118 case MSG_PLAYER4:
119 /* Log prefix */
120 prefix = _("Player 4: ");
121 break;
122 case MSG_PLAYER5:
123 /* Log prefix */
124 prefix = _("Player 5: ");
125 break;
126 case MSG_PLAYER6:
127 /* Log prefix */
128 prefix = _("Player 6: ");
129 break;
130 case MSG_PLAYER7:
131 /* Log prefix */
132 prefix = _("Player 7: ");
133 break;
134 case MSG_PLAYER8:
135 /* Log prefix */
136 prefix = _("Player 8: ");
137 break;
138 case MSG_SPECTATOR_CHAT:
139 /* Log prefix */
140 prefix = _("Spectator: ");
141 break;
142 default:
143 /* Log prefix */
144 prefix = _("** UNKNOWN MESSAGE TYPE ** ");
145 }
146
147 if (prefix)
148 fprintf(stderr, "%s%s", prefix, text);
149 else
150 fprintf(stderr, "%s", text);
151 }
152
debug_type(int type)153 static const char *debug_type(int type)
154 {
155 switch (type) {
156 case MSG_ERROR:
157 return "ERROR";
158 case MSG_INFO:
159 return "INFO";
160 case MSG_CHAT:
161 return "CHAT";
162 case MSG_RESOURCE:
163 return "RESOURCE";
164 case MSG_BUILD:
165 return "BUILD";
166 case MSG_DICE:
167 return "DICE";
168 case MSG_STEAL:
169 return "STEAL";
170 case MSG_TRADE:
171 return "TRADE";
172 case MSG_DEVCARD:
173 return "DEVCARD";
174 case MSG_LARGESTARMY:
175 return "LARGESTARMY";
176 case MSG_LONGESTROAD:
177 return "LONGESTROAD";
178 case MSG_BEEP:
179 return "BEEP";
180 case MSG_PLAYER1:
181 return "PLAYER1";
182 case MSG_PLAYER2:
183 return "PLAYER2";
184 case MSG_PLAYER3:
185 return "PLAYER3";
186 case MSG_PLAYER4:
187 return "PLAYER4";
188 case MSG_PLAYER5:
189 return "PLAYER5";
190 case MSG_PLAYER6:
191 return "PLAYER6";
192 case MSG_PLAYER7:
193 return "PLAYER7";
194 case MSG_PLAYER8:
195 return "PLAYER8";
196 case MSG_SPECTATOR_CHAT:
197 return "SPECTATOR_CHAT";
198 default:
199 return "*UNKNOWN MESSAGE TYPE*";
200 }
201 }
202
log_message_chat(const gchar * player_name,const gchar * joining_text,gint msg_type,const gchar * chat)203 void log_message_chat(const gchar * player_name,
204 const gchar * joining_text, gint msg_type,
205 const gchar * chat)
206 {
207 if (driver->log_write && driver->log_write != LOG_FUNC_DEFAULT) {
208 log_message(MSG_INFO, "%s%s", player_name, joining_text);
209 debug("[%s] %s", debug_type(msg_type), chat);
210
211 /* No timestamp here: */
212 driver->log_write(msg_type, chat);
213 driver->log_write(msg_type, "\n");
214 } else {
215 log_message(msg_type, "%s%s%s\n", player_name,
216 joining_text, chat);
217 }
218 }
219
log_message(gint msg_type,const gchar * fmt,...)220 void log_message(gint msg_type, const gchar * fmt, ...)
221 {
222 gchar *text;
223 gchar *timestamp;
224 va_list ap;
225 time_t t;
226 struct tm *alpha;
227
228 va_start(ap, fmt);
229 text = g_strdup_vprintf(fmt, ap);
230 va_end(ap);
231
232 debug("[%s] %s", debug_type(msg_type), text);
233
234 t = time(NULL);
235 alpha = localtime(&t);
236
237 timestamp = g_strdup_printf("%02d:%02d:%02d ", alpha->tm_hour,
238 alpha->tm_min, alpha->tm_sec);
239
240 if (driver->log_write) {
241 driver->log_write(MSG_TIMESTAMP, timestamp);
242 driver->log_write(msg_type, text);
243 } else {
244 LOG_FUNC_DEFAULT(MSG_TIMESTAMP, timestamp);
245 LOG_FUNC_DEFAULT(msg_type, text);
246 }
247 g_free(text);
248 g_free(timestamp);
249 }
250
set_enable_debug(gboolean enabled)251 void set_enable_debug(gboolean enabled)
252 {
253 debug_enabled = enabled;
254 }
255
debug(const gchar * fmt,...)256 void debug(const gchar * fmt, ...)
257 {
258 va_list ap;
259 gchar *buff;
260 gint idx;
261 time_t t;
262 struct tm *alpha;
263
264 if (!debug_enabled)
265 return;
266
267 va_start(ap, fmt);
268 buff = g_strdup_vprintf(fmt, ap);
269 va_end(ap);
270
271 t = time(NULL);
272 alpha = localtime(&t);
273
274 g_print("%02d:%02d:%02d ", alpha->tm_hour,
275 alpha->tm_min, alpha->tm_sec);
276
277 for (idx = 0; buff[idx] != '\0'; idx++) {
278 if (isprint(buff[idx]))
279 g_print("%c", buff[idx]);
280 else
281 switch (buff[idx]) {
282 case '\n':
283 g_print("\\n");
284 break;
285 case '\r':
286 g_print("\\r");
287 break;
288 case '\t':
289 g_print("\\t");
290 break;
291 default:
292 g_print("\\x%02x", (buff[idx] & 0xff));
293 break;
294 }
295 }
296 g_print("\n");
297 g_free(buff);
298 }
299