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");
1112 LOG(
LOG_INFO,
"mapedit",
"Launching map editor on '%s'", path);
1113 char *argv[] = {editor, path, NULL};
1115 if (!g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, &err)) {
1116 LOG(
LOG_ERROR,
"mapedit",
"Could not launch CF_MAP_EDITOR: %s", err->message);
1172 char *msg_cpy = strdup(message);
1173 char *ptr = msg_cpy;
1174 ptr = strtok(ptr,
")");
1176 ptr = strtok(ptr,
"(");
1177 ptr = strtok(NULL,
"(");
1181 LOG(
LOG_INFO,
"mapedit",
"Could not parse map path from '%s'", message);
1243 if (! strcmp(message,
info_buffer[search].message)) {
1251 "type: %d-%d empty: %d found: %d oldest: %d oldest_age: %d",
1252 type, subtype, empty, found, oldest, oldest_age);
1286 "Buffer full; oldest unknown", strlen(message));
1334 gtk_text_buffer_set_text(
info_pane[i].textbuffer,
"", 0);
1350 GtkTableChild* child;
1369 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1374 GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_spinbutton_count"));
1377 GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_spinbutton_timer"));
1391 gtk_table_get_size(table, &title_rows, &title_cols);
1409 gtk_table_resize(table,
1421 row = type + title_rows;
1428 gtk_misc_set_alignment(GTK_MISC(widget), 0.0f, 0.5f);
1429 gtk_misc_set_padding(GTK_MISC(widget), 2, 0);
1430 gtk_table_attach_defaults(table, widget, 0, 1, row, row + 1);
1431 gtk_widget_show(widget);
1437 gtk_table_attach_defaults(
1451 gtk_table_attach_defaults(
1453 pane + 2, pane + 3, row, row + 1);
1468 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_save"));
1469 g_signal_connect((gpointer) widget,
"clicked",
1472 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_load"));
1473 g_signal_connect((gpointer) widget,
"clicked",
1476 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_defaults"));
1477 g_signal_connect((gpointer) widget,
"clicked",
1480 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_apply"));
1481 g_signal_connect((gpointer) widget,
"clicked",
1484 widget = GTK_WIDGET(gtk_builder_get_object(
dialog_xml,
"msgctrl_button_close"));
1485 g_signal_connect((gpointer) widget,
"clicked",
1500 gtk_spin_button_set_value(
1504 gtk_spin_button_set_value(
1509 gtk_toggle_button_set_active(
1513 gtk_toggle_button_set_active(
1535 snprintf(pathbuf,
sizeof(pathbuf),
"%s/msgs",
config_dir);
1539 "gtk-v2::save_msgctrl_configuration",
"Error creating %s",pathbuf);
1540 snprintf(textbuf,
sizeof(textbuf),
1541 "Error creating %s, Message Control settings not saved.",pathbuf);
1546 if ((fptr = fopen(pathbuf,
"w")) == NULL) {
1547 snprintf(textbuf,
sizeof(textbuf),
1548 "Error opening %s, Message Control settings not saved.", pathbuf);
1557 fprintf(fptr,
"# Message Control System Configuration\n");
1558 fprintf(fptr,
"#\n");
1559 fprintf(fptr,
"# Count: 1-96\n");
1560 fprintf(fptr,
"#\n");
1562 fprintf(fptr,
"#\n");
1563 fprintf(fptr,
"# Timer: 1-96 (8 ~= one second)\n");
1564 fprintf(fptr,
"#\n");
1566 fprintf(fptr,
"#\n");
1567 fprintf(fptr,
"# type, buffer, pane[0], pane[1]...\n");
1568 fprintf(fptr,
"# Do not edit the 'type' field.\n");
1569 fprintf(fptr,
"# 0 == disable; 1 == enable.\n");
1570 fprintf(fptr,
"#\n");
1577 fprintf(fptr,
"\n");
1579 fprintf(fptr,
"#\n# End of Message Control System Configuration\n");
1583 "Message control settings saved to '%s'", pathbuf);
1585 snprintf(textbuf,
sizeof(textbuf),
"Message control settings saved!");
1606 guint cvalid, tvalid, mvalid;
1608 snprintf(pathbuf,
sizeof(pathbuf),
"%s/msgs",
config_dir);
1610 if ((fptr = fopen(pathbuf,
"r")) == NULL) {
1611 snprintf(textbuf,
sizeof(textbuf),
1612 "Error opening %s, Message Control settings not loaded.",pathbuf);
1632 while(fgets(textbuf,
MAX_BUF-1, fptr) != NULL) {
1633 if (textbuf[0] ==
'#' || textbuf[0] ==
'\n') {
1640 cptr = strtok(textbuf,
"\t ");
1642 || ((*cptr !=
'C') && (*cptr !=
'T') && (*cptr !=
'M'))) {
1651 if (recordtype ==
'C') {
1652 cptr = strtok(NULL,
"\n");
1654 || (sscanf(cptr,
"%u", &countbuf.
state) != 1)
1655 || (countbuf.
state < 1)
1656 || (countbuf.
state > 96)) {
1661 if (recordtype ==
'T') {
1662 cptr = strtok(NULL,
"\n");
1664 || (sscanf(cptr,
"%u", &timerbuf.
state) != 1)
1665 || (timerbuf.
state < 1)
1666 || (timerbuf.
state > 96)) {
1671 if (recordtype ==
'M') {
1672 cptr = strtok(NULL,
"\t ");
1674 || (sscanf(cptr,
"%d", &type) != 1)
1680 cptr = strtok(NULL,
"\t ");
1682 || (sscanf(cptr,
"%d", &statebuf.
buffer.
state) != 1)
1689 cptr = strtok(NULL,
"\t ");
1691 || (sscanf(cptr,
"%d", &statebuf.
pane[pane].
state) != 1)
1704 cptr = strtok(NULL,
"\n");
1718 if (recordtype ==
'C') {
1722 if (recordtype ==
'T') {
1726 if (recordtype ==
'M') {
1747 snprintf(textbuf,
sizeof(textbuf),
1748 "Corrupted Message Control settings in %s.", pathbuf);
1752 "Error loading %s. %s\n", pathbuf, textbuf);
1759 if ((cvalid + tvalid + mvalid) > 0) {
1761 "Message control settings loaded from '%s'", pathbuf);
1802 gtk_spin_button_get_value_as_int(
1805 gtk_spin_button_get_value_as_int(
1815 gtk_toggle_button_get_active(
1819 gtk_toggle_button_get_active(