mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r23623) -Add: allow bi-directional communication with the AdminPort and GameScript
This commit is contained in:
parent
77b7366c29
commit
3a535690d4
|
@ -926,6 +926,7 @@
|
||||||
<ClCompile Include="..\src\game\game_scanner.cpp" />
|
<ClCompile Include="..\src\game\game_scanner.cpp" />
|
||||||
<ClInclude Include="..\src\game\game_scanner.hpp" />
|
<ClInclude Include="..\src\game\game_scanner.hpp" />
|
||||||
<ClInclude Include="..\src\script\api\script_accounting.hpp" />
|
<ClInclude Include="..\src\script\api\script_accounting.hpp" />
|
||||||
|
<ClInclude Include="..\src\script\api\script_admin.hpp" />
|
||||||
<ClInclude Include="..\src\script\api\script_airport.hpp" />
|
<ClInclude Include="..\src\script\api\script_airport.hpp" />
|
||||||
<ClInclude Include="..\src\script\api\script_base.hpp" />
|
<ClInclude Include="..\src\script\api\script_base.hpp" />
|
||||||
<ClInclude Include="..\src\script\api\script_basestation.hpp" />
|
<ClInclude Include="..\src\script\api\script_basestation.hpp" />
|
||||||
|
@ -980,6 +981,7 @@
|
||||||
<ClInclude Include="..\src\script\api\script_waypoint.hpp" />
|
<ClInclude Include="..\src\script\api\script_waypoint.hpp" />
|
||||||
<ClInclude Include="..\src\script\api\script_waypointlist.hpp" />
|
<ClInclude Include="..\src\script\api\script_waypointlist.hpp" />
|
||||||
<ClCompile Include="..\src\script\api\script_accounting.cpp" />
|
<ClCompile Include="..\src\script\api\script_accounting.cpp" />
|
||||||
|
<ClCompile Include="..\src\script\api\script_admin.cpp" />
|
||||||
<ClCompile Include="..\src\script\api\script_airport.cpp" />
|
<ClCompile Include="..\src\script\api\script_airport.cpp" />
|
||||||
<ClCompile Include="..\src\script\api\script_base.cpp" />
|
<ClCompile Include="..\src\script\api\script_base.cpp" />
|
||||||
<ClCompile Include="..\src\script\api\script_basestation.cpp" />
|
<ClCompile Include="..\src\script\api\script_basestation.cpp" />
|
||||||
|
|
|
@ -2007,6 +2007,9 @@
|
||||||
<ClInclude Include="..\src\script\api\script_accounting.hpp">
|
<ClInclude Include="..\src\script\api\script_accounting.hpp">
|
||||||
<Filter>Script API</Filter>
|
<Filter>Script API</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\script\api\script_admin.hpp">
|
||||||
|
<Filter>Script API</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\src\script\api\script_airport.hpp">
|
<ClInclude Include="..\src\script\api\script_airport.hpp">
|
||||||
<Filter>Script API</Filter>
|
<Filter>Script API</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -2169,6 +2172,9 @@
|
||||||
<ClCompile Include="..\src\script\api\script_accounting.cpp">
|
<ClCompile Include="..\src\script\api\script_accounting.cpp">
|
||||||
<Filter>Script API Implementation</Filter>
|
<Filter>Script API Implementation</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\script\api\script_admin.cpp">
|
||||||
|
<Filter>Script API Implementation</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\script\api\script_airport.cpp">
|
<ClCompile Include="..\src\script\api\script_airport.cpp">
|
||||||
<Filter>Script API Implementation</Filter>
|
<Filter>Script API Implementation</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -3038,6 +3038,10 @@
|
||||||
RelativePath=".\..\src\script\api\script_accounting.hpp"
|
RelativePath=".\..\src\script\api\script_accounting.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\script\api\script_admin.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\script\api\script_airport.hpp"
|
RelativePath=".\..\src\script\api\script_airport.hpp"
|
||||||
>
|
>
|
||||||
|
@ -3258,6 +3262,10 @@
|
||||||
RelativePath=".\..\src\script\api\script_accounting.cpp"
|
RelativePath=".\..\src\script\api\script_accounting.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\script\api\script_admin.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\script\api\script_airport.cpp"
|
RelativePath=".\..\src\script\api\script_airport.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -3035,6 +3035,10 @@
|
||||||
RelativePath=".\..\src\script\api\script_accounting.hpp"
|
RelativePath=".\..\src\script\api\script_accounting.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\script\api\script_admin.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\script\api\script_airport.hpp"
|
RelativePath=".\..\src\script\api\script_airport.hpp"
|
||||||
>
|
>
|
||||||
|
@ -3255,6 +3259,10 @@
|
||||||
RelativePath=".\..\src\script\api\script_accounting.cpp"
|
RelativePath=".\..\src\script\api\script_accounting.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\script\api\script_admin.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\script\api\script_airport.cpp"
|
RelativePath=".\..\src\script\api\script_airport.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -704,6 +704,7 @@ game/game_scanner.hpp
|
||||||
|
|
||||||
# Script API
|
# Script API
|
||||||
script/api/script_accounting.hpp
|
script/api/script_accounting.hpp
|
||||||
|
script/api/script_admin.hpp
|
||||||
script/api/script_airport.hpp
|
script/api/script_airport.hpp
|
||||||
script/api/script_base.hpp
|
script/api/script_base.hpp
|
||||||
script/api/script_basestation.hpp
|
script/api/script_basestation.hpp
|
||||||
|
@ -760,6 +761,7 @@ script/api/script_waypointlist.hpp
|
||||||
|
|
||||||
# Script API Implementation
|
# Script API Implementation
|
||||||
script/api/script_accounting.cpp
|
script/api/script_accounting.cpp
|
||||||
|
script/api/script_admin.cpp
|
||||||
script/api/script_airport.cpp
|
script/api/script_airport.cpp
|
||||||
script/api/script_base.cpp
|
script/api/script_base.cpp
|
||||||
script/api/script_basestation.cpp
|
script/api/script_basestation.cpp
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
/* Convert all Game related classes to Squirrel data.
|
/* Convert all Game related classes to Squirrel data.
|
||||||
* Note: this line is a marker in squirrel_export.sh. Do not change! */
|
* Note: this line is a marker in squirrel_export.sh. Do not change! */
|
||||||
#include "../script/api/game/game_accounting.hpp.sq"
|
#include "../script/api/game/game_accounting.hpp.sq"
|
||||||
|
#include "../script/api/game/game_admin.hpp.sq"
|
||||||
#include "../script/api/game/game_airport.hpp.sq"
|
#include "../script/api/game/game_airport.hpp.sq"
|
||||||
#include "../script/api/game/game_base.hpp.sq"
|
#include "../script/api/game/game_base.hpp.sq"
|
||||||
#include "../script/api/game/game_basestation.hpp.sq"
|
#include "../script/api/game/game_basestation.hpp.sq"
|
||||||
|
@ -92,6 +93,7 @@ void GameInstance::RegisterAPI()
|
||||||
/* Register all classes */
|
/* Register all classes */
|
||||||
SQGSList_Register(this->engine);
|
SQGSList_Register(this->engine);
|
||||||
SQGSAccounting_Register(this->engine);
|
SQGSAccounting_Register(this->engine);
|
||||||
|
SQGSAdmin_Register(this->engine);
|
||||||
SQGSAirport_Register(this->engine);
|
SQGSAirport_Register(this->engine);
|
||||||
SQGSBase_Register(this->engine);
|
SQGSBase_Register(this->engine);
|
||||||
SQGSBaseStation_Register(this->engine);
|
SQGSBaseStation_Register(this->engine);
|
||||||
|
@ -110,6 +112,7 @@ void GameInstance::RegisterAPI()
|
||||||
SQGSEngineList_Register(this->engine);
|
SQGSEngineList_Register(this->engine);
|
||||||
SQGSError_Register(this->engine);
|
SQGSError_Register(this->engine);
|
||||||
SQGSEvent_Register(this->engine);
|
SQGSEvent_Register(this->engine);
|
||||||
|
SQGSEventAdminPort_Register(this->engine);
|
||||||
SQGSEventCompanyBankrupt_Register(this->engine);
|
SQGSEventCompanyBankrupt_Register(this->engine);
|
||||||
SQGSEventCompanyInTrouble_Register(this->engine);
|
SQGSEventCompanyInTrouble_Register(this->engine);
|
||||||
SQGSEventCompanyMerger_Register(this->engine);
|
SQGSEventCompanyMerger_Register(this->engine);
|
||||||
|
|
|
@ -48,6 +48,7 @@ static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum lengt
|
||||||
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
|
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
|
||||||
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
|
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
|
||||||
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
|
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
|
||||||
|
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = 1450; ///< The maximum length of a gamescript json string, in bytes including '\0'
|
||||||
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
|
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
|
||||||
|
|
||||||
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
||||||
|
|
|
@ -60,6 +60,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
|
||||||
case ADMIN_PACKET_ADMIN_POLL: return this->Receive_ADMIN_POLL(p);
|
case ADMIN_PACKET_ADMIN_POLL: return this->Receive_ADMIN_POLL(p);
|
||||||
case ADMIN_PACKET_ADMIN_CHAT: return this->Receive_ADMIN_CHAT(p);
|
case ADMIN_PACKET_ADMIN_CHAT: return this->Receive_ADMIN_CHAT(p);
|
||||||
case ADMIN_PACKET_ADMIN_RCON: return this->Receive_ADMIN_RCON(p);
|
case ADMIN_PACKET_ADMIN_RCON: return this->Receive_ADMIN_RCON(p);
|
||||||
|
case ADMIN_PACKET_ADMIN_GAMESCRIPT: return this->Receive_ADMIN_GAMESCRIPT(p);
|
||||||
|
|
||||||
case ADMIN_PACKET_SERVER_FULL: return this->Receive_SERVER_FULL(p);
|
case ADMIN_PACKET_SERVER_FULL: return this->Receive_SERVER_FULL(p);
|
||||||
case ADMIN_PACKET_SERVER_BANNED: return this->Receive_SERVER_BANNED(p);
|
case ADMIN_PACKET_SERVER_BANNED: return this->Receive_SERVER_BANNED(p);
|
||||||
|
@ -134,6 +135,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENCY(Pack
|
||||||
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_POLL); }
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_POLL); }
|
||||||
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_CHAT); }
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_CHAT); }
|
||||||
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_RCON); }
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_RCON); }
|
||||||
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_GAMESCRIPT); }
|
||||||
|
|
||||||
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_FULL(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_FULL); }
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_FULL(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_FULL); }
|
||||||
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_BANNED(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_BANNED); }
|
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_BANNED(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_BANNED); }
|
||||||
|
|
|
@ -32,6 +32,7 @@ enum PacketAdminType {
|
||||||
ADMIN_PACKET_ADMIN_POLL, ///< The admin explicitly polls for a piece of information.
|
ADMIN_PACKET_ADMIN_POLL, ///< The admin explicitly polls for a piece of information.
|
||||||
ADMIN_PACKET_ADMIN_CHAT, ///< The admin sends a chat message to be distributed.
|
ADMIN_PACKET_ADMIN_CHAT, ///< The admin sends a chat message to be distributed.
|
||||||
ADMIN_PACKET_ADMIN_RCON, ///< The admin sends a remote console command.
|
ADMIN_PACKET_ADMIN_RCON, ///< The admin sends a remote console command.
|
||||||
|
ADMIN_PACKET_ADMIN_GAMESCRIPT, ///< The admin sends a JSON string for the GameScript.
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_FULL = 100, ///< The server tells the admin it cannot accept the admin.
|
ADMIN_PACKET_SERVER_FULL = 100, ///< The server tells the admin it cannot accept the admin.
|
||||||
ADMIN_PACKET_SERVER_BANNED, ///< The server tells the admin it is banned.
|
ADMIN_PACKET_SERVER_BANNED, ///< The server tells the admin it is banned.
|
||||||
|
@ -58,6 +59,7 @@ enum PacketAdminType {
|
||||||
ADMIN_PACKET_SERVER_CONSOLE, ///< The server gives the admin the data that got printed to its console.
|
ADMIN_PACKET_SERVER_CONSOLE, ///< The server gives the admin the data that got printed to its console.
|
||||||
ADMIN_PACKET_SERVER_CMD_NAMES, ///< The server sends out the names of the DoCommands to the admins.
|
ADMIN_PACKET_SERVER_CMD_NAMES, ///< The server sends out the names of the DoCommands to the admins.
|
||||||
ADMIN_PACKET_SERVER_CMD_LOGGING, ///< The server gives the admin copies of incoming command packets.
|
ADMIN_PACKET_SERVER_CMD_LOGGING, ///< The server gives the admin copies of incoming command packets.
|
||||||
|
ADMIN_PACKET_SERVER_GAMESCRIPT, ///< The server gives the admin information from the GameScript in JSON.
|
||||||
|
|
||||||
INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets.
|
INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets.
|
||||||
};
|
};
|
||||||
|
@ -80,6 +82,7 @@ enum AdminUpdateType {
|
||||||
ADMIN_UPDATE_CONSOLE, ///< The admin would like to have console messages.
|
ADMIN_UPDATE_CONSOLE, ///< The admin would like to have console messages.
|
||||||
ADMIN_UPDATE_CMD_NAMES, ///< The admin would like a list of all DoCommand names.
|
ADMIN_UPDATE_CMD_NAMES, ///< The admin would like a list of all DoCommand names.
|
||||||
ADMIN_UPDATE_CMD_LOGGING, ///< The admin would like to have DoCommand information.
|
ADMIN_UPDATE_CMD_LOGGING, ///< The admin would like to have DoCommand information.
|
||||||
|
ADMIN_UPDATE_GAMESCRIPT, ///< The admin would like to have gamescript messages.
|
||||||
ADMIN_UPDATE_END, ///< Must ALWAYS be on the end of this list!! (period)
|
ADMIN_UPDATE_END, ///< Must ALWAYS be on the end of this list!! (period)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,6 +172,14 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual NetworkRecvStatus Receive_ADMIN_RCON(Packet *p);
|
virtual NetworkRecvStatus Receive_ADMIN_RCON(Packet *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a JSON string to the current active GameScript.
|
||||||
|
* json JSON string for the GameScript.
|
||||||
|
* @param p The packet that was just received.
|
||||||
|
* @return The state the network should have.
|
||||||
|
*/
|
||||||
|
virtual NetworkRecvStatus Receive_ADMIN_GAMESCRIPT(Packet *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server is full (connection gets closed).
|
* The server is full (connection gets closed).
|
||||||
* @param p The packet that was just received.
|
* @param p The packet that was just received.
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../core/pool_func.hpp"
|
#include "../core/pool_func.hpp"
|
||||||
#include "../map_func.h"
|
#include "../map_func.h"
|
||||||
#include "../rev.h"
|
#include "../rev.h"
|
||||||
|
#include "../game/game.hpp"
|
||||||
|
|
||||||
|
|
||||||
/* This file handles all the admin network commands. */
|
/* This file handles all the admin network commands. */
|
||||||
|
@ -52,6 +53,7 @@ static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
|
||||||
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CONSOLE
|
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CONSOLE
|
||||||
ADMIN_FREQUENCY_POLL, ///< ADMIN_UPDATE_CMD_NAMES
|
ADMIN_FREQUENCY_POLL, ///< ADMIN_UPDATE_CMD_NAMES
|
||||||
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CMD_LOGGING
|
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CMD_LOGGING
|
||||||
|
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_GAMESCRIPT
|
||||||
};
|
};
|
||||||
/** Sanity check. */
|
/** Sanity check. */
|
||||||
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
|
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
|
||||||
|
@ -510,6 +512,20 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
|
||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Packet *p)
|
||||||
|
{
|
||||||
|
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
|
||||||
|
|
||||||
|
char json[NETWORK_GAMESCRIPT_JSON_LENGTH];
|
||||||
|
|
||||||
|
p->Recv_string(json, sizeof(json));
|
||||||
|
|
||||||
|
DEBUG(net, 2, "[admin] GameScript JSON from '%s' (%s): '%s'", this->admin_name, this->admin_version, json);
|
||||||
|
|
||||||
|
Game::NewEvent(new ScriptEventAdminPort(json));
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send console output of other clients.
|
* Send console output of other clients.
|
||||||
* @param origin The origin of the string.
|
* @param origin The origin of the string.
|
||||||
|
@ -532,6 +548,25 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi
|
||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send GameScript JSON output.
|
||||||
|
* @param json The JSON string.
|
||||||
|
*/
|
||||||
|
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const char *json)
|
||||||
|
{
|
||||||
|
/* At the moment we cannot transmit anything larger than MTU. So the string
|
||||||
|
* has to be no longer than the length of the json + '\0' + 3 bytes of the
|
||||||
|
* packet header. */
|
||||||
|
if (strlen(json) + 1 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
|
||||||
|
Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT);
|
||||||
|
|
||||||
|
p->Send_string(json);
|
||||||
|
this->SendPacket(p);
|
||||||
|
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
/** Send the names of the commands. */
|
/** Send the names of the commands. */
|
||||||
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
|
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
|
||||||
{
|
{
|
||||||
|
@ -895,6 +930,20 @@ void NetworkAdminConsole(const char *origin, const char *string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send GameScript JSON to the admin network (if they did opt in for the respective update).
|
||||||
|
* @param json The JSON data as received from the GameScript.
|
||||||
|
*/
|
||||||
|
void NetworkAdminGameScript(const char *json)
|
||||||
|
{
|
||||||
|
ServerNetworkAdminSocketHandler *as;
|
||||||
|
FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) {
|
||||||
|
if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {
|
||||||
|
as->SendGameScript(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Distribute CommandPacket details over the admin network for logging purposes.
|
* Distribute CommandPacket details over the admin network for logging purposes.
|
||||||
* @param owner The owner of the CommandPacket (who sent us the CommandPacket).
|
* @param owner The owner of the CommandPacket (who sent us the CommandPacket).
|
||||||
|
|
|
@ -34,6 +34,7 @@ protected:
|
||||||
virtual NetworkRecvStatus Receive_ADMIN_POLL(Packet *p);
|
virtual NetworkRecvStatus Receive_ADMIN_POLL(Packet *p);
|
||||||
virtual NetworkRecvStatus Receive_ADMIN_CHAT(Packet *p);
|
virtual NetworkRecvStatus Receive_ADMIN_CHAT(Packet *p);
|
||||||
virtual NetworkRecvStatus Receive_ADMIN_RCON(Packet *p);
|
virtual NetworkRecvStatus Receive_ADMIN_RCON(Packet *p);
|
||||||
|
virtual NetworkRecvStatus Receive_ADMIN_GAMESCRIPT(Packet *p);
|
||||||
|
|
||||||
NetworkRecvStatus SendProtocol();
|
NetworkRecvStatus SendProtocol();
|
||||||
public:
|
public:
|
||||||
|
@ -65,6 +66,7 @@ public:
|
||||||
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data);
|
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data);
|
||||||
NetworkRecvStatus SendRcon(uint16 colour, const char *command);
|
NetworkRecvStatus SendRcon(uint16 colour, const char *command);
|
||||||
NetworkRecvStatus SendConsole(const char *origin, const char *command);
|
NetworkRecvStatus SendConsole(const char *origin, const char *command);
|
||||||
|
NetworkRecvStatus SendGameScript(const char *json);
|
||||||
NetworkRecvStatus SendCmdNames();
|
NetworkRecvStatus SendCmdNames();
|
||||||
NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp);
|
NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp);
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i
|
||||||
void NetworkAdminUpdate(AdminUpdateFrequency freq);
|
void NetworkAdminUpdate(AdminUpdateFrequency freq);
|
||||||
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string);
|
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string);
|
||||||
void NetworkAdminConsole(const char *origin, const char *string);
|
void NetworkAdminConsole(const char *origin, const char *string);
|
||||||
|
void NetworkAdminGameScript(const char *json);
|
||||||
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp);
|
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp);
|
||||||
|
|
||||||
#endif /* ENABLE_NETWORK */
|
#endif /* ENABLE_NETWORK */
|
||||||
|
|
|
@ -45,6 +45,7 @@ void SQAIEvent_Register(Squirrel *engine)
|
||||||
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
|
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
|
||||||
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
|
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
|
||||||
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
|
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
|
||||||
|
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_ADMIN_PORT, "ET_ADMIN_PORT");
|
||||||
|
|
||||||
SQAIEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
|
SQAIEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* $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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
|
||||||
|
|
||||||
|
#include "../script_admin.hpp"
|
||||||
|
#include "../template/template_admin.hpp.sq"
|
||||||
|
|
||||||
|
|
||||||
|
template <> const char *GetClassName<ScriptAdmin, ST_GS>() { return "GSAdmin"; }
|
||||||
|
|
||||||
|
void SQGSAdmin_Register(Squirrel *engine)
|
||||||
|
{
|
||||||
|
DefSQClass<ScriptAdmin, ST_GS> SQGSAdmin("GSAdmin");
|
||||||
|
SQGSAdmin.PreRegister(engine);
|
||||||
|
SQGSAdmin.AddConstructor<void (ScriptAdmin::*)(), 1>(engine, "x");
|
||||||
|
|
||||||
|
SQGSAdmin.DefSQAdvancedStaticMethod(engine, &ScriptAdmin::Send, "Send");
|
||||||
|
|
||||||
|
SQGSAdmin.PostRegister(engine);
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ void SQGSEvent_Register(Squirrel *engine)
|
||||||
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
|
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
|
||||||
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
|
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
|
||||||
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
|
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
|
||||||
|
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_ADMIN_PORT, "ET_ADMIN_PORT");
|
||||||
|
|
||||||
SQGSEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
|
SQGSEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
|
||||||
|
|
||||||
|
|
|
@ -217,3 +217,18 @@ void SQGSEventTownFounded_Register(Squirrel *engine)
|
||||||
|
|
||||||
SQGSEventTownFounded.PostRegister(engine);
|
SQGSEventTownFounded.PostRegister(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <> const char *GetClassName<ScriptEventAdminPort, ST_GS>() { return "GSEventAdminPort"; }
|
||||||
|
|
||||||
|
void SQGSEventAdminPort_Register(Squirrel *engine)
|
||||||
|
{
|
||||||
|
DefSQClass<ScriptEventAdminPort, ST_GS> SQGSEventAdminPort("GSEventAdminPort");
|
||||||
|
SQGSEventAdminPort.PreRegister(engine, "GSEvent");
|
||||||
|
|
||||||
|
SQGSEventAdminPort.DefSQStaticMethod(engine, &ScriptEventAdminPort::Convert, "Convert", 2, ".x");
|
||||||
|
|
||||||
|
SQGSEventAdminPort.DefSQAdvancedMethod(engine, &ScriptEventAdminPort::GetObject, "GetObject");
|
||||||
|
|
||||||
|
SQGSEventAdminPort.PostRegister(engine);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* $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.hpp Everything to communicate with the AdminPort. */
|
||||||
|
|
||||||
|
#ifndef SCRIPT_ADMIN_HPP
|
||||||
|
#define SCRIPT_ADMIN_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "script_object.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that handles communication with the AdminPort.
|
||||||
|
* @api game
|
||||||
|
*/
|
||||||
|
class ScriptAdmin : public ScriptObject {
|
||||||
|
public:
|
||||||
|
#ifndef DOXYGEN_API
|
||||||
|
/**
|
||||||
|
* Internal representation of the Send function.
|
||||||
|
*/
|
||||||
|
static SQInteger Send(HSQUIRRELVM vm);
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* Send information to the AdminPort. The information can be anything
|
||||||
|
* as long as it isn't a class or instance thereof.
|
||||||
|
* @param table The information to send, in a table. For example: { param = "param" }.
|
||||||
|
* @return True if and only if the data was successfully converted to JSON
|
||||||
|
* and send to the AdminPort.
|
||||||
|
* @note If the resulting JSON of your table is larger than 1450 bytes,
|
||||||
|
* nothing will be sent (and false will be returned).
|
||||||
|
*/
|
||||||
|
static bool Send(table);
|
||||||
|
#endif /* DOXYGEN_API */
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Convert a Squirrel structure into a JSON string.
|
||||||
|
* @param vm The VM to operate on.
|
||||||
|
* @param index The index we are currently working for.
|
||||||
|
* @param max_depth The maximal depth to follow the squirrel struct.
|
||||||
|
* @param data The resulting json string.
|
||||||
|
*/
|
||||||
|
static bool MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SCRIPT_ADMIN_HPP */
|
|
@ -50,6 +50,7 @@ public:
|
||||||
ET_DISASTER_ZEPPELINER_CLEARED,
|
ET_DISASTER_ZEPPELINER_CLEARED,
|
||||||
ET_TOWN_FOUNDED,
|
ET_TOWN_FOUNDED,
|
||||||
ET_AIRCRAFT_DEST_TOO_FAR,
|
ET_AIRCRAFT_DEST_TOO_FAR,
|
||||||
|
ET_ADMIN_PORT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../../stdafx.h"
|
#include "../../stdafx.h"
|
||||||
#include "script_event_types.hpp"
|
#include "script_event_types.hpp"
|
||||||
#include "script_vehicle.hpp"
|
#include "script_vehicle.hpp"
|
||||||
|
#include "script_log.hpp"
|
||||||
#include "../../command_type.h"
|
#include "../../command_type.h"
|
||||||
#include "../../strings_func.h"
|
#include "../../strings_func.h"
|
||||||
#include "../../settings_type.h"
|
#include "../../settings_type.h"
|
||||||
|
@ -119,3 +120,185 @@ bool ScriptEventCompanyAskMerger::AcceptMerger()
|
||||||
{
|
{
|
||||||
return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
|
return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
|
||||||
|
#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return NULL; }
|
||||||
|
|
||||||
|
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
char *p = this->json;
|
||||||
|
|
||||||
|
if (this->ReadTable(vm, p) == NULL) {
|
||||||
|
sq_pushnull(vm);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
|
||||||
|
{
|
||||||
|
char *value = p;
|
||||||
|
|
||||||
|
bool escape = false;
|
||||||
|
for (;;) {
|
||||||
|
if (*p == '\\') {
|
||||||
|
escape = true;
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*p == '"' && escape) {
|
||||||
|
escape = false;
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
|
||||||
|
if (*p == '"') break;
|
||||||
|
if (*p == '\0') RETURN_ERROR(0);
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
sq_pushstring(vm, OTTD2SQ(value), -1);
|
||||||
|
*p++ = '"';
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
|
||||||
|
{
|
||||||
|
sq_newtable(vm);
|
||||||
|
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p++ != '{') RETURN_ERROR(1);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p++ != '"') RETURN_ERROR(1);
|
||||||
|
|
||||||
|
p = ReadString(vm, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p++ != ':') RETURN_ERROR(2);
|
||||||
|
|
||||||
|
p = this->ReadValue(vm, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
sq_pop(vm, 2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_rawset(vm, -3);
|
||||||
|
/* The key (-2) and value (-1) are popped from the stack by squirrel. */
|
||||||
|
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p == ',') {
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p++ != '}') RETURN_ERROR(1);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
|
||||||
|
{
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
|
||||||
|
if (strncmp(p, "false", 5) == 0) {
|
||||||
|
sq_pushinteger(vm, 0);
|
||||||
|
return p + 5;
|
||||||
|
}
|
||||||
|
if (strncmp(p, "true", 4) == 0) {
|
||||||
|
sq_pushinteger(vm, 1);
|
||||||
|
return p + 4;
|
||||||
|
}
|
||||||
|
if (strncmp(p, "null", 4) == 0) {
|
||||||
|
sq_pushnull(vm);
|
||||||
|
return p + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*p) {
|
||||||
|
case '"': {
|
||||||
|
/* String */
|
||||||
|
p = ReadString(vm, ++p);
|
||||||
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '{': {
|
||||||
|
/* Table */
|
||||||
|
p = this->ReadTable(vm, p);
|
||||||
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '[': {
|
||||||
|
/* Array */
|
||||||
|
sq_newarray(vm, 0);
|
||||||
|
|
||||||
|
while (*p++ != ']') {
|
||||||
|
p = this->ReadValue(vm, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sq_arrayappend(vm, -2);
|
||||||
|
|
||||||
|
SKIP_EMPTY(p);
|
||||||
|
if (*p == ',') continue;
|
||||||
|
if (*p == ']') break;
|
||||||
|
RETURN_ERROR(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '1': case '2': case '3': case '4': case '5':
|
||||||
|
case '6': case '7': case '8': case '9': case '0':
|
||||||
|
case '-': {
|
||||||
|
/* Integer */
|
||||||
|
|
||||||
|
const char *value = p++;
|
||||||
|
for (;;) {
|
||||||
|
switch (*p++) {
|
||||||
|
case '1': case '2': case '3': case '4': case '5':
|
||||||
|
case '6': case '7': case '8': case '9': case '0':
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = atoi(value);
|
||||||
|
sq_pushinteger(vm, (SQInteger)res);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
RETURN_ERROR(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SKIP_EMPTY
|
||||||
|
#undef RETURN_ERROR
|
||||||
|
|
|
@ -829,4 +829,60 @@ private:
|
||||||
VehicleID vehicle_id; ///< The vehicle aircraft whose destination is too far away.
|
VehicleID vehicle_id; ///< The vehicle aircraft whose destination is too far away.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event Admin Port, indicating the admin port is sending you information.
|
||||||
|
* @api game
|
||||||
|
*/
|
||||||
|
class ScriptEventAdminPort : public ScriptEvent {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @param json The JSON string which got sent.
|
||||||
|
*/
|
||||||
|
ScriptEventAdminPort(const char *json) :
|
||||||
|
ScriptEvent(ET_ADMIN_PORT),
|
||||||
|
json(strdup(json))
|
||||||
|
{}
|
||||||
|
|
||||||
|
~ScriptEventAdminPort()
|
||||||
|
{
|
||||||
|
free(this->json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an ScriptEvent to the real instance.
|
||||||
|
* @param instance The instance to convert.
|
||||||
|
* @return The converted instance.
|
||||||
|
*/
|
||||||
|
static ScriptEventAdminPort *Convert(ScriptEvent *instance) { return (ScriptEventAdminPort *)instance; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the information that was sent to you back as Squirrel object.
|
||||||
|
*/
|
||||||
|
SQInteger GetObject(HSQUIRRELVM vm);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char *json; ///< The JSON string.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a table from a JSON string.
|
||||||
|
* @param vm The VM used.
|
||||||
|
* @param p The (part of the) JSON string reading.
|
||||||
|
*/
|
||||||
|
char *ReadTable(HSQUIRRELVM vm, char *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a value from a JSON string.
|
||||||
|
* @param vm The VM used.
|
||||||
|
* @param p The (part of the) JSON string reading.
|
||||||
|
*/
|
||||||
|
char *ReadValue(HSQUIRRELVM vm, char *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a string from a JSON string.
|
||||||
|
* @param vm The VM used.
|
||||||
|
* @param p The (part of the) JSON string reading.
|
||||||
|
*/
|
||||||
|
char *ReadString(HSQUIRRELVM vm, char *p);
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SCRIPT_EVENT_TYPES_HPP */
|
#endif /* SCRIPT_EVENT_TYPES_HPP */
|
||||||
|
|
|
@ -385,7 +385,11 @@ BEGIN {
|
||||||
if (mlen <= length(static_methods[i, 0])) mlen = length(static_methods[i, 0])
|
if (mlen <= length(static_methods[i, 0])) mlen = length(static_methods[i, 0])
|
||||||
}
|
}
|
||||||
for (i = 1; i <= static_method_size; i++) {
|
for (i = 1; i <= static_method_size; i++) {
|
||||||
|
if (static_methods[i, 2] == "v") {
|
||||||
|
print " SQ" api_cls ".DefSQAdvancedStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0]) - 8) "\"" static_methods[i, 0] "\");"
|
||||||
|
} else {
|
||||||
print " SQ" api_cls ".DefSQStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "\"" static_methods[i, 0] "\", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "" static_methods[i, 1] ", \"" static_methods[i, 2] "\");"
|
print " SQ" api_cls ".DefSQStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "\"" static_methods[i, 0] "\", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "" static_methods[i, 1] ", \"" static_methods[i, 2] "\");"
|
||||||
|
}
|
||||||
delete static_methods[i]
|
delete static_methods[i]
|
||||||
}
|
}
|
||||||
if (static_method_size != 0) print ""
|
if (static_method_size != 0) print ""
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* $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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
|
||||||
|
|
||||||
|
#include "../script_admin.hpp"
|
||||||
|
|
||||||
|
namespace SQConvert {
|
||||||
|
/* Allow ScriptAdmin to be used as Squirrel parameter */
|
||||||
|
template <> inline ScriptAdmin *GetParam(ForceType<ScriptAdmin *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAdmin *)instance; }
|
||||||
|
template <> inline ScriptAdmin &GetParam(ForceType<ScriptAdmin &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; }
|
||||||
|
template <> inline const ScriptAdmin *GetParam(ForceType<const ScriptAdmin *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAdmin *)instance; }
|
||||||
|
template <> inline const ScriptAdmin &GetParam(ForceType<const ScriptAdmin &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; }
|
||||||
|
template <> inline int Return<ScriptAdmin *>(HSQUIRRELVM vm, ScriptAdmin *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Admin", res, NULL, DefSQDestructorCallback<ScriptAdmin>, true); return 1; }
|
||||||
|
} // namespace SQConvert
|
|
@ -212,3 +212,12 @@ namespace SQConvert {
|
||||||
template <> inline const ScriptEventAircraftDestTooFar &GetParam(ForceType<const ScriptEventAircraftDestTooFar &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; }
|
template <> inline const ScriptEventAircraftDestTooFar &GetParam(ForceType<const ScriptEventAircraftDestTooFar &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; }
|
||||||
template <> inline int Return<ScriptEventAircraftDestTooFar *>(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, NULL, DefSQDestructorCallback<ScriptEventAircraftDestTooFar>, true); return 1; }
|
template <> inline int Return<ScriptEventAircraftDestTooFar *>(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, NULL, DefSQDestructorCallback<ScriptEventAircraftDestTooFar>, true); return 1; }
|
||||||
} // namespace SQConvert
|
} // namespace SQConvert
|
||||||
|
|
||||||
|
namespace SQConvert {
|
||||||
|
/* Allow ScriptEventAdminPort to be used as Squirrel parameter */
|
||||||
|
template <> inline ScriptEventAdminPort *GetParam(ForceType<ScriptEventAdminPort *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAdminPort *)instance; }
|
||||||
|
template <> inline ScriptEventAdminPort &GetParam(ForceType<ScriptEventAdminPort &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; }
|
||||||
|
template <> inline const ScriptEventAdminPort *GetParam(ForceType<const ScriptEventAdminPort *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAdminPort *)instance; }
|
||||||
|
template <> inline const ScriptEventAdminPort &GetParam(ForceType<const ScriptEventAdminPort &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; }
|
||||||
|
template <> inline int Return<ScriptEventAdminPort *>(HSQUIRRELVM vm, ScriptEventAdminPort *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAdminPort", res, NULL, DefSQDestructorCallback<ScriptEventAdminPort>, true); return 1; }
|
||||||
|
} // namespace SQConvert
|
||||||
|
|
|
@ -297,12 +297,10 @@ static const SaveLoad _script_byte[] = {
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint SCRIPTSAVE_MAX_DEPTH = 25; ///< The maximum recursive depth for items stored in the savegame.
|
|
||||||
|
|
||||||
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
|
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
|
||||||
{
|
{
|
||||||
if (max_depth == 0) {
|
if (max_depth == 0) {
|
||||||
ScriptLog::Error("Savedata can only be nested to 25 deep. No data saved.");
|
ScriptLog::Error("Savedata can only be nested to 25 deep. No data saved."); // SQUIRREL_MAX_DEPTH = 25
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +437,7 @@ void ScriptInstance::Save()
|
||||||
_script_sl_byte = 1;
|
_script_sl_byte = 1;
|
||||||
SlObject(NULL, _script_byte);
|
SlObject(NULL, _script_byte);
|
||||||
/* Save the data that was just loaded. */
|
/* Save the data that was just loaded. */
|
||||||
SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, false);
|
SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false);
|
||||||
} else if (!this->is_started) {
|
} else if (!this->is_started) {
|
||||||
SaveEmpty();
|
SaveEmpty();
|
||||||
return;
|
return;
|
||||||
|
@ -478,10 +476,10 @@ void ScriptInstance::Save()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sq_pushobject(vm, savedata);
|
sq_pushobject(vm, savedata);
|
||||||
if (SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, true)) {
|
if (SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, true)) {
|
||||||
_script_sl_byte = 1;
|
_script_sl_byte = 1;
|
||||||
SlObject(NULL, _script_byte);
|
SlObject(NULL, _script_byte);
|
||||||
SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, false);
|
SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false);
|
||||||
this->is_save_data_on_stack = true;
|
this->is_save_data_on_stack = true;
|
||||||
} else {
|
} else {
|
||||||
SaveEmpty();
|
SaveEmpty();
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include "../command_type.h"
|
#include "../command_type.h"
|
||||||
|
|
||||||
|
static const uint SQUIRREL_MAX_DEPTH = 25; ///< The maximum recursive depth for items stored in the savegame.
|
||||||
|
|
||||||
/** Runtime information about a script like a pointer to the squirrel vm and the current state. */
|
/** Runtime information about a script like a pointer to the squirrel vm and the current state. */
|
||||||
class ScriptInstance {
|
class ScriptInstance {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -71,6 +71,16 @@ public:
|
||||||
engine->AddMethod(function_name, DefSQStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
|
engine->AddMethod(function_name, DefSQStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This defines a static method inside a class for Squirrel, which has access to the 'engine' (experts only!).
|
||||||
|
*/
|
||||||
|
template <typename Func>
|
||||||
|
void DefSQAdvancedStaticMethod(Squirrel *engine, Func function_proc, const char *function_name)
|
||||||
|
{
|
||||||
|
using namespace SQConvert;
|
||||||
|
engine->AddMethod(function_name, DefSQAdvancedStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This defines a static method inside a class for Squirrel with defined params.
|
* This defines a static method inside a class for Squirrel with defined params.
|
||||||
* @note If you define nparam, make sure that he first param is always 'x',
|
* @note If you define nparam, make sure that he first param is always 'x',
|
||||||
|
|
|
@ -831,6 +831,28 @@ namespace SQConvert {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A general template for all static advanced method callbacks from Squirrel.
|
||||||
|
* In here the function_proc is recovered, and the SQCall is called that
|
||||||
|
* can handle this exact amount of params.
|
||||||
|
*/
|
||||||
|
template <typename Tcls, typename Tmethod>
|
||||||
|
inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
/* Find the amount of params we got */
|
||||||
|
int nparam = sq_gettop(vm);
|
||||||
|
SQUserPointer ptr = NULL;
|
||||||
|
|
||||||
|
/* Get the real function pointer */
|
||||||
|
sq_getuserdata(vm, nparam, &ptr, 0);
|
||||||
|
/* Remove the userdata from the stack */
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
|
||||||
|
/* Call the function, which its only param is always the VM */
|
||||||
|
return (SQInteger)(*(*(Tmethod *)ptr))(vm);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A general template for the destructor of SQ instances. This is needed
|
* A general template for the destructor of SQ instances. This is needed
|
||||||
* here as it has to be in the same scope as DefSQConstructorCallback.
|
* here as it has to be in the same scope as DefSQConstructorCallback.
|
||||||
|
|
Loading…
Reference in New Issue