2023-01-05 13:25:55 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*  scene_rpc_interface.cpp                                               */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                         This file is part of:                          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                             GODOT ENGINE                               */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                        https://godotengine.org                         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* a copy of this software and associated documentation files (the        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* "Software"), to deal in the Software without restriction, including    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* the following conditions:                                              */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* The above copyright notice and this permission notice shall be         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* included in all copies or substantial portions of the Software.        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "scene_rpc_interface.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-13 16:56:21 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "scene_multiplayer.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/debugger/engine_debugger.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/io/marshalls.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "scene/main/multiplayer_api.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  "scene/main/node.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "scene/main/window.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// The RPC meta is composed by a single byte that contains (starting from the least significant bit):
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// - `NetworkCommands` in the first four bits.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// - `NetworkNodeIdCompression` in the next 2 bits.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// - `NetworkNameIdCompression` in the next 1 bit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// - `byte_only_or_no_args` in the next 1 bit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NODE_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_0_SHIFT 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NAME_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_2_SHIFT 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define BYTE_ONLY_OR_NO_ARGS_SHIFT SceneMultiplayer::CMD_FLAG_3_SHIFT 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NODE_ID_COMPRESSION_FLAG ((1 << NODE_ID_COMPRESSION_SHIFT) | (1 << (NODE_ID_COMPRESSION_SHIFT + 1))) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NAME_ID_COMPRESSION_FLAG (1 << NAME_ID_COMPRESSION_SHIFT) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define BYTE_ONLY_OR_NO_ARGS_FLAG (1 << BYTE_ONLY_OR_NO_ARGS_SHIFT) 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_ENABLED 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-16 22:48:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								_FORCE_INLINE_  void  SceneRPCInterface : : _profile_node_data ( const  String  & p_what ,  ObjectID  p_id ,  int  p_size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-17 03:31:23 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( EngineDebugger : : is_profiling ( " multiplayer:rpc " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-22 22:53:26 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Array  values  =  {  p_what ,  p_id ,  p_size  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-17 03:31:23 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										EngineDebugger : : profiler_add_frame_data ( " multiplayer:rpc " ,  values ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Returns the packet size stripping the node path added when the node is not yet cached.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  get_packet_len ( uint32_t  p_node_target ,  int  p_packet_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_node_target  &  0x80000000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  ofs  =  p_node_target  &  0x7FFFFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  p_packet_len  -  ( p_packet_len  -  ofs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  p_packet_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SceneRPCInterface : : _parse_rpc_config ( const  Variant  & p_config ,  bool  p_for_node ,  RPCConfigCache  & r_cache )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_config . get_type ( )  = =  Variant : : NIL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND ( p_config . get_type ( )  ! =  Variant : : DICTIONARY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  Dictionary  config  =  p_config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Array  names  =  config . keys ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 21:31:54 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									names . sort_custom ( callable_mp_static ( & StringLikeVariantOrder : : compare ) ) ;  // Ensure ID order
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( int  i  =  0 ;  i  <  names . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-28 14:44:23 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_CONTINUE ( ! names [ i ] . is_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										String  name  =  names [ i ] . operator  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_CONTINUE ( config [ name ] . get_type ( )  ! =  Variant : : DICTIONARY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_CONTINUE ( ! config [ name ] . operator  Dictionary ( ) . has ( " rpc_mode " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Dictionary  dict  =  config [ name ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										RPCConfig  cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cfg . name  =  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cfg . rpc_mode  =  ( ( MultiplayerAPI : : RPCMode ) dict . get ( " rpc_mode " ,  MultiplayerAPI : : RPC_MODE_AUTHORITY ) . operator  int ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cfg . transfer_mode  =  ( ( MultiplayerPeer : : TransferMode ) dict . get ( " transfer_mode " ,  MultiplayerPeer : : TRANSFER_MODE_RELIABLE ) . operator  int ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cfg . call_local  =  dict . get ( " call_local " ,  false ) . operator  bool ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cfg . channel  =  dict . get ( " channel " ,  0 ) . operator  int ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										uint16_t  id  =  ( ( uint16_t ) i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( p_for_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											id  | =  ( 1  < <  15 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										r_cache . configs [ id ]  =  cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										r_cache . ids [ name ]  =  id ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  SceneRPCInterface : : RPCConfigCache  & SceneRPCInterface : : _get_node_config ( const  Node  * p_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  ObjectID  oid  =  p_node - > get_instance_id ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( rpc_cache . has ( oid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  rpc_cache [ oid ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									RPCConfigCache  cache ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-26 15:57:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_parse_rpc_config ( p_node - > get_node_rpc_config ( ) ,  true ,  cache ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( p_node - > get_script_instance ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										_parse_rpc_config ( p_node - > get_script_instance ( ) - > get_rpc_config ( ) ,  false ,  cache ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									rpc_cache [ oid ]  =  cache ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  rpc_cache [ oid ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								String  SceneRPCInterface : : get_rpc_md5 ( const  Object  * p_obj )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  Node  * node  =  Object : : cast_to < Node > ( p_obj ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:40:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_NULL_V ( node ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  RPCConfigCache  cache  =  _get_node_config ( node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									String  rpc_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( const  KeyValue < uint16_t ,  RPCConfig >  & config  :  cache . configs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										rpc_list  + =  String ( config . value . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  rpc_list . md5_text ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Node  * SceneRPCInterface : : _process_get_node ( int  p_from ,  const  uint8_t  * p_packet ,  uint32_t  p_node_target ,  int  p_packet_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Node  * root_node  =  SceneTree : : get_singleton ( ) - > get_root ( ) - > get_node ( multiplayer - > get_root_path ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:40:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_NULL_V ( root_node ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									Node  * node  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_node_target  &  0x80000000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Use full path (not cached yet).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  ofs  =  p_node_target  &  0x7FFFFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND_V_MSG ( ofs  > =  p_packet_len ,  nullptr ,  " Invalid packet received. Size smaller than declared. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-30 19:56:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										String  paths  =  String : : utf8 ( ( const  char  * ) & p_packet [ ofs ] ,  p_packet_len  -  ofs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										NodePath  np  =  paths ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										node  =  root_node - > get_node ( np ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_PRINT ( " Failed to get path from RPC:  "  +  String ( np )  +  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Use cached path.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  Object : : cast_to < Node > ( multiplayer_cache - > get_cached_object ( p_from ,  p_node_target ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SceneRPCInterface : : process_rpc ( int  p_from ,  const  uint8_t  * p_packet ,  int  p_packet_len )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Extract packet meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  packet_min_size  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  name_id_offset  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( p_packet_len  <  packet_min_size ,  " Invalid packet received. Size too small. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Compute the meta size, which depends on the compression level.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  node_id_compression  =  ( p_packet [ 0 ]  &  NODE_ID_COMPRESSION_FLAG )  > >  NODE_ID_COMPRESSION_SHIFT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  name_id_compression  =  ( p_packet [ 0 ]  &  NAME_ID_COMPRESSION_FLAG )  > >  NAME_ID_COMPRESSION_SHIFT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( node_id_compression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_min_size  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_id_offset  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_min_size  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_id_offset  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_min_size  + =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_id_offset  + =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_FAIL_MSG ( " Was not possible to extract the node id compression mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( name_id_compression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NAME_ID_COMPRESSION_8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_min_size  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NAME_ID_COMPRESSION_16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_min_size  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_FAIL_MSG ( " Was not possible to extract the name id compression mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( p_packet_len  <  packet_min_size ,  " Invalid packet received. Size too small. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint32_t  node_target  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( node_id_compression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_target  =  p_packet [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_target  =  decode_uint16 ( p_packet  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NODE_ID_COMPRESSION_32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_target  =  decode_uint32 ( p_packet  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Unreachable, checked before.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CRASH_NOW ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Node  * node  =  _process_get_node ( p_from ,  p_packet ,  node_target ,  p_packet_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:40:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_NULL_MSG ( node ,  " Invalid packet received. Requested node was not found. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint16_t  name_id  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( name_id_compression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NAME_ID_COMPRESSION_8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_id  =  p_packet [ name_id_offset ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  NETWORK_NAME_ID_COMPRESSION_16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_id  =  decode_uint16 ( p_packet  +  name_id_offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Unreachable, checked before.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CRASH_NOW ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  int  packet_len  =  get_packet_len ( node_target ,  p_packet_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									_process_rpc ( node ,  name_id ,  p_from ,  p_packet ,  packet_len ,  packet_min_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-06 19:37:06 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  String  _get_rpc_mode_string ( MultiplayerAPI : : RPCMode  p_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( p_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_DISABLED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  " disabled " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_ANY_PEER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  " any_peer " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_AUTHORITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  " authority " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_V_MSG ( String ( ) ,  " Invalid RPC mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SceneRPCInterface : : _process_rpc ( Node  * p_node ,  const  uint16_t  p_rpc_method_id ,  int  p_from ,  const  uint8_t  * p_packet ,  int  p_packet_len ,  int  p_offset )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( p_offset  >  p_packet_len ,  " Invalid packet received. Size too small. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Check that remote can call the RPC on this node.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  RPCConfigCache  & cache_config  =  _get_node_config ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND ( ! cache_config . configs . has ( p_rpc_method_id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  RPCConfig  & config  =  cache_config . configs [ p_rpc_method_id ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:12:58 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									bool  can_call  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( config . rpc_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_DISABLED :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											can_call  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_ANY_PEER :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											can_call  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  MultiplayerAPI : : RPC_MODE_AUTHORITY :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											can_call  =  p_from  = =  p_node - > get_multiplayer_authority ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-06 19:37:06 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( ! can_call ,  " RPC ' "  +  String ( config . name )  +  " ' is not allowed on node  "  +  String ( p_node - > get_path ( ) )  +  "  from:  "  +  itos ( p_from )  +  " . Mode is  \" "  +  _get_rpc_mode_string ( config . rpc_mode )  +  " \" , authority is  "  +  itos ( p_node - > get_multiplayer_authority ( ) )  +  " . " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  argc  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  bool  byte_only_or_no_args  =  p_packet [ 0 ]  &  BYTE_ONLY_OR_NO_ARGS_FLAG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( byte_only_or_no_args )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( p_offset  <  p_packet_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// This packet contains only bytes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											argc  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Normal variant, takes the argument count from the packet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND_MSG ( p_offset  > =  p_packet_len ,  " Invalid packet received. Size too small. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										argc  =  p_packet [ p_offset ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										p_offset  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < Variant >  args ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < const  Variant  * >  argp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									args . resize ( argc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									argp . resize ( argc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_ENABLED 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-16 22:48:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_profile_node_data ( " rpc_in " ,  p_node - > get_instance_id ( ) ,  p_packet_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 14:13:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MultiplayerAPI : : decode_and_decompress_variants ( args ,  & p_packet [ p_offset ] ,  p_packet_len  -  p_offset ,  out ,  byte_only_or_no_args ,  multiplayer - > is_object_decoding_allowed ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( int  i  =  0 ;  i  <  argc ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										argp . write [ i ]  =  & args [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Callable : : CallError  ce ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-09 14:58:40 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									p_node - > callp ( config . name ,  ( const  Variant  * * ) argp . ptr ( ) ,  argc ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  error  =  Variant : : get_call_error_text ( p_node ,  config . name ,  ( const  Variant  * * ) argp . ptr ( ) ,  argc ,  ce ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										error  =  " RPC -  "  +  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_PRINT ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SceneRPCInterface : : _send_rpc ( Node  * p_node ,  int  p_to ,  uint16_t  p_rpc_id ,  const  RPCConfig  & p_config ,  const  StringName  & p_name ,  const  Variant  * * p_arg ,  int  p_argcount )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Ref < MultiplayerPeer >  peer  =  multiplayer - > get_multiplayer_peer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( peer . is_null ( ) ,  " Attempt to call RPC without active multiplayer peer. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( peer - > get_connection_status ( )  = =  MultiplayerPeer : : CONNECTION_CONNECTING ,  " Attempt to call RPC while multiplayer peer is not connected yet. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( peer - > get_connection_status ( )  = =  MultiplayerPeer : : CONNECTION_DISCONNECTED ,  " Attempt to call RPC while multiplayer peer is disconnected. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( p_argcount  >  255 ,  " Too many arguments (>255). " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-30 17:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( p_to  ! =  0  & &  ! multiplayer - > get_connected_peers ( ) . has ( Math : : abs ( p_to ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND_MSG ( p_to  = =  multiplayer - > get_unique_id ( ) ,  " Attempt to call RPC on yourself! Peer unique ID:  "  +  itos ( multiplayer - > get_unique_id ( ) )  +  " . " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_FAIL_MSG ( " Attempt to call RPC with unknown peer ID:  "  +  itos ( p_to )  +  " . " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// See if all peers have cached path (if so, call can be fast) while building the RPC target list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									HashSet < int >  targets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  psc_id  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  has_all_peers  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  ObjectID  oid  =  p_node - > get_instance_id ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_to  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND_MSG ( ! multiplayer_replicator - > is_rpc_visible ( oid ,  p_to ) ,  " Attempt to call an RPC to a peer that cannot see this node. Peer ID:  "  +  itos ( p_to ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										targets . insert ( p_to ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										has_all_peers  =  multiplayer_cache - > send_object_cache ( p_node ,  p_to ,  psc_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										bool  restricted  =  ! multiplayer_replicator - > is_rpc_visible ( oid ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( const  int  & P  :  multiplayer - > get_connected_peers ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( p_to  <  0  & &  P  = =  - p_to )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ;  // Excluded peer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( restricted  & &  ! multiplayer_replicator - > is_rpc_visible ( oid ,  P ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												continue ;  // Not visible to this peer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											targets . insert ( P ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											bool  has_peer  =  multiplayer_cache - > send_object_cache ( p_node ,  P ,  psc_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											has_all_peers  =  has_all_peers  & &  has_peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( targets . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ;  // No one in sight.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Create base packet, lots of hardcode because it must be tight.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  ofs  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define MAKE_ROOM(m_amount)             \ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( packet_cache . size ( )  <  m_amount )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										packet_cache . resize ( m_amount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Encode meta.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									uint8_t  command_type  =  SceneMultiplayer : : NETWORK_COMMAND_REMOTE_CALL ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									uint8_t  node_id_compression  =  UINT8_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint8_t  name_id_compression  =  UINT8_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  byte_only_or_no_args  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MAKE_ROOM ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// The meta is composed along the way, so just set 0 for now.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									packet_cache . write [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ofs  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Encode Node ID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( has_all_peers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Compress the node ID only if all the target peers already know it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( psc_id  > =  0  & &  psc_id  < =  255 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// We can encode the id in 1 byte
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_id_compression  =  NETWORK_NODE_ID_COMPRESSION_8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											MAKE_ROOM ( ofs  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											packet_cache . write [ ofs ]  =  static_cast < uint8_t > ( psc_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ofs  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  ( psc_id  > =  0  & &  psc_id  < =  65535 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// We can encode the id in 2 bytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_id_compression  =  NETWORK_NODE_ID_COMPRESSION_16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											MAKE_ROOM ( ofs  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											encode_uint16 ( static_cast < uint16_t > ( psc_id ) ,  & ( packet_cache . write [ ofs ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ofs  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Too big, let's use 4 bytes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											node_id_compression  =  NETWORK_NODE_ID_COMPRESSION_32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											MAKE_ROOM ( ofs  +  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											encode_uint32 ( psc_id ,  & ( packet_cache . write [ ofs ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ofs  + =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// The targets don't know the node yet, so we need to use 32 bits int.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										node_id_compression  =  NETWORK_NODE_ID_COMPRESSION_32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										encode_uint32 ( psc_id ,  & ( packet_cache . write [ ofs ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ofs  + =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Encode method ID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_rpc_id  < =  UINT8_MAX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// The ID fits in 1 byte
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										name_id_compression  =  NETWORK_NAME_ID_COMPRESSION_8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										packet_cache . write [ ofs ]  =  static_cast < uint8_t > ( p_rpc_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ofs  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// The ID is larger, let's use 2 bytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										name_id_compression  =  NETWORK_NAME_ID_COMPRESSION_16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										encode_uint16 ( p_rpc_id ,  & ( packet_cache . write [ ofs ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ofs  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 14:13:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Error  err  =  MultiplayerAPI : : encode_and_compress_variants ( p_arg ,  p_argcount ,  nullptr ,  len ,  & byte_only_or_no_args ,  multiplayer - > is_object_decoding_allowed ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( err  ! =  OK ,  " Unable to encode RPC arguments. THIS IS LIKELY A BUG IN THE ENGINE! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( byte_only_or_no_args )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 14:13:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  1  +  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										packet_cache . write [ ofs ]  =  p_argcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ofs  + =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 14:13:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MultiplayerAPI : : encode_and_compress_variants ( p_arg ,  p_argcount ,  & packet_cache . write [ ofs ] ,  len ,  & byte_only_or_no_args ,  multiplayer - > is_object_decoding_allowed ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ofs  + =  len ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND ( command_type  >  7 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND ( node_id_compression  >  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND ( name_id_compression  >  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_ENABLED 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_profile_node_data ( " rpc_out " ,  p_node - > get_instance_id ( ) ,  ofs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-16 22:48:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// We can now set the meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									packet_cache . write [ 0 ]  =  command_type  +  ( node_id_compression  < <  NODE_ID_COMPRESSION_SHIFT )  +  ( name_id_compression  < <  NAME_ID_COMPRESSION_SHIFT )  +  ( byte_only_or_no_args  ?  BYTE_ONLY_OR_NO_ARGS_FLAG  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Take chance and set transfer mode, since all send methods will use it.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									peer - > set_transfer_channel ( p_config . channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									peer - > set_transfer_mode ( p_config . transfer_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( has_all_peers )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( const  int  P  :  targets )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											multiplayer - > send_command ( P ,  packet_cache . ptr ( ) ,  ofs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Unreachable because the node ID is never compressed if the peers doesn't know it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										CRASH_COND ( node_id_compression  ! =  NETWORK_NODE_ID_COMPRESSION_32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Not all verified path, so send one by one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Append path at the end, since we will need it for some packets.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 20:27:53 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										CharString  pname  =  String ( multiplayer - > get_root_path ( ) . rel_path_to ( p_node - > get_path ( ) ) ) . utf8 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										int  path_len  =  encode_cstring ( pname . get_data ( ) ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										MAKE_ROOM ( ofs  +  path_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										encode_cstring ( pname . get_data ( ) ,  & ( packet_cache . write [ ofs ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-01 13:14:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// Not all verified path, so check which needs the longer packet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( const  int  P  :  targets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-27 01:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											bool  confirmed  =  multiplayer_cache - > is_cache_confirmed ( p_node ,  P ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											if  ( confirmed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// This one confirmed path, so use id.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												encode_uint32 ( psc_id ,  & ( packet_cache . write [ 1 ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 20:50:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												multiplayer - > send_command ( P ,  packet_cache . ptr ( ) ,  ofs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// This one did not confirm path yet, so use entire path (sorry!).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												encode_uint32 ( 0x80000000  |  ofs ,  & ( packet_cache . write [ 1 ] ) ) ;  // Offset to path and flag.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 20:50:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												multiplayer - > send_command ( P ,  packet_cache . ptr ( ) ,  ofs  +  path_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Error  SceneRPCInterface : : rpcp ( Object  * p_obj ,  int  p_peer_id ,  const  StringName  & p_method ,  const  Variant  * * p_arg ,  int  p_argcount )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-07 23:35:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Ref < MultiplayerPeer >  peer  =  multiplayer - > get_multiplayer_peer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-25 14:15:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_V_MSG ( peer . is_null ( ) ,  ERR_UNCONFIGURED ,  " Trying to call an RPC while no multiplayer peer is active. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Node  * node  =  Object : : cast_to < Node > ( p_obj ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_V_MSG ( ! node  | |  ! node - > is_inside_tree ( ) ,  ERR_INVALID_PARAMETER ,  " The object must be a valid Node inside the SceneTree " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_V_MSG ( peer - > get_connection_status ( )  ! =  MultiplayerPeer : : CONNECTION_CONNECTED ,  ERR_CONNECTION_ERROR ,  " Trying to call an RPC via a multiplayer peer which is not connected. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  caller_id  =  multiplayer - > get_unique_id ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									bool  call_local_native  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  call_local_script  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  RPCConfigCache  & config_cache  =  _get_node_config ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint16_t  rpc_id  =  config_cache . ids . has ( p_method )  ?  config_cache . ids [ p_method ]  :  UINT16_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_V_MSG ( rpc_id  = =  UINT16_MAX ,  ERR_INVALID_PARAMETER , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 21:43:26 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											vformat ( " Unable to get the RPC configuration for the function  \" %s \"  at path:  \" %s \" . This happens when the method is missing or not marked for RPCs in the local script. " ,  p_method ,  node - > get_path ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  RPCConfig  & config  =  config_cache . configs [ rpc_id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_V_MSG ( p_peer_id  = =  caller_id  & &  ! config . call_local ,  ERR_INVALID_PARAMETER ,  " RPC ' "  +  p_method  +  " ' on yourself is not allowed by selected mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_peer_id  = =  0  | |  p_peer_id  = =  caller_id  | |  ( p_peer_id  <  0  & &  p_peer_id  ! =  - caller_id ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  ( rpc_id  &  ( 1  < <  15 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:10:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											call_local_native  =  config . call_local ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-06 17:10:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											call_local_script  =  config . call_local ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( p_peer_id  ! =  caller_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										_send_rpc ( node ,  p_peer_id ,  rpc_id ,  config ,  p_method ,  p_arg ,  p_argcount ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( call_local_native )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Callable : : CallError  ce ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										multiplayer - > set_remote_sender_override ( multiplayer - > get_unique_id ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-09 14:58:40 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										node - > callp ( p_method ,  p_arg ,  p_argcount ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										multiplayer - > set_remote_sender_override ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											String  error  =  Variant : : get_call_error_text ( node ,  p_method ,  p_arg ,  p_argcount ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											error  =  " rpc() aborted in local call:  -  "  +  error  +  " . " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_PRINT ( error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( call_local_script )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Callable : : CallError  ce ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ce . error  =  Callable : : CallError : : CALL_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										multiplayer - > set_remote_sender_override ( multiplayer - > get_unique_id ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-09 14:58:40 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										node - > get_script_instance ( ) - > callp ( p_method ,  p_arg ,  p_argcount ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										multiplayer - > set_remote_sender_override ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 16:24:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											String  error  =  Variant : : get_call_error_text ( node ,  p_method ,  p_arg ,  p_argcount ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											error  =  " rpc() aborted in script local call:  -  "  +  error  +  " . " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_PRINT ( error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 23:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 19:40:47 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}