Crossfire Server, Trunk
MessageLoader.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2020 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include "MessageLoader.h"
14 #include "Messages.h"
15 
16 extern "C" {
17 #include "global.h"
18 #include "compat.h"
19 #include "string.h"
20 }
21 
23 }
24 
25 void MessageLoader::load(BufferReader *reader, const std::string &filename) {
26  char *buf, msgbuf[HUGE_BUF], *cp;
27  int text = 0, nrofmsg = 0;
28 
29  LOG(llevDebug, "Reading messages from %s...\n", filename.c_str());
30 
31  GeneralMessage *tmp = NULL;
32 
33  while ((buf = bufferreader_next_line(reader)) != NULL) {
34  if (*buf == '#' || (*buf == '\0' && !text))
35  continue;
36 
37  // Remove trailing whitespace
38  cp = buf + strlen(buf);
39  while (cp > buf && (cp[-1] == ' ' || cp[-1] == '\t'))
40  cp--;
41  if (cp > buf) {
42  *cp = '\0';
43  }
44 
45  if (tmp != NULL) {
46  if (text && strncmp(buf, "ENDMSG", 6) == 0) {
47  if (strlen(msgbuf) > BOOK_BUF) {
48  LOG(llevDebug, "Warning: this string exceeded max book buf size:\n");
49  LOG(llevDebug, " %s\n", msgbuf);
50  }
51  tmp->message = add_string(msgbuf);
52  if (tmp->identifier[0] != '\n' && tmp->title == NULL) {
53  LOG(llevError, "Error: message can't have identifier without title, file %s on line %ld\n", filename.c_str(), bufferreader_current_line(reader));
54  }
55  m_messages->define(tmp->identifier, tmp);
56  nrofmsg++;
57  tmp = NULL;
58  text = 0;
59  } else if (text) {
60  if (!buf_overflow(msgbuf, buf, HUGE_BUF-1)) {
61  strcat(msgbuf, buf);
62  strcat(msgbuf, "\n");
63  } else {
64  LOG(llevInfo, "Warning: truncating book at %s, line %ld\n", filename.c_str(), bufferreader_current_line(reader));
65  }
66  } else if (strcmp(buf, "TEXT") == 0) {
67  text = 1;
68  } else if (strncmp(buf, "CHANCE ", 7) == 0) {
69  tmp->chance = atoi(buf + 7);
70  } else if (strncmp(buf, "TITLE ", 6) == 0) {
71  tmp->title = add_string(buf + 6);
72  } else if (strncmp(buf, "QUEST ", 6) == 0) {
73  tmp->quest_code = add_string(buf + 6);
74  } else if (strncmp(buf, "FACE ", 5) == 0) {
75  const Face *face = find_face(buf + 5);
76  tmp->face = face;
77  } else {
78  LOG(llevInfo, "Warning: unknown line %s, in file %s line %ld\n", buf, filename.c_str(), bufferreader_current_line(reader));
79  }
80  } else if (strncmp(buf, "MSG", 3) == 0) {
81  tmp = (GeneralMessage *)calloc(1, sizeof(GeneralMessage));
82  tmp->face = NULL;
83  if (buf[3] == ' ') {
84  int i = 4;
85  while (buf[i] == ' ' && buf[i] != '\0')
86  i++;
87  if (buf[i] != '\0') {
88  tmp->identifier = add_string(buf + i);
89  }
90  }
91  /* We need an identifier, so generate one from filename and line, that should be unique enough! */
92  if (!tmp->identifier) {
93  snprintf(msgbuf, sizeof(msgbuf), "\n%s\n%ld", filename.c_str(), bufferreader_current_line(reader));
94  tmp->identifier = add_string(msgbuf);
95  }
96  strcpy(msgbuf, ""); /* reset msgbuf for new message */
97  } else {
98  LOG(llevInfo, "Warning: syntax error at %s, line %ld\n", filename.c_str(), bufferreader_current_line(reader));
99  }
100  }
101 
102  if (tmp != NULL) {
103  LOG(llevError, "Invalid file %s", filename.c_str());
105  }
106 
107  LOG(llevDebug, "done messages %s, found %d messages.\n", filename.c_str(), nrofmsg);
108 }
Face
Definition: face.h:14
global.h
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
GeneralMessage
Definition: book.h:44
llevError
@ llevError
Definition: logger.h:11
Messages.h
MessageLoader::m_messages
Messages * m_messages
Definition: MessageLoader.h:32
msgbuf
static char msgbuf[HUGE_BUF]
Definition: loader.c:2079
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.c:102
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Definition: bufferreader.c:140
Ice.tmp
int tmp
Definition: Ice.py:207
Messages
Definition: Messages.h:24
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
npc_dialog.filename
filename
Definition: npc_dialog.py:99
find_face
const Face * find_face(const char *name)
Definition: assets.cpp:302
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:97
fatal
void fatal(enum fatal_error err)
Definition: utils.c:597
compat.h
buf_overflow
int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
Definition: shstr.c:398
guild_entry.text
text
Definition: guild_entry.py:44
navar-midane_apply.messages
list messages
Definition: navar-midane_apply.py:8
llevInfo
@ llevInfo
Definition: logger.h:12
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
BOOK_BUF
#define BOOK_BUF
Definition: book.h:16
buf
StringBuffer * buf
Definition: readable.c:1606
MessageLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Definition: MessageLoader.cpp:25
MessageLoader.h
MessageLoader::MessageLoader
MessageLoader(Messages *messages)
Definition: MessageLoader.cpp:22
BufferReader
Definition: bufferreader.c:21
llevDebug
@ llevDebug
Definition: logger.h:13