1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-19 14:31:59 +00:00

Revert "RPCMode refactor, more sync modes"

This commit is contained in:
Max Hilbrunner
2018-05-29 11:47:52 +02:00
committed by GitHub
parent d0b62ce155
commit 4c69a495c9
30 changed files with 333 additions and 319 deletions

View File

@@ -32,61 +32,6 @@
#include "core/io/marshalls.h" #include "core/io/marshalls.h"
#include "scene/main/node.h" #include "scene/main/node.h"
_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 also, no need to call local
} break;
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_SLAVESYNC:
case MultiplayerAPI::RPC_MODE_SYNC: {
//call it, sync always results in call
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
if (is_master)
r_skip_rpc = true; //no other master so..
return is_master;
} break;
case MultiplayerAPI::RPC_MODE_SLAVE: {
return !is_master;
} break;
}
return false;
}
_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) {
switch (mode) {
case MultiplayerAPI::RPC_MODE_DISABLED: {
return false;
} break;
case MultiplayerAPI::RPC_MODE_REMOTE: {
return true;
} break;
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
case MultiplayerAPI::RPC_MODE_SYNC: {
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_MASTER: {
return p_node->is_network_master();
} break;
case MultiplayerAPI::RPC_MODE_SLAVESYNC:
case MultiplayerAPI::RPC_MODE_SLAVE: {
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
} break;
}
return false;
}
void MultiplayerAPI::poll() { void MultiplayerAPI::poll() {
if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED)
@@ -257,19 +202,11 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
} }
void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) { void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
if (!p_node->can_call_rpc(p_name, p_from))
return;
ERR_FAIL_COND(p_offset >= p_packet_len); ERR_FAIL_COND(p_offset >= p_packet_len);
// Check that remote can call the RPC on this node
RPCMode rpc_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_name);
if (E) {
rpc_mode = E->get();
} else if (p_node->get_script_instance()) {
rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
}
ERR_FAIL_COND(!_can_call_mode(p_node, rpc_mode, p_from));
int argc = p_packet[p_offset]; int argc = p_packet[p_offset];
Vector<Variant> args; Vector<Variant> args;
Vector<const Variant *> argp; Vector<const Variant *> argp;
@@ -301,17 +238,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) { void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
ERR_FAIL_COND(p_offset >= p_packet_len); if (!p_node->can_call_rset(p_name, p_from))
return;
// Check that remote can call the RSET on this node ERR_FAIL_COND(p_offset >= p_packet_len);
RPCMode rset_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_name);
if (E) {
rset_mode = E->get();
} else if (p_node->get_script_instance()) {
rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
}
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
Variant value; Variant value;
decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset); decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset);
@@ -592,6 +522,57 @@ void MultiplayerAPI::_server_disconnected() {
emit_signal("server_disconnected"); emit_signal("server_disconnected");
} }
bool _should_call_native(Node::RPCMode mode, bool is_master, bool &r_skip_rpc) {
switch (mode) {
case Node::RPC_MODE_DISABLED: {
//do nothing
} break;
case Node::RPC_MODE_REMOTE: {
//do nothing also, no need to call local
} break;
case Node::RPC_MODE_SYNC: {
//call it, sync always results in call
return true;
} break;
case Node::RPC_MODE_MASTER: {
if (is_master)
r_skip_rpc = true; //no other master so..
return is_master;
} break;
case Node::RPC_MODE_SLAVE: {
return !is_master;
} break;
}
return false;
}
bool _should_call_script(ScriptInstance::RPCMode mode, bool is_master, bool &r_skip_rpc) {
switch (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
return true;
} break;
case ScriptInstance::RPC_MODE_MASTER: {
if (is_master)
r_skip_rpc = true; //no other master so..
return is_master;
} break;
case ScriptInstance::RPC_MODE_SLAVE: {
return !is_master;
} break;
}
return false;
}
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) { 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(!p_node->is_inside_tree());
@@ -606,17 +587,17 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
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)) {
//check that send mode can use local call //check that send mode can use local call
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method); const Map<StringName, Node::RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
if (E) { if (E) {
call_local_native = _should_call_local(E->get(), is_master, skip_rpc); call_local_native = _should_call_native(E->get(), is_master, skip_rpc);
} }
if (call_local_native) { if (call_local_native) {
// done below // done below
} else if (p_node->get_script_instance()) { } else if (p_node->get_script_instance()) {
//attempt with script //attempt with script
RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method); ScriptInstance::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); call_local_script = _should_call_script(rpc_mode, is_master, skip_rpc);
} }
} }
@@ -662,10 +643,10 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
bool set_local = false; bool set_local = false;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property); const Map<StringName, Node::RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
if (E) { if (E) {
set_local = _should_call_local(E->get(), is_master, skip_rset); set_local = _should_call_native(E->get(), is_master, skip_rset);
} }
if (set_local) { if (set_local) {
@@ -679,9 +660,9 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
} }
} else if (p_node->get_script_instance()) { } else if (p_node->get_script_instance()) {
//attempt with script //attempt with script
RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property); ScriptInstance::RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
set_local = _should_call_local(rpc_mode, is_master, skip_rset); set_local = _should_call_script(rpc_mode, is_master, skip_rset);
if (set_local) { if (set_local) {
@@ -797,15 +778,6 @@ void MultiplayerAPI::_bind_methods() {
ADD_SIGNAL(MethodInfo("connected_to_server")); ADD_SIGNAL(MethodInfo("connected_to_server"));
ADD_SIGNAL(MethodInfo("connection_failed")); ADD_SIGNAL(MethodInfo("connection_failed"));
ADD_SIGNAL(MethodInfo("server_disconnected")); ADD_SIGNAL(MethodInfo("server_disconnected"));
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
BIND_ENUM_CONSTANT(RPC_MODE_SYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
BIND_ENUM_CONSTANT(RPC_MODE_SLAVE);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
BIND_ENUM_CONSTANT(RPC_MODE_SLAVESYNC);
} }
MultiplayerAPI::MultiplayerAPI() { MultiplayerAPI::MultiplayerAPI() {

View File

@@ -87,18 +87,6 @@ public:
NETWORK_COMMAND_RAW, NETWORK_COMMAND_RAW,
}; };
enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers
RPC_MODE_SYNC, // Using rpc() on it will call method / set property in all remote peers and locally
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
RPC_MODE_SLAVE, // Using rpc() on it will call method for all slaves
RPC_MODE_REMOTESYNC, // Same as RPC_MODE_SYNC, compatibility
RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally
RPC_MODE_SLAVESYNC, // Using rpc() on it will call method / set property in all slave peers and locally
};
void poll(); void poll();
void clear(); void clear();
void set_root_node(Node *p_node); void set_root_node(Node *p_node);
@@ -129,6 +117,4 @@ public:
~MultiplayerAPI(); ~MultiplayerAPI();
}; };
VARIANT_ENUM_CAST(MultiplayerAPI::RPCMode);
#endif // MULTIPLAYER_PROTOCOL_H #endif // MULTIPLAYER_PROTOCOL_H

View File

@@ -31,7 +31,6 @@
#ifndef SCRIPT_LANGUAGE_H #ifndef SCRIPT_LANGUAGE_H
#define SCRIPT_LANGUAGE_H #define SCRIPT_LANGUAGE_H
#include "io/multiplayer_api.h"
#include "map.h" #include "map.h"
#include "pair.h" #include "pair.h"
#include "resource.h" #include "resource.h"
@@ -158,8 +157,16 @@ public:
virtual bool is_placeholder() const { return false; } virtual bool is_placeholder() const { return false; }
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0; enum RPCMode {
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0; RPC_MODE_DISABLED,
RPC_MODE_REMOTE,
RPC_MODE_SYNC,
RPC_MODE_MASTER,
RPC_MODE_SLAVE,
};
virtual RPCMode get_rpc_mode(const StringName &p_method) const = 0;
virtual RPCMode get_rset_mode(const StringName &p_variable) const = 0;
virtual ScriptLanguage *get_language() = 0; virtual ScriptLanguage *get_language() = 0;
virtual ~ScriptInstance(); virtual ~ScriptInstance();
@@ -325,8 +332,8 @@ public:
virtual bool is_placeholder() const { return true; } virtual bool is_placeholder() const { return true; }
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const { return MultiplayerAPI::RPC_MODE_DISABLED; } virtual RPCMode get_rpc_mode(const StringName &p_method) const { return RPC_MODE_DISABLED; }
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const { return MultiplayerAPI::RPC_MODE_DISABLED; } virtual RPCMode get_rset_mode(const StringName &p_variable) const { return RPC_MODE_DISABLED; }
PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner); PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner);
~PlaceHolderScriptInstance(); ~PlaceHolderScriptInstance();

View File

@@ -136,29 +136,5 @@
</signal> </signal>
</signals> </signals>
<constants> <constants>
<constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode">
Used with [method Node.rpc_config] or [method Node.rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods.
</constant>
<constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode">
Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or slaves.
</constant>
<constant name="RPC_MODE_SYNC" value="2" enum="RPCMode">
Behave like [constant RPC_MODE_REMOTE] but also make the call or property change locally. Analogous to the [code]sync[/code] keyword.
</constant>
<constant name="RPC_MODE_MASTER" value="3" enum="RPCMode">
Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network slaves, see [method Node.set_network_master].
</constant>
<constant name="RPC_MODE_SLAVE" value="4" enum="RPCMode">
Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on slaves for this node. Analogous to the [code]slave[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master].
</constant>
<constant name="RPC_MODE_REMOTESYNC" value="5" enum="RPCMode">
Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Same as [constant RPC_MODE_SYNC] which is only kept for compatibility. Analogous to the [code]remotesync[/code] keyword.
</constant>
<constant name="RPC_MODE_MASTERSYNC" value="6" enum="RPCMode">
Behave like [code]RPC_MODE_MASTER[/code] but also make the call or property change locally. Analogous to the [code]mastersync[/code] keyword.
</constant>
<constant name="RPC_MODE_SLAVESYNC" value="7" enum="RPCMode">
Behave like [code]RPC_MODE_SLAVE[/code] but also make the call or property change locally. Analogous to the [code]slavesync[/code] keyword.
</constant>
</constants> </constants>
</class> </class>

View File

@@ -572,10 +572,10 @@
</return> </return>
<argument index="0" name="method" type="String"> <argument index="0" name="method" type="String">
</argument> </argument>
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> <argument index="1" name="mode" type="int" enum="Node.RPCMode">
</argument> </argument>
<description> <description>
Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties. Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties.
</description> </description>
</method> </method>
<method name="rpc_id" qualifiers="vararg"> <method name="rpc_id" qualifiers="vararg">
@@ -625,10 +625,10 @@
</return> </return>
<argument index="0" name="property" type="String"> <argument index="0" name="property" type="String">
</argument> </argument>
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> <argument index="1" name="mode" type="int" enum="Node.RPCMode">
</argument> </argument>
<description> <description>
Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods. Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods.
</description> </description>
</method> </method>
<method name="rset_id"> <method name="rset_id">
@@ -860,6 +860,21 @@
<constant name="NOTIFICATION_INTERNAL_PHYSICS_PROCESS" value="26"> <constant name="NOTIFICATION_INTERNAL_PHYSICS_PROCESS" value="26">
Notification received every frame when the internal physics process flag is set (see [method set_physics_process_internal]). Notification received every frame when the internal physics process flag is set (see [method set_physics_process_internal]).
</constant> </constant>
<constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode">
Used with [method rpc_config] or [method rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods.
</constant>
<constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode">
Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword.
</constant>
<constant name="RPC_MODE_SYNC" value="2" enum="RPCMode">
Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed both on the remote end and locally. Analogous to the [code]sync[/code] keyword.
</constant>
<constant name="RPC_MODE_MASTER" value="3" enum="RPCMode">
Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. See [method set_network_master].
</constant>
<constant name="RPC_MODE_SLAVE" value="4" enum="RPCMode">
Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on slaves for this node. Analogous to the [code]slave[/code] keyword. See [method set_network_master].
</constant>
<constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode"> <constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode">
Inherits pause mode from the node's parent. For the root node, it is equivalent to PAUSE_MODE_STOP. Default. Inherits pause mode from the node's parent. For the root node, it is equivalent to PAUSE_MODE_STOP. Default.
</constant> </constant>

View File

@@ -43,9 +43,6 @@ typedef enum {
GODOT_METHOD_RPC_MODE_SYNC, GODOT_METHOD_RPC_MODE_SYNC,
GODOT_METHOD_RPC_MODE_MASTER, GODOT_METHOD_RPC_MODE_MASTER,
GODOT_METHOD_RPC_MODE_SLAVE, GODOT_METHOD_RPC_MODE_SLAVE,
GODOT_METHOD_RPC_MODE_REMOTESYNC,
GODOT_METHOD_RPC_MODE_MASTERSYNC,
GODOT_METHOD_RPC_MODE_SLAVESYNC,
} godot_method_rpc_mode; } godot_method_rpc_mode;
typedef enum { typedef enum {

View File

@@ -747,7 +747,7 @@ Ref<Script> NativeScriptInstance::get_script() const {
return script; return script;
} }
MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
NativeScriptDesc *script_data = GET_SCRIPT_DESC(); NativeScriptDesc *script_data = GET_SCRIPT_DESC();
@@ -757,33 +757,27 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_m
if (E) { if (E) {
switch (E->get().rpc_mode) { switch (E->get().rpc_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED: case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE: case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE; return RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_SYNC: case GODOT_METHOD_RPC_MODE_SYNC:
return MultiplayerAPI::RPC_MODE_SYNC; return RPC_MODE_SYNC;
case GODOT_METHOD_RPC_MODE_MASTER: case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER; return RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_SLAVE: case GODOT_METHOD_RPC_MODE_SLAVE:
return MultiplayerAPI::RPC_MODE_SLAVE; return RPC_MODE_SLAVE;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
case GODOT_METHOD_RPC_MODE_SLAVESYNC:
return MultiplayerAPI::RPC_MODE_SLAVESYNC;
default: default:
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
} }
script_data = script_data->base_data; script_data = script_data->base_data;
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
NativeScriptDesc *script_data = GET_SCRIPT_DESC(); NativeScriptDesc *script_data = GET_SCRIPT_DESC();
@@ -793,24 +787,24 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_
if (E) { if (E) {
switch (E.get().rset_mode) { switch (E.get().rset_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED: case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE: case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE; return RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_SYNC: case GODOT_METHOD_RPC_MODE_SYNC:
return MultiplayerAPI::RPC_MODE_SYNC; return RPC_MODE_SYNC;
case GODOT_METHOD_RPC_MODE_MASTER: case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER; return RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_SLAVE: case GODOT_METHOD_RPC_MODE_SLAVE:
return MultiplayerAPI::RPC_MODE_SLAVE; return RPC_MODE_SLAVE;
default: default:
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
} }
script_data = script_data->base_data; script_data = script_data->base_data;
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
ScriptLanguage *NativeScriptInstance::get_language() { ScriptLanguage *NativeScriptInstance::get_language() {

View File

@@ -196,8 +196,8 @@ public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
virtual void notification(int p_notification); virtual void notification(int p_notification);
virtual Ref<Script> get_script() const; virtual Ref<Script> get_script() const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rpc_mode(const StringName &p_method) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const;
virtual ScriptLanguage *get_language(); virtual ScriptLanguage *get_language();
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);

View File

@@ -138,11 +138,11 @@ void PluginScriptInstance::notification(int p_notification) {
_desc->notification(_data, p_notification); _desc->notification(_data, p_notification);
} }
MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { ScriptInstance::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
return _script->get_rpc_mode(p_method); return _script->get_rpc_mode(p_method);
} }
MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { ScriptInstance::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
return _script->get_rset_mode(p_variable); return _script->get_rset_mode(p_variable);
} }

View File

@@ -76,8 +76,8 @@ public:
void set_path(const String &p_path); void set_path(const String &p_path);
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rpc_mode(const StringName &p_method) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void refcount_incremented(); virtual void refcount_incremented();
virtual bool refcount_decremented(); virtual bool refcount_decremented();

View File

@@ -245,9 +245,9 @@ Error PluginScript::reload(bool p_keep_state) {
// rpc_mode is passed as an optional field and is not part of MethodInfo // rpc_mode is passed as an optional field and is not part of MethodInfo
Variant var = v["rpc_mode"]; Variant var = v["rpc_mode"];
if (var == Variant()) { if (var == Variant()) {
_methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED; _methods_rpc_mode[mi.name] = ScriptInstance::RPC_MODE_DISABLED;
} else { } else {
_methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var)); _methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var));
} }
} }
Array *signals = (Array *)&manifest.signals; Array *signals = (Array *)&manifest.signals;
@@ -265,9 +265,9 @@ Error PluginScript::reload(bool p_keep_state) {
// rset_mode is passed as an optional field and is not part of PropertyInfo // rset_mode is passed as an optional field and is not part of PropertyInfo
Variant var = v["rset_mode"]; Variant var = v["rset_mode"];
if (var == Variant()) { if (var == Variant()) {
_methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED; _methods_rpc_mode[pi.name] = ScriptInstance::RPC_MODE_DISABLED;
} else { } else {
_methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var)); _methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var));
} }
} }
// Manifest's attributes must be explicitly freed // Manifest's attributes must be explicitly freed
@@ -402,23 +402,23 @@ int PluginScript::get_member_line(const StringName &p_member) const {
return -1; return -1;
} }
MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
if (e != NULL) { if (e != NULL) {
return e->get(); return e->get();
} else { } else {
return MultiplayerAPI::RPC_MODE_DISABLED; return ScriptInstance::RPC_MODE_DISABLED;
} }
} }
MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
if (e != NULL) { if (e != NULL) {
return e->get(); return e->get();
} else { } else {
return MultiplayerAPI::RPC_MODE_DISABLED; return ScriptInstance::RPC_MODE_DISABLED;
} }
} }

View File

@@ -62,8 +62,8 @@ private:
Map<StringName, PropertyInfo> _properties_info; Map<StringName, PropertyInfo> _properties_info;
Map<StringName, MethodInfo> _signals_info; Map<StringName, MethodInfo> _signals_info;
Map<StringName, MethodInfo> _methods_info; Map<StringName, MethodInfo> _methods_info;
Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode; Map<StringName, ScriptInstance::RPCMode> _variables_rset_mode;
Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode; Map<StringName, ScriptInstance::RPCMode> _methods_rpc_mode;
Set<Object *> _instances; Set<Object *> _instances;
//exported members //exported members
@@ -116,8 +116,8 @@ public:
virtual int get_member_line(const StringName &p_member) const; virtual int get_member_line(const StringName &p_member) const;
MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; ScriptInstance::RPCMode get_rpc_mode(const StringName &p_method) const;
MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; ScriptInstance::RPCMode get_rset_mode(const StringName &p_variable) const;
PluginScript(); PluginScript();
void init(PluginScriptLanguage *language); void init(PluginScriptLanguage *language);

View File

@@ -1220,7 +1220,7 @@ ScriptLanguage *GDScriptInstance::get_language() {
return GDScriptLanguage::get_singleton(); return GDScriptLanguage::get_singleton();
} }
MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const { GDScriptInstance::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
const GDScript *cscript = script.ptr(); const GDScript *cscript = script.ptr();
@@ -1228,17 +1228,17 @@ MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_metho
const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method); const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method);
if (E) { if (E) {
if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { if (E->get()->get_rpc_mode() != RPC_MODE_DISABLED) {
return E->get()->get_rpc_mode(); return E->get()->get_rpc_mode();
} }
} }
cscript = cscript->_base; cscript = cscript->_base;
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const { GDScriptInstance::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
const GDScript *cscript = script.ptr(); const GDScript *cscript = script.ptr();
@@ -1253,7 +1253,7 @@ MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_vari
cscript = cscript->_base; cscript = cscript->_base;
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
void GDScriptInstance::reload_members() { void GDScriptInstance::reload_members() {
@@ -1769,9 +1769,6 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"sync", "sync",
"master", "master",
"slave", "slave",
"remotesync",
"mastersync",
"slavesync",
0 0
}; };

View File

@@ -63,7 +63,7 @@ class GDScript : public Script {
int index; int index;
StringName setter; StringName setter;
StringName getter; StringName getter;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
}; };
friend class GDScriptInstance; friend class GDScriptInstance;
@@ -248,8 +248,8 @@ public:
void reload_members(); void reload_members();
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rpc_mode(const StringName &p_method) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const;
GDScriptInstance(); GDScriptInstance();
~GDScriptInstance(); ~GDScriptInstance();

View File

@@ -1455,7 +1455,7 @@ GDScriptFunction::GDScriptFunction() :
_stack_size = 0; _stack_size = 0;
_call_size = 0; _call_size = 0;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
name = "<anonymous>"; name = "<anonymous>";
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
_func_cname = NULL; _func_cname = NULL;

View File

@@ -96,6 +96,14 @@ public:
ADDR_TYPE_NIL = 9 ADDR_TYPE_NIL = 9
}; };
enum RPCMode {
RPC_DISABLED,
RPC_ENABLED,
RPC_SYNC,
RPC_SYNC_MASTER,
RPC_SYNC_SLAVE
};
struct StackDebug { struct StackDebug {
int line; int line;
@@ -127,7 +135,7 @@ private:
int _call_size; int _call_size;
int _initial_line; int _initial_line;
bool _static; bool _static;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
GDScript *_script; GDScript *_script;
@@ -222,7 +230,7 @@ public:
Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL); Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL);
_FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; } _FORCE_INLINE_ ScriptInstance::RPCMode get_rpc_mode() const { return rpc_mode; }
GDScriptFunction(); GDScriptFunction();
~GDScriptFunction(); ~GDScriptFunction();
}; };

View File

@@ -3373,7 +3373,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
function->line = fnline; function->line = fnline;
function->rpc_mode = rpc_mode; function->rpc_mode = rpc_mode;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
if (_static) if (_static)
p_class->static_functions.push_back(function); p_class->static_functions.push_back(function);
@@ -3931,10 +3931,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance(); tokenizer->advance();
} }
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVESYNC) { if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC) {
current_export = PropertyInfo(); current_export = PropertyInfo();
_set_error("Expected 'var', 'onready', 'remote', 'master', 'slave', 'sync', 'remotesync', 'mastersync', 'slavesync'."); _set_error("Expected 'var', 'onready', 'remote', 'master', 'slave' or 'sync'.");
return; return;
} }
@@ -3967,7 +3967,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return; return;
} }
} }
rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE; rpc_mode = ScriptInstance::RPC_MODE_REMOTE;
continue; continue;
} break; } break;
@@ -3988,7 +3988,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} }
} }
rpc_mode = MultiplayerAPI::RPC_MODE_MASTER; rpc_mode = ScriptInstance::RPC_MODE_MASTER;
continue; continue;
} break; } break;
case GDScriptTokenizer::TK_PR_SLAVE: { case GDScriptTokenizer::TK_PR_SLAVE: {
@@ -4008,10 +4008,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} }
} }
rpc_mode = MultiplayerAPI::RPC_MODE_SLAVE; rpc_mode = ScriptInstance::RPC_MODE_SLAVE;
continue; continue;
} break; } break;
case GDScriptTokenizer::TK_PR_REMOTESYNC:
case GDScriptTokenizer::TK_PR_SYNC: { case GDScriptTokenizer::TK_PR_SYNC: {
//may be fallthrough from export, ignore if so //may be fallthrough from export, ignore if so
@@ -4024,37 +4023,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return; return;
} }
rpc_mode = MultiplayerAPI::RPC_MODE_SYNC; rpc_mode = ScriptInstance::RPC_MODE_SYNC;
continue;
} break;
case GDScriptTokenizer::TK_PR_MASTERSYNC: {
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
if (current_export.type)
_set_error("Expected 'var'.");
else
_set_error("Expected 'var' or 'func'.");
return;
}
rpc_mode = MultiplayerAPI::RPC_MODE_MASTERSYNC;
continue;
} break;
case GDScriptTokenizer::TK_PR_SLAVESYNC: {
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
if (current_export.type)
_set_error("Expected 'var'.");
else
_set_error("Expected 'var' or 'func'.");
return;
}
rpc_mode = MultiplayerAPI::RPC_MODE_SLAVESYNC;
continue; continue;
} break; } break;
case GDScriptTokenizer::TK_PR_VAR: { case GDScriptTokenizer::TK_PR_VAR: {
@@ -4084,7 +4053,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance(); tokenizer->advance();
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
@@ -4509,7 +4478,7 @@ void GDScriptParser::clear() {
current_class = NULL; current_class = NULL;
completion_found = false; completion_found = false;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
current_function = NULL; current_function = NULL;

View File

@@ -89,7 +89,7 @@ public:
StringName getter; StringName getter;
int line; int line;
Node *expression; Node *expression;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
}; };
struct Constant { struct Constant {
StringName identifier; StringName identifier;
@@ -125,7 +125,7 @@ public:
struct FunctionNode : public Node { struct FunctionNode : public Node {
bool _static; bool _static;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
StringName name; StringName name;
Vector<StringName> arguments; Vector<StringName> arguments;
Vector<Node *> default_values; Vector<Node *> default_values;
@@ -134,7 +134,7 @@ public:
FunctionNode() { FunctionNode() {
type = TYPE_FUNCTION; type = TYPE_FUNCTION;
_static = false; _static = false;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
} }
}; };
@@ -493,7 +493,7 @@ private:
PropertyInfo current_export; PropertyInfo current_export;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
void _set_error(const String &p_error, int p_line = -1, int p_column = -1); void _set_error(const String &p_error, int p_line = -1, int p_column = -1);
bool _recover_from_completion(); bool _recover_from_completion();

View File

@@ -110,9 +110,6 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = {
"sync", "sync",
"master", "master",
"slave", "slave",
"remotesync",
"mastersync",
"slavesync",
"'['", "'['",
"']'", "']'",
"'{'", "'{'",
@@ -204,9 +201,6 @@ static const _kws _keyword_list[] = {
{ GDScriptTokenizer::TK_PR_MASTER, "master" }, { GDScriptTokenizer::TK_PR_MASTER, "master" },
{ GDScriptTokenizer::TK_PR_SLAVE, "slave" }, { GDScriptTokenizer::TK_PR_SLAVE, "slave" },
{ GDScriptTokenizer::TK_PR_SYNC, "sync" }, { GDScriptTokenizer::TK_PR_SYNC, "sync" },
{ GDScriptTokenizer::TK_PR_REMOTESYNC, "remotesync" },
{ GDScriptTokenizer::TK_PR_MASTERSYNC, "mastersync" },
{ GDScriptTokenizer::TK_PR_SLAVESYNC, "slavesync" },
{ GDScriptTokenizer::TK_PR_CONST, "const" }, { GDScriptTokenizer::TK_PR_CONST, "const" },
{ GDScriptTokenizer::TK_PR_ENUM, "enum" }, { GDScriptTokenizer::TK_PR_ENUM, "enum" },
//controlflow //controlflow
@@ -253,9 +247,6 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const
case TK_PR_MASTER: case TK_PR_MASTER:
case TK_PR_SLAVE: case TK_PR_SLAVE:
case TK_PR_SYNC: case TK_PR_SYNC:
case TK_PR_REMOTESYNC:
case TK_PR_MASTERSYNC:
case TK_PR_SLAVESYNC:
return true; return true;
// Literal for non-variables only: // Literal for non-variables only:

View File

@@ -115,9 +115,6 @@ public:
TK_PR_SYNC, TK_PR_SYNC,
TK_PR_MASTER, TK_PR_MASTER,
TK_PR_SLAVE, TK_PR_SLAVE,
TK_PR_REMOTESYNC,
TK_PR_MASTERSYNC,
TK_PR_SLAVESYNC,
TK_BRACKET_OPEN, TK_BRACKET_OPEN,
TK_BRACKET_CLOSE, TK_BRACKET_CLOSE,
TK_CURLY_BRACKET_OPEN, TK_CURLY_BRACKET_OPEN,

View File

@@ -1310,27 +1310,21 @@ bool CSharpInstance::refcount_decremented() {
return ref_dying; return ref_dying;
} }
MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember *p_member) const { ScriptInstance::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember *p_member) const {
if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
return MultiplayerAPI::RPC_MODE_REMOTE; return RPC_MODE_REMOTE;
if (p_member->has_attribute(CACHED_CLASS(SyncAttribute))) if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
return MultiplayerAPI::RPC_MODE_SYNC; return RPC_MODE_SYNC;
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
return MultiplayerAPI::RPC_MODE_MASTER; return RPC_MODE_MASTER;
if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute))) if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
return MultiplayerAPI::RPC_MODE_SLAVE; return RPC_MODE_SLAVE;
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(SlaveSyncAttribute)))
return MultiplayerAPI::RPC_MODE_SLAVESYNC;
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const { ScriptInstance::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
GDMonoClass *top = script->script_class; GDMonoClass *top = script->script_class;
@@ -1343,10 +1337,10 @@ MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method)
top = top->get_parent_class(); top = top->get_parent_class();
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const { ScriptInstance::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const {
GDMonoClass *top = script->script_class; GDMonoClass *top = script->script_class;
@@ -1364,7 +1358,7 @@ MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variab
top = top->get_parent_class(); top = top->get_parent_class();
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
void CSharpInstance::notification(int p_notification) { void CSharpInstance::notification(int p_notification) {
@@ -1973,15 +1967,15 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
return NULL; return NULL;
#endif #endif
} }
if (!script_class) { if (!script_class) {
if (GDMono::get_singleton()->get_project_assembly() == NULL) { if (GDMono::get_singleton()->get_project_assembly() == NULL) {
// The project assembly is not loaded // The project assembly is not loaded
ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path()); ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path());
ERR_FAIL_V(NULL); ERR_FAIL_V(NULL);
} }
// The project assembly is loaded, but the class could not found // The project assembly is loaded, but the class could not found
ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path()); ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
ERR_FAIL_V(NULL); ERR_FAIL_V(NULL);
} }

View File

@@ -192,7 +192,7 @@ class CSharpInstance : public ScriptInstance {
void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount); void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount);
MultiplayerAPI::RPCMode _member_get_rpc_mode(GDMonoClassMember *p_member) const; RPCMode _member_get_rpc_mode(GDMonoClassMember *p_member) const;
public: public:
MonoObject *get_mono_object() const; MonoObject *get_mono_object() const;
@@ -213,8 +213,8 @@ public:
virtual void refcount_incremented(); virtual void refcount_incremented();
virtual bool refcount_decremented(); virtual bool refcount_decremented();
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rpc_mode(const StringName &p_method) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void notification(int p_notification); virtual void notification(int p_notification);
void call_notification_no_check(MonoObject *p_mono_object, int p_notification); void call_notification_no_check(MonoObject *p_mono_object, int p_notification);

View File

@@ -13,13 +13,4 @@ namespace Godot
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
public class SlaveAttribute : Attribute {} public class SlaveAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
public class RemoteSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
public class MasterSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
public class SlaveSyncAttribute : Attribute {}
} }

View File

@@ -120,9 +120,6 @@ void MonoCache::clear_members() {
class_SyncAttribute = NULL; class_SyncAttribute = NULL;
class_MasterAttribute = NULL; class_MasterAttribute = NULL;
class_SlaveAttribute = NULL; class_SlaveAttribute = NULL;
class_RemoteSyncAttribute = NULL;
class_MasterSyncAttribute = NULL;
class_SlaveSyncAttribute = NULL;
class_GodotMethodAttribute = NULL; class_GodotMethodAttribute = NULL;
field_GodotMethodAttribute_methodName = NULL; field_GodotMethodAttribute_methodName = NULL;
@@ -211,9 +208,6 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute)); CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute));
CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute)); CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute));
CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute)); CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute));
CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute));
CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute));
CACHE_CLASS_AND_CHECK(SlaveSyncAttribute, GODOT_API_CLASS(SlaveSyncAttribute));
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"));

View File

@@ -1971,11 +1971,11 @@ Ref<Script> VisualScriptInstance::get_script() const {
return script; return script;
} }
MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const { ScriptInstance::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
const Map<StringName, VisualScript::Function>::Element *E = script->functions.find(p_method); const Map<StringName, VisualScript::Function>::Element *E = script->functions.find(p_method);
if (!E) { if (!E) {
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) { if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) {
@@ -1987,12 +1987,12 @@ MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_m
} }
} }
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const { ScriptInstance::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
return MultiplayerAPI::RPC_MODE_DISABLED; return RPC_MODE_DISABLED;
} }
void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) {

View File

@@ -433,8 +433,8 @@ public:
virtual ScriptLanguage *get_language(); virtual ScriptLanguage *get_language();
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rpc_mode(const StringName &p_method) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const;
VisualScriptInstance(); VisualScriptInstance();
~VisualScriptInstance(); ~VisualScriptInstance();

View File

@@ -93,7 +93,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value
} }
if (p_name == "rpc/mode") { if (p_name == "rpc/mode") {
rpc_mode = MultiplayerAPI::RPCMode(int(p_value)); rpc_mode = ScriptInstance::RPCMode(int(p_value));
return true; return true;
} }
@@ -267,11 +267,11 @@ int VisualScriptFunction::get_argument_count() const {
return arguments.size(); return arguments.size();
} }
void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) { void VisualScriptFunction::set_rpc_mode(ScriptInstance::RPCMode p_mode) {
rpc_mode = p_mode; rpc_mode = p_mode;
} }
MultiplayerAPI::RPCMode VisualScriptFunction::get_rpc_mode() const { ScriptInstance::RPCMode VisualScriptFunction::get_rpc_mode() const {
return rpc_mode; return rpc_mode;
} }
@@ -319,7 +319,7 @@ VisualScriptFunction::VisualScriptFunction() {
stack_size = 256; stack_size = 256;
stack_less = false; stack_less = false;
sequenced = true; sequenced = true;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
} }
void VisualScriptFunction::set_stack_less(bool p_enable) { void VisualScriptFunction::set_stack_less(bool p_enable) {

View File

@@ -46,7 +46,7 @@ class VisualScriptFunction : public VisualScriptNode {
bool stack_less; bool stack_less;
int stack_size; int stack_size;
MultiplayerAPI::RPCMode rpc_mode; ScriptInstance::RPCMode rpc_mode;
bool sequenced; bool sequenced;
protected: protected:
@@ -93,8 +93,8 @@ public:
void set_return_type(Variant::Type p_type); void set_return_type(Variant::Type p_type);
Variant::Type get_return_type() const; Variant::Type get_return_type() const;
void set_rpc_mode(MultiplayerAPI::RPCMode p_mode); void set_rpc_mode(ScriptInstance::RPCMode p_mode);
MultiplayerAPI::RPCMode get_rpc_mode() const; ScriptInstance::RPCMode get_rpc_mode() const;
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance); virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);

View File

@@ -40,6 +40,7 @@
#include "viewport.h" #include "viewport.h"
VARIANT_ENUM_CAST(Node::PauseMode); VARIANT_ENUM_CAST(Node::PauseMode);
VARIANT_ENUM_CAST(Node::RPCMode);
void Node::_notification(int p_notification) { void Node::_notification(int p_notification) {
@@ -484,18 +485,18 @@ bool Node::is_network_master() const {
/***** RPC CONFIG ********/ /***** RPC CONFIG ********/
void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { void Node::rpc_config(const StringName &p_method, RPCMode p_mode) {
if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { if (p_mode == RPC_MODE_DISABLED) {
data.rpc_methods.erase(p_method); data.rpc_methods.erase(p_method);
} else { } else {
data.rpc_methods[p_method] = p_mode; data.rpc_methods[p_method] = p_mode;
}; };
} }
void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { void Node::rset_config(const StringName &p_property, RPCMode p_mode) {
if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { if (p_mode == RPC_MODE_DISABLED) {
data.rpc_properties.erase(p_property); data.rpc_properties.erase(p_property);
} else { } else {
data.rpc_properties[p_property] = p_mode; data.rpc_properties[p_property] = p_mode;
@@ -717,14 +718,121 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer; multiplayer = p_multiplayer;
} }
const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) { const Map<StringName, Node::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) {
return data.rpc_methods.find(p_method); return data.rpc_methods.find(p_method);
} }
const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) { const Map<StringName, Node::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) {
return data.rpc_properties.find(p_property); return data.rpc_properties.find(p_property);
} }
bool Node::can_call_rpc(const StringName &p_method, int p_from) const {
const Map<StringName, RPCMode>::Element *E = data.rpc_methods.find(p_method);
if (E) {
switch (E->get()) {
case RPC_MODE_DISABLED: {
return false;
} break;
case RPC_MODE_REMOTE: {
return true;
} break;
case RPC_MODE_SYNC: {
return true;
} break;
case RPC_MODE_MASTER: {
return is_network_master();
} break;
case RPC_MODE_SLAVE: {
return !is_network_master() && p_from == get_network_master();
} break;
}
}
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: {
return false;
} break;
case ScriptInstance::RPC_MODE_REMOTE: {
return true;
} break;
case ScriptInstance::RPC_MODE_SYNC: {
return true;
} break;
case ScriptInstance::RPC_MODE_MASTER: {
return is_network_master();
} break;
case ScriptInstance::RPC_MODE_SLAVE: {
return !is_network_master() && p_from == get_network_master();
} break;
}
}
ERR_PRINTS("RPC from " + itos(p_from) + " on unauthorized method attempted: " + String(p_method) + " on base: " + String(Variant(this)));
return false;
}
bool Node::can_call_rset(const StringName &p_property, int p_from) const {
const Map<StringName, RPCMode>::Element *E = data.rpc_properties.find(p_property);
if (E) {
switch (E->get()) {
case RPC_MODE_DISABLED: {
return false;
} break;
case RPC_MODE_REMOTE: {
return true;
} break;
case RPC_MODE_SYNC: {
return true;
} break;
case RPC_MODE_MASTER: {
return is_network_master();
} break;
case RPC_MODE_SLAVE: {
return !is_network_master() && p_from == get_network_master();
} break;
}
}
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: {
return false;
} break;
case ScriptInstance::RPC_MODE_REMOTE: {
return true;
} break;
case ScriptInstance::RPC_MODE_SYNC: {
return true;
} break;
case ScriptInstance::RPC_MODE_MASTER: {
return is_network_master();
} break;
case ScriptInstance::RPC_MODE_SLAVE: {
return !is_network_master() && p_from == get_network_master();
} break;
}
}
ERR_PRINTS("RSET from " + itos(p_from) + " on unauthorized property attempted: " + String(p_property) + " on base: " + String(Variant(this)));
return false;
}
bool Node::can_process() const { bool Node::can_process() const {
ERR_FAIL_COND_V(!is_inside_tree(), false); ERR_FAIL_COND_V(!is_inside_tree(), false);
@@ -2694,6 +2802,12 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS);
BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
BIND_ENUM_CONSTANT(RPC_MODE_SYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
BIND_ENUM_CONSTANT(RPC_MODE_SLAVE);
BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT);
BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS); BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS);

View File

@@ -65,6 +65,15 @@ public:
#endif #endif
}; };
enum RPCMode {
RPC_MODE_DISABLED, //no rpc for this method, calls to this will be blocked (default)
RPC_MODE_REMOTE, // using rpc() on it will call method / set property in all other peers
RPC_MODE_SYNC, // using rpc() on it will call method / set property in all other peers and locally
RPC_MODE_MASTER, // usinc rpc() on it will call method on wherever the master is, be it local or remote
RPC_MODE_SLAVE, // usinc rpc() on it will call method for all slaves, be it local or remote
};
struct Comparator { struct Comparator {
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); } bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
@@ -111,8 +120,8 @@ private:
Node *pause_owner; Node *pause_owner;
int network_master; int network_master;
Map<StringName, MultiplayerAPI::RPCMode> rpc_methods; Map<StringName, RPCMode> rpc_methods;
Map<StringName, MultiplayerAPI::RPCMode> rpc_properties; Map<StringName, RPCMode> rpc_properties;
// variables used to properly sort the node when processing, ignored otherwise // variables used to properly sort the node when processing, ignored otherwise
//should move all the stuff below to bits //should move all the stuff below to bits
@@ -395,8 +404,8 @@ public:
int get_network_master() const; int get_network_master() const;
bool is_network_master() const; bool is_network_master() const;
void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC void rpc_config(const StringName &p_method, RPCMode p_mode); // config a local method for RPC
void rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC void rset_config(const StringName &p_property, RPCMode p_mode); // config a local property for RPC
void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
@@ -414,8 +423,11 @@ public:
Ref<MultiplayerAPI> get_multiplayer() const; Ref<MultiplayerAPI> get_multiplayer() const;
Ref<MultiplayerAPI> get_custom_multiplayer() const; Ref<MultiplayerAPI> get_custom_multiplayer() const;
void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer); void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method); const Map<StringName, RPCMode>::Element *get_node_rpc_mode(const StringName &p_method);
const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rset_mode(const StringName &p_property); const Map<StringName, RPCMode>::Element *get_node_rset_mode(const StringName &p_property);
bool can_call_rpc(const StringName &p_method, int p_from) const;
bool can_call_rset(const StringName &p_property, int p_from) const;
Node(); Node();
~Node(); ~Node();