Merge pull request #49882 from Faless/mp/4.x_rpc_gd

[Net] New `@rpc` annotation, "sync" is no longer part of mode.
This commit is contained in:
Fabio Alessandrelli 2021-07-20 13:55:54 +02:00 committed by GitHub
commit de4ad63e6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 72 additions and 127 deletions

View file

@ -94,52 +94,17 @@ const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_i
return MultiplayerAPI::RPCConfig(); return MultiplayerAPI::RPCConfig();
} }
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
switch (mode) {
case MultiplayerAPI::RPC_MODE_DISABLED: {
// Do nothing.
} break;
case MultiplayerAPI::RPC_MODE_REMOTE: {
// Do nothing. Remote cannot produce a local call.
} break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call.
}
[[fallthrough]];
}
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
// Call it, sync always results in a local call.
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call.
}
return is_master;
} break;
case MultiplayerAPI::RPC_MODE_PUPPET: {
return !is_master;
} break;
}
return false;
}
_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) { _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) {
switch (mode) { switch (mode) {
case MultiplayerAPI::RPC_MODE_DISABLED: { case MultiplayerAPI::RPC_MODE_DISABLED: {
return false; return false;
} break; } break;
case MultiplayerAPI::RPC_MODE_REMOTE: case MultiplayerAPI::RPC_MODE_REMOTE: {
case MultiplayerAPI::RPC_MODE_REMOTESYNC: {
return true; return true;
} break; } break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_MASTER: { case MultiplayerAPI::RPC_MODE_MASTER: {
return p_node->is_network_master(); return p_node->is_network_master();
} break; } break;
case MultiplayerAPI::RPC_MODE_PUPPETSYNC:
case MultiplayerAPI::RPC_MODE_PUPPET: { case MultiplayerAPI::RPC_MODE_PUPPET: {
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master(); return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
} break; } break;
@ -977,23 +942,21 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected."); ERR_FAIL_COND_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
int node_id = network_peer->get_unique_id(); int node_id = network_peer->get_unique_id();
bool skip_rpc = node_id == p_peer_id;
bool call_local_native = false; bool call_local_native = false;
bool call_local_script = false; bool call_local_script = false;
bool is_master = p_node->is_network_master();
uint16_t rpc_id = UINT16_MAX; uint16_t rpc_id = UINT16_MAX;
const RPCConfig config = _get_rpc_config(p_node, p_method, rpc_id); const RPCConfig config = _get_rpc_config(p_node, p_method, rpc_id);
ERR_FAIL_COND_MSG(config.name == StringName(), ERR_FAIL_COND_MSG(config.name == StringName(),
vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is not marked for RPCs.", p_method, p_node->get_path())); vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is not marked for RPCs.", p_method, p_node->get_path()));
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
if (rpc_id & (1 << 15)) { if (rpc_id & (1 << 15)) {
call_local_native = _should_call_local(config.rpc_mode, is_master, skip_rpc); call_local_native = config.sync;
} else { } else {
call_local_script = _should_call_local(config.rpc_mode, is_master, skip_rpc); call_local_script = config.sync;
} }
} }
if (!skip_rpc) { if (p_peer_id != node_id) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
_profile_node_data("out_rpc", p_node->get_instance_id()); _profile_node_data("out_rpc", p_node->get_instance_id());
#endif #endif
@ -1030,7 +993,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
} }
} }
ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode."); ERR_FAIL_COND_MSG(p_peer_id == node_id && !config.sync, "RPC '" + p_method + "' on yourself is not allowed by selected mode.");
} }
Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode) { Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode) {
@ -1136,9 +1099,6 @@ void MultiplayerAPI::_bind_methods() {
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE); BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER); BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
BIND_ENUM_CONSTANT(RPC_MODE_PUPPET); BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
} }
MultiplayerAPI::MultiplayerAPI() { MultiplayerAPI::MultiplayerAPI() {

View file

@ -43,14 +43,12 @@ public:
RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets
RPC_MODE_REMOTESYNC, // Using rpc() on it will call method in all remote peers and locally
RPC_MODE_MASTERSYNC, // Using rpc() on it will call method in the master peer and locally
RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method in all puppets peers and locally
}; };
struct RPCConfig { struct RPCConfig {
StringName name; StringName name;
RPCMode rpc_mode = RPC_MODE_DISABLED; RPCMode rpc_mode = RPC_MODE_DISABLED;
bool sync = false;
MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
int channel = 0; int channel = 0;

View file

@ -146,14 +146,5 @@
<constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode"> <constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master]. Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master].
</constant> </constant>
<constant name="RPC_MODE_REMOTESYNC" value="4" enum="RPCMode">
Behave like [constant RPC_MODE_REMOTE] but also make the call or property change locally. Analogous to the [code]remotesync[/code] keyword.
</constant>
<constant name="RPC_MODE_MASTERSYNC" value="5" enum="RPCMode">
Behave like [constant RPC_MODE_MASTER] but also make the call or property change locally. Analogous to the [code]mastersync[/code] keyword.
</constant>
<constant name="RPC_MODE_PUPPETSYNC" value="6" enum="RPCMode">
Behave like [constant RPC_MODE_PUPPET] but also make the call or property change locally. Analogous to the [code]puppetsync[/code] keyword.
</constant>
</constants> </constants>
</class> </class>

View file

@ -1165,15 +1165,11 @@ void GDScript::_init_rpc_methods_properties() {
while (cscript) { while (cscript) {
// RPC Methods // RPC Methods
for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) {
if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { MultiplayerAPI::RPCConfig config = E->get()->get_rpc_config();
MultiplayerAPI::RPCConfig nd; if (config.rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
nd.name = E->key(); config.name = E->get()->get_name();
nd.rpc_mode = E->get()->get_rpc_mode(); if (rpc_functions.find(config) == -1) {
// TODO rpc_functions.push_back(config);
nd.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
nd.channel = 0;
if (-1 == rpc_functions.find(nd)) {
rpc_functions.push_back(nd);
} }
} }
} }

View file

@ -64,7 +64,6 @@ class GDScript : public Script {
int index = 0; int index = 0;
StringName setter; StringName setter;
StringName getter; StringName getter;
MultiplayerAPI::RPCMode rpc_mode;
GDScriptDataType data_type; GDScriptDataType data_type;
}; };

View file

@ -155,7 +155,7 @@ void GDScriptByteCodeGenerator::end_parameters() {
function->default_arguments.reverse(); function->default_arguments.reverse();
} }
void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) { void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) {
function = memnew(GDScriptFunction); function = memnew(GDScriptFunction);
debug_stack = EngineDebugger::is_active(); debug_stack = EngineDebugger::is_active();
@ -170,7 +170,7 @@ void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName
function->_static = p_static; function->_static = p_static;
function->return_type = p_return_type; function->return_type = p_return_type;
function->rpc_mode = p_rpc_mode; function->rpc_config = p_rpc_config;
function->_argument_count = 0; function->_argument_count = 0;
} }

View file

@ -419,7 +419,7 @@ public:
virtual void start_block() override; virtual void start_block() override;
virtual void end_block() override; virtual void end_block() override;
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) override; virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) override;
virtual GDScriptFunction *write_end() override; virtual GDScriptFunction *write_end() override;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED

View file

@ -80,7 +80,7 @@ public:
virtual void start_block() = 0; virtual void start_block() = 0;
virtual void end_block() = 0; virtual void end_block() = 0;
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) = 0; virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) = 0;
virtual GDScriptFunction *write_end() = 0; virtual GDScriptFunction *write_end() = 0;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED

View file

@ -1859,7 +1859,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
StringName func_name; StringName func_name;
bool is_static = false; bool is_static = false;
MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; MultiplayerAPI::RPCConfig rpc_config;
GDScriptDataType return_type; GDScriptDataType return_type;
return_type.has_type = true; return_type.has_type = true;
return_type.kind = GDScriptDataType::BUILTIN; return_type.kind = GDScriptDataType::BUILTIN;
@ -1872,7 +1872,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
func_name = "<anonymous lambda>"; func_name = "<anonymous lambda>";
} }
is_static = p_func->is_static; is_static = p_func->is_static;
rpc_mode = p_func->rpc_mode; rpc_config = p_func->rpc_config;
return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script); return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script);
} else { } else {
if (p_for_ready) { if (p_for_ready) {
@ -1883,7 +1883,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
} }
codegen.function_name = func_name; codegen.function_name = func_name;
codegen.generator->write_start(p_script, func_name, is_static, rpc_mode, return_type); codegen.generator->write_start(p_script, func_name, is_static, rpc_config, return_type);
int optional_parameters = 0; int optional_parameters = 0;
@ -2088,7 +2088,7 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
return_type = _gdtype_from_datatype(p_variable->get_datatype(), p_script); return_type = _gdtype_from_datatype(p_variable->get_datatype(), p_script);
} }
codegen.generator->write_start(p_script, func_name, false, p_variable->rpc_mode, return_type); codegen.generator->write_start(p_script, func_name, false, MultiplayerAPI::RPCConfig(), return_type);
if (p_is_setter) { if (p_is_setter) {
uint32_t par_addr = codegen.generator->add_parameter(p_variable->setter_parameter->name, false, _gdtype_from_datatype(p_variable->get_datatype())); uint32_t par_addr = codegen.generator->add_parameter(p_variable->setter_parameter->name, false, _gdtype_from_datatype(p_variable->get_datatype()));
@ -2268,7 +2268,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
} }
break; break;
} }
minfo.rpc_mode = variable->rpc_mode;
minfo.data_type = _gdtype_from_datatype(variable->get_datatype(), p_script); minfo.data_type = _gdtype_from_datatype(variable->get_datatype(), p_script);
PropertyInfo prop_info = minfo.data_type; PropertyInfo prop_info = minfo.data_type;

View file

@ -472,7 +472,7 @@ private:
int _initial_line = 0; int _initial_line = 0;
bool _static = false; bool _static = false;
MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; MultiplayerAPI::RPCConfig rpc_config;
GDScript *_script = nullptr; GDScript *_script = nullptr;
@ -592,7 +592,7 @@ public:
void disassemble(const Vector<String> &p_code_lines) const; void disassemble(const Vector<String> &p_code_lines) const;
#endif #endif
_FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; } _FORCE_INLINE_ MultiplayerAPI::RPCConfig get_rpc_config() const { return rpc_config; }
GDScriptFunction(); GDScriptFunction();
~GDScriptFunction(); ~GDScriptFunction();
}; };

View file

@ -168,12 +168,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
// Networking. // Networking.
register_annotation(MethodInfo("@remote"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTE>); register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>, 4, true);
register_annotation(MethodInfo("@master"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>);
register_annotation(MethodInfo("@puppet"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPET>);
register_annotation(MethodInfo("@remotesync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTESYNC>);
register_annotation(MethodInfo("@mastersync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTERSYNC>);
register_annotation(MethodInfo("@puppetsync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPETSYNC>);
// TODO: Warning annotations. // TODO: Warning annotations.
} }
@ -3430,27 +3425,60 @@ template <MultiplayerAPI::RPCMode t_mode>
bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) { bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) {
ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name)); ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name));
switch (p_node->type) { MultiplayerAPI::RPCConfig rpc_config;
case Node::VARIABLE: { rpc_config.rpc_mode = t_mode;
VariableNode *variable = static_cast<VariableNode *>(p_node); for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
if (variable->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { if (i == 0) {
push_error(R"(RPC annotations can only be used once per variable.)", p_annotation); String mode = p_annotation->resolved_arguments[i].operator String();
if (mode == "any") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
} else if (mode == "master") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
} else if (mode == "puppet") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
} else {
push_error(R"(Invalid RPC mode. Must be one of: 'any', 'master', or 'puppet')", p_annotation);
return false;
} }
variable->rpc_mode = t_mode; } else if (i == 1) {
break; String sync = p_annotation->resolved_arguments[i].operator String();
if (sync == "sync") {
rpc_config.sync = true;
} else if (sync == "nosync") {
rpc_config.sync = false;
} else {
push_error(R"(Invalid RPC sync mode. Must be one of: 'sync' or 'nosync')", p_annotation);
return false;
}
} else if (i == 2) {
String mode = p_annotation->resolved_arguments[i].operator String();
if (mode == "reliable") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
} else if (mode == "unreliable") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE;
} else if (mode == "ordered") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED;
} else {
push_error(R"(Invalid RPC transfer mode. Must be one of: 'reliable', 'unreliable', 'ordered')", p_annotation);
return false;
}
} else if (i == 3) {
rpc_config.channel = p_annotation->resolved_arguments[i].operator int();
} }
}
switch (p_node->type) {
case Node::FUNCTION: { case Node::FUNCTION: {
FunctionNode *function = static_cast<FunctionNode *>(p_node); FunctionNode *function = static_cast<FunctionNode *>(p_node);
if (function->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { if (function->rpc_config.rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
push_error(R"(RPC annotations can only be used once per function.)", p_annotation); push_error(R"(RPC annotations can only be used once per function.)", p_annotation);
return false;
} }
function->rpc_mode = t_mode; function->rpc_config = rpc_config;
break; break;
} }
default: default:
return false; // Unreachable. return false; // Unreachable.
} }
return true; return true;
} }

View file

@ -729,7 +729,7 @@ public:
SuiteNode *body = nullptr; SuiteNode *body = nullptr;
bool is_static = false; bool is_static = false;
bool is_coroutine = false; bool is_coroutine = false;
MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; MultiplayerAPI::RPCConfig rpc_config;
MethodInfo info; MethodInfo info;
LambdaNode *source_lambda = nullptr; LambdaNode *source_lambda = nullptr;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -1117,7 +1117,6 @@ public:
bool exported = false; bool exported = false;
bool onready = false; bool onready = false;
PropertyInfo export_info; PropertyInfo export_info;
MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
int assignments = 0; int assignments = 0;
int usages = 0; int usages = 0;
bool use_conversion_assign = false; bool use_conversion_assign = false;

View file

@ -695,7 +695,9 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio
ERR_FAIL_NULL_V(p_func, func); ERR_FAIL_NULL_V(p_func, func);
func["name"] = p_func->identifier->name; func["name"] = p_func->identifier->name;
func["return_type"] = p_func->get_datatype().to_string(); func["return_type"] = p_func->get_datatype().to_string();
func["rpc_mode"] = p_func->rpc_mode; func["rpc_mode"] = p_func->rpc_config.rpc_mode;
func["rpc_transfer_mode"] = p_func->rpc_config.transfer_mode;
func["rpc_transfer_channel"] = p_func->rpc_config.channel;
Array parameters; Array parameters;
for (int i = 0; i < p_func->parameters.size(); i++) { for (int i = 0; i < p_func->parameters.size(); i++) {
Dictionary arg; Dictionary arg;

View file

@ -3472,15 +3472,6 @@ MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_m
if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) { if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPET; return MultiplayerAPI::RPC_MODE_PUPPET;
} }
if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
}
if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
}
if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
}
return MultiplayerAPI::RPC_MODE_DISABLED; return MultiplayerAPI::RPC_MODE_DISABLED;
} }

View file

@ -2,21 +2,12 @@ using System;
namespace Godot namespace Godot
{ {
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Method)]
public class RemoteAttribute : Attribute {} public class RemoteAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Method)]
public class MasterAttribute : Attribute {} public class MasterAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Method)]
public class PuppetAttribute : Attribute {} public class PuppetAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class RemoteSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class MasterSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class PuppetSyncAttribute : Attribute {}
} }

View file

@ -143,9 +143,6 @@ void CachedData::clear_godot_api_cache() {
class_RemoteAttribute = nullptr; class_RemoteAttribute = nullptr;
class_MasterAttribute = nullptr; class_MasterAttribute = nullptr;
class_PuppetAttribute = nullptr; class_PuppetAttribute = nullptr;
class_RemoteSyncAttribute = nullptr;
class_MasterSyncAttribute = nullptr;
class_PuppetSyncAttribute = nullptr;
class_GodotMethodAttribute = nullptr; class_GodotMethodAttribute = nullptr;
field_GodotMethodAttribute_methodName = nullptr; field_GodotMethodAttribute_methodName = nullptr;
class_ScriptPathAttribute = nullptr; class_ScriptPathAttribute = nullptr;
@ -272,9 +269,6 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute)); CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute)); CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute));
CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute)); CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute));
CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute));
CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute));
CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute)); CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute)); CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));

View file

@ -114,9 +114,6 @@ struct CachedData {
GDMonoClass *class_RemoteAttribute; GDMonoClass *class_RemoteAttribute;
GDMonoClass *class_MasterAttribute; GDMonoClass *class_MasterAttribute;
GDMonoClass *class_PuppetAttribute; GDMonoClass *class_PuppetAttribute;
GDMonoClass *class_RemoteSyncAttribute;
GDMonoClass *class_MasterSyncAttribute;
GDMonoClass *class_PuppetSyncAttribute;
GDMonoClass *class_GodotMethodAttribute; GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName; GDMonoField *field_GodotMethodAttribute_methodName;
GDMonoClass *class_ScriptPathAttribute; GDMonoClass *class_ScriptPathAttribute;