예제 #1
0
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {

	ERR_FAIL_COND(!p_node->is_inside_tree());
	ERR_FAIL_COND(!network_peer.is_valid());

	int node_id = network_peer->get_unique_id();
	bool is_master = p_node->is_network_master();
	bool skip_rset = false;

	if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
		//check that send mode can use local call

		bool set_local = false;

		const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
		if (E) {

			set_local = _should_call_local(E->get(), is_master, skip_rset);
		}

		if (set_local) {
			bool valid;
			p_node->set(p_property, p_value, &valid);

			if (!valid) {
				String error = "rset() aborted in local set, property not found:  - " + String(p_property);
				ERR_PRINTS(error);
				return;
			}
		} else if (p_node->get_script_instance()) {
			//attempt with script
			RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);

			set_local = _should_call_local(rpc_mode, is_master, skip_rset);

			if (set_local) {

				bool valid = p_node->get_script_instance()->set(p_property, p_value);

				if (!valid) {
					String error = "rset() aborted in local script set, property not found:  - " + String(p_property);
					ERR_PRINTS(error);
					return;
				}
			}
		}
	}

	if (skip_rset)
		return;

	const Variant *vptr = &p_value;

	_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
}
예제 #2
0
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {

	ERR_FAIL_COND(!p_node->is_inside_tree());
	ERR_FAIL_COND(!network_peer.is_valid());

	int node_id = network_peer->get_unique_id();
	bool skip_rpc = false;
	bool call_local_native = false;
	bool call_local_script = false;
	bool is_master = p_node->is_network_master();

	if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
		//check that send mode can use local call

		const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
		if (E) {
			call_local_native = _should_call_local(E->get(), is_master, skip_rpc);
		}

		if (call_local_native) {
			// done below
		} else if (p_node->get_script_instance()) {
			//attempt with script
			RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
			call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
		}
	}

	if (!skip_rpc) {
		_send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
	}

	if (call_local_native) {
		Variant::CallError ce;
		p_node->call(p_method, p_arg, p_argcount, ce);
		if (ce.error != Variant::CallError::CALL_OK) {
			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
			error = "rpc() aborted in local call:  - " + error;
			ERR_PRINTS(error);
			return;
		}
	}

	if (call_local_script) {
		Variant::CallError ce;
		ce.error = Variant::CallError::CALL_OK;
		p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
		if (ce.error != Variant::CallError::CALL_OK) {
			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
			error = "rpc() aborted in script local call:  - " + error;
			ERR_PRINTS(error);
			return;
		}
	}
}
예제 #3
0
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {

	ERR_EXPLAIN("Trying to RSET while no network peer is active.");
	ERR_FAIL_COND(!network_peer.is_valid());
	ERR_EXPLAIN("Trying to RSET on a node which is not inside SceneTree.");
	ERR_FAIL_COND(!p_node->is_inside_tree());
	ERR_EXPLAIN("Trying to send an RSET via a network peer which is not connected.");
	ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);

	int node_id = network_peer->get_unique_id();
	bool is_master = p_node->is_network_master();
	bool skip_rset = node_id == p_peer_id;
	bool set_local = false;

	if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
		// Check that send mode can use local call.
		const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
		if (E) {

			set_local = _should_call_local(E->get(), is_master, skip_rset);
		}

		if (set_local) {
			bool valid;
			int temp_id = rpc_sender_id;

			rpc_sender_id = get_network_unique_id();
			p_node->set(p_property, p_value, &valid);
			rpc_sender_id = temp_id;

			if (!valid) {
				String error = "rset() aborted in local set, property not found:  - " + String(p_property);
				ERR_PRINTS(error);
				return;
			}
		} else if (p_node->get_script_instance()) {
			// Attempt with script.
			RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);

			set_local = _should_call_local(rpc_mode, is_master, skip_rset);

			if (set_local) {
				int temp_id = rpc_sender_id;

				rpc_sender_id = get_network_unique_id();
				bool valid = p_node->get_script_instance()->set(p_property, p_value);
				rpc_sender_id = temp_id;

				if (!valid) {
					String error = "rset() aborted in local script set, property not found:  - " + String(p_property);
					ERR_PRINTS(error);
					return;
				}
			}
		}
	}

	if (skip_rset) {
		ERR_EXPLAIN("RSET for '" + p_property + "' on yourself is not allowed by selected mode");
		ERR_FAIL_COND(!set_local);
		return;
	}

	const Variant *vptr = &p_value;

	_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
}
예제 #4
0
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {

	ERR_EXPLAIN("Trying to call an RPC while no network peer is active.");
	ERR_FAIL_COND(!network_peer.is_valid());
	ERR_EXPLAIN("Trying to call an RPC on a node which is not inside SceneTree.");
	ERR_FAIL_COND(!p_node->is_inside_tree());
	ERR_EXPLAIN("Trying to call an RPC via a network peer which is not connected.");
	ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);

	int node_id = network_peer->get_unique_id();
	bool skip_rpc = node_id == p_peer_id;
	bool call_local_native = false;
	bool call_local_script = false;
	bool is_master = p_node->is_network_master();

	if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
		// Check that send mode can use local call.

		const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
		if (E) {
			call_local_native = _should_call_local(E->get(), is_master, skip_rpc);
		}

		if (call_local_native) {
			// Done below.
		} else if (p_node->get_script_instance()) {
			// Attempt with script.
			RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
			call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
		}
	}

	if (!skip_rpc) {
		_send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
	}

	if (call_local_native) {
		int temp_id = rpc_sender_id;
		rpc_sender_id = get_network_unique_id();
		Variant::CallError ce;
		p_node->call(p_method, p_arg, p_argcount, ce);
		rpc_sender_id = temp_id;
		if (ce.error != Variant::CallError::CALL_OK) {
			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
			error = "rpc() aborted in local call:  - " + error;
			ERR_PRINTS(error);
			return;
		}
	}

	if (call_local_script) {
		int temp_id = rpc_sender_id;
		rpc_sender_id = get_network_unique_id();
		Variant::CallError ce;
		ce.error = Variant::CallError::CALL_OK;
		p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
		rpc_sender_id = temp_id;
		if (ce.error != Variant::CallError::CALL_OK) {
			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
			error = "rpc() aborted in script local call:  - " + error;
			ERR_PRINTS(error);
			return;
		}
	}

	ERR_EXPLAIN("RPC '" + p_method + "' on yourself is not allowed by selected mode");
	ERR_FAIL_COND(skip_rpc && !(call_local_native || call_local_script));
}