Crossfire Server, Trunk
dialog.c
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 (message) {
172  /* Needed to set initial \0 */
173  int wasnull = FALSE;
174  tmplen += strlen(current)+2;
175  if (!tmp)
176  wasnull = TRUE;
177  tmp = realloc(tmp, tmplen*sizeof(char));
178  if (!tmp)
180  if (wasnull)
181  tmp[0] = 0;
182  strncat(tmp, current, tmplen-strlen(tmp)-1);
183  strncat(tmp, "\n", tmplen-strlen(tmp)-1);
184  }
185  current = strtok_r(NULL, "\n", &save);
186  }
187 
188  if (message) {
189  if (!tmp)
190  message->message = strdup("");
191  else
192  message->message = tmp;
193  tmp = NULL;
194  tmplen = 0;
195  }
196 
197  free(msg);
198 }
199 
212 
213  for (*message = op->dialog_information->all_messages; *message; *message = (*message)->next) {
214  if (matches((*message)->match, text)) {
215  break;
216  }
217  }
218  if (!*message)
219  return 0;
220 
221  for (*reply = op->dialog_information->all_replies; *reply; *reply = (*reply)->next) {
222  if (strcmp((*reply)->reply, text) == 0)
223  break;
224  }
225 
226  return 1;
227 }
give.next
def next
Definition: give.py:44
global.h
struct_dialog_reply::next
struct struct_dialog_reply * next
Definition: dialog.h:22
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
re_cmp
const char * re_cmp(const char *, const char *)
Definition: re-cmp.c:69
FLAG_DIALOG_PARSED
#define FLAG_DIALOG_PARSED
Definition: define.h:243
struct_dialog_reply::message
char * message
Definition: dialog.h:20
fatal
void fatal(enum fatal_error err)
Definition: utils.c:580
navar-midane_pickup.msg
list msg
Definition: navar-midane_pickup.py:13
struct_dialog_reply
Definition: dialog.h:18
parse_dialog_information
static void parse_dialog_information(object *op)
Definition: dialog.c:107
push.match
bool match
Definition: push.py:61
free_dialog_information
void free_dialog_information(object *op)
Definition: dialog.c:32
struct_dialog_information
Definition: dialog.h:38
rt_reply
@ rt_reply
Definition: dialog.h:11
guild_entry.text
text
Definition: guild_entry.py:44
diamondslots.message
string message
Definition: diamondslots.py:57
struct_dialog_reply::reply
char * reply
Definition: dialog.h:19
dialog.h
struct_dialog_message
Definition: dialog.h:28
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
rt_question
@ rt_question
Definition: dialog.h:12
give.op
op
Definition: give.py:33
define.h
get_dialog_message
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
Definition: dialog.c:209
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
matches
static int matches(const char *exp, const char *text)
Definition: dialog.c:79
TRUE
#define TRUE
Definition: compat.h:11
replace.current
current
Definition: replace.py:64
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
object.h
llevDebug
@ llevDebug
Definition: logger.h:13