1 /***************************************************************************** 2 * Copyright (c) 2014-2020 OpenRCT2 developers 3 * 4 * For a complete list of all authors, please refer to contributors.md 5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 6 * 7 * OpenRCT2 is licensed under the GNU General Public License version 3. 8 *****************************************************************************/ 9 10 #ifdef ENABLE_SCRIPTING 11 12 # include "ScNetwork.hpp" 13 14 # include "../../../Context.h" 15 # include "../../../actions/NetworkModifyGroupAction.h" 16 # include "../../../actions/PlayerKickAction.h" 17 # include "../../../network/NetworkAction.h" 18 # include "../../../network/network.h" 19 20 namespace OpenRCT2::Scripting 21 { ScNetwork(duk_context * ctx)22 ScNetwork::ScNetwork(duk_context* ctx) 23 : _context(ctx) 24 { 25 } 26 mode_get() const27 std::string ScNetwork::mode_get() const 28 { 29 # ifndef DISABLE_NETWORK 30 switch (network_get_mode()) 31 { 32 case NETWORK_MODE_SERVER: 33 return "server"; 34 case NETWORK_MODE_CLIENT: 35 return "client"; 36 } 37 # endif 38 return "none"; 39 } 40 numPlayers_get() const41 int32_t ScNetwork::numPlayers_get() const 42 { 43 # ifndef DISABLE_NETWORK 44 return network_get_num_players(); 45 # else 46 return 0; 47 # endif 48 } 49 numGroups_get() const50 int32_t ScNetwork::numGroups_get() const 51 { 52 # ifndef DISABLE_NETWORK 53 return network_get_num_groups(); 54 # else 55 return 0; 56 # endif 57 } 58 defaultGroup_get() const59 int32_t ScNetwork::defaultGroup_get() const 60 { 61 # ifndef DISABLE_NETWORK 62 return network_get_default_group(); 63 # else 64 return 0; 65 # endif 66 } 67 defaultGroup_set(int32_t value)68 void ScNetwork::defaultGroup_set(int32_t value) 69 { 70 # ifndef DISABLE_NETWORK 71 auto action = NetworkModifyGroupAction(ModifyGroupType::SetDefault, value); 72 GameActions::Execute(&action); 73 # endif 74 } 75 groups_get() const76 std::vector<std::shared_ptr<ScPlayerGroup>> ScNetwork::groups_get() const 77 { 78 std::vector<std::shared_ptr<ScPlayerGroup>> groups; 79 # ifndef DISABLE_NETWORK 80 auto numGroups = network_get_num_groups(); 81 for (int32_t i = 0; i < numGroups; i++) 82 { 83 auto groupId = network_get_group_id(i); 84 groups.push_back(std::make_shared<ScPlayerGroup>(groupId)); 85 } 86 # endif 87 return groups; 88 } 89 players_get() const90 std::vector<std::shared_ptr<ScPlayer>> ScNetwork::players_get() const 91 { 92 std::vector<std::shared_ptr<ScPlayer>> players; 93 # ifndef DISABLE_NETWORK 94 auto numPlayers = network_get_num_players(); 95 for (int32_t i = 0; i < numPlayers; i++) 96 { 97 auto playerId = network_get_player_id(i); 98 players.push_back(std::make_shared<ScPlayer>(playerId)); 99 } 100 # endif 101 return players; 102 } 103 currentPlayer_get() const104 std::shared_ptr<ScPlayer> ScNetwork::currentPlayer_get() const 105 { 106 std::shared_ptr<ScPlayer> player; 107 # ifndef DISABLE_NETWORK 108 auto playerId = network_get_current_player_id(); 109 player = std::make_shared<ScPlayer>(playerId); 110 # endif 111 return player; 112 } 113 getPlayer(int32_t index) const114 std::shared_ptr<ScPlayer> ScNetwork::getPlayer(int32_t index) const 115 { 116 # ifndef DISABLE_NETWORK 117 auto numPlayers = network_get_num_players(); 118 if (index < numPlayers) 119 { 120 auto playerId = network_get_player_id(index); 121 return std::make_shared<ScPlayer>(playerId); 122 } 123 # endif 124 return nullptr; 125 } 126 stats_get() const127 DukValue ScNetwork::stats_get() const 128 { 129 # ifndef DISABLE_NETWORK 130 auto obj = OpenRCT2::Scripting::DukObject(_context); 131 auto networkStats = network_get_stats(); 132 { 133 duk_push_array(_context); 134 duk_uarridx_t index = 0; 135 for (auto v : networkStats.bytesReceived) 136 { 137 duk_push_number(_context, v); 138 duk_put_prop_index(_context, -2, index); 139 index++; 140 } 141 obj.Set("bytesReceived", DukValue::take_from_stack(_context)); 142 } 143 { 144 duk_push_array(_context); 145 duk_uarridx_t index = 0; 146 for (auto v : networkStats.bytesSent) 147 { 148 duk_push_number(_context, v); 149 duk_put_prop_index(_context, -2, index); 150 index++; 151 } 152 obj.Set("bytesSent", DukValue::take_from_stack(_context)); 153 } 154 return obj.Take(); 155 # else 156 return ToDuk(_context, nullptr); 157 # endif 158 } 159 getGroup(int32_t index) const160 std::shared_ptr<ScPlayerGroup> ScNetwork::getGroup(int32_t index) const 161 { 162 # ifndef DISABLE_NETWORK 163 auto numGroups = network_get_num_groups(); 164 if (index < numGroups) 165 { 166 auto groupId = network_get_group_id(index); 167 return std::make_shared<ScPlayerGroup>(groupId); 168 } 169 # endif 170 return nullptr; 171 } 172 addGroup()173 void ScNetwork::addGroup() 174 { 175 # ifndef DISABLE_NETWORK 176 auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::AddGroup); 177 GameActions::Execute(&networkModifyGroup); 178 # endif 179 } 180 removeGroup(int32_t index)181 void ScNetwork::removeGroup(int32_t index) 182 { 183 # ifndef DISABLE_NETWORK 184 auto numGroups = network_get_num_groups(); 185 if (index < numGroups) 186 { 187 auto groupId = network_get_group_id(index); 188 auto networkAction = NetworkModifyGroupAction(ModifyGroupType::RemoveGroup, groupId); 189 GameActions::Execute(&networkAction); 190 } 191 # endif 192 } 193 kickPlayer(int32_t index)194 void ScNetwork::kickPlayer(int32_t index) 195 { 196 # ifndef DISABLE_NETWORK 197 auto numPlayers = network_get_num_players(); 198 if (index < numPlayers) 199 { 200 auto playerId = network_get_player_id(index); 201 auto kickPlayerAction = PlayerKickAction(playerId); 202 GameActions::Execute(&kickPlayerAction); 203 } 204 # endif 205 } 206 sendMessage(std::string message,DukValue players)207 void ScNetwork::sendMessage(std::string message, DukValue players) 208 { 209 # ifndef DISABLE_NETWORK 210 if (players.is_array()) 211 { 212 if (network_get_mode() == NETWORK_MODE_SERVER) 213 { 214 std::vector<uint8_t> playerIds; 215 auto playerArray = players.as_array(); 216 for (const auto& item : playerArray) 217 { 218 if (item.type() == DukValue::Type::NUMBER) 219 { 220 playerIds.push_back(static_cast<uint8_t>(item.as_int())); 221 } 222 } 223 if (!playerArray.empty()) 224 { 225 network_send_chat(message.c_str(), playerIds); 226 } 227 } 228 else 229 { 230 duk_error(players.context(), DUK_ERR_ERROR, "Only servers can send private messages."); 231 } 232 } 233 else 234 { 235 network_send_chat(message.c_str()); 236 } 237 # endif 238 } 239 240 # ifndef DISABLE_NETWORK createListener()241 std::shared_ptr<ScListener> ScNetwork::createListener() 242 { 243 auto& scriptEngine = GetContext()->GetScriptEngine(); 244 auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); 245 auto socket = std::make_shared<ScListener>(plugin); 246 scriptEngine.AddSocket(socket); 247 return socket; 248 } 249 # else createListener()250 void ScNetwork::createListener() 251 { 252 duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); 253 } 254 # endif 255 256 # ifndef DISABLE_NETWORK createSocket()257 std::shared_ptr<ScSocket> ScNetwork::createSocket() 258 { 259 auto& scriptEngine = GetContext()->GetScriptEngine(); 260 auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); 261 auto socket = std::make_shared<ScSocket>(plugin); 262 scriptEngine.AddSocket(socket); 263 return socket; 264 } 265 # else createSocket()266 void ScNetwork::createSocket() 267 { 268 duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); 269 } 270 # endif 271 Register(duk_context * ctx)272 void ScNetwork::Register(duk_context* ctx) 273 { 274 dukglue_register_property(ctx, &ScNetwork::mode_get, nullptr, "mode"); 275 dukglue_register_property(ctx, &ScNetwork::numGroups_get, nullptr, "numGroups"); 276 dukglue_register_property(ctx, &ScNetwork::numPlayers_get, nullptr, "numPlayers"); 277 dukglue_register_property(ctx, &ScNetwork::groups_get, nullptr, "groups"); 278 dukglue_register_property(ctx, &ScNetwork::players_get, nullptr, "players"); 279 dukglue_register_property(ctx, &ScNetwork::currentPlayer_get, nullptr, "currentPlayer"); 280 dukglue_register_property(ctx, &ScNetwork::defaultGroup_get, &ScNetwork::defaultGroup_set, "defaultGroup"); 281 dukglue_register_property(ctx, &ScNetwork::stats_get, nullptr, "stats"); 282 dukglue_register_method(ctx, &ScNetwork::addGroup, "addGroup"); 283 dukglue_register_method(ctx, &ScNetwork::getGroup, "getGroup"); 284 dukglue_register_method(ctx, &ScNetwork::removeGroup, "removeGroup"); 285 dukglue_register_method(ctx, &ScNetwork::getPlayer, "getPlayer"); 286 dukglue_register_method(ctx, &ScNetwork::kickPlayer, "kickPlayer"); 287 dukglue_register_method(ctx, &ScNetwork::sendMessage, "sendMessage"); 288 289 dukglue_register_method(ctx, &ScNetwork::createListener, "createListener"); 290 dukglue_register_method(ctx, &ScNetwork::createSocket, "createSocket"); 291 } 292 293 } // namespace OpenRCT2::Scripting 294 295 #endif 296