Crossfire Server, Trunk  1.75.0
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 #include "global.h"
17 #include "compat.h"
18 #include "string.h"
19 #include "AssetsTracker.h"
20 
21 MessageLoader::MessageLoader(Messages* messages, AssetsTracker *tracker) : m_messages(messages), m_tracker(tracker) {
22 }
23 
24 void MessageLoader::load(BufferReader *reader, const std::string &filename) {
25  char *buf, msgbuf[HUGE_BUF], *cp;
26  int text = 0, nrofmsg = 0;
27 
28  LOG(llevDebug, "Reading messages from %s...\n", filename.c_str());
29 
30  GeneralMessage *tmp = NULL;
31 
32  while ((buf = bufferreader_next_line(reader)) != NULL) {
33  if (*buf == '#' || (*buf == '\0' && !text))
34  continue;
35 
36  // Remove trailing whitespace
37  cp = buf + strlen(buf);
38  while (cp > buf && (cp[-1] == ' ' || cp[-1] == '\t'))
39  cp--;
40  if (cp > buf) {
41  *cp = '\0';
42  }
43 
44  if (tmp != NULL) {
45  if (text && strncmp(buf, "ENDMSG", 6) == 0) {
46  if (strlen(msgbuf) > BOOK_BUF) {
47  LOG(llevDebug, "Warning: this string exceeded max book buf size:\n");
48  LOG(llevDebug, " %s\n", msgbuf);
49  }
50  tmp->message = add_string(msgbuf);
51  if (tmp->identifier[0] != '\n' && tmp->title == NULL) {
52  LOG(llevError, "Error: message can't have identifier without title, file %s on line %zu\n", filename.c_str(), bufferreader_current_line(reader));
53  }
54  tmp = m_messages->define(tmp->identifier, tmp);
55  if (m_tracker) {
56  m_tracker->assetDefined(tmp, filename);
57  }
58  nrofmsg++;
59  tmp = NULL;
60  text = 0;
61  } else if (text) {
62  if (!buf_overflow(msgbuf, buf, HUGE_BUF-1)) {
63  strcat(msgbuf, buf);
64  strcat(msgbuf, "\n");
65  } else {
66  LOG(llevInfo, "Warning: truncating book at %s, line %zu\n", filename.c_str(), bufferreader_current_line(reader));
67  }
68  } else if (strcmp(buf, "TEXT") == 0) {
69  text = 1;
70  } else if (strncmp(buf, "CHANCE ", 7) == 0) {
71  tmp->chance = atoi(buf + 7);
72  } else if (strncmp(buf, "TITLE ", 6) == 0) {
73  tmp->title = add_string(buf + 6);
74  } else if (strncmp(buf, "QUEST ", 6) == 0) {
75  tmp->quest_code = add_string(buf + 6);
76  } else if (strncmp(buf, "FACE ", 5) == 0) {
77  const Face *face = find_face(buf + 5);
78  tmp->face = face;
79  } else {
80  LOG(llevInfo, "Warning: unknown line %s, in file %s line %zu\n", buf, filename.c_str(), bufferreader_current_line(reader));
81  }
82  } else if (strncmp(buf, "MSG", 3) == 0) {
83  tmp = (GeneralMessage *)calloc(1, sizeof(GeneralMessage));
84  tmp->face = NULL;
85  if (buf[3] == ' ') {
86  int i = 4;
87  while (buf[i] == ' ')
88  i++;
89  if (buf[i] != '\0') {
90  tmp->identifier = add_string(buf + i);
91  }
92  }
93  /* We need an identifier, so generate one from filename and line, that should be unique enough! */
94  if (!tmp->identifier) {
95  snprintf(msgbuf, sizeof(msgbuf), "\n%s\n%zu", filename.c_str(), bufferreader_current_line(reader));
97  }
98  strcpy(msgbuf, ""); /* reset msgbuf for new message */
99  } else {
100  LOG(llevInfo, "Warning: syntax error at %s, line %zu\n", filename.c_str(), bufferreader_current_line(reader));
101  }
102  }
103 
104  if (tmp != NULL) {
105  LOG(llevError, "Invalid file %s", filename.c_str());
107  }
108 
109  LOG(llevDebug, "done messages %s, found %d messages.\n", filename.c_str(), nrofmsg);
110 }
Face
New face structure - this enforces the notion that data is face by face only - you can not change the...
Definition: face.h:14
global.h
GeneralMessage
One general message, from the lib/messages file.
Definition: book.h:44
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
Definition: bufferreader.cpp:140
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
MessageLoader::m_tracker
AssetsTracker * m_tracker
Definition: MessageLoader.h:34
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
MessageLoader::MessageLoader
MessageLoader(Messages *messages, AssetsTracker *tracker)
Definition: MessageLoader.cpp:21
Messages.h
MessageLoader::m_messages
Messages * m_messages
Definition: MessageLoader.h:33
GeneralMessage::title
sstring title
The message's title, only used for knowledge.
Definition: book.h:48
GeneralMessage::identifier
sstring identifier
Message identifier, can be NULL.
Definition: book.h:47
Messages
Definition: Messages.h:22
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
find_face
const Face * find_face(const char *name)
Definition: assets.cpp:282
buf
StringBuffer * buf
Definition: readable.cpp:1565
HUGE_BUF
#define HUGE_BUF
Used for messages - some can be quite long.
Definition: define.h:37
AssetsTracker
Base class to be informed of where an asset is defined.
Definition: AssetsTracker.h:24
GeneralMessage::chance
int chance
Relative chance of the message appearing randomly.
Definition: book.h:45
AssetsCollection::define
T * define(const Key &name, T *asset)
Define an asset, erasing an existing one.
Definition: AssetsCollection.h:120
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
compat.h
AssetsTracker::assetDefined
virtual void assetDefined(const archetype *asset, const std::string &filename)
Function called when an asset is defined in a file.
Definition: AssetsTracker.h:32
AssetsTracker.h
fatal
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
GeneralMessage::message
sstring message
The message's body.
Definition: book.h:49
llevInfo
@ llevInfo
Information.
Definition: logger.h:12
msgbuf
static char msgbuf[HUGE_BUF]
Definition: loader.cpp:35880
BOOK_BUF
#define BOOK_BUF
Maximum message buf size for books.
Definition: book.h:16
text
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old full of dirt and partially destroyed[hand] My dear as you two years i had to leave quickly Words have come to me of powerful magic scrolls discovered in an old temple by my uncle I have moved to study them I not forgot your knowledge in ancient languages I need your help for[print][b] Some parts of document are to damaged to be readable[/b][arcane] Arghis[color=Red] k h[color=dark slate blue] ark[color=#004000] fido[/color][hand] please come as fast as possible my friend[print][b] The bottom of letter seems deliberatly shredded What is but not limited book signs rules Media tags are made of with inside them the name of tag and optional parameters for the tag Unlike html or there is no notion of opening and closing tag A client not able to understand a tag is supposed to ignore it when server is communicating with and old client that does not understand a a specific extended text
Definition: media-tags.txt:35
MessageLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Load assets from the specified reader.
Definition: MessageLoader.cpp:24
MessageLoader.h
buf_overflow
int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
We don't want to exceed the buffer size of buf1 by adding on buf2!
Definition: shstr.cpp:398
GeneralMessage::face
const Face * face
Face the message displays at in the knowledge dialog, NULL if no face defined.
Definition: book.h:51
BufferReader
Definition: bufferreader.cpp:21
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
GeneralMessage::quest_code
sstring quest_code
Optional quest code and state this message will start.
Definition: book.h:50
face
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific and settings file datadir Usually usr share crossfire Contains data that the server does not need to modify while such as the etc A default install will pack the and treasurelist definitions into a single or trs file and the graphics into a face(metadata) and .tar(bitmaps) file
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:102