OpenTTD-patches/src/script/api/script_admin.cpp

151 lines
3.6 KiB
C++

/* $Id$ */
/*
* This file is part of OpenTTD.
* 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.
* 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.
* 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/>.
*/
/** @file script_admin.cpp Implementation of ScriptAdmin. */
#include "../../stdafx.h"
#include "script_admin.hpp"
#include "script_log.hpp"
#include "../../network/network_admin.h"
#include "../script_instance.hpp"
/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
{
if (max_depth == 0) {
ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
return false;
}
switch (sq_gettype(vm, index)) {
case OT_INTEGER: {
SQInteger res;
sq_getinteger(vm, index, &res);
char buf[10];
snprintf(buf, sizeof(buf), "%d", (int32)res);
data = buf;
return true;
}
case OT_STRING: {
const SQChar *res;
sq_getstring(vm, index, &res);
/* @bug if a string longer than 512 characters is given to SQ2OTTD, the
* internal buffer overflows. */
const char *buf = SQ2OTTD(res);
size_t len = strlen(buf) + 1;
if (len >= 255) {
ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
return false;
}
data = std::string("\"") + buf + "\"";
return true;
}
case OT_ARRAY: {
data = "[ ";
bool first = true;
sq_pushnull(vm);
while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
if (!first) data += ", ";
if (first) first = false;
std::string tmp;
bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
sq_pop(vm, 2);
if (!res) {
sq_pop(vm, 1);
return false;
}
data += tmp;
}
sq_pop(vm, 1);
data += " ]";
return true;
}
case OT_TABLE: {
data = "{ ";
bool first = true;
sq_pushnull(vm);
while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
if (!first) data += ", ";
if (first) first = false;
std::string key;
std::string value;
/* Store the key + value */
bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
sq_pop(vm, 2);
if (!res) {
sq_pop(vm, 1);
return false;
}
data += key + ": " + value;
}
sq_pop(vm, 1);
data += " }";
return true;
}
case OT_BOOL: {
SQBool res;
sq_getbool(vm, index, &res);
if (res) {
data = "true";
return true;
}
data = "false";
return true;
}
case OT_NULL: {
data = "null";
return true;
}
default:
ScriptLog::Error("You tried to send an unsupported type. No data sent.");
return false;
}
}
/* static */ SQInteger ScriptAdmin::Send(HSQUIRRELVM vm)
{
if (sq_gettop(vm) - 1 != 1) return sq_throwerror(vm, _SC("wrong number of parameters"));
if (sq_gettype(vm, 2) != OT_TABLE) {
return sq_throwerror(vm, _SC("ScriptAdmin::Send requires a table as first parameter. No data sent."));
}
std::string json;
ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json);
#ifdef ENABLE_NETWORK
if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) {
ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent.");
sq_pushinteger(vm, 0);
return 1;
}
NetworkAdminGameScript(json.c_str());
#endif /* ENABLE_NETWORK */
sq_pushinteger(vm, 1);
return 1;
}