Use MultiplayerAPI class for high level networking
Remove networking related logic from Node and SceneTree. SceneTree now simply relay all networking related stuff to MultiplayerAPI for compatibility
This commit is contained in:
@@ -477,7 +477,7 @@ bool Node::is_network_master() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
return get_tree()->get_network_unique_id() == data.network_master;
|
||||
return get_multiplayer_api()->get_network_unique_id() == data.network_master;
|
||||
}
|
||||
|
||||
/***** RPC CONFIG ********/
|
||||
@@ -667,200 +667,16 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Va
|
||||
}
|
||||
|
||||
void Node::rpcp(int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
get_multiplayer_api()->rpcp(this, p_peer_id, p_unreliable, p_method, p_arg, p_argcount);
|
||||
}
|
||||
|
||||
bool skip_rpc = false;
|
||||
bool call_local_native = false;
|
||||
bool call_local_script = false;
|
||||
|
||||
if (p_peer_id == 0 || p_peer_id == get_tree()->get_network_unique_id() || (p_peer_id < 0 && p_peer_id != -get_tree()->get_network_unique_id())) {
|
||||
//check that send mode can use local call
|
||||
|
||||
Map<StringName, RPCMode>::Element *E = data.rpc_methods.find(p_method);
|
||||
if (E) {
|
||||
|
||||
switch (E->get()) {
|
||||
|
||||
case RPC_MODE_DISABLED: {
|
||||
//do nothing
|
||||
} break;
|
||||
case RPC_MODE_REMOTE: {
|
||||
//do nothing also, no need to call local
|
||||
} break;
|
||||
case RPC_MODE_SYNC: {
|
||||
//call it, sync always results in call
|
||||
call_local_native = true;
|
||||
} break;
|
||||
case RPC_MODE_MASTER: {
|
||||
call_local_native = is_network_master();
|
||||
if (call_local_native) {
|
||||
skip_rpc = true; //no other master so..
|
||||
}
|
||||
} break;
|
||||
case RPC_MODE_SLAVE: {
|
||||
call_local_native = !is_network_master();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (call_local_native) {
|
||||
// done below
|
||||
} else if (get_script_instance()) {
|
||||
//attempt with script
|
||||
ScriptInstance::RPCMode rpc_mode = get_script_instance()->get_rpc_mode(p_method);
|
||||
|
||||
switch (rpc_mode) {
|
||||
|
||||
case ScriptInstance::RPC_MODE_DISABLED: {
|
||||
//do nothing
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_REMOTE: {
|
||||
//do nothing also, no need to call local
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_SYNC: {
|
||||
//call it, sync always results in call
|
||||
call_local_script = true;
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_MASTER: {
|
||||
call_local_script = is_network_master();
|
||||
if (call_local_script) {
|
||||
skip_rpc = true; //no other master so..
|
||||
}
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_SLAVE: {
|
||||
call_local_script = !is_network_master();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip_rpc) {
|
||||
get_tree()->_rpc(this, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
|
||||
}
|
||||
|
||||
if (call_local_native) {
|
||||
Variant::CallError ce;
|
||||
call(p_method, p_arg, p_argcount, ce);
|
||||
if (ce.error != Variant::CallError::CALL_OK) {
|
||||
String error = Variant::get_call_error_text(this, 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;
|
||||
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(this, p_method, p_arg, p_argcount, ce);
|
||||
error = "rpc() aborted in script local call: - " + error;
|
||||
ERR_PRINTS(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void Node::rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
get_multiplayer_api()->rsetp(this, p_peer_id, p_unreliable, p_property, p_value);
|
||||
}
|
||||
|
||||
/******** RSET *********/
|
||||
|
||||
void Node::rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
bool skip_rset = false;
|
||||
|
||||
if (p_peer_id == 0 || p_peer_id == get_tree()->get_network_unique_id() || (p_peer_id < 0 && p_peer_id != -get_tree()->get_network_unique_id())) {
|
||||
//check that send mode can use local call
|
||||
|
||||
bool set_local = false;
|
||||
|
||||
Map<StringName, RPCMode>::Element *E = data.rpc_properties.find(p_property);
|
||||
if (E) {
|
||||
|
||||
switch (E->get()) {
|
||||
|
||||
case RPC_MODE_DISABLED: {
|
||||
//do nothing
|
||||
} break;
|
||||
case RPC_MODE_REMOTE: {
|
||||
//do nothing also, no need to call local
|
||||
} break;
|
||||
case RPC_MODE_SYNC: {
|
||||
//call it, sync always results in call
|
||||
set_local = true;
|
||||
} break;
|
||||
case RPC_MODE_MASTER: {
|
||||
set_local = is_network_master();
|
||||
if (set_local) {
|
||||
skip_rset = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case RPC_MODE_SLAVE: {
|
||||
set_local = !is_network_master();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_local) {
|
||||
bool valid;
|
||||
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 (get_script_instance()) {
|
||||
//attempt with script
|
||||
ScriptInstance::RPCMode rpc_mode = get_script_instance()->get_rset_mode(p_property);
|
||||
|
||||
switch (rpc_mode) {
|
||||
|
||||
case ScriptInstance::RPC_MODE_DISABLED: {
|
||||
//do nothing
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_REMOTE: {
|
||||
//do nothing also, no need to call local
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_SYNC: {
|
||||
//call it, sync always results in call
|
||||
set_local = true;
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_MASTER: {
|
||||
set_local = is_network_master();
|
||||
if (set_local) {
|
||||
skip_rset = true;
|
||||
}
|
||||
} break;
|
||||
case ScriptInstance::RPC_MODE_SLAVE: {
|
||||
set_local = !is_network_master();
|
||||
} break;
|
||||
}
|
||||
|
||||
if (set_local) {
|
||||
|
||||
bool valid = 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;
|
||||
|
||||
get_tree()->_rpc(this, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
|
||||
}
|
||||
|
||||
void Node::rset(const StringName &p_property, const Variant &p_value) {
|
||||
|
||||
rsetp(0, false, p_property, p_value);
|
||||
@@ -882,6 +698,30 @@ void Node::rset_unreliable_id(int p_peer_id, const StringName &p_property, const
|
||||
}
|
||||
|
||||
//////////// end of rpc
|
||||
Ref<MultiplayerAPI> Node::get_multiplayer_api() const {
|
||||
if (multiplayer_api.is_valid())
|
||||
return multiplayer_api;
|
||||
if (!is_inside_tree())
|
||||
return Ref<MultiplayerAPI>();
|
||||
return get_tree()->get_multiplayer_api();
|
||||
}
|
||||
|
||||
Ref<MultiplayerAPI> Node::get_custom_multiplayer_api() const {
|
||||
return multiplayer_api;
|
||||
}
|
||||
|
||||
void Node::set_custom_multiplayer_api(Ref<MultiplayerAPI> p_multiplayer_api) {
|
||||
|
||||
multiplayer_api = p_multiplayer_api;
|
||||
}
|
||||
|
||||
const Map<StringName, Node::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) {
|
||||
return data.rpc_methods.find(p_method);
|
||||
}
|
||||
|
||||
const Map<StringName, Node::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) {
|
||||
return data.rpc_properties.find(p_property);
|
||||
}
|
||||
|
||||
bool Node::can_call_rpc(const StringName &p_method, int p_from) const {
|
||||
|
||||
@@ -2886,6 +2726,9 @@ void Node::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_network_master"), &Node::is_network_master);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_multiplayer_api"), &Node::get_multiplayer_api);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_multiplayer_api"), &Node::get_custom_multiplayer_api);
|
||||
ClassDB::bind_method(D_METHOD("set_custom_multiplayer_api", "api"), &Node::set_custom_multiplayer_api);
|
||||
ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config);
|
||||
ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config);
|
||||
|
||||
@@ -2967,6 +2810,8 @@ void Node::_bind_methods() {
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "multiplayer_api", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer_api");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "custom_multiplayer_api", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer_api", "get_custom_multiplayer_api");
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta")));
|
||||
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta")));
|
||||
|
||||
Reference in New Issue
Block a user