68 #define NUM_TEXT_VIEWS 2
116 #define MESSAGE_BUFFER_COUNT 10
120 #define MESSAGE_BUFFER_SIZE 56
124 #define COUNT_BUFFER_SIZE 16
129 #define MESSAGE_COUNT_MAX 16
134 #define MESSAGE_AGE_MAX 16
148 struct info_buffer_t {
276 {
"Books", FALSE, { TRUE, FALSE } },
277 {
"Cards", FALSE, { TRUE, FALSE } },
278 {
"Paper", FALSE, { TRUE, FALSE } },
279 {
"Signs & Magic Mouths", FALSE, { TRUE, FALSE } },
280 {
"Monuments", FALSE, { TRUE, FALSE } },
281 {
"Dialogs (Altar/NPC/Magic Ear)" , FALSE, { TRUE, FALSE } },
282 {
"Message of the day", FALSE, { TRUE, FALSE } },
283 {
"Administrative", FALSE, { TRUE, FALSE } },
284 {
"Shops", TRUE, { TRUE, FALSE } },
285 {
"Command responses", FALSE, { TRUE, FALSE } },
286 {
"Changes to attributes", TRUE, { TRUE, TRUE } },
287 {
"Skill-related messages", TRUE, { TRUE, FALSE } },
288 {
"Apply results", TRUE, { TRUE, FALSE } },
289 {
"Attack results", TRUE, { TRUE, FALSE } },
290 {
"Player communication", FALSE, { TRUE, TRUE } },
291 {
"Spell results", TRUE, { TRUE, FALSE } },
292 {
"Item information", TRUE, { TRUE, FALSE } },
293 {
"Miscellaneous", TRUE, { TRUE, FALSE } },
294 {
"Victim notification", FALSE, { TRUE, TRUE } },
295 {
"Client-generated messages", FALSE, { TRUE, FALSE } }
319 g_object_set(tag,
"foreground-set", FALSE, NULL);
320 g_object_set(tag,
"background-set", FALSE, NULL);
321 g_object_set(tag,
"font-desc", NULL, NULL);
324 &style->fg[GTK_STATE_NORMAL],
325 &base_style->fg[GTK_STATE_NORMAL],
329 g_object_set(tag,
"foreground-gdk", &style->fg[GTK_STATE_NORMAL], NULL);
333 &style->bg[GTK_STATE_NORMAL],
334 &base_style->bg[GTK_STATE_NORMAL],
338 g_object_set(tag,
"background-gdk", &style->bg[GTK_STATE_NORMAL], NULL);
341 if (style->font_desc != base_style->font_desc) {
342 g_object_set(tag,
"font-desc", style->font_desc, NULL);
380 "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
384 "italic",
"style", PANGO_STYLE_ITALIC, NULL);
388 "underline",
"underline", PANGO_UNDERLINE_SINGLE, NULL);
398 gtk_text_buffer_create_tag(pane->
textbuffer,
"default", NULL);
423 gtk_rc_get_style_by_paths(
424 gtk_settings_get_default(), NULL, style_name, G_TYPE_NONE);
429 gtk_text_buffer_create_tag(
436 gtk_text_tag_table_remove(
437 gtk_text_buffer_get_tag_table(
447 gtk_rc_get_style_by_paths(
448 gtk_settings_get_default(),
454 gtk_text_buffer_create_tag(
458 pane->
font_tags[i], tmp_style, base_style);
461 gtk_text_tag_table_remove(
462 gtk_text_buffer_get_tag_table(pane->
textbuffer),
472 gtk_text_tag_table_remove(
473 gtk_text_buffer_get_tag_table(
481 gtk_text_tag_table_remove(
482 gtk_text_buffer_get_tag_table(
503 GtkStyle *tmp_style, *base_style;
517 for (i = 0; i <
sizeof(msg_type_names) /
sizeof(
Msg_Type_Names); i++) {
528 base_style = gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,
529 "info_default", G_TYPE_NONE);
532 "Unable to find base style info_default"
533 " - will not process most info tag styles!");
549 for (i = 0; i <
sizeof(msg_type_names) /
sizeof(
Msg_Type_Names); i++) {
553 snprintf(style_name,
sizeof(style_name),
554 "msg_%s", msg_type_names[i].style_name);
555 type = msg_type_names[i].type;
556 subtype = msg_type_names[i].subtype;
559 gtk_rc_get_style_by_paths(
560 gtk_settings_get_default(), NULL, style_name, G_TYPE_NONE);
569 if (!
info_pane[j].msg_type_tags[type][subtype]) {
571 gtk_text_buffer_create_tag(
575 info_pane[j].msg_type_tags[type][subtype],
576 tmp_style, base_style);
583 if (
info_pane[j].msg_type_tags[type][subtype]) {
584 gtk_text_tag_table_remove(
585 gtk_text_buffer_get_tag_table(
587 info_pane[j].msg_type_tags[type][subtype]);
604 for (i = 0; i <
sizeof(msg_type_names) /
sizeof(
Msg_Type_Names); i++) {
607 type = msg_type_names[i].type;
608 subtype = msg_type_names[i].subtype;
611 if (
info_pane[j].msg_type_tags[type][subtype]) {
612 gtk_text_tag_table_remove(
613 gtk_text_buffer_get_tag_table(
615 info_pane[j].msg_type_tags[type][subtype]);
639 snprintf(widget_name,
MAX_BUF,
"textview_info%d", i+1);
641 GTK_WIDGET(gtk_builder_get_object(
window_xml, widget_name));
643 snprintf(widget_name,
MAX_BUF,
"scrolledwindow_textview%d", i+1);
646 GTK_WIDGET(gtk_builder_get_object(
window_xml, widget_name));
648 gtk_text_view_set_wrap_mode(
649 GTK_TEXT_VIEW(
info_pane[i].textview), GTK_WRAP_WORD_CHAR);
652 gtk_text_view_get_buffer(GTK_TEXT_VIEW(
info_pane[i].textview));
655 gtk_scrolled_window_get_vadjustment(
656 GTK_SCROLLED_WINDOW(
info_pane[i].scrolled_window));
658 gtk_text_buffer_get_end_iter(
info_pane[i].textbuffer, &end);
661 gtk_text_buffer_create_mark(
662 info_pane[i].textbuffer, NULL, &end, FALSE);
664 gtk_widget_realize(
info_pane[i].textview);
694 int type,
int subtype,
695 int bold,
int italic,
696 int font,
const char *color,
int underline)
700 int scroll_to_end=0, color_num;
701 GtkTextTag *color_tag=NULL, *type_tag=NULL;
714 for (color_num = 0; color_num <
NUM_COLORS; color_num++)
745 || type < 0 || subtype < 0 ) {
747 "type (%d) >= MSG_TYPE_LAST (%d) or "
748 "subtype (%d) >= max_subtype (%d)\n",
758 gtk_text_view_get_visible_rect(
759 GTK_TEXT_VIEW(pane->
textview), &rect);
766 (gtk_adjustment_get_value(pane->
adjustment) + rect.height) >=
771 gtk_text_buffer_get_end_iter(pane->
textbuffer, &end);
773 gtk_text_buffer_insert_with_tags(
774 pane->
textbuffer, &end, message, strlen(message),
780 color_tag, type_tag, NULL);
783 gtk_text_view_scroll_mark_onscreen(
804 char *marker, *current, *original;
805 int bold=0, italic=0, font=0, underline=0;
806 const char *color=NULL;
811 current = g_strdup(message);
825 "Passed invalid color from server: %d, max allowed is %d\n",
836 while ((marker = strchr(current,
'[')) != NULL) {
839 if (strlen(current) > 0)
841 bold, italic, font, color, underline);
843 current = marker + 1;
845 if ((marker = strchr(current,
']')) == NULL) {
851 if (!strcmp(current,
"b")) {
853 }
else if (!strcmp(current,
"/b")) {
855 }
else if (!strcmp(current,
"i")) {
857 }
else if (!strcmp(current,
"/i")) {
859 }
else if (!strcmp(current,
"ul")) {
861 }
else if (!strcmp(current,
"/ul")) {
863 }
else if (!strcmp(current,
"fixed")) {
865 }
else if (!strcmp(current,
"arcane")) {
867 }
else if (!strcmp(current,
"hand")) {
869 }
else if (!strcmp(current,
"strange")) {
871 }
else if (!strcmp(current,
"print")) {
873 }
else if (!strcmp(current,
"/color")) {
875 }
else if (!strncmp(current,
"color=", 6)) {
879 "unrecognized tag: [%s]\n", current);
881 current = marker + 1;
885 pane, current, type, subtype,
886 bold, italic, font, color, underline);
889 pane,
"\n", type, subtype,
890 bold, italic, font, color, underline);
915 void draw_ext_info(
int orig_color,
int type,
int subtype,
const char *message)
923 const char *draw = NULL;
928 stamp = calloc(1, strlen(message) + 7);
929 curtime = time(NULL);
930 ltime = localtime(&curtime);
931 strftime(stamp, 6,
"%I:%M", ltime);
933 strcat(stamp, message);
947 "Invalid message type: %d", type);
1035 snprintf(output_buffer,
sizeof(output_buffer),
"%u times %s",
1104 char *editor = getenv(
"CF_MAP_EDITOR");
1105 if (editor == NULL) {
1106 LOG(
LOG_ERROR,
"mapedit",
"CF_MAP_EDITOR is not defined");
1109 LOG(
LOG_INFO,
"mapedit",
"Launching map editor on '%s'", path);
1110 char *argv[] = {editor, path, NULL};
1112 if (!g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, &err)) {
1113 LOG(
LOG_ERROR,
"mapedit",
"Could not launch CF_MAP_EDITOR: %s", err->message);
1169 char *msg_cpy = strdup(message);
1170 char *ptr = msg_cpy;
1171 ptr = strtok(ptr,
")");
1173 ptr = strtok(ptr,
"(");
1174 ptr = strtok(NULL,
"(");
1178 LOG(
LOG_INFO,
"mapedit",
"Could not parse map path from '%s'", message);
1240 if (! strcmp(message,
info_buffer[search].message)) {
1248 "type: %d-%d empty: %d found: %d oldest: %d oldest_age: %d",
1249 type, subtype, empty, found, oldest, oldest_age);
1283 "Buffer full; oldest unknown", strlen(message));
1331 gtk_text_buffer_set_text(
info_pane[i].textbuffer,
"", 0);
1347 GtkTableChild* child;
1366 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1371 GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_spinbutton_count"));
1374 GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_spinbutton_timer"));
1388 gtk_table_get_size(table, &title_rows, &title_cols);
1406 gtk_table_resize(table,
1418 row = type + title_rows;
1425 gtk_misc_set_alignment(GTK_MISC(widget), 0.0f, 0.5f);
1426 gtk_misc_set_padding(GTK_MISC(widget), 2, 0);
1427 gtk_table_attach_defaults(table, widget, 0, 1, row, row + 1);
1428 gtk_widget_show(widget);
1434 gtk_table_attach_defaults(
1448 gtk_table_attach_defaults(
1450 pane + 2, pane + 3, row, row + 1);
1465 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_save"));
1466 g_signal_connect((gpointer) widget,
"clicked",
1469 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_load"));
1470 g_signal_connect((gpointer) widget,
"clicked",
1473 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_defaults"));
1474 g_signal_connect((gpointer) widget,
"clicked",
1477 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_apply"));
1478 g_signal_connect((gpointer) widget,
"clicked",
1481 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_close"));
1482 g_signal_connect((gpointer) widget,
"clicked",
1497 gtk_spin_button_set_value(
1501 gtk_spin_button_set_value(
1506 gtk_toggle_button_set_active(
1510 gtk_toggle_button_set_active(
1532 snprintf(pathbuf,
sizeof(pathbuf),
"%s/msgs",
config_dir);
1536 "gtk-v2::save_msgctrl_configuration",
"Error creating %s",pathbuf);
1537 snprintf(textbuf,
sizeof(textbuf),
1538 "Error creating %s, Message Control settings not saved.",pathbuf);
1543 if ((fptr = fopen(pathbuf,
"w")) == NULL) {
1544 snprintf(textbuf,
sizeof(textbuf),
1545 "Error opening %s, Message Control settings not saved.", pathbuf);
1554 fprintf(fptr,
"# Message Control System Configuration\n");
1555 fprintf(fptr,
"#\n");
1556 fprintf(fptr,
"# Count: 1-96\n");
1557 fprintf(fptr,
"#\n");
1559 fprintf(fptr,
"#\n");
1560 fprintf(fptr,
"# Timer: 1-96 (8 ~= one second)\n");
1561 fprintf(fptr,
"#\n");
1563 fprintf(fptr,
"#\n");
1564 fprintf(fptr,
"# type, buffer, pane[0], pane[1]...\n");
1565 fprintf(fptr,
"# Do not edit the 'type' field.\n");
1566 fprintf(fptr,
"# 0 == disable; 1 == enable.\n");
1567 fprintf(fptr,
"#\n");
1574 fprintf(fptr,
"\n");
1576 fprintf(fptr,
"#\n# End of Message Control System Configuration\n");
1580 "Message control settings saved to '%s'", pathbuf);
1582 snprintf(textbuf,
sizeof(textbuf),
"Message control settings saved!");
1603 guint cvalid, tvalid, mvalid;
1605 snprintf(pathbuf,
sizeof(pathbuf),
"%s/msgs",
config_dir);
1607 if ((fptr = fopen(pathbuf,
"r")) == NULL) {
1608 snprintf(textbuf,
sizeof(textbuf),
1609 "Error opening %s, Message Control settings not loaded.",pathbuf);
1629 while(fgets(textbuf,
MAX_BUF-1, fptr) != NULL) {
1630 if (textbuf[0] ==
'#' || textbuf[0] ==
'\n') {
1637 cptr = strtok(textbuf,
"\t ");
1639 || ((*cptr !=
'C') && (*cptr !=
'T') && (*cptr !=
'M'))) {
1648 if (recordtype ==
'C') {
1649 cptr = strtok(NULL,
"\n");
1651 || (sscanf(cptr,
"%u", &countbuf.
state) != 1)
1652 || (countbuf.
state < 1)
1653 || (countbuf.
state > 96)) {
1658 if (recordtype ==
'T') {
1659 cptr = strtok(NULL,
"\n");
1661 || (sscanf(cptr,
"%u", &timerbuf.
state) != 1)
1662 || (timerbuf.
state < 1)
1663 || (timerbuf.
state > 96)) {
1668 if (recordtype ==
'M') {
1669 cptr = strtok(NULL,
"\t ");
1671 || (sscanf(cptr,
"%d", &type) != 1)
1677 cptr = strtok(NULL,
"\t ");
1679 || (sscanf(cptr,
"%d", &statebuf.
buffer.
state) != 1)
1686 cptr = strtok(NULL,
"\t ");
1688 || (sscanf(cptr,
"%d", &statebuf.
pane[pane].
state) != 1)
1701 cptr = strtok(NULL,
"\n");
1715 if (recordtype ==
'C') {
1719 if (recordtype ==
'T') {
1723 if (recordtype ==
'M') {
1744 snprintf(textbuf,
sizeof(textbuf),
1745 "Corrupted Message Control settings in %s.", pathbuf);
1749 "Error loading %s. %s\n", pathbuf, textbuf);
1756 if ((cvalid + tvalid + mvalid) > 0) {
1758 "Message control settings loaded from '%s'", pathbuf);
1799 gtk_spin_button_get_value_as_int(
1802 gtk_spin_button_get_value_as_int(
1812 gtk_toggle_button_get_active(
1816 gtk_toggle_button_get_active(