script_admin.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../../stdafx.h"
00013 #include "script_admin.hpp"
00014 #include "script_log.hpp"
00015 #include "../../network/network_admin.h"
00016 #include "../script_instance.hpp"
00017 #include "../../game/game.hpp"
00018 
00019 /* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
00020 {
00021   if (max_depth == 0) {
00022     ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
00023     return false;
00024   }
00025 
00026   switch (sq_gettype(vm, index)) {
00027     case OT_INTEGER: {
00028       SQInteger res;
00029       sq_getinteger(vm, index, &res);
00030 
00031       char buf[10];
00032       snprintf(buf, sizeof(buf), "%d", (int32)res);
00033       data = buf;
00034       return true;
00035     }
00036 
00037     case OT_STRING: {
00038       const SQChar *res;
00039       sq_getstring(vm, index, &res);
00040 
00041       /* @bug if a string longer than 512 characters is given to SQ2OTTD, the
00042        *  internal buffer overflows. */
00043       const char *buf = SQ2OTTD(res);
00044       size_t len = strlen(buf) + 1;
00045       if (len >= 255) {
00046         ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
00047         return false;
00048       }
00049 
00050       data = std::string("\"") + buf + "\"";
00051       return true;
00052     }
00053 
00054     case OT_ARRAY: {
00055       data = "[ ";
00056 
00057       bool first = true;
00058       sq_pushnull(vm);
00059       while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
00060         if (!first) data += ", ";
00061         if (first) first = false;
00062 
00063         std::string tmp;
00064 
00065         bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
00066         sq_pop(vm, 2);
00067         if (!res) {
00068           sq_pop(vm, 1);
00069           return false;
00070         }
00071         data += tmp;
00072       }
00073       sq_pop(vm, 1);
00074       data += " ]";
00075       return true;
00076     }
00077 
00078     case OT_TABLE: {
00079       data = "{ ";
00080 
00081       bool first = true;
00082       sq_pushnull(vm);
00083       while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
00084         if (!first) data += ", ";
00085         if (first) first = false;
00086 
00087         std::string key;
00088         std::string value;
00089 
00090         /* Store the key + value */
00091         bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
00092         sq_pop(vm, 2);
00093         if (!res) {
00094           sq_pop(vm, 1);
00095           return false;
00096         }
00097         data += key + ": " + value;
00098       }
00099       sq_pop(vm, 1);
00100       data += " }";
00101       return true;
00102     }
00103 
00104     case OT_BOOL: {
00105       SQBool res;
00106       sq_getbool(vm, index, &res);
00107 
00108       if (res) {
00109         data = "true";
00110         return true;
00111       }
00112 
00113       data = "false";
00114       return true;
00115     }
00116 
00117     case OT_NULL: {
00118       data = "null";
00119       return true;
00120     }
00121 
00122     default:
00123       ScriptLog::Error("You tried to send an unsupported type. No data sent.");
00124       return false;
00125   }
00126 }
00127 
00128 /* static */ SQInteger ScriptAdmin::Send(HSQUIRRELVM vm)
00129 {
00130   if (sq_gettop(vm) - 1 != 1) return sq_throwerror(vm, _SC("wrong number of parameters"));
00131 
00132   if (sq_gettype(vm, 2) != OT_TABLE) {
00133     return sq_throwerror(vm, _SC("ScriptAdmin::Send requires a table as first parameter. No data sent."));
00134   }
00135 
00136   std::string json;
00137   ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json);
00138 
00139 #ifdef ENABLE_NETWORK
00140   if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) {
00141     ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent.");
00142     sq_pushinteger(vm, 0);
00143     return 1;
00144   }
00145 
00146   NetworkAdminGameScript(json.c_str());
00147 #endif /* ENABLE_NETWORK */
00148 
00149   sq_pushinteger(vm, 1);
00150   return 1;
00151 }