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 #include "AssetsTracker.h"
22 
23 MessageLoader::MessageLoader(Messages* messages, AssetsTracker *tracker) : m_messages(messages), m_tracker(tracker) {
24 }
25 
26 void MessageLoader::load(BufferReader *reader, const std::string &filename) {
27  char *buf, msgbuf[HUGE_BUF], *cp;
28  int text = 0, nrofmsg = 0;
29 
30  LOG(llevDebug, "Reading messages from %s...\n", filename.c_str());
31 
32  GeneralMessage *tmp = NULL;
33 
34  while ((buf = bufferreader_next_line(reader)) != NULL) {
35  if (*buf == '#' || (*buf == '\0' && !text))
36  continue;
37 
38  // Remove trailing whitespace
39  cp = buf + strlen(buf);
40  while (cp > buf && (cp[-1] == ' ' || cp[-1] == '\t'))
41  cp--;
42  if (cp > buf) {
43  *cp = '\0';
44  }
45 
46  if (tmp != NULL) {
47  if (text && strncmp(buf, "ENDMSG", 6) == 0) {
48  if (strlen(msgbuf) > BOOK_BUF) {
49  LOG(llevDebug, "Warning: this string exceeded max book buf size:\n");
50  LOG(llevDebug, " %s\n", msgbuf);
51  }
52  tmp->message = add_string(msgbuf);
53  if (tmp->identifier[0] != '\n' && tmp->title == NULL) {
54  LOG(llevError, "Error: message can't have identifier without title, file %s on line %ld\n", filename.c_str(), bufferreader_current_line(reader));
55  }
56  tmp = m_messages->define(tmp->identifier, tmp);
57  if (m_tracker) {
59  }
60  nrofmsg++;
61  tmp = NULL;
62  text = 0;
63  } else if (text) {
64  if (!buf_overflow(msgbuf, buf, HUGE_BUF-1)) {
65  strcat(msgbuf, buf);
66  strcat(msgbuf, "\n");
67  } else {
68  LOG(llevInfo, "Warning: truncating book at %s, line %ld\n", filename.c_str(), bufferreader_current_line(reader));
69  }
70  } else if (strcmp(buf, "TEXT") == 0) {
71  text = 1;
72  } else if (strncmp(buf, "CHANCE ", 7) == 0) {
73  tmp->chance = atoi(buf + 7);
74  } else if (strncmp(buf, "TITLE ", 6) == 0) {
75  tmp->title = add_string(buf + 6);
76  } else if (strncmp(buf, "QUEST ", 6) == 0) {
77  tmp->quest_code = add_string(buf + 6);
78  } else if (strncmp(buf, "FACE ", 5) == 0) {
79  const Face *face = find_face(buf + 5);
80  tmp->face = face;
81  } else {
82  LOG(llevInfo, "Warning: unknown line %s, in file %s line %ld\n", buf, filename.c_str(), bufferreader_current_line(reader));
83  }
84  } else if (strncmp(buf, "MSG", 3) == 0) {
85  tmp = (GeneralMessage *)calloc(1, sizeof(GeneralMessage));
86  tmp->face = NULL;
87  if (buf[3] == ' ') {
88  int i = 4;
89  while (buf[i] == ' ')
90  i++;
91  if (buf[i] != '\0') {
92  tmp->identifier = add_string(buf + i);
93  }
94  }
95  /* We need an identifier, so generate one from filename and line, that should be unique enough! */
96  if (!tmp->identifier) {
97  snprintf(msgbuf, sizeof(msgbuf), "\n%s\n%ld", filename.c_str(), bufferreader_current_line(reader));
98  tmp->identifier = add_string(msgbuf);
99  }
100  strcpy(msgbuf, ""); /* reset msgbuf for new message */
101  } else {
102  LOG(llevInfo, "Warning: syntax error at %s, line %ld\n", filename.c_str(), bufferreader_current_line(reader));
103  }
104  }
105 
106  if (tmp != NULL) {
107  LOG(llevError, "Invalid file %s", filename.c_str());
109  }
110 
111  LOG(llevDebug, "done messages %s, found %d messages.\n", filename.c_str(), nrofmsg);
112 }
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
MessageLoader::m_tracker
AssetsTracker * m_tracker
Definition: MessageLoader.h:34
MessageLoader::MessageLoader
MessageLoader(Messages *messages, AssetsTracker *tracker)
Definition: MessageLoader.cpp:23
Messages.h
MessageLoader::m_messages
Messages * m_messages
Definition: MessageLoader.h:33
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:308
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
AssetsTracker
Definition: AssetsTracker.h:28
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:97
fatal
void fatal(enum fatal_error err)
Definition: utils.c:580
compat.h
AssetsTracker::assetDefined
virtual void assetDefined(const archetype *asset, const std::string &filename)
Definition: AssetsTracker.h:36
AssetsTracker.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:1610
MessageLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Definition: MessageLoader.cpp:26
MessageLoader.h
BufferReader
Definition: bufferreader.c:21
llevDebug
@ llevDebug
Definition: logger.h:13