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