Advertisement
Kalashnikov

Untitled

Oct 3rd, 2011
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 62.07 KB | None | 0 0
  1. #include "server.h"
  2. #include "player.h"
  3. #include "security.h"
  4. #include "antidos.h"
  5. #include "waitingobject.h"
  6. #include "tiermachine.h"
  7. #include "tier.h"
  8. #include "scriptengine.h"
  9. #include "../PokemonInfo/pokemoninfo.h"
  10. #include "../PokemonInfo/movesetchecker.h"
  11. #include "battle.h"
  12. #include <QRegExp>
  13. #include "analyze.h"
  14.  
  15. ScriptEngine::ScriptEngine(Server *s) {
  16.     setParent(s);
  17.     myserver = s;
  18.     mySessionDataFactory = new SessionDataFactory(&myengine);
  19.  
  20.     QScriptValue sys = myengine.newQObject(this);
  21.     myengine.globalObject().setProperty("sys", sys);
  22.     QScriptValue printfun = myengine.newFunction(nativePrint);
  23.     printfun.setData(sys);
  24.     myengine.globalObject().setProperty("print", printfun);
  25.     myengine.globalObject().setProperty(
  26.         "SESSION",
  27.         myengine.newQObject(mySessionDataFactory),
  28.         QScriptValue::ReadOnly | QScriptValue::Undeletable
  29.     );
  30.     // DB object.
  31.     myScriptDB = new ScriptDB(myserver, &myengine);
  32.     QScriptValue sysdb = myengine.newQObject(myScriptDB);
  33.     sys.setProperty("db", sysdb, QScriptValue::ReadOnly | QScriptValue::Undeletable);
  34.  
  35. #ifndef PO_SCRIPT_SAFE_ONLY
  36.     connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(webCall_replyFinished(QNetworkReply*)));
  37. #endif
  38.  
  39.     QFile f("scripts.js");
  40.     f.open(QIODevice::ReadOnly);
  41.  
  42.     changeScript(QString::fromUtf8(f.readAll()));
  43.  
  44.     QTimer *step_timer = new QTimer(this);
  45.     step_timer->setSingleShot(false);
  46.     step_timer->start(1000);
  47.     connect(step_timer, SIGNAL(timeout()), SLOT(timer_step()));
  48. }
  49.  
  50. ScriptEngine::~ScriptEngine()
  51. {
  52.     delete mySessionDataFactory;
  53. }
  54.  
  55. void ScriptEngine::changeScript(const QString &script, const bool triggerStartUp)
  56. {
  57.     mySessionDataFactory->disableAll();
  58.     myscript = myengine.evaluate(script);
  59.     myengine.globalObject().setProperty("script", myscript);
  60.  
  61.     if (myscript.isError()) {
  62.         printLine("Fatal Script Error line " + QString::number(myengine.uncaughtExceptionLineNumber()) + ": " + myscript.toString());
  63.     } else {
  64.         printLine("Script Check: OK");
  65.         if(triggerStartUp) {
  66.             serverStartUp();
  67.         }
  68.     }
  69.  
  70.     mySessionDataFactory->handleInitialState();
  71.     if (mySessionDataFactory->isRefillNeeded()) {
  72.         // Refill player session info if session data is no longer valid.
  73.         QList<int> keys = myserver->myplayers.keys();
  74.         for (int i = 0; i < keys.size(); i++) {
  75.             mySessionDataFactory->handleUserLogIn(keys[i]);
  76.         }
  77.         // Refill channels as well.
  78.         keys = myserver->channels.keys();
  79.         for (int i = 0; i < keys.size(); i++) {
  80.             int current_channel = keys[i];
  81.             // Default channel is already there.
  82.             if (current_channel != 0) {
  83.                 mySessionDataFactory->handleChannelCreate(current_channel);
  84.             }
  85.         }
  86.  
  87.         mySessionDataFactory->refillDone();
  88.     }
  89.     // Error check?
  90. }
  91.  
  92. void ScriptEngine::setPA(const QString &name)
  93. {
  94.     QScriptString str = myengine.toStringHandle(name);
  95.     if(playerArrays.contains(str))
  96.         return;
  97.  
  98.     playerArrays.push_back(str);
  99.     QScriptValue pa = myengine.newArray();
  100.  
  101.     myengine.globalObject().setProperty(name, pa);
  102. }
  103.  
  104. void ScriptEngine::unsetPA(const QString &name)
  105. {
  106.     QScriptString str = myengine.toStringHandle(name);
  107.     if (!playerArrays.contains(str))
  108.         return;
  109.  
  110.     playerArrays.removeOne(str);
  111.     myengine.globalObject().setProperty(name, QScriptValue());
  112. }
  113.  
  114. QScriptValue ScriptEngine::nativePrint(QScriptContext *context, QScriptEngine *engine)
  115. {
  116.     QString result;
  117.     for (int i = 0; i < context->argumentCount(); ++i) {
  118.         if (i > 0)
  119.             result.append(" ");
  120.         result.append(context->argument(i).toString());
  121.     }
  122.  
  123.     QScriptValue calleeData = context->callee().data();
  124.     ScriptEngine *obj = qobject_cast<ScriptEngine*>(calleeData.toQObject());
  125.     obj->printLine(result);
  126.  
  127.     return engine->undefinedValue();
  128. }
  129.  
  130. void ScriptEngine::print(QScriptContext *context, QScriptEngine *)
  131. {
  132.     QString result;
  133.     for (int i = 0; i < context->argumentCount(); ++i) {
  134.         if (i > 0)
  135.             result.append(" ");
  136.         result.append(context->argument(i).toString());
  137.     }
  138.  
  139.     printLine(result);
  140. }
  141.  
  142. bool ScriptEngine::testChannel(const QString &function, int id)
  143. {
  144.     if (!myserver->channelExist(id)) {
  145.         if (function.length() > 0)
  146.             warn(function, QString("No channel numbered %1 existing").arg(id));
  147.         return false;
  148.     }
  149.  
  150.     return true;
  151. }
  152.  
  153. bool ScriptEngine::testPlayer(const QString &function, int id)
  154. {
  155.     if (!loggedIn(id)) {
  156.         if (function.length() > 0)
  157.             warn(function, QString("No player numbered %1 existing").arg(id));
  158.         return false;
  159.     }
  160.  
  161.     return true;
  162. }
  163.  
  164. bool ScriptEngine::testPlayerInChannel(const QString &function, int id, int chan)
  165. {
  166.     if (!myserver->player(id)->getChannels().contains(chan)) {
  167.         if (function.length() > 0)
  168.             warn(function, QString("Player number %1 is not in channel number %2").arg(id).arg(chan));
  169.         return false;
  170.     }
  171.  
  172.     return true;
  173. }
  174.  
  175. bool ScriptEngine::testRange(const QString &function, int val, int min, int max)
  176. {
  177.     if (val < min || val > max) {
  178.         if (function.length() > 0)
  179.             warn(function, QString("%1 is out of the range [%2, %3]").arg(val).arg(min).arg(max));
  180.         return false;
  181.     }
  182.  
  183.     return true;
  184. }
  185.  
  186. void ScriptEngine::warn(const QString &function, const QString &message)
  187. {
  188.     printLine(QString("Script Warning in %1: %2").arg(function, message));
  189. }
  190.  
  191. bool ScriptEngine::beforeChatMessage(int src, const QString &message, int channel)
  192. {
  193.     return makeSEvent("beforeChatMessage", src, message, channel);
  194. }
  195.  
  196. void ScriptEngine::afterChatMessage(int src, const QString &message, int channel)
  197. {
  198.     makeEvent("afterChatMessage", src, message, channel);
  199. }
  200.  
  201. bool ScriptEngine::beforeSpectateBattle(int src, int p1, int p2)
  202. {
  203.     return makeSEvent("beforeSpectateBattle", src, p1, p2);
  204. }
  205.  
  206. void ScriptEngine::afterSpectateBattle(int src, int p1, int p2)
  207. {
  208.     makeEvent("beforeSpectateBattle", src, p1, p2);
  209. }
  210.  
  211.  
  212. bool ScriptEngine::beforeNewMessage(const QString &message)
  213. {
  214.     return makeSEvent("beforeNewMessage", message);
  215. }
  216.  
  217. void ScriptEngine::afterNewMessage(const QString &message)
  218. {
  219.     makeEvent("afterNewMessage", message);
  220. }
  221.  
  222. void ScriptEngine::serverStartUp()
  223. {
  224.     evaluate(myscript.property("serverStartUp").call(myscript, QScriptValueList()));
  225. }
  226.  
  227. void ScriptEngine::stepEvent()
  228. {
  229.     evaluate(myscript.property("step").call(myscript, QScriptValueList()));
  230. }
  231.  
  232. void ScriptEngine::serverShutDown()
  233. {
  234.     evaluate(myscript.property("serverShutDown").call(myscript, QScriptValueList()));
  235. }
  236.  
  237. bool ScriptEngine::beforeLogIn(int src)
  238. {
  239.     return makeSEvent("beforeLogIn", src);
  240. }
  241.  
  242. void ScriptEngine::afterLogIn(int src)
  243. {
  244.     mySessionDataFactory->handleUserLogIn(src);
  245.     makeEvent("afterLogIn", src);
  246. }
  247.  
  248. bool ScriptEngine::beforeChannelCreated(int channelid, const QString &channelname, int playerid)
  249. {
  250.     return makeSEvent("beforeChannelCreated", channelid, channelname, playerid);
  251. }
  252.  
  253. void ScriptEngine::afterChannelCreated(int channelid, const QString &channelname, int playerid)
  254. {
  255.     mySessionDataFactory->handleChannelCreate(channelid);
  256.     makeEvent("afterChannelCreated", channelid, channelname, playerid);
  257. }
  258.  
  259. bool ScriptEngine::beforeChannelDestroyed(int channelid)
  260. {
  261.     return makeSEvent("beforeChannelDestroyed", channelid);
  262. }
  263.  
  264. void ScriptEngine::afterChannelDestroyed(int channelid)
  265. {
  266.     makeEvent("afterChannelDestroyed", channelid);
  267.     mySessionDataFactory->handleChannelDestroy(channelid);
  268. }
  269.  
  270. bool ScriptEngine::beforeChannelJoin(int playerid, int channelid)
  271. {
  272.     return makeSEvent("beforeChannelJoin", playerid, channelid);
  273. }
  274.  
  275. void ScriptEngine::afterChannelJoin(int playerid, int channelid)
  276. {
  277.     makeEvent("afterChannelJoin", playerid, channelid);
  278. }
  279.  
  280. void ScriptEngine::beforeChannelLeave(int playerid, int channelid)
  281. {
  282.     makeEvent("beforeChannelLeave", playerid, channelid);
  283. }
  284.  
  285. void ScriptEngine::afterChannelLeave(int playerid, int channelid)
  286. {
  287.     makeEvent("afterChannelLeave", playerid, channelid);
  288. }
  289.  
  290. void ScriptEngine::beforeChangeTeam(int src)
  291. {
  292.     makeEvent("beforeChangeTeam", src);
  293. }
  294.  
  295. void ScriptEngine::afterChangeTeam(int src)
  296. {
  297.     makeEvent("afterChangeTeam", src);
  298. }
  299.  
  300. bool ScriptEngine::beforeChangeTier(int src, const QString &oldTier, const QString &newTier)
  301. {
  302.     return makeSEvent("beforeChangeTier", src, oldTier, newTier);
  303. }
  304.  
  305. void ScriptEngine::afterChangeTier(int src, const QString &oldTier, const QString &newTier)
  306. {
  307.     makeEvent("afterChangeTier", src, oldTier, newTier);
  308. }
  309.  
  310. bool ScriptEngine::beforeChallengeIssued(int src, int dest, const ChallengeInfo &c)
  311. {
  312.     if (!myscript.property("beforeChallengeIssued", QScriptValue::ResolveLocal).isValid())
  313.         return true;
  314.  
  315.     startStopEvent();
  316.  
  317.     evaluate(myscript.property("beforeChallengeIssued").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode));
  318.  
  319.     return !endStopEvent();
  320. }
  321.  
  322. void ScriptEngine::afterChallengeIssued(int src, int dest, const ChallengeInfo &c)
  323. {
  324.     if (!myscript.property("afterChallengeIssued", QScriptValue::ResolveLocal).isValid())
  325.         return;
  326.  
  327.     evaluate(myscript.property("afterChallengeIssued").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode));
  328. }
  329.  
  330. bool ScriptEngine::beforeBattleMatchup(int src, int dest, const ChallengeInfo &c)
  331. {
  332.     if (!myscript.property("beforeBattleMatchup", QScriptValue::ResolveLocal).isValid())
  333.         return true;
  334.  
  335.     startStopEvent();
  336.  
  337.     evaluate(myscript.property("beforeBattleMatchup").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode));
  338.  
  339.     return !endStopEvent();
  340. }
  341.  
  342. void ScriptEngine::afterBattleMatchup(int src, int dest, const ChallengeInfo &c)
  343. {
  344.     if (!myscript.property("afterBattleMatchup", QScriptValue::ResolveLocal).isValid())
  345.         return;
  346.  
  347.     evaluate(myscript.property("afterBattleMatchup").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode));
  348. }
  349.  
  350.  
  351. void ScriptEngine::beforeBattleStarted(int src, int dest, const ChallengeInfo &c, int id)
  352. {
  353.     if (!myscript.property("beforeBattleStarted", QScriptValue::ResolveLocal).isValid())
  354.         return;
  355.  
  356.     evaluate(myscript.property("beforeBattleStarted").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode << id));
  357. }
  358.  
  359. void ScriptEngine::afterBattleStarted(int src, int dest, const ChallengeInfo &c, int id)
  360. {
  361.     if (!myscript.property("afterBattleStarted", QScriptValue::ResolveLocal).isValid())
  362.         return;
  363.  
  364.     evaluate(myscript.property("afterBattleStarted").call(myscript, QScriptValueList() << src << dest << c.clauses << c.rated << c.mode << id));
  365. }
  366.  
  367. QString battleDesc[3] = {
  368.     "forfeit",
  369.     "win",
  370.     "tie"
  371. };
  372.  
  373. void ScriptEngine::beforeBattleEnded(int src, int dest, int desc, int battleid)
  374. {
  375.     if (!myscript.property("beforeBattleEnded", QScriptValue::ResolveLocal).isValid())
  376.         return;
  377.     if (desc < 0 || desc > 2)
  378.         return;
  379.     evaluate(myscript.property("beforeBattleEnded").call(myscript, QScriptValueList() << src << dest << battleDesc[desc] << battleid));
  380. }
  381.  
  382. void ScriptEngine::afterBattleEnded(int src, int dest, int desc, int battleid)
  383. {
  384.     if (!myscript.property("afterBattleEnded", QScriptValue::ResolveLocal).isValid())
  385.         return;
  386.     if (desc < 0 || desc > 2)
  387.         return;
  388.     evaluate(myscript.property("afterBattleEnded").call(myscript, QScriptValueList() << src << dest << battleDesc[desc] << battleid));
  389. }
  390.  
  391. void ScriptEngine::beforeLogOut(int src)
  392. {
  393.     makeEvent("beforeLogOut", src);
  394. }
  395.  
  396. void ScriptEngine::afterLogOut(int src)
  397. {
  398.     makeEvent("afterLogOut", src);
  399.  
  400.     /* Removes the player from the player array */
  401.     foreach(QScriptString pa, playerArrays) {
  402.         if (!myengine.globalObject().property(pa).isNull()) {
  403.             myengine.globalObject().property(pa).setProperty(src, QScriptValue());
  404.         }
  405.     }
  406.  
  407.     mySessionDataFactory->handleUserLogOut(src);
  408. }
  409.  
  410. bool ScriptEngine::beforePlayerKick(int src, int dest)
  411. {
  412.     return makeSEvent("beforePlayerKick", src, dest);
  413. }
  414.  
  415. void ScriptEngine::afterPlayerKick(int src, int dest)
  416. {
  417.     makeEvent("afterPlayerKick", src, dest);
  418. }
  419.  
  420. bool ScriptEngine::beforePlayerBan(int src, int dest)
  421. {
  422.     return makeSEvent("beforePlayerBan", src, dest);
  423. }
  424.  
  425. void ScriptEngine::afterPlayerBan(int src, int dest)
  426. {
  427.     makeEvent("afterPlayerBan", src, dest);
  428. }
  429.  
  430. bool ScriptEngine::beforePlayerAway(int src, bool away)
  431. {
  432.     return makeSEvent("beforePlayerAway", src, away);
  433. }
  434.  
  435. void ScriptEngine::afterPlayerAway(int src, bool away)
  436. {
  437.     makeEvent("afterPlayerAway", src, away);
  438. }
  439.  
  440. void ScriptEngine::evaluate(const QScriptValue &expr)
  441. {
  442.     if (expr.isError()) {
  443.         printLine(QString("Script Error line %1: %2").arg(myengine.uncaughtExceptionLineNumber()).arg(expr.toString()));
  444.     }
  445. }
  446.  
  447. void ScriptEngine::sendAll(const QString &mess)
  448. {
  449.     myserver->sendAll(mess);
  450. }
  451.  
  452. void ScriptEngine::sendAll(const QString &mess, int channel)
  453. {
  454.     if (testChannel("sendAll(mess, channel)", channel)) {
  455.         myserver->sendChannelMessage(channel, mess);
  456.     }
  457. }
  458.  
  459. void ScriptEngine::sendMessage(int id, const QString &mess)
  460. {
  461.     if (testPlayer("sendMessage(id, mess)", id)) {
  462.         myserver->sendMessage(id, mess);
  463.     }
  464. }
  465.  
  466. void ScriptEngine::sendMessage(int id, const QString &mess, int channel)
  467. {
  468.     if (testChannel("sendMessage(id, mess, channel)", channel) && testPlayer("sendMessage(id, mess, channel)", id) &&
  469.         testPlayerInChannel("sendMessage(id, mess, channel)", id, channel))
  470.     {
  471.         myserver->sendChannelMessage(id, channel, mess);
  472.     }
  473. }
  474.  
  475. void ScriptEngine::sendHtmlAll(const QString &mess)
  476. {
  477.     myserver->sendAll(mess, false, true);
  478. }
  479.  
  480. void ScriptEngine::sendHtmlAll(const QString &mess, int channel)
  481. {
  482.     if (testChannel("sendAll(mess, channel)", channel)) {
  483.         myserver->sendChannelMessage(channel, mess, false, true);
  484.     }
  485. }
  486.  
  487. void ScriptEngine::sendHtmlMessage(int id, const QString &mess)
  488. {
  489.     if (testPlayer("sendMessage(id, mess)", id)) {
  490.         myserver->sendMessage(id, mess, true);
  491.     }
  492. }
  493.  
  494. void ScriptEngine::sendHtmlMessage(int id, const QString &mess, int channel)
  495. {
  496.     if (testChannel("sendMessage(id, mess, channel)", channel) && testPlayer("sendMessage(id, mess, channel)", id) &&
  497.         testPlayerInChannel("sendMessage(id, mess, channel)", id, channel))
  498.     {
  499.         myserver->sendChannelMessage(id, channel, mess, true);
  500.     }
  501. }
  502.  
  503. void ScriptEngine::kick(int id)
  504. {
  505.     if (testPlayer("kick(id)", id)) {
  506.         myserver->silentKick(id);
  507.     }
  508. }
  509.  
  510. void ScriptEngine::kick(int id, int chanid)
  511. {
  512.     if (testPlayer("kick(id, channel)", id) && testChannel("kick(id, channel)", chanid)
  513.         && testPlayerInChannel("kick(id, channel)", id, chanid))
  514.     {
  515.         myserver->leaveRequest(id, chanid);
  516.     }
  517. }
  518.  
  519. void ScriptEngine::updatePlayer(int playerid)
  520. {
  521.     /* Updates all the info of the player to the other players
  522.        (mainly if you changed their team and want it to show in the challenge window) */
  523.     if (testPlayer("updatePlayer(playerid)", playerid)) {
  524.         myserver->sendPlayer(playerid);
  525.     }
  526. }
  527.  
  528. void ScriptEngine::putInChannel(int id, int chanid)
  529. {
  530.     if (!testPlayer("putInChannel(id, chanid)", id) || !testChannel("putInChannel(id, chanid)", chanid)) {
  531.         return;
  532.     }
  533.     if (myserver->player(id)->getChannels().contains(chanid)){
  534.         printLine(QString("Script Warning in sys.putInChannel(id, chan): player %1 is already in channel %2").arg(id).arg(chanid));
  535.     } else {
  536.         myserver->joinChannel(id, chanid);
  537.     }
  538. }
  539.  
  540. QScriptValue ScriptEngine::createChannel(const QString &channame)
  541. {
  542.     if (myserver->channelExist(channame)) {
  543.         return myengine.undefinedValue();
  544.     } else {
  545.         return myserver->addChannel(channame);
  546.     }
  547. }
  548.  
  549. bool ScriptEngine::existChannel(const QString &channame)
  550. {
  551.     return myserver->channelExist(channame);
  552. }
  553.  
  554. void ScriptEngine::clearPass(const QString &name)
  555. {
  556.     if (!SecurityManager::exist(name)) {
  557.         printLine("Script Warning in sys.clearPass(name): no such player name as " + name);
  558.     }
  559.     SecurityManager::clearPass(name);
  560. }
  561.  
  562. void ScriptEngine::changeAuth(int id, int auth)
  563. {
  564.     if (testPlayer("changeAuth(id, auth)", id)) {
  565.         if (myserver->isSafeScripts() && ((myserver->auth(id) > 2) || (auth > 2))) {
  566.             warn("changeAuth", "Safe scripts option is on. Unable to change auth to/from 3 and above.");
  567.         } else {
  568.             myserver->changeAuth(myserver->name(id), auth);
  569.         }
  570.     }
  571. }
  572.  
  573. void ScriptEngine::changeDbAuth(const QString &name, int auth)
  574. {
  575.     if (myserver->isSafeScripts()) {
  576.         if (!SecurityManager::exist(name)) return;
  577.         if ((SecurityManager::member(name).auth > 2) || (auth > 2)) {
  578.             warn("changeDbAuth", "Safe scripts option is on. Unable to change auth to/from 3 and above.");
  579.             return;
  580.         }
  581.     }
  582.     SecurityManager::setAuth(name, auth);
  583. }
  584.  
  585. void ScriptEngine::changeAway(int id, bool away)
  586. {
  587.     if (testPlayer("changeAway(id, away)", id)) {
  588.         myserver->player(id)->executeAwayChange(away);
  589.     }
  590. }
  591.  
  592. void ScriptEngine::changeRating(const QString& name, const QString& tier, int newRating)
  593. {
  594.     if (!TierMachine::obj()->exists(tier))
  595.         printLine("Script Warning in sys.changeRating(name, tier, rating): no such tier as " + tier);
  596.     else
  597.         TierMachine::obj()->changeRating(name, tier, newRating);
  598. }
  599.  
  600. void ScriptEngine::changeTier(int id, const QString &tier)
  601. {
  602.     if (!TierMachine::obj()->exists(tier))
  603.         printLine("Script Warning in sys.changeTier(id, tier): no such tier as " + tier);
  604.     else if (testPlayer("changeTier(id, tier)", id)) {
  605.         myserver->player(id)->executeTierChange(tier);
  606.     }
  607. }
  608.  
  609. void ScriptEngine::reloadTiers()
  610. {
  611.     TierMachine::obj()->load();
  612. }
  613.  
  614. void ScriptEngine::changePokeItem(int id, int slot, int item)
  615. {
  616.     if (!testPlayer("changePokeItem(id, slot, item)", id) || !testRange("changePokeItem(id, slot, item)", slot, 0, 5))
  617.         return;
  618.     if (!ItemInfo::Exists(item))
  619.         return;
  620.     myserver->player(id)->team().poke(slot).item() = item;
  621. }
  622.  
  623. void ScriptEngine::changePokeNum(int id, int slot, int num)
  624. {
  625.     if (!testPlayer("changePokeNum(id, slot, item)", id) || !testRange("changePokeNum(id, slot, num)", slot, 0, 5))
  626.         return;
  627.     if (!PokemonInfo::Exists(num, myserver->player(id)->gen()))
  628.         return;
  629.     myserver->player(id)->team().poke(slot).num() = num;
  630. }
  631.  
  632. void ScriptEngine::changePokeLevel(int id, int slot, int level)
  633. {
  634.     if (!testPlayer("changePokeLevel(id, slot, level)", id) || !testRange("changePokeLevel(id, slot, level)", slot, 0, 5) || !testRange("changePokeLevel(id, slot, level)", level, 1, 100))
  635.         return;
  636.     Player *p = myserver->player(id);
  637.     p->team().poke(slot).level() = level;
  638.     p->team().poke(slot).updateStats(p->gen());
  639. }
  640.  
  641. void ScriptEngine::changePokeMove(int id, int pslot, int mslot, int move)
  642. {
  643.     if (!testPlayer("changePokeLevel(id, pokeslot, moveslot, move)", id) || !testRange("changePokeLevel(id, pokeslot, moveslot, move)", pslot, 0, 5) || !testRange("changePokeLevel(id, pokeslot, moveslot, move)", mslot, 0, 3))
  644.         return;
  645.     if (!MoveInfo::Exists(move, GEN_MAX))
  646.         return;
  647.     Player *p = myserver->player(id);
  648.     p->team().poke(pslot).move(mslot).num() = move;
  649.     p->team().poke(pslot).move(mslot).load(p->gen());
  650. }
  651.  
  652. void ScriptEngine::changePokeGender(int id, int pokeslot, int gender)
  653. {
  654.     if (!testPlayer("changePokeGender(id, pokeslot, gender)", id) || !testRange("changePokeGender(id, pokeslot, gender)", pokeslot, 0, 5) || !testRange("changePokeGender(id, pokeslot, gender)", gender, 0, 2))
  655.         return;
  656.     Player *p = myserver->player(id);
  657.     p->team().poke(pokeslot).gender() = gender;
  658. }
  659.  
  660. void ScriptEngine::changePokeName(int id, int pokeslot, const QString &name)
  661. {
  662.     if (!testPlayer("changePokeName(id, pokeslot, name)", id)|| !testRange("changePokeName(id, pokeslot, name)", pokeslot, 0, 5))
  663.         return;
  664.     Player *p = myserver->player(id);
  665.     p->team().poke(pokeslot).nick() = name;
  666. }
  667.  
  668. bool ScriptEngine::hasLegalTeamForTier(int id, const QString &tier)
  669. {
  670.     if (!TierMachine::obj()->exists(tier))
  671.         return false;
  672.     return TierMachine::obj()->isValid(myserver->player(id)->team(),tier);
  673. }
  674.  
  675. int ScriptEngine::maxAuth(const QString &ip)
  676. {
  677.     return SecurityManager::maxAuth(ip);
  678. }
  679.  
  680. QScriptValue ScriptEngine::aliases(const QString &ip)
  681. {
  682.     QStringList mip = SecurityManager::membersForIp(ip);
  683.  
  684.     QScriptValue ret = myengine.newArray(mip.count());
  685.  
  686.     for(int i = 0; i < mip.size(); i++) {
  687.         ret.setProperty(i, mip[i]);
  688.     }
  689.  
  690.     return ret;
  691. }
  692.  
  693. QScriptValue ScriptEngine::memoryDump()
  694. {
  695.     QString ret;
  696.  
  697.     ret += QString("Members\n\tCached in memory> %1\n\tCached as non-existing> %2\n").arg(SecurityManager::holder.cachedMembersCount()).arg(SecurityManager::holder.cachedNonExistingCount());
  698.     ret += QString("Waiting Objects\n\tFree Objects> %1\n\tTotal Objects> %2\n").arg(WaitingObjects::freeObjects.count()).arg(WaitingObjects::objectCount);
  699.     ret += QString("Battles\n\tActive> %1\n\tRated Battles History> %2\n").arg(myserver->mybattles.count()).arg(myserver->lastRatedIps.count());
  700.     ret += QString("Antidos\n\tConnections Per IP> %1\n\tLogins per IP> %2\n\tTransfers Per Id> %3\n\tSize of Transfers> %4\n\tKicks per IP> %5\n").arg(AntiDos::obj()->connectionsPerIp.count()).arg(
  701.             AntiDos::obj()->loginsPerIp.count()).arg(AntiDos::obj()->transfersPerId.count()).arg(AntiDos::obj()->sizeOfTransfers.count())
  702.            .arg(AntiDos::obj()->kicksPerIp.count());
  703.     ret += QString("-------------------------\n-------------------------\n");
  704.  
  705.     foreach (QString tier, TierMachine::obj()->tierList().split('\n')) {
  706.         const Tier &t = TierMachine::obj()->tier(tier);
  707.         ret += QString("Tier %1\n\tCached in memory> %2\n\tCached as non-existing> %3\n").arg(tier).arg(t.holder.cachedMembersCount()).arg(t.holder.cachedNonExistingCount());
  708.     }
  709.  
  710.     return ret;
  711. }
  712.  
  713. void ScriptEngine::exportMemberDatabase()
  714. {
  715.     SecurityManager::exportDatabase();
  716. }
  717.  
  718. void ScriptEngine::exportTierDatabase()
  719. {
  720.     TierMachine::obj()->exportDatabase();
  721. }
  722.  
  723. void ScriptEngine::clearChat()
  724. {
  725.     emit clearTheChat();
  726. }
  727.  
  728. bool ScriptEngine::dbRegistered(const QString &name)
  729. {
  730.     return SecurityManager::member(name).isProtected();
  731. }
  732.  
  733. void ScriptEngine::callLater(const QString &expr, int delay)
  734. {
  735.     if (delay <= 0) {
  736.         return;
  737.     }
  738.     //qDebug() << "Call Later in " << delay << expr;
  739.     QTimer *t = new QTimer();
  740.  
  741.     timerEvents[t] = expr;
  742.     t->setSingleShot(true);
  743.     t->start(delay*1000);
  744.     connect(t, SIGNAL(timeout()), SLOT(timer()), Qt::DirectConnection);
  745. }
  746.  
  747. void ScriptEngine::callQuickly(const QString &expr, int delay)
  748. {
  749.     if (delay <= 0) {
  750.         return;
  751.     }
  752.  
  753.     QTimer *t = new QTimer(this);
  754.  
  755.     timerEvents[t] = expr;
  756.     t->setSingleShot(true);
  757.     t->start(delay);
  758.     connect(t, SIGNAL(timeout()), SLOT(timer()));
  759. }
  760.  
  761. void ScriptEngine::timer()
  762. {
  763.     //qDebug() << "timer()";
  764.     QTimer *t = (QTimer*) sender();
  765.     //qDebug() << timerEvents[t];
  766.     eval(timerEvents[t]);
  767.  
  768.     timerEvents.remove(t);
  769.     t->deleteLater();
  770. }
  771.  
  772. void ScriptEngine::timer_step()
  773. {
  774.     this->stepEvent();
  775. }
  776.  
  777. void ScriptEngine::delayedCall(const QScriptValue &func, int delay)
  778. {
  779.     if (delay <= 0) return;
  780.     if (func.isFunction()) {
  781.         QTimer *t = new QTimer(this);
  782.         timerEventsFunc[t] = func;
  783.         t->setSingleShot(true);
  784.         t->start(delay*1000);
  785.         connect(t, SIGNAL(timeout()), SLOT(timerFunc()));
  786.     }
  787. }
  788.  
  789. void ScriptEngine::timerFunc()
  790. {
  791.     QTimer *t = (QTimer*) sender();
  792.     timerEventsFunc[t].call();
  793.     timerEventsFunc.remove(t);
  794.     t->deleteLater();
  795. }
  796.  
  797.  
  798. QScriptValue ScriptEngine::eval(const QString &script)
  799. {
  800.     return myengine.evaluate(script);
  801. }
  802.  
  803. QScriptValue ScriptEngine::auth(int id)
  804. {
  805.     if (!myserver->playerLoggedIn(id)) {
  806.         return myengine.undefinedValue();
  807.     } else {
  808.         return myserver->auth(id);
  809.     }
  810. }
  811.  
  812. QScriptValue ScriptEngine::dbAuth(const QString &name)
  813. {
  814.     if (!SecurityManager::exist(name)) {
  815.         return myengine.undefinedValue();
  816.     } else {
  817.         return SecurityManager::member(name).auth;
  818.     }
  819. }
  820.  
  821. QScriptValue ScriptEngine::dbAuths()
  822. {
  823.     QStringList sl = SecurityManager::authList();
  824.  
  825.     QScriptValue ret = myengine.newArray(sl.count());
  826.  
  827.     for (int i = 0; i < sl.size(); i++) {
  828.         ret.setProperty(i, sl[i]);
  829.     }
  830.  
  831.     return ret;
  832. }
  833.  
  834. QScriptValue ScriptEngine::dbAll()
  835. {
  836.     QStringList sl = SecurityManager::userList();
  837.  
  838.     QScriptValue ret = myengine.newArray(sl.count());
  839.  
  840.     for (int i = 0; i < sl.size(); i++) {
  841.         ret.setProperty(i, sl[i]);
  842.     }
  843.  
  844.     return ret;
  845. }
  846.  
  847. QScriptValue ScriptEngine::dbIp(const QString &name)
  848. {
  849.     if (!SecurityManager::exist(name)) {
  850.         return myengine.undefinedValue();
  851.     } else {
  852.         return QString(SecurityManager::member(name).ip);
  853.     }
  854. }
  855.  
  856. QScriptValue ScriptEngine::dbDelete(const QString &name)
  857. {
  858.     if (!SecurityManager::exist(name)) {
  859.         return myengine.undefinedValue();
  860.     } else {
  861.         SecurityManager::deleteUser(name);
  862.         return myengine.undefinedValue();
  863.     }
  864. }
  865.  
  866. QScriptValue ScriptEngine::dbLastOn(const QString &name)
  867. {
  868.     if (!SecurityManager::exist(name)) {
  869.         return myengine.undefinedValue();
  870.     } else {
  871.         return QString(SecurityManager::member(name).date);
  872.     }
  873. }
  874.  
  875.  
  876. QScriptValue ScriptEngine::battling(int id)
  877. {
  878.     if (!myserver->playerLoggedIn(id)) {
  879.         return myengine.undefinedValue();
  880.     } else {
  881.         return myserver->player(id)->battling();
  882.     }
  883. }
  884.  
  885. QScriptValue ScriptEngine::away(int id)
  886. {
  887.     if (!myserver->playerLoggedIn(id)) {
  888.         return myengine.undefinedValue();
  889.     } else {
  890.         return myserver->player(id)->away();
  891.     }
  892. }
  893.  
  894. QScriptValue ScriptEngine::getColor(int id)
  895. {
  896.     if (!myserver->playerLoggedIn(id)) {
  897.         return myengine.undefinedValue();
  898.     } else {
  899.         return myserver->player(id)->color().name();
  900.     }
  901. }
  902.  
  903. QScriptValue ScriptEngine::tier(int id)
  904. {
  905.     if (!myserver->playerLoggedIn(id)) {
  906.         return myengine.undefinedValue();
  907.     } else {
  908.         return myserver->player(id)->tier();
  909.     }
  910. }
  911.  
  912. QScriptValue ScriptEngine::ranking(int id)
  913. {
  914.     Player *p = myserver->player(id);
  915.     return ranking(p->name(), p->tier());
  916. }
  917.  
  918. QScriptValue ScriptEngine::ratedBattles(int id)
  919. {
  920.     Player *p = myserver->player(id);
  921.     return ratedBattles(p->name(), p->tier());
  922. }
  923.  
  924. QScriptValue ScriptEngine::ranking(const QString &name, const QString &tier)
  925. {
  926.     if (!TierMachine::obj()->existsPlayer(tier, name)) {
  927.         return myengine.undefinedValue();
  928.     }
  929.     return TierMachine::obj()->ranking(name, tier);
  930. }
  931.  
  932. QScriptValue ScriptEngine::ratedBattles(const QString &name, const QString &tier)
  933. {
  934.     if (!TierMachine::obj()->existsPlayer(tier, name)) {
  935.         return 0;
  936.     }
  937.     return TierMachine::obj()->tier(tier).ratedBattles(name);
  938. }
  939.  
  940. QScriptValue ScriptEngine::totalPlayersByTier(const QString &tier)
  941. {
  942.     return TierMachine::obj()->count(tier);
  943. }
  944.  
  945. QScriptValue ScriptEngine::ladderRating(int id, const QString &tier)
  946. {
  947.     if (!myserver->playerLoggedIn(id)) {
  948.         return myengine.undefinedValue();
  949.     } else {
  950.         if (tier.isEmpty()) {
  951.             return myserver->player(id)->rating();
  952.         } else {
  953.             return TierMachine::obj()->rating(myserver->player(id)->name(), tier);
  954.         }
  955.     }
  956. }
  957.  
  958. QScriptValue ScriptEngine::ladderEnabled(int id)
  959. {
  960.     if (!myserver->playerLoggedIn(id)) {
  961.         return myengine.undefinedValue();
  962.     } else {
  963.         return myserver->player(id)->ladder();
  964.     }
  965. }
  966.  
  967. QScriptValue ScriptEngine::ip(int id)
  968. {
  969.     if (!myserver->playerLoggedIn(id)) {
  970.         return myengine.undefinedValue();
  971.     } else {
  972.         return myserver->player(id)->ip();
  973.     }
  974. }
  975.  
  976. QScriptValue ScriptEngine::proxyIp(int id)
  977. {
  978.     if (!myserver->playerLoggedIn(id)) {
  979.         return myengine.undefinedValue();
  980.     } else {
  981.         return myserver->player(id)->proxyIp();
  982.     }
  983. }
  984.  
  985. QScriptValue ScriptEngine::gen(int id)
  986. {
  987.     if (!myserver->playerLoggedIn(id)) {
  988.         return myengine.undefinedValue();
  989.     } else {
  990.         return myserver->player(id)->gen();
  991.     }
  992. }
  993.  
  994. QScriptValue ScriptEngine::name(int id)
  995. {
  996.     if (!myserver->playerExist(id)) {
  997.         return myengine.undefinedValue();
  998.     } else {
  999.         return myserver->name(id);
  1000.     }
  1001. }
  1002.  
  1003. QScriptValue ScriptEngine::id(const QString &name)
  1004. {
  1005.     if (!myserver->nameExist(name)) {
  1006.         return myengine.undefinedValue();
  1007.     } else {
  1008.         return myserver->id(name);
  1009.     }
  1010. }
  1011.  
  1012. QScriptValue ScriptEngine::pokemon(int num)
  1013. {
  1014.     return PokemonInfo::Name(num);
  1015. }
  1016.  
  1017. QScriptValue ScriptEngine::pokeNum(const QString &name)
  1018. {
  1019.     QString copy = name;
  1020.     bool up = true;
  1021.     for (int i = 0; i < copy.length(); i++) {
  1022.         if (up) {
  1023.             copy[i] = copy[i].toUpper();
  1024.             up = false;
  1025.         } else {
  1026.             if (copy[i] == '-' || copy[i] == ' ')
  1027.                 up = true;
  1028.             copy[i] = copy[i].toLower();
  1029.         }
  1030.     }
  1031.     Pokemon::uniqueId num = PokemonInfo::Number(copy);
  1032.     if (num.toPokeRef() == Pokemon::NoPoke) {
  1033.         return myengine.undefinedValue();
  1034.     } else {
  1035.         return num.toPokeRef();
  1036.     }
  1037. }
  1038.  
  1039. QScriptValue ScriptEngine::move(int num)
  1040. {
  1041.     if (num < 0  || num >= MoveInfo::NumberOfMoves()) {
  1042.         return myengine.undefinedValue();
  1043.     } else {
  1044.         return MoveInfo::Name(num);
  1045.     }
  1046. }
  1047.  
  1048. QString convertToSerebiiName(const QString input)
  1049. {
  1050.     QString truename = input;
  1051.     bool blankbefore = true;
  1052.     for (int i = 0; i < truename.length(); i++) {
  1053.         if (truename[i].isSpace()) {
  1054.             blankbefore = true;
  1055.         } else {
  1056.             if (blankbefore) {
  1057.                 truename[i] = truename[i].toUpper();
  1058.                 blankbefore = false;
  1059.             } else {
  1060.                 truename[i] = truename[i].toLower();
  1061.             }
  1062.         }
  1063.     }
  1064.     return truename;
  1065. }
  1066.  
  1067. QScriptValue ScriptEngine::moveNum(const QString &name)
  1068. {
  1069.     int num = MoveInfo::Number(convertToSerebiiName(name));
  1070.     return num == 0 ? myengine.undefinedValue() : num;
  1071. }
  1072.  
  1073. QScriptValue ScriptEngine::item(int num)
  1074. {
  1075.     if (ItemInfo::Exists(num)) {
  1076.         return ItemInfo::Name(num);
  1077.     } else {
  1078.         return myengine.undefinedValue();
  1079.     }
  1080. }
  1081.  
  1082. QScriptValue ScriptEngine::itemNum(const QString &name)
  1083. {
  1084.     int num = ItemInfo::Number(convertToSerebiiName(name));
  1085.     return num == 0 ? myengine.undefinedValue() : num;
  1086. }
  1087.  
  1088.  
  1089. QScriptValue ScriptEngine::nature(int num)
  1090. {
  1091.     if (num >= 0 && num < NatureInfo::NumberOfNatures()) {
  1092.         return NatureInfo::Name(num);
  1093.     } else {
  1094.         return myengine.undefinedValue();
  1095.     }
  1096. }
  1097.  
  1098. QScriptValue ScriptEngine::natureNum(const QString &name)
  1099. {
  1100.     return NatureInfo::Number(convertToSerebiiName(name));
  1101. }
  1102.  
  1103. QScriptValue ScriptEngine::ability(int num)
  1104. {
  1105.     if (num >= 0 && num < AbilityInfo::NumberOfAbilities()) {
  1106.         return AbilityInfo::Name(num);
  1107.     } else {
  1108.         return myengine.undefinedValue();
  1109.     }
  1110. }
  1111.  
  1112. QScriptValue ScriptEngine::abilityNum(const QString &ability)
  1113. {
  1114.     return AbilityInfo::Number(ability);
  1115. }
  1116.  
  1117. QScriptValue ScriptEngine::genderNum(QString genderName)
  1118. {
  1119.     if(genderName.toLower() == "genderless") {
  1120.         return 0;
  1121.     }
  1122.     if(genderName.toLower() == "male") {
  1123.         return 1;
  1124.     }
  1125.     if(genderName.toLower() == "female") {
  1126.         return 2;
  1127.     }
  1128.     return "";
  1129. }
  1130.  
  1131. QString ScriptEngine::gender(int genderNum)
  1132. {
  1133.     switch(genderNum) {
  1134.         case 0:
  1135.             return "genderless";
  1136.         case 1:
  1137.             return "male";
  1138.         case 2:
  1139.             return "female";
  1140.     }
  1141.     return "";
  1142. }
  1143.  
  1144. QScriptValue ScriptEngine::teamPoke(int id, int index)
  1145. {
  1146.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1147.         return myengine.undefinedValue();
  1148.     } else {
  1149.         return myserver->player(id)->team().poke(index).num().toPokeRef();
  1150.     }
  1151. }
  1152.  
  1153. QScriptValue ScriptEngine::teamPokeLevel(int id, int index)
  1154. {
  1155.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1156.         return myengine.undefinedValue();
  1157.     } else {
  1158.         return myserver->player(id)->team().poke(index).level();
  1159.     }
  1160. }
  1161.  
  1162.  
  1163. bool ScriptEngine::hasTeamPoke(int id, int pokemonnum)
  1164. {
  1165.     if (!testPlayer("hasTeamPoke(id, poke)",id)) {
  1166.         return false;
  1167.     }
  1168.     TeamBattle &t = myserver->player(id)->team();
  1169.     for (int i = 0; i < 6; i++) {
  1170.         if (t.poke(i).num() == pokemonnum) {
  1171.             return true;
  1172.         }
  1173.     }
  1174.     return false;
  1175. }
  1176.  
  1177. QScriptValue ScriptEngine::indexOfTeamPoke(int id, int pokenum)
  1178. {
  1179.     if (!loggedIn(id)) {
  1180.         printLine("Script Warning in sys.indexOfTeamPoke(id, pokenum): no such player logged in with id " + QString::number(id));
  1181.         return myengine.undefinedValue();
  1182.     }
  1183.     TeamBattle &t = myserver->player(id)->team();
  1184.     for (int i = 0; i < 6; i++) {
  1185.         if (t.poke(i).num() == pokenum) {
  1186.             return i;
  1187.         }
  1188.     }
  1189.     return myengine.undefinedValue();
  1190. }
  1191.  
  1192. bool ScriptEngine::hasDreamWorldAbility(int id, int index)
  1193. {
  1194.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1195.         return false;
  1196.     } else {
  1197.         PokeBattle &p = myserver->player(id)->team().poke(index);
  1198.  
  1199.         AbilityGroup ag = PokemonInfo::Abilities(p.num(), 5);
  1200.  
  1201.         return p.ability() != ag.ab(0) && p.ability() != ag.ab(1);
  1202.     }
  1203. }
  1204.  
  1205. bool ScriptEngine::compatibleAsDreamWorldEvent(int id, int index)
  1206. {
  1207.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1208.         return false;
  1209.     } else {
  1210.         PokeBattle &p = myserver->player(id)->team().poke(index);
  1211.  
  1212.         return MoveSetChecker::isValid(p.num(),5,p.move(0).num(),p.move(1).num(),p.move(2).num(),p.move(3).num(),p.ability(),p.gender(), p.level(), true);
  1213.     }
  1214. }
  1215.  
  1216. QScriptValue ScriptEngine::teamPokeMove(int id, int pokeindex, int moveindex)
  1217. {
  1218.     if (!loggedIn(id) || pokeindex < 0 || moveindex < 0 || pokeindex >= 6 || moveindex >= 4) {
  1219.         return myengine.undefinedValue();
  1220.     }
  1221.     return myserver->player(id)->team().poke(pokeindex).move(moveindex).num();
  1222. }
  1223.  
  1224. bool ScriptEngine::hasTeamPokeMove(int id, int pokeindex, int movenum)
  1225. {
  1226.     if (!loggedIn(id) || pokeindex < 0 || pokeindex >= 6) {
  1227.         return false;
  1228.     }
  1229.     PokeBattle &poke = myserver->player(id)->team().poke(pokeindex);
  1230.  
  1231.     for (int i = 0; i < 4; i++) {
  1232.         if (poke.move(i).num() == movenum) {
  1233.             return true;
  1234.         }
  1235.     }
  1236.     return false;
  1237. }
  1238.  
  1239. QScriptValue ScriptEngine::indexOfTeamPokeMove(int id, int pokeindex, int movenum)
  1240. {
  1241.     if (!loggedIn(id) || pokeindex < 0 || pokeindex >= 6) {
  1242.         return myengine.undefinedValue();
  1243.     }
  1244.     PokeBattle &poke = myserver->player(id)->team().poke(pokeindex);
  1245.  
  1246.     for (int i = 0; i < 4; i++) {
  1247.         if (poke.move(i).num() == movenum) {
  1248.             return i;
  1249.         }
  1250.     }
  1251.     return myengine.undefinedValue();
  1252. }
  1253.  
  1254. bool ScriptEngine::hasTeamMove(int id, int movenum)
  1255. {
  1256.     if (!loggedIn(id)) {
  1257.         printLine("Script Warning in sys.hasTeamMove(id, pokenum): no such player logged in with id " + QString::number(id));
  1258.         return false;
  1259.     }
  1260.     for (int i = 0; i < 6; i++) {
  1261.         if (hasTeamPokeMove(id,i,movenum))
  1262.             return true;
  1263.     }
  1264.     return false;
  1265. }
  1266.  
  1267. QScriptValue ScriptEngine::teamPokeItem(int id, int index)
  1268. {
  1269.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1270.         return myengine.undefinedValue();
  1271.     } else {
  1272.         return myserver->player(id)->team().poke(index).item();
  1273.     }
  1274. }
  1275.  
  1276. bool ScriptEngine::hasTeamItem(int id, int itemnum)
  1277. {
  1278.     if (!loggedIn(id)) {
  1279.         printLine("Script Warning in sys.hasTeamPoke(id, pokenum): no such player logged in with id " + QString::number(id));
  1280.         return false;
  1281.     }
  1282.     TeamBattle &t = myserver->player(id)->team();
  1283.     for (int i = 0; i < 6; i++) {
  1284.         if (t.poke(i).item() == itemnum) {
  1285.             return true;
  1286.         }
  1287.     }
  1288.     return false;
  1289. }
  1290.  
  1291. long ScriptEngine::time()
  1292. {
  1293.     return ::time(NULL);
  1294. }
  1295.  
  1296. QScriptValue ScriptEngine::getTierList()
  1297. {
  1298.     QStringList origin = TierMachine::obj()->tierNames();
  1299.  
  1300.     QScriptValue ret = myengine.newArray(origin.count());
  1301.  
  1302.     for(int i = 0;i < origin.size(); i++) {
  1303.         ret.setProperty(i, origin[i]);
  1304.     }
  1305.  
  1306.     return  ret;
  1307. }
  1308.  
  1309. QScriptValue ScriptEngine::playerIds()
  1310. {
  1311.     QList<int> keys = myserver->myplayers.keys();
  1312.  
  1313.     QScriptValue ret = myengine.newArray(keys.count());
  1314.  
  1315.     for (int i = 0; i < keys.size(); i++) {
  1316.         ret.setProperty(i, keys[i]);
  1317.     }
  1318.  
  1319.     return ret;
  1320. }
  1321.  
  1322. QScriptValue ScriptEngine::channelIds()
  1323. {
  1324.     QList<int> keys = myserver->channels.keys();
  1325.  
  1326.     QScriptValue ret = myengine.newArray(keys.count());
  1327.  
  1328.     for (int i = 0; i < keys.size(); i++) {
  1329.         ret.setProperty(i, keys[i]);
  1330.     }
  1331.  
  1332.     return ret;
  1333. }
  1334.  
  1335. QScriptValue ScriptEngine::channel(int id)
  1336. {
  1337.     if (!myserver->channelExist(id)) {
  1338.         return myengine.undefinedValue();
  1339.     } else {
  1340.         return myserver->channel(id).name;
  1341.     }
  1342. }
  1343.  
  1344. QScriptValue ScriptEngine::channelId(const QString &name)
  1345. {
  1346.     if (!myserver->channelExist(name)) {
  1347.         return myengine.undefinedValue();
  1348.     } else {
  1349.         return myserver->channelids.value(name.toLower());
  1350.     }
  1351. }
  1352.  
  1353. bool ScriptEngine::isInChannel(int playerid, int channelid)
  1354. {
  1355.     if (!loggedIn(playerid))
  1356.         return false;
  1357.     return (myserver->player(playerid)->getChannels().contains(channelid));
  1358. }
  1359.  
  1360. bool ScriptEngine::isInSameChannel(int playerid, int player2)
  1361. {
  1362.     if (!loggedIn(playerid) || !loggedIn(player2))
  1363.         return false;
  1364.     return (myserver->player(playerid)->isInSameChannel(myserver->player(player2)));
  1365. }
  1366.  
  1367. QScriptValue ScriptEngine::channelsOfPlayer(int playerid)
  1368. {
  1369.     if (!myserver->playerExist(playerid)) {
  1370.         return myengine.undefinedValue();
  1371.     } else {
  1372.         Player *p = myserver->player(playerid);
  1373.  
  1374.         QSet<int> chans = p->getChannels();
  1375.         int i = 0;
  1376.         QScriptValue ret = myengine.newArray(chans.count());
  1377.  
  1378.         foreach(int chan, chans) {
  1379.             ret.setProperty(i, chan);
  1380.             i += 1;
  1381.         }
  1382.  
  1383.         return ret;
  1384.     }
  1385. }
  1386.  
  1387. QScriptValue ScriptEngine::playersOfChannel(int channelid)
  1388. {
  1389.     if (!myserver->channelExist(channelid)) {
  1390.         return myengine.undefinedValue();
  1391.     } else {
  1392.         Channel &c = myserver->channel(channelid);
  1393.  
  1394.         int i = 0;
  1395.         QScriptValue ret = myengine.newArray(c.players.count());
  1396.  
  1397.         foreach(Player *p, c.players) {
  1398.             ret.setProperty(i, p->id());
  1399.             i += 1;
  1400.         }
  1401.  
  1402.         return ret;
  1403.     }
  1404. }
  1405.  
  1406. QScriptValue ScriptEngine::teamPokeNature(int id, int index)
  1407. {
  1408.     if (!loggedIn(id) || index < 0 || index >= 6) {
  1409.         return myengine.undefinedValue();
  1410.     } else {
  1411.         return myserver->player(id)->team().poke(index).nature();
  1412.     }
  1413. }
  1414.  
  1415. QScriptValue ScriptEngine::teamPokeEV(int id, int index, int stat)
  1416. {
  1417.     if (!loggedIn(id) || index < 0 || index >= 6 || stat < 0 || stat >= 6) {
  1418.         return myengine.undefinedValue();
  1419.     } else {
  1420.         return myserver->player(id)->team().poke(index).evs()[stat];
  1421.     }
  1422. }
  1423.  
  1424. QScriptValue ScriptEngine::teamPokeDV(int id, int index, int stat)
  1425. {
  1426.     if (!loggedIn(id) || index < 0 || index >= 6 || stat < 0 || stat >= 6) {
  1427.         return myengine.undefinedValue();
  1428.     } else {
  1429.         return myserver->player(id)->team().poke(index).dvs()[stat];
  1430.     }
  1431. }
  1432.  
  1433. void ScriptEngine::setTeamPokeDV(int id, int slot, int stat, int newValue)
  1434. {
  1435.     if(loggedIn(id) && slot >=0 && slot <=5 && stat >=0 && stat <= 5 && newValue >= 0 && newValue <= 31) {
  1436.         myserver->player(id)->team().poke(slot).dvs()[stat] = newValue;
  1437.     }
  1438. }
  1439.  
  1440. void ScriptEngine::changeTeamPokeIV(int id, int slot, int stat, int newValue)
  1441. {
  1442.     this->setTeamPokeDV(id, slot, stat, newValue);
  1443.     return;
  1444. }
  1445.  
  1446. void ScriptEngine::changeTeamPokeEV(int id, int slot, int stat, int newValue)
  1447. {
  1448.     if(loggedIn(id) && slot >=0 && slot <=5 && stat >=0 && stat <= 5 && newValue >= 0 && newValue <= 255) {
  1449.         myserver->player(id)->team().poke(slot).evs()[stat] = newValue;     // can't it exceed 510?
  1450.     }
  1451. }
  1452.  
  1453. int ScriptEngine::rand(int min, int max)
  1454. {
  1455.     if (min == max)
  1456.         return min;
  1457.     return (::rand()%(max-min)) + min;
  1458. }
  1459.  
  1460. int ScriptEngine::numPlayers()
  1461. {
  1462.     return myserver->numberOfPlayersLoggedIn;
  1463. }
  1464.  
  1465. bool ScriptEngine::loggedIn(int id)
  1466. {
  1467.     return myserver->playerLoggedIn(id);
  1468. }
  1469.  
  1470. void ScriptEngine::printLine(const QString &s)
  1471. {
  1472.     myserver->printLine(s, false, true);
  1473. }
  1474.  
  1475. void ScriptEngine::stopEvent()
  1476. {
  1477.     if (stopevents.size() == 0) {
  1478.         printLine("Script Warning: calling sys.stopEvent() in an unstoppable event.");
  1479.     } else {
  1480.         stopevents.back() = true;
  1481.     }
  1482. }
  1483.  
  1484. void ScriptEngine::shutDown()
  1485. {
  1486.     Server::print("Scripted server shutdown");
  1487.     serverShutDown();
  1488.     exit(0);
  1489. }
  1490.  
  1491. void ScriptEngine::modifyTypeChart(int type_attack, int type_defend, const QString &modifier)
  1492. {
  1493.     QString compare_to = modifier.toLower();
  1494.     QString modifiers[] = { "none", "ineffective", "normal", "effective" };
  1495.     int real_modifiers[] = { 0, 1, 2, 4 };
  1496.     int i = 0;
  1497.     while((i < 4) && (modifiers[i] != compare_to)) i++;
  1498.     if(i < 4) TypeInfo::modifyTypeChart(type_attack, type_defend, real_modifiers[i]);
  1499. }
  1500.  
  1501. QScriptValue ScriptEngine::type(int id)
  1502. {
  1503.     if (id >= 0  && id < TypeInfo::NumberOfTypes()) {
  1504.         return TypeInfo::Name(id);
  1505.     } else {
  1506.         return myengine.undefinedValue();
  1507.     }
  1508. }
  1509.  
  1510. QScriptValue ScriptEngine::typeNum(const QString &typeName)
  1511. {
  1512.     int num = TypeInfo::Number(convertToSerebiiName(typeName));
  1513.     if (num >= 0  && num < TypeInfo::NumberOfTypes()) {
  1514.         return num;
  1515.     } else {
  1516.         return myengine.undefinedValue();
  1517.     }
  1518. }
  1519.  
  1520. int ScriptEngine::hiddenPowerType(int gen, quint8 hpdv, quint8 attdv, quint8 defdv, quint8 spddv, quint8 sattdv, quint8 sdefdv)
  1521. {
  1522.     return HiddenPowerInfo::Type(gen, hpdv, attdv, defdv, spddv, sattdv, sdefdv);
  1523. }
  1524.  
  1525. ScriptWindow::ScriptWindow()
  1526. {
  1527.     setAttribute(Qt::WA_DeleteOnClose, true);
  1528.     setWindowTitle(tr("Scripts"));
  1529.  
  1530.     QGridLayout *l = new QGridLayout(this);
  1531.     myedit = new QTextEdit();
  1532.     l->addWidget(myedit, 0, 0, 1, 4);
  1533.  
  1534.     QPushButton *ok = new QPushButton(tr("&Ok"));
  1535.     QPushButton *cancel = new QPushButton(tr("&Cancel"));
  1536.  
  1537.     l->addWidget(cancel,1,2);
  1538.     l->addWidget(ok,1,3);
  1539.  
  1540.     connect(ok, SIGNAL(clicked()), SLOT(okPressed()));
  1541.     connect(cancel, SIGNAL(clicked()), SLOT(deleteLater()));
  1542.  
  1543.     QFile f("scripts.js");
  1544.     f.open(QIODevice::ReadOnly);
  1545.  
  1546.     myedit->setPlainText(QString::fromUtf8(f.readAll()));
  1547.     myedit->setFont(QFont("Courier New", 10));
  1548.     myedit->setLineWrapMode(QTextEdit::NoWrap);
  1549.     myedit->setTabStopWidth(25);
  1550.  
  1551.     resize(700, 550);
  1552. }
  1553.  
  1554. void ScriptWindow::okPressed()
  1555. {
  1556.     QFile f("scripts.js");
  1557.     f.open(QIODevice::WriteOnly);
  1558.  
  1559.     QString plainText = myedit->toPlainText();
  1560.     f.write(plainText.toUtf8());
  1561.  
  1562.     emit scriptChanged(plainText);
  1563.  
  1564.     close();
  1565. }
  1566.  
  1567. QScriptValue ScriptEngine::getScript()
  1568. {
  1569.     return myscript;
  1570. }
  1571.  
  1572. int ScriptEngine::pokeType1(int id, int gen)
  1573. {
  1574.     int result = Pokemon::Curse;
  1575.     if((gen >= GEN_MIN) && (gen <= GEN_MAX)) {
  1576.         result = PokemonInfo::Type1(Pokemon::uniqueId(id), gen);
  1577.     }else{
  1578.         warn("pokeType1", "generation is not supported.");
  1579.     }
  1580.     return result;
  1581. }
  1582.  
  1583. int ScriptEngine::pokeType2(int id, int gen)
  1584. {
  1585.     int result = Pokemon::Curse;
  1586.     if((gen >= GEN_MIN) && (gen <= GEN_MAX)) {
  1587.         result = PokemonInfo::Type2(Pokemon::uniqueId(id), gen);
  1588.     }else{
  1589.         warn("pokeType2", "generation is not supported.");
  1590.     }
  1591.     return result;
  1592. }
  1593.  
  1594. void ScriptEngine::modifyMovePower(int moveNum, unsigned char power, int gen)
  1595. {
  1596.     MoveInfo::setPower(moveNum, power, gen);
  1597. }
  1598.  
  1599. void ScriptEngine::modifyMoveAccuracy(int moveNum, char accuracy, int gen)
  1600. {
  1601.     MoveInfo::setAccuracy(moveNum, accuracy, gen);
  1602. }
  1603.  
  1604. void ScriptEngine::modifyMovePP(int moveNum, char pp, int gen)
  1605. {
  1606.     MoveInfo::setPP(moveNum, pp, gen);
  1607. }
  1608.  
  1609. void ScriptEngine::modifyMovePriority(int moveNum, qint8 priority, int gen)
  1610. {
  1611.     MoveInfo::setPriority(moveNum, priority, gen);
  1612. }
  1613.  
  1614. QScriptValue ScriptEngine::banList()
  1615. {
  1616.     QList<QString> keys = SecurityManager::banList().keys();
  1617.     int size = keys.size();
  1618.     QScriptValue result = myengine.newArray(size);
  1619.     for(int i = 0; i < size; i++) {
  1620.         result.setProperty(i, keys.at(i));
  1621.     }
  1622.     return result;
  1623. }
  1624.  
  1625. void ScriptEngine::ban(QString name)
  1626. {
  1627.     SecurityManager::ban(name);
  1628. }
  1629.  
  1630. void ScriptEngine::unban(QString name)
  1631. {
  1632.     SecurityManager::unban(name);
  1633. }
  1634.  
  1635. void ScriptEngine::battleSetup(int src, int dest, int battleId)
  1636. {
  1637.     makeEvent("battleSetup", src, dest, battleId);
  1638. }
  1639.  
  1640. QString ScriptEngine::getBattleLogFileName(int battleId)
  1641. {
  1642.     BattleSituation * battle = myserver->getBattle(battleId);
  1643.     if (battle) {
  1644.         return battle->getBattleLogFilename();
  1645.     }else{
  1646.         warn("getBattleLogFileName", "can't find a battle with specified id.");
  1647.         return QString();
  1648.     }
  1649. }
  1650.  
  1651. void ScriptEngine::prepareWeather(int battleId, int weatherId)
  1652. {
  1653.     if((weatherId >= 0) && (weatherId <= 4)) {
  1654.         BattleSituation * battle = myserver->getBattle(battleId);
  1655.         if (battle) {
  1656.             battle->setupLongWeather(weatherId);
  1657.         }else{
  1658.             warn("prepareWeather", "can't find a battle with specified id.");
  1659.         }
  1660.     }
  1661. }
  1662.  
  1663. QScriptValue ScriptEngine::weatherNum(const QString &weatherName)
  1664. {
  1665.     QString weatherSimplified = weatherName.toLower();
  1666.     bool found = false;
  1667.     int i = 0;
  1668.     while(i <= 4) {
  1669.         if(weatherSimplified == TypeInfo::weatherName(i)) {
  1670.             found = true;
  1671.             break;
  1672.         }
  1673.         ++i;
  1674.     }
  1675.     if (found) {
  1676.         return i;
  1677.     } else {
  1678.         return myengine.undefinedValue();
  1679.     }
  1680. }
  1681.  
  1682. QScriptValue ScriptEngine::weather(int weatherId)
  1683. {
  1684.     if (weatherId >= 0  && weatherId < 4) {
  1685.         return TypeInfo::weatherName(weatherId);
  1686.     } else {
  1687.         return myengine.undefinedValue();
  1688.     }
  1689. }
  1690.  
  1691. void ScriptEngine::setAnnouncement(const QString &html, int id) {
  1692.     if (testPlayer("setAnnouncment(html, id)", id)) {
  1693.         myserver->setAnnouncement(id, html); }
  1694.     }
  1695. void ScriptEngine::setAnnouncement(const QString &html) {
  1696.         myserver->setAllAnnouncement(html);
  1697.     }
  1698.  
  1699. void ScriptEngine::changeAnnouncement(const QString &html) {
  1700.         QSettings settings("config", QSettings::IniFormat);
  1701.         settings.setValue("server_announcement", html);
  1702.         myserver->announcementChanged(html);
  1703.     }
  1704.  
  1705. void ScriptEngine::makeServerPublic(bool isPublic)
  1706. {
  1707.     myserver->regPrivacyChanged(!isPublic);
  1708. }
  1709.  
  1710. QScriptValue ScriptEngine::getAnnouncement() {
  1711.     return myserver->serverAnnouncement;
  1712. }
  1713.  
  1714. /* Causes crash...
  1715. void ScriptEngine::setTimer(int milisec) {
  1716.     if (milisec <= 0)
  1717.         return;
  1718.     step_timer->stop();
  1719.     step_timer->start(ms);
  1720.     }
  1721. */
  1722. int ScriptEngine::teamPokeAbility(int id, int slot)
  1723. {
  1724.     if (!loggedIn(id) || slot < 0 || slot >= 6) {
  1725.         return Ability::NoAbility;
  1726.     } else {
  1727.         return myserver->player(id)->team().poke(slot).ability();
  1728.     }
  1729. }
  1730.  
  1731. void ScriptEngine::changeName(int playerId, QString newName)
  1732. {
  1733.     if (!loggedIn(playerId)) return;
  1734.     myserver->player(playerId)->setName(newName);
  1735.     myserver->sendPlayer(playerId);
  1736. }
  1737.  
  1738. void ScriptEngine::changeInfo(int playerId, QString newInfo)
  1739. {
  1740.     if (!loggedIn(playerId)) return;
  1741.     myserver->player(playerId)->setInfo(newInfo);
  1742.     myserver->sendPlayer(playerId);
  1743. }
  1744.  
  1745. QScriptValue ScriptEngine::info(int playerId)
  1746. {
  1747.     if (loggedIn(playerId)) {
  1748.         return myserver->player(playerId)->team().info;
  1749.     }else{
  1750.         return myengine.undefinedValue();
  1751.     }
  1752. }
  1753.  
  1754. void ScriptEngine::modifyPokeAbility(int id, int slot, int ability, int gen)
  1755. {
  1756.     bool res = PokemonInfo::modifyAbility(Pokemon::uniqueId(id), slot, ability, gen);
  1757.     if (!res) {
  1758.         warn(
  1759.             "modifyPokeAbility",
  1760.             QString("slot out of range or pokemon do not exist in gen %1.").arg(QString::number(gen))
  1761.         );
  1762.     }
  1763. }
  1764.  
  1765. void ScriptEngine::changePokeAbility(int id, int slot, int ability)
  1766. {
  1767.     if (!testPlayer("changePokeAbility", id) || !testRange("changePokeAbility", slot, 0, 5)) {
  1768.         return;
  1769.     }
  1770.     myserver->player(id)->team().poke(slot).ability() = ability;
  1771. }
  1772.  
  1773. QScriptValue ScriptEngine::pokeAbility(int poke, int slot, int gen)
  1774. {
  1775.     Pokemon::uniqueId pokemon(poke);
  1776.     if (PokemonInfo::Exists(pokemon, gen)
  1777.         && (slot >= 0) && (slot <= 2)
  1778.         && (gen >= GEN_MIN) && (gen <= GEN_MAX)) {
  1779.         return PokemonInfo::Abilities(pokemon, gen).ab(slot);
  1780.     }
  1781.     return myengine.undefinedValue();
  1782. }
  1783.  
  1784. void ScriptEngine::changePokeHappiness(int id, int slot, int value)
  1785. {
  1786.     if (!testPlayer("changePokeHappiness", id)
  1787.         || !testRange("changePokeHappiness", slot, 0, 5)
  1788.         || !testRange("changePokeHappiness", value, 0, 255)) {
  1789.         return;
  1790.     }
  1791.     myserver->player(id)->team().poke(slot).happiness() = value;
  1792. }
  1793.  
  1794. void ScriptEngine::changePokeShine(int id, int slot, bool value)
  1795. {
  1796.     if (!testPlayer("changePokeShine", id) || !testRange("changePokeShine", slot, 0, 5)) {
  1797.         return;
  1798.     }
  1799.     myserver->player(id)->team().poke(slot).shiny() = value;
  1800. }
  1801.  
  1802. void ScriptEngine::changePokeNature(int id, int slot, int nature)
  1803. {
  1804.     if(!testPlayer("changePokeNature(id, slot, forme)", id) || !testRange("changePokeNature(id, slot, forme)",slot, 0, 15))
  1805.         return;
  1806.       // Ugly, we don't have NatureInfo::Exists(nature) or we do?
  1807.     myserver->player(id)->team().poke(slot).nature() = nature;
  1808. }
  1809.  
  1810. QScriptValue ScriptEngine::teamPokeGender(int id, int slot)
  1811. {
  1812.     if (!testPlayer("teamPokeGender", id) || !testRange("teamPokeGender", slot, 0, 5)) {
  1813.         return myengine.undefinedValue();
  1814.     }
  1815.     return myserver->player(id)->team().poke(slot).gender();
  1816. }
  1817.  
  1818. QScriptValue ScriptEngine::teamPokeNick(int id, int index)
  1819. {
  1820.     if(!loggedIn(id) || index < 0 ||index >= 6) {
  1821.         return myengine.undefinedValue();
  1822.     }else{
  1823.         return myserver->player(id)->team().poke(index).nick();
  1824.     }
  1825. }
  1826.  
  1827. void ScriptEngine::inflictStatus(int battleId, bool toFirstPlayer, int slot, int status)
  1828. {
  1829.     if (!testRange("inflictStatus", status, Pokemon::Fine, Pokemon::Koed)
  1830.         || !testRange("inflictStatus", slot, 0, 5)) {
  1831.         return;
  1832.     }
  1833.     BattleSituation * battle = myserver->getBattle(battleId);
  1834.     if (battle) {
  1835.         if (toFirstPlayer) {
  1836.             battle->changeStatus(0, slot, status);
  1837.         }else{
  1838.             battle->changeStatus(1, slot, status);
  1839.         }
  1840.     }else{
  1841.         warn("inflictStatus", "can't find a battle with specified id.");
  1842.     }
  1843. }
  1844.  
  1845. void ScriptEngine::modifyPokeStat(int poke, int stat, quint8 value)
  1846. {
  1847.     bool res = PokemonInfo::modifyBaseStat(Pokemon::uniqueId(poke), stat, value);
  1848.     if (!res) {
  1849.         warn("modifyPokeStat", "unable to modify.");
  1850.     }
  1851. }
  1852.  
  1853. void ScriptEngine::updateRatings()
  1854. {
  1855.     TierMachine::obj()->processDailyRun();
  1856. }
  1857.  
  1858. void ScriptEngine::resetLadder(const QString &tier)
  1859. {
  1860.     if (!TierMachine::obj()->exists(tier)) {
  1861.         warn("resetLadder", "tier doesn't exist");
  1862.         return;
  1863.     }
  1864.  
  1865.     TierMachine::obj()->tier(tier).resetLadder();
  1866.  
  1867.     /* Updates the rating of all the players of the tier */
  1868.     foreach(Player *p, myserver->myplayers) {
  1869.         if (p->tier() == tier)
  1870.             p->findRating();
  1871.     }
  1872. }
  1873.  
  1874. void ScriptEngine::synchronizeTierWithSQL(const QString &tier)
  1875. {
  1876.     if (!TierMachine::obj()->exists(tier)) {
  1877.         warn("resetLadder", "tier doesn't exist");
  1878.         return;
  1879.     }
  1880.  
  1881.     TierMachine::obj()->tier(tier).clearCache();
  1882.  
  1883.     /* Updates the rating of all the players of the tier */
  1884.     foreach(Player *p, myserver->myplayers) {
  1885.         if (p->tier() == tier)
  1886.             p->findRating();
  1887.     }
  1888. }
  1889.  
  1890. void ScriptEngine::forceBattle(int player1, int player2, int clauses, int mode, bool is_rated)
  1891. {
  1892.     if (!loggedIn(player1) || !loggedIn(player2)) {
  1893.         warn("forceBattle", "player is not online.");
  1894.         return;
  1895.     }
  1896.     if (player1 == player2) {
  1897.         warn("forceBattle", "player1 == player2");
  1898.         return;
  1899.     }
  1900.     if (!testRange("forceBattle", mode, ChallengeInfo::ModeFirst, ChallengeInfo::ModeLast)) {
  1901.         return;
  1902.     }
  1903.  
  1904.     ChallengeInfo c;
  1905.     c.clauses = clauses;
  1906.     c.mode = mode;
  1907.     c.rated = is_rated;
  1908.    
  1909.     myserver->startBattle(player1, player2, c);
  1910. }
  1911.  
  1912. void ScriptEngine::sendNetworkCommand(int id, int command)
  1913. {
  1914.     if (!testPlayer("sendNetworkCommand(id, command)", id))
  1915.         return;
  1916.  
  1917.     myserver->player(id)->relay().notify(command);
  1918. }
  1919.  
  1920. int ScriptEngine::getClauses(const QString &tier)
  1921. {
  1922.     return TierMachine::obj()->tier(tier).getClauses();
  1923. }
  1924.  
  1925. bool ScriptEngine::attemptToSpectateBattle(int src, int p1, int p2)
  1926. {
  1927.     if (!myscript.property("attemptToSpectateBattle", QScriptValue::ResolveLocal).isValid()) {
  1928.         return false;
  1929.     }
  1930.     QScriptValue res = myscript.property("attemptToSpectateBattle").call(myscript, QScriptValueList() << src << p1 << p2);
  1931.     if (res.isError()) {
  1932.         printLine(QString("Script Error line %1: %2").arg(myengine.uncaughtExceptionLineNumber()).arg(res.toString()));
  1933.     }
  1934.     return res.isString() && (res.toString().toLower() == "allow");
  1935. }
  1936.  
  1937. void ScriptEngine::changeAvatar(int playerId, quint16 avatarId)
  1938. {
  1939.     if (!loggedIn(playerId)) {
  1940.         warn("changeAvatar","unknown player.");
  1941.         return;
  1942.     }
  1943.     myserver->player(playerId)->avatar() = avatarId;
  1944.     myserver->sendPlayer(playerId);
  1945. }
  1946.  
  1947. QScriptValue ScriptEngine::avatar(int playerId)
  1948. {
  1949.     if (!loggedIn(playerId)) {
  1950.         return myengine.nullValue();
  1951.     }
  1952.     return myserver->player(playerId)->avatar();
  1953. }
  1954.  
  1955. // Potentially unsafe functions.
  1956. #ifndef PO_SCRIPT_SAFE_ONLY
  1957.  
  1958. void ScriptEngine::saveVal(const QString &key, const QVariant &val)
  1959. {
  1960.     QSettings s;
  1961.     s.setValue("Script_"+key, val);
  1962. }
  1963.  
  1964. QScriptValue ScriptEngine::getVal(const QString &key)
  1965. {
  1966.     QSettings s;
  1967.     return s.value("Script_"+key).toString();
  1968. }
  1969.  
  1970. void ScriptEngine::removeVal(const QString &key)
  1971. {
  1972.     QSettings s;
  1973.     s.remove("Script_"+key);
  1974. }
  1975.  
  1976. void ScriptEngine::saveVal(const QString &file, const QString &key, const QVariant &val)
  1977. {
  1978.     QSettings s(file, QSettings::IniFormat);
  1979.     s.setValue("Script_"+key, val);
  1980. }
  1981.  
  1982. QScriptValue ScriptEngine::getVal(const QString &file, const QString &key)
  1983. {
  1984.     QSettings s(file, QSettings::IniFormat);
  1985.     return s.value("Script_"+key).toString();
  1986. }
  1987.  
  1988. void ScriptEngine::removeVal(const QString &file, const QString &key)
  1989. {
  1990.     QSettings s(file, QSettings::IniFormat);
  1991.     s.remove("Script_"+key);
  1992. }
  1993.  
  1994. void ScriptEngine::appendToFile(const QString &fileName, const QString &content)
  1995. {
  1996.     QFile out(fileName);
  1997.  
  1998.     if (!out.open(QIODevice::Append)) {
  1999.         printLine("Script Warning in sys.appendToFile(filename, content): error when opening " + fileName + ": " + out.errorString());
  2000.         return;
  2001.     }
  2002.  
  2003.     out.write(content.toUtf8());
  2004. }
  2005.  
  2006. void ScriptEngine::writeToFile(const QString &fileName, const QString &content)
  2007. {
  2008.     QFile out(fileName);
  2009.  
  2010.     if (!out.open(QIODevice::WriteOnly)) {
  2011.         printLine("Script Warning in sys.writeToFile(filename, content): error when opening " + fileName + ": " + out.errorString());
  2012.         return;
  2013.     }
  2014.  
  2015.     out.write(content.toUtf8());
  2016. }
  2017.  
  2018. void ScriptEngine::deleteFile(const QString &fileName)
  2019. {
  2020.     QFile out(fileName);
  2021.  
  2022.     if (!out.open(QIODevice::WriteOnly)) {
  2023.         printLine("Script Warning in sys.deleteFile(filename): error when opening " + fileName + ": " + out.errorString());
  2024.         return;
  2025.     }
  2026.  
  2027.     out.remove();
  2028. }
  2029.  
  2030. /**
  2031.  * Function will perform a GET-Request server side
  2032.  * @param urlstring web-url
  2033.  * @author Remco vd Zon
  2034.  */
  2035. void ScriptEngine::webCall(const QString &urlstring, const QScriptValue &callback)
  2036. {
  2037.     if (!callback.isString() && !callback.isFunction()) {
  2038.         printLine("Script Warning in sys.webCall(urlstring, callback): callback is not a string or a function.");
  2039.         return;
  2040.     }
  2041.  
  2042.     QNetworkRequest request;
  2043.  
  2044.     request.setUrl(QUrl(urlstring));
  2045.     request.setRawHeader("User-Agent", "Pokemon-Online serverscript");
  2046.  
  2047.     QNetworkReply *reply = manager.get(request);
  2048.     webCallEvents[reply] = callback;
  2049. }
  2050.  
  2051. /**
  2052.  * Function will perform a POST-Request server side
  2053.  * @param urlstring web-url
  2054.  * @param params_array javascript array [key]=>value.
  2055.  * @author Remco vd Zon
  2056.  */
  2057. void ScriptEngine::webCall(const QString &urlstring, const QScriptValue &callback, const QScriptValue &params_array)
  2058. {
  2059.     if (!callback.isString() && !callback.isFunction()) {
  2060.         printLine("Script Warning in sys.webCall(urlstring, callback, params_array): callback is not a string or a function.");
  2061.         return;
  2062.     }
  2063.    
  2064.     QNetworkRequest request;
  2065.     QByteArray postData;
  2066.  
  2067.     request.setUrl(QUrl(urlstring));
  2068.     request.setRawHeader("User-Agent", "Pokemon-Online serverscript");
  2069.  
  2070.     //parse the POST fields
  2071.     QScriptValueIterator it(params_array);
  2072.     while (it.hasNext()) {
  2073.         it.next();
  2074.         postData.append( it.name() + "=" + it.value().toString().replace(QString("&"), QString("%26"))); //encode ampersands!
  2075.         if(it.hasNext()) postData.append("&");
  2076.     }
  2077.  
  2078.     QNetworkReply *reply = manager.post(request, postData);
  2079.     webCallEvents[reply] = callback;
  2080. }
  2081.  
  2082. void ScriptEngine::webCall_replyFinished(QNetworkReply* reply){
  2083.     QScriptValue val = webCallEvents.take(reply);
  2084.     if (val.isString()) {
  2085.         //escape reply before sending it to the javascript evaluator
  2086.         QString x = reply->readAll();
  2087.         x = x.replace(QString("\\"), QString("\\\\"));
  2088.         x = x.replace(QString("'"), QString("\\'"));
  2089.         x = x.replace(QString("\n"), QString("\\n"));
  2090.         x = x.replace(QString("\r"), QString(""));
  2091.  
  2092.         //put reply in a var "resp", can be used in expr
  2093.         // i.e. expr = 'print("The resp was: "+resp);'
  2094.         eval( "var resp = '"+x+"';"+val.toString());
  2095.     } else if (val.isFunction()) {
  2096.         QScriptValueList args;
  2097.         args << QString(reply->readAll());
  2098.         val.call(QScriptValue(), args); // uses globalObject as this
  2099.     }
  2100.     reply->deleteLater();
  2101. }
  2102.  
  2103. /**
  2104.  * Function will perform a GET-Request server side, synchronously
  2105.  * @param urlstring web-url
  2106.  * @author Remco cd Zon and Toni Fadjukoff
  2107.  */
  2108. QScriptValue ScriptEngine::synchronousWebCall(const QString &urlstring) {
  2109.     QNetworkAccessManager *manager = new QNetworkAccessManager(this);
  2110.     QNetworkRequest request;
  2111.  
  2112.     request.setUrl(QUrl(urlstring));
  2113.     request.setRawHeader("User-Agent", "Pokemon-Online serverscript");
  2114.  
  2115.     connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(synchronousWebCall_replyFinished(QNetworkReply*)));
  2116.     manager->get(request);
  2117.  
  2118.     sync_loop.exec();
  2119.  
  2120.     manager->deleteLater();
  2121.     return sync_data;
  2122. }
  2123.  
  2124. /**
  2125.  * Function will perform a POST-Request server side, synchronously
  2126.  * @param urlstring web-url
  2127.  * @param params_array javascript array [key]=>value.
  2128.  * @author Remco vd Zon and Toni Fadjukoff
  2129.  */
  2130. QScriptValue ScriptEngine::synchronousWebCall(const QString &urlstring, const QScriptValue &params_array)
  2131. {
  2132.     QNetworkAccessManager *manager = new QNetworkAccessManager(this);
  2133.     QNetworkRequest request;
  2134.     QByteArray postData;
  2135.  
  2136.     request.setUrl(QUrl(urlstring));
  2137.     request.setRawHeader("User-Agent", "Pokemon-Online serverscript");
  2138.  
  2139.     //parse the POST fields
  2140.     QScriptValueIterator it(params_array);
  2141.     while (it.hasNext()) {
  2142.         it.next();
  2143.         postData.append( it.name() + "=" + it.value().toString().replace(QString("&"), QString("%26"))); //encode ampersands!
  2144.         if(it.hasNext()) postData.append("&");
  2145.     }
  2146.  
  2147.     connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(synchronousWebCall_replyFinished(QNetworkReply*)));
  2148.     manager->post(request, postData);
  2149.  
  2150.     sync_loop.exec();
  2151.     manager->deleteLater();
  2152.     return sync_data;
  2153. }
  2154.  
  2155. void ScriptEngine::synchronousWebCall_replyFinished(QNetworkReply* reply) {
  2156.     sync_data = reply->readAll();
  2157.     sync_loop.exit();
  2158. }
  2159.  
  2160. QScriptValue ScriptEngine::getValKeys()
  2161. {
  2162.     QSettings s;
  2163.     QStringList list = s.childKeys();
  2164.     QStringList result_data;
  2165.    
  2166.     QStringListIterator it(list);
  2167.     while (it.hasNext()) {
  2168.         QString v = it.next();
  2169.         if (v.startsWith("Script_")) {
  2170.             result_data.append(v.mid(7));
  2171.         }
  2172.     }
  2173.     int len = result_data.length();
  2174.     QScriptValue result_array = myengine.newArray(len);
  2175.     for (int i = 0; i < len; ++i) {
  2176.         result_array.setProperty(i, result_data.at(i));
  2177.     }
  2178.     return result_array;
  2179. }
  2180.  
  2181. QScriptValue ScriptEngine::getValKeys(const QString &file)
  2182. {
  2183.     QSettings s(file, QSettings::IniFormat);
  2184.     QStringList list = s.childKeys();
  2185.     QStringList result_data;
  2186.    
  2187.     QStringListIterator it(list);
  2188.     while (it.hasNext()) {
  2189.         QString v = it.next();
  2190.         if (v.startsWith("Script_")) {
  2191.             result_data.append(v.mid(7));
  2192.         }
  2193.     }
  2194.     int len = result_data.length();
  2195.     QScriptValue result_array = myengine.newArray(len);
  2196.     for (int i = 0; i < len; ++i) {
  2197.         result_array.setProperty(i, result_data.at(i));
  2198.     }
  2199.     return result_array;
  2200. }
  2201.  
  2202. QScriptValue ScriptEngine::getFileContent(const QString &fileName)
  2203. {
  2204.     QFile out(fileName);
  2205.  
  2206.     if (!out.open(QIODevice::ReadOnly)) {
  2207.         printLine("Script Warning in sys.getFileContent(filename): error when opening " + fileName + ": " + out.errorString());
  2208.         return myengine.undefinedValue();
  2209.     }
  2210.  
  2211.     return QString::fromUtf8(out.readAll());
  2212. }
  2213.  
  2214. #endif // PO_SCRIPT_SAFE_ONLY
  2215.  
  2216. #if !defined(PO_SCRIPT_NO_SYSTEM) && !defined(PO_SCRIPT_SAFE_ONLY)
  2217. int ScriptEngine::system(const QString &command)
  2218. {
  2219.     if (myserver->isSafeScripts()) {
  2220.         warn("system", "Safe scripts option is on. Unable to invoke system command.");
  2221.         return -1;
  2222.     } else {
  2223.         return ::system(command.toUtf8());
  2224.     }
  2225. }
  2226. #endif // PO_SCRIPT_NO_SYSTEM
  2227.  
  2228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement