| 295 | } |
| 296 | |
| 297 | void SceneMultiplayer::_process_sys(int p_from, const uint8_t *p_packet, int p_packet_len, MultiplayerPeer::TransferMode p_mode, int p_channel) { |
| 298 | ERR_FAIL_COND_MSG(p_packet_len < SYS_CMD_SIZE, "Invalid packet received. Size too small."); |
| 299 | uint8_t sys_cmd_type = p_packet[1]; |
| 300 | int32_t peer = int32_t(decode_uint32(&p_packet[2])); |
| 301 | switch (sys_cmd_type) { |
| 302 | case SYS_COMMAND_ADD_PEER: { |
| 303 | ERR_FAIL_COND(!server_relay || !multiplayer_peer->is_server_relay_supported() || get_unique_id() == 1 || p_from != 1); |
| 304 | _admit_peer(peer); // Relayed peers are automatically accepted. |
| 305 | } break; |
| 306 | case SYS_COMMAND_DEL_PEER: { |
| 307 | ERR_FAIL_COND(!server_relay || !multiplayer_peer->is_server_relay_supported() || get_unique_id() == 1 || p_from != 1); |
| 308 | _del_peer(peer); |
| 309 | } break; |
| 310 | case SYS_COMMAND_RELAY: { |
| 311 | ERR_FAIL_COND(!server_relay || !multiplayer_peer->is_server_relay_supported()); |
| 312 | ERR_FAIL_COND(p_packet_len < SYS_CMD_SIZE + 1); |
| 313 | const uint8_t *packet = p_packet + SYS_CMD_SIZE; |
| 314 | int len = p_packet_len - SYS_CMD_SIZE; |
| 315 | bool should_process = false; |
| 316 | if (get_unique_id() == 1) { // I am the server. |
| 317 | // The requested target might have disconnected while the packet was in transit. |
| 318 | if (unlikely(peer > 0 && !connected_peers.has(peer))) { |
| 319 | return; |
| 320 | } |
| 321 | // Send relay packet. |
| 322 | relay_buffer->seek(0); |
| 323 | relay_buffer->put_u8(NETWORK_COMMAND_SYS); |
| 324 | relay_buffer->put_u8(SYS_COMMAND_RELAY); |
| 325 | relay_buffer->put_32(p_from); // Set the source. |
| 326 | relay_buffer->put_data(packet, len); |
| 327 | const Vector<uint8_t> data = relay_buffer->get_data_array(); |
| 328 | multiplayer_peer->set_transfer_mode(p_mode); |
| 329 | multiplayer_peer->set_transfer_channel(p_channel); |
| 330 | if (peer > 0) { |
| 331 | // Single destination. |
| 332 | multiplayer_peer->set_target_peer(peer); |
| 333 | _send(data.ptr(), relay_buffer->get_position()); |
| 334 | } else { |
| 335 | // Multiple destinations. |
| 336 | for (const int &P : connected_peers) { |
| 337 | // Not to sender, nor excluded. |
| 338 | if (P == p_from || P == -peer) { |
| 339 | continue; |
| 340 | } |
| 341 | multiplayer_peer->set_target_peer(P); |
| 342 | _send(data.ptr(), relay_buffer->get_position()); |
| 343 | } |
| 344 | if (peer != -1) { |
| 345 | // The server is one of the targets, process the packet with sender as source. |
| 346 | should_process = true; |
| 347 | peer = p_from; |
| 348 | } |
| 349 | } |
| 350 | } else { |
| 351 | ERR_FAIL_COND(p_from != 1); // Bug. |
| 352 | should_process = true; |
| 353 | } |
| 354 | if (should_process) { |
nothing calls this directly
no test coverage detected