Crossfire Server, Trunk  R20513
MessageFile.cpp
Go to the documentation of this file.
1 #include <qiodevice.h>
2 #include <qfile.h>
3 #include <qscriptengine.h>
4 #include <QDebug>
5 
6 #include "MessageFile.h"
7 
8 extern "C" {
9  #include "global.h"
10 }
11 
13 {
14  myIsModified = false;
15 }
16 
17 MessageRule::MessageRule(const MessageRule& original) : QObject()
18 {
19  myIsModified = true;
20  myMatch = original.match();
21  myPreconditions = original.preconditions();
22  myMessages = original.messages();
23  myPostconditions = original.postconditions();
24  myReplies = original.replies();
25 }
26 
28 {
29 }
30 
31 const QString& MessageRule::comment() const
32 {
33  return myComment;
34 }
35 
36 void MessageRule::setComment(const QString& comment)
37 {
39 }
40 
41 const QStringList& MessageRule::match() const
42 {
43  return myMatch;
44 }
45 
46 QStringList& MessageRule::match()
47 {
48  return myMatch;
49 }
50 
51 void MessageRule::setMatch(const QStringList& match)
52 {
53  myMatch = match;
54 }
55 
56 const QList<QStringList>& MessageRule::preconditions() const
57 {
58  return myPreconditions;
59 }
60 
61 void MessageRule::setPreconditions(const QList<QStringList>& preconditions)
62 {
64 }
65 
66 const QList<QStringList>& MessageRule::postconditions() const
67 {
68  return myPostconditions;
69 }
70 
71 void MessageRule::setPostconditions(const QList<QStringList>& postconditions)
72 {
74 }
75 
76 const QStringList& MessageRule::messages() const
77 {
78  return myMessages;
79 }
80 
81 void MessageRule::setMessages(const QStringList& messages)
82 {
84 }
85 
86 const QStringList& MessageRule::include() const
87 {
88  return myInclude;
89 }
90 
91 void MessageRule::setInclude(const QStringList& include)
92 {
94 }
95 
96 const QList<QStringList>& MessageRule::replies() const
97 {
98  return myReplies;
99 }
100 
101 void MessageRule::setReplies(const QList<QStringList>& replies)
102 {
103  myReplies = replies;
104 }
105 
107 {
108  return myIsModified;
109 }
110 
111 void MessageRule::setModified(bool modified)
112 {
113  myIsModified = modified;
114 }
115 
116 MessageFile::MessageFile(const QString& path)
117 {
118  myPath = path;
119  myIsModified = false;
120 }
121 
123 {
124  qDeleteAll(myRules);
125 }
126 
127 const QString& MessageFile::location() const
128 {
129  return myLocation;
130 }
131 
132 const QString& MessageFile::path() const
133 {
134  return myPath;
135 }
136 
137 void MessageFile::setPath(const QString& path)
138 {
139  if (myPath != path)
140  {
141  myPath = path;
142  setModified();
143  }
144 }
145 
146 void MessageFile::setLocation(const QString& location)
147 {
148  if (myLocation != location)
149  {
150  myLocation = location;
151  setModified();
152  }
153 }
154 
155 void convert(QScriptValue& value, QList<QStringList>& list)
156 {
157  list.clear();
158  int length = value.property("length").toInt32();
159  for (int l = 0; l < length; l++)
160  {
161  QStringList items;
162  QScriptValue sub = value.property(l);
163 
164  int subl = sub.property("length").toInt32();
165  for (int s = 0; s < subl; s++)
166  items.append(sub.property(s).toString());
167 
168  list.append(items);
169  }
170 }
171 
173 {
174  QString full = QString("%1/%2/%3").arg(settings.datadir, settings.mapdir, myPath);
175  QFile file(full);
176  file.open(QIODevice::ReadOnly);
177 
178  QByteArray data = file.readAll();
179  if (data.size() == 0)
180  return false;
181  QString script = data;
182  if (!script.startsWith('['))
183  script = "[" + script + "]";
184 
185  QScriptValue value;
186  QScriptEngine engine;
187  value = engine.evaluate(script);
188  if (engine.hasUncaughtException())
189  {
190  qDebug() << "message file evaluate error" << myPath << engine.uncaughtException().toString();
191  return false;
192  }
193 
194  QScriptValue first = value.property(0);
195  myLocation = first.property("location").toString();
196 
197  QScriptValue rules = first.property("rules");
198  int length = rules.property("length").toInt32();
199  for (int r = 0; r < length; r++)
200  {
201  MessageRule* rule = new MessageRule();
202  myRules.append(rule);
203  QScriptValue v = rules.property(r);
204 
205  rule->setComment(v.property("comment").toString());
206 
207  QStringList items;
208  qScriptValueToSequence(v.property("match"), items);
209  rule->setMatch(items);
210 
211  QList<QStringList> lists;
212  QScriptValue p = v.property("pre");
213  convert(p, lists);
214  rule->setPreconditions(lists);
215 
216  p = v.property("post");
217  convert(p, lists);
218  rule->setPostconditions(lists);
219 
220  items.clear();
221  qScriptValueToSequence(v.property("include"), items);
222  rule->setInclude(items);
223 
224  items.clear();
225  qScriptValueToSequence(v.property("msg"), items);
226  rule->setMessages(items);
227 
228  p = v.property("replies");
229  convert(p, lists);
230  rule->setReplies(lists);
231  }
232  return true;
233 }
234 
235 QList<MessageRule*>& MessageFile::rules()
236 {
237  return myRules;
238 }
239 
240 QList<CREMapInformation*>& MessageFile::maps()
241 {
242  return myMaps;
243 }
244 
245 QString convert(const QString& text)
246 {
247  QString tmp(text);
248  return tmp.replace('"', "\\\"").replace('\n', "\\n");
249 }
250 
251 QString convert(const QStringList& list)
252 {
253  QStringList one;
254  foreach(const QString& line, list)
255  {
256  one.append("\"" + convert(line) + "\"");
257  }
258  return "[" + one.join(", ") + "]";
259 }
260 
261 QString convert(const QList<QStringList>& data)
262 {
263  QStringList lines;
264 
265  foreach(const QStringList& list, data)
266  {
267  lines.append(convert(list));
268  }
269 
270  return "[" + lines.join(", ") + "]";
271 }
272 
273 QString convert(const MessageRule* rule)
274 {
275  QString result;
276 
277  if (!rule->include().isEmpty())
278  {
279  result += "{\n \"include\" : " + convert(rule->include());
280  if (!rule->preconditions().isEmpty())
281  result += ",\n \"pre\" : " + convert(rule->preconditions());
282  result += "\n }";
283  return result;
284  }
285 
286  result += "{\n";
287 
288  if (!rule->comment().isEmpty())
289  {
290  result += " \"comment\" : \"";
291  result += convert(rule->comment());
292  result += "\",\n";
293  }
294 
295  result += " \"match\" : ";
296  result += convert(rule->match());
297 
298  result += ",\n \"pre\" : ";
299  result += convert(rule->preconditions());
300 
301  result += ",\n \"post\" : ";
302  result += convert(rule->postconditions());
303 
304  result += ",\n \"msg\" : ";
305  result += convert(rule->messages());
306 
307  if (!rule->replies().isEmpty())
308  {
309  result += ",\n \"replies\" : ";
310  result += convert(rule->replies());
311  }
312 
313  result += "\n }";
314 
315  return result;
316 }
317 
319 {
320  bool one = myIsModified;
321  foreach(MessageRule* rule, myRules)
322  {
323  if (rule->isModified())
324  {
325  one = true;
326  break;
327  }
328  }
329  if (!one)
330  return;
331 
332  qDebug() << "MessageFile saving" << myPath;
333 
334  QString data = "{\n";
335  if (!myLocation.isEmpty())
336  data += " \"location\" : \"" + myLocation + "\",\n";
337  data += " \"rules\": [\n ";
338 
339  QStringList rules;
340  foreach(MessageRule* rule, myRules)
341  {
342  rules.append(convert(rule));
343  rule->setModified(false);
344  }
345 
346  data += rules.join(", ");
347  data += "\n]}\n";
348 
349  QString full = QString("%1/%2/%3").arg(settings.datadir, settings.mapdir, myPath);
350  QFile file(full);
351  file.open(QIODevice::WriteOnly | QIODevice::Truncate);
352  file.write(data.toAscii());
353  file.close();
354 
355  setModified(false);
356 }
357 
359 {
360  return myIsModified;
361 }
362 
363 void MessageFile::setModified(bool modified)
364 {
365  myIsModified = modified;
366 }
const QList< QStringList > & postconditions() const
Definition: MessageFile.cpp:66
const QString & location() const
const QList< QStringList > & preconditions() const
Definition: MessageFile.cpp:56
bool isModified() const
QStringList myInclude
Definition: MessageFile.h:44
const QString & comment() const
Definition: MessageFile.cpp:31
void setPostconditions(const QList< QStringList > &postconditions)
Definition: MessageFile.cpp:71
Global type definitions and header inclusions.
void setModified(bool modified=true)
virtual ~MessageRule()
Definition: MessageFile.cpp:27
void setPath(const QString &path)
QString myComment
Definition: MessageFile.h:39
QList< MessageRule * > & rules()
QStringList myMatch
Definition: MessageFile.h:40
void setPreconditions(const QList< QStringList > &preconditions)
Definition: MessageFile.cpp:61
void setModified(bool modified=true)
QList< QStringList > myPostconditions
Definition: MessageFile.h:42
void convert(QScriptValue &value, QList< QStringList > &list)
void setMatch(const QStringList &match)
Definition: MessageFile.cpp:51
void setReplies(const QList< QStringList > &replies)
ignore_list ** lists
void setInclude(const QStringList &include)
Definition: MessageFile.cpp:91
void setComment(const QString &comment)
Definition: MessageFile.cpp:36
void setLocation(const QString &location)
const QStringList & match() const
Definition: MessageFile.cpp:41
const char * datadir
Read only data files.
Definition: global.h:244
bool myIsModified
Definition: MessageFile.h:38
QList< QStringList > myPreconditions
Definition: MessageFile.h:41
void setMessages(const QStringList &messages)
Definition: MessageFile.cpp:81
QStringList myMessages
Definition: MessageFile.h:43
const char * mapdir
Where the map files are.
Definition: global.h:247
struct Settings settings
Server settings.
Definition: init.c:40
const QStringList & include() const
Definition: MessageFile.cpp:86
QList< QStringList > myReplies
Definition: MessageFile.h:45
MessageFile(const QString &path)
bool parseFile()
virtual ~MessageFile()
QList< CREMapInformation * > & maps()
const QString & path() const
bool isModified() const
const QStringList & messages() const
Definition: MessageFile.cpp:76
const QList< QStringList > & replies() const
Definition: MessageFile.cpp:96