Crossfire Server, Trunk
dialog.cpp
Go to the documentation of this file.
1 
2 /*
3  * Crossfire -- cooperative multi-player graphical RPG and adventure game
4  *
5  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
6  * Copyright (c) 1992 Frank Tore Johansen
7  *
8  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
9  * welcome to redistribute it under certain conditions. For details, please
10  * see COPYING and LICENSE.
11  *
12  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
13  */
14 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "global.h"
24 #include "define.h"
25 #include "object.h"
26 #include "dialog.h"
27 
32 void free_dialog_information(object *op) {
34  struct_dialog_reply *currep, *nextrep;
35 
37  return;
38 
40  if (!op->dialog_information)
41  return;
42 
43  current = op->dialog_information->all_messages;
44  while (current) {
45  next = current->next;
46  free(current->match);
47  free(current->message);
48  currep = current->replies;
49  while (currep) {
50  nextrep = currep->next;
51  free(currep->reply);
52  free(currep->message);
53  currep = nextrep;
54  }
55  free(current);
56  current = next;
57  }
58 
59  currep = op->dialog_information->all_replies;
60  while (currep) {
61  nextrep = currep->next;
62  free(currep->reply);
63  free(currep->message);
64  free(currep);
65  currep = nextrep;
66  }
67 
68  free(op->dialog_information);
69  op->dialog_information = NULL;
70 }
71 
79 static int matches(const char *exp, const char *text) {
80  char *pipe, *save = NULL, *msg;
81  int match = 0;
82 
83  if (exp[0] == '*')
84  return 1;
85 
86  msg = strdup(exp);
87 
88  pipe = strtok_r(msg, "|", &save);
89  while (pipe) {
90  if (re_cmp(text, pipe)) {
91  match = 1;
92  break;
93  }
94  pipe = strtok_r(NULL, "|", &save);
95  }
96 
97  free(msg);
98  return match;
99 }
100 
107 static void parse_dialog_information(object *op) {
108  struct_dialog_message *message = NULL, *last = NULL;
109  struct_dialog_reply *reply = NULL;
110  char *current, *save = NULL, *msg, *cp;
111  int len;
112  /* Used for constructing message with */
113  char *tmp = NULL;
114  size_t tmplen = 0;
115 
117  return;
119 
120  op->dialog_information = (struct_dialog_information *)calloc(1, sizeof(struct_dialog_information));
121  if (op->dialog_information == NULL)
123 
124  if (!op->msg)
125  return;
126 
127  msg = strdup(op->msg);
128  current = strtok_r(msg, "\n", &save);
129 
130  while (current) {
131  if (strncmp(current, "@match ", 7) == 0) {
132  if (message) {
133  message->message = tmp;
134  tmp = NULL;
135  tmplen = 0;
136  }
137 
138  message = (struct_dialog_message *)calloc(1, sizeof(struct_dialog_message));
139  if (last)
140  last->next = message;
141  else
142  op->dialog_information->all_messages = message;
143  last = message;
144 
145  message->match = strdup(current+7);
146  } else if ((strncmp(current, "@reply ", 7) == 0 && (len = 7)) || (strncmp(current, "@question ", 10) == 0 && (len = 10))) {
147  if (message) {
148  reply = (struct_dialog_reply *)calloc(1, sizeof(struct_dialog_reply));
149  reply->type = (len == 7 ? rt_reply : rt_question);
150  cp = strchr(current+len, ' ');
151  if (cp) {
152  *cp = '\0';
153  reply->reply = strdup(current+len);
154  reply->message = strdup(cp+1);
155  } else {
156  reply->reply = strdup(current+len);
157  reply->message = strdup(reply->reply);
158  LOG(llevDebug, "Warning: @reply/@question without message for %s!\n", op->name);
159  }
160  reply->next = message->replies;
161  message->replies = reply;
162 
163  reply = (struct_dialog_reply *)calloc(1, sizeof(struct_dialog_reply));
164  reply->reply = strdup(message->replies->reply);
165  reply->message = strdup(message->replies->message);
166  reply->type = message->replies->type;
167  reply->next = op->dialog_information->all_replies;
168  op->dialog_information->all_replies = reply;
169  } else
170  LOG(llevDebug, "Warning: @reply not in @match block for %s!\n", op->name);
171  } else if ((strncmp(current, "@identify", 9) == 0 && (len = 9))) {
172  if (message) {
173  message->identifies = true;
174  }
175  } else if (message) {
176  /* Needed to set initial \0 */
177  int wasnull = FALSE;
178  tmplen += strlen(current)+2;
179  if (!tmp)
180  wasnull = TRUE;
181  tmp = static_cast<char *>(realloc(tmp, tmplen*sizeof(char)));
182  if (!tmp)
184  if (wasnull)
185  tmp[0] = 0;
186  strncat(tmp, current, tmplen-strlen(tmp)-1);
187  strncat(tmp, "\n", tmplen-strlen(tmp)-1);
188  }
189  current = strtok_r(NULL, "\n", &save);
190  }
191 
192  if (message) {
193  if (!tmp)
194  message->message = strdup("");
195  else
196  message->message = tmp;
197  tmp = NULL;
198  tmplen = 0;
199  }
200 
201  free(msg);
202 }
203 
216 
217  for (*message = op->dialog_information->all_messages; *message; *message = (*message)->next) {
218  if (matches((*message)->match, text)) {
219  break;
220  }
221  }
222  if (!*message)
223  return 0;
224 
225  for (*reply = op->dialog_information->all_replies; *reply; *reply = (*reply)->next) {
226  if (strcmp((*reply)->reply, text) == 0)
227  break;
228  }
229 
230  return 1;
231 }
give.next
def next
Definition: give.py:44
global.h
struct_dialog_reply::next
struct struct_dialog_reply * next
Definition: dialog.h:20
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
FALSE
#define FALSE
Definition: compat.h:14
say.reply
string reply
Definition: say.py:77
Ice.tmp
int tmp
Definition: Ice.py:207
FLAG_DIALOG_PARSED
#define FLAG_DIALOG_PARSED
Definition: define.h:243
struct_dialog_reply::message
char * message
Definition: dialog.h:18
navar-midane_pickup.msg
list msg
Definition: navar-midane_pickup.py:13
struct_dialog_reply
Definition: dialog.h:16
push.match
bool match
Definition: push.py:61
struct_dialog_information
Definition: dialog.h:37
rt_reply
@ rt_reply
Definition: dialog.h:9
guild_entry.text
text
Definition: guild_entry.py:41
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:590
diamondslots.message
string message
Definition: diamondslots.py:57
struct_dialog_reply::reply
char * reply
Definition: dialog.h:17
dialog.h
struct_dialog_message
Definition: dialog.h:26
get_dialog_message
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
Definition: dialog.cpp:213
rt_question
@ rt_question
Definition: dialog.h:10
give.op
op
Definition: give.py:33
define.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
TRUE
#define TRUE
Definition: compat.h:11
replace.current
current
Definition: replace.py:64
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
re_cmp
const char * re_cmp(const char *, const char *)
Definition: re-cmp.cpp:68
free_dialog_information
void free_dialog_information(object *op)
Definition: dialog.cpp:32
matches
static int matches(const char *exp, const char *text)
Definition: dialog.cpp:79
object.h
llevDebug
@ llevDebug
Definition: logger.h:13
parse_dialog_information
static void parse_dialog_information(object *op)
Definition: dialog.cpp:107