diff options
author | truebrain <truebrain@openttd.org> | 2011-12-19 21:00:32 +0000 |
---|---|---|
committer | truebrain <truebrain@openttd.org> | 2011-12-19 21:00:32 +0000 |
commit | 3a535690d4e9aaa896a062e7b5b5454b1b07ac47 (patch) | |
tree | 600859d25db8391542b9cc0da9e063c7bdc6f4fc /src/script/api/script_admin.cpp | |
parent | 77b7366c2947a3f2545d5542021be1cc203a74e8 (diff) | |
download | openttd-3a535690d4e9aaa896a062e7b5b5454b1b07ac47.tar.xz |
(svn r23623) -Add: allow bi-directional communication with the AdminPort and GameScript
Diffstat (limited to 'src/script/api/script_admin.cpp')
-rw-r--r-- | src/script/api/script_admin.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp new file mode 100644 index 000000000..c3845b897 --- /dev/null +++ b/src/script/api/script_admin.cpp @@ -0,0 +1,151 @@ +/* $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" +#include "../../game/game.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; +} |