Merge pull request #19021 from Faless/rpc_sync_fix
RPCMode refactor, more sync modes
This commit is contained in:
commit
d0b62ce155
30 changed files with 319 additions and 333 deletions
|
@ -32,6 +32,61 @@
|
||||||
#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)
|
||||||
|
@ -202,11 +257,19 @@ 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;
|
||||||
|
@ -238,11 +301,18 @@ 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) {
|
||||||
|
|
||||||
if (!p_node->can_call_rset(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 RSET on this node
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -522,57 +592,6 @@ 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());
|
||||||
|
@ -587,17 +606,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, Node::RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
|
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
|
||||||
if (E) {
|
if (E) {
|
||||||
call_local_native = _should_call_native(E->get(), is_master, skip_rpc);
|
call_local_native = _should_call_local(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
|
||||||
ScriptInstance::RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
|
RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
|
||||||
call_local_script = _should_call_script(rpc_mode, is_master, skip_rpc);
|
call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,10 +662,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, Node::RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
|
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
|
||||||
if (E) {
|
if (E) {
|
||||||
|
|
||||||
set_local = _should_call_native(E->get(), is_master, skip_rset);
|
set_local = _should_call_local(E->get(), is_master, skip_rset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_local) {
|
if (set_local) {
|
||||||
|
@ -660,9 +679,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
|
||||||
ScriptInstance::RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
|
RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
|
||||||
|
|
||||||
set_local = _should_call_script(rpc_mode, is_master, skip_rset);
|
set_local = _should_call_local(rpc_mode, is_master, skip_rset);
|
||||||
|
|
||||||
if (set_local) {
|
if (set_local) {
|
||||||
|
|
||||||
|
@ -778,6 +797,15 @@ 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() {
|
||||||
|
|
|
@ -87,6 +87,18 @@ 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);
|
||||||
|
@ -117,4 +129,6 @@ public:
|
||||||
~MultiplayerAPI();
|
~MultiplayerAPI();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VARIANT_ENUM_CAST(MultiplayerAPI::RPCMode);
|
||||||
|
|
||||||
#endif // MULTIPLAYER_PROTOCOL_H
|
#endif // MULTIPLAYER_PROTOCOL_H
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#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"
|
||||||
|
@ -157,16 +158,8 @@ public:
|
||||||
|
|
||||||
virtual bool is_placeholder() const { return false; }
|
virtual bool is_placeholder() const { return false; }
|
||||||
|
|
||||||
enum RPCMode {
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0;
|
||||||
RPC_MODE_DISABLED,
|
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0;
|
||||||
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();
|
||||||
|
@ -332,8 +325,8 @@ public:
|
||||||
|
|
||||||
virtual bool is_placeholder() const { return true; }
|
virtual bool is_placeholder() const { return true; }
|
||||||
|
|
||||||
virtual RPCMode get_rpc_mode(const StringName &p_method) const { return RPC_MODE_DISABLED; }
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const { return RPC_MODE_DISABLED; }
|
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const { return MultiplayerAPI::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();
|
||||||
|
|
|
@ -136,5 +136,29 @@
|
||||||
</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>
|
||||||
|
|
|
@ -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="Node.RPCMode">
|
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode">
|
||||||
</argument>
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
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.
|
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.
|
||||||
</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="Node.RPCMode">
|
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode">
|
||||||
</argument>
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
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.
|
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.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="rset_id">
|
<method name="rset_id">
|
||||||
|
@ -860,21 +860,6 @@
|
||||||
<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>
|
||||||
|
|
|
@ -43,6 +43,9 @@ 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 {
|
||||||
|
|
|
@ -747,7 +747,7 @@ Ref<Script> NativeScriptInstance::get_script() const {
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
||||||
|
|
||||||
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
|
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
|
||||||
|
|
||||||
|
@ -757,27 +757,33 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringNam
|
||||||
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 RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
case GODOT_METHOD_RPC_MODE_REMOTE:
|
case GODOT_METHOD_RPC_MODE_REMOTE:
|
||||||
return RPC_MODE_REMOTE;
|
return MultiplayerAPI::RPC_MODE_REMOTE;
|
||||||
case GODOT_METHOD_RPC_MODE_SYNC:
|
case GODOT_METHOD_RPC_MODE_SYNC:
|
||||||
return RPC_MODE_SYNC;
|
return MultiplayerAPI::RPC_MODE_SYNC;
|
||||||
case GODOT_METHOD_RPC_MODE_MASTER:
|
case GODOT_METHOD_RPC_MODE_MASTER:
|
||||||
return RPC_MODE_MASTER;
|
return MultiplayerAPI::RPC_MODE_MASTER;
|
||||||
case GODOT_METHOD_RPC_MODE_SLAVE:
|
case GODOT_METHOD_RPC_MODE_SLAVE:
|
||||||
return RPC_MODE_SLAVE;
|
return MultiplayerAPI::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 RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
script_data = script_data->base_data;
|
script_data = script_data->base_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
||||||
|
|
||||||
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
|
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
|
||||||
|
|
||||||
|
@ -787,24 +793,24 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringNa
|
||||||
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 RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
case GODOT_METHOD_RPC_MODE_REMOTE:
|
case GODOT_METHOD_RPC_MODE_REMOTE:
|
||||||
return RPC_MODE_REMOTE;
|
return MultiplayerAPI::RPC_MODE_REMOTE;
|
||||||
case GODOT_METHOD_RPC_MODE_SYNC:
|
case GODOT_METHOD_RPC_MODE_SYNC:
|
||||||
return RPC_MODE_SYNC;
|
return MultiplayerAPI::RPC_MODE_SYNC;
|
||||||
case GODOT_METHOD_RPC_MODE_MASTER:
|
case GODOT_METHOD_RPC_MODE_MASTER:
|
||||||
return RPC_MODE_MASTER;
|
return MultiplayerAPI::RPC_MODE_MASTER;
|
||||||
case GODOT_METHOD_RPC_MODE_SLAVE:
|
case GODOT_METHOD_RPC_MODE_SLAVE:
|
||||||
return RPC_MODE_SLAVE;
|
return MultiplayerAPI::RPC_MODE_SLAVE;
|
||||||
default:
|
default:
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
script_data = script_data->base_data;
|
script_data = script_data->base_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptLanguage *NativeScriptInstance::get_language() {
|
ScriptLanguage *NativeScriptInstance::get_language() {
|
||||||
|
|
|
@ -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 RPCMode get_rpc_mode(const StringName &p_method) const;
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const;
|
virtual MultiplayerAPI::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);
|
||||||
|
|
|
@ -138,11 +138,11 @@ void PluginScriptInstance::notification(int p_notification) {
|
||||||
_desc->notification(_data, p_notification);
|
_desc->notification(_data, p_notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
||||||
return _script->get_rpc_mode(p_method);
|
return _script->get_rpc_mode(p_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
||||||
return _script->get_rset_mode(p_variable);
|
return _script->get_rset_mode(p_variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,8 @@ public:
|
||||||
|
|
||||||
void set_path(const String &p_path);
|
void set_path(const String &p_path);
|
||||||
|
|
||||||
virtual RPCMode get_rpc_mode(const StringName &p_method) const;
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const;
|
virtual MultiplayerAPI::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();
|
||||||
|
|
|
@ -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] = ScriptInstance::RPC_MODE_DISABLED;
|
_methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
} else {
|
} else {
|
||||||
_methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var));
|
_methods_rpc_mode[mi.name] = MultiplayerAPI::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] = ScriptInstance::RPC_MODE_DISABLED;
|
_methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
} else {
|
} else {
|
||||||
_methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var));
|
_methods_rpc_mode[pi.name] = MultiplayerAPI::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;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
|
||||||
ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
|
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
|
||||||
const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
|
const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
|
||||||
if (e != NULL) {
|
if (e != NULL) {
|
||||||
return e->get();
|
return e->get();
|
||||||
} else {
|
} else {
|
||||||
return ScriptInstance::RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
|
||||||
ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
|
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
|
||||||
const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
|
const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
|
||||||
if (e != NULL) {
|
if (e != NULL) {
|
||||||
return e->get();
|
return e->get();
|
||||||
} else {
|
} else {
|
||||||
return ScriptInstance::RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, ScriptInstance::RPCMode> _variables_rset_mode;
|
Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode;
|
||||||
Map<StringName, ScriptInstance::RPCMode> _methods_rpc_mode;
|
Map<StringName, MultiplayerAPI::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;
|
||||||
|
|
||||||
ScriptInstance::RPCMode get_rpc_mode(const StringName &p_method) const;
|
MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
ScriptInstance::RPCMode get_rset_mode(const StringName &p_variable) const;
|
MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
|
||||||
|
|
||||||
PluginScript();
|
PluginScript();
|
||||||
void init(PluginScriptLanguage *language);
|
void init(PluginScriptLanguage *language);
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ ScriptLanguage *GDScriptInstance::get_language() {
|
||||||
return GDScriptLanguage::get_singleton();
|
return GDScriptLanguage::get_singleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
GDScriptInstance::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
||||||
|
|
||||||
const GDScript *cscript = script.ptr();
|
const GDScript *cscript = script.ptr();
|
||||||
|
|
||||||
|
@ -1228,17 +1228,17 @@ GDScriptInstance::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_met
|
||||||
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() != RPC_MODE_DISABLED) {
|
if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
|
||||||
return E->get()->get_rpc_mode();
|
return E->get()->get_rpc_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cscript = cscript->_base;
|
cscript = cscript->_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
GDScriptInstance::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
||||||
|
|
||||||
const GDScript *cscript = script.ptr();
|
const GDScript *cscript = script.ptr();
|
||||||
|
|
||||||
|
@ -1253,7 +1253,7 @@ GDScriptInstance::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_va
|
||||||
cscript = cscript->_base;
|
cscript = cscript->_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptInstance::reload_members() {
|
void GDScriptInstance::reload_members() {
|
||||||
|
@ -1769,6 +1769,9 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
|
||||||
"sync",
|
"sync",
|
||||||
"master",
|
"master",
|
||||||
"slave",
|
"slave",
|
||||||
|
"remotesync",
|
||||||
|
"mastersync",
|
||||||
|
"slavesync",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ class GDScript : public Script {
|
||||||
int index;
|
int index;
|
||||||
StringName setter;
|
StringName setter;
|
||||||
StringName getter;
|
StringName getter;
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::RPCMode rpc_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class GDScriptInstance;
|
friend class GDScriptInstance;
|
||||||
|
@ -248,8 +248,8 @@ public:
|
||||||
|
|
||||||
void reload_members();
|
void reload_members();
|
||||||
|
|
||||||
virtual RPCMode get_rpc_mode(const StringName &p_method) const;
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const;
|
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
|
||||||
|
|
||||||
GDScriptInstance();
|
GDScriptInstance();
|
||||||
~GDScriptInstance();
|
~GDScriptInstance();
|
||||||
|
|
|
@ -1455,7 +1455,7 @@ GDScriptFunction::GDScriptFunction() :
|
||||||
|
|
||||||
_stack_size = 0;
|
_stack_size = 0;
|
||||||
_call_size = 0;
|
_call_size = 0;
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
name = "<anonymous>";
|
name = "<anonymous>";
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
_func_cname = NULL;
|
_func_cname = NULL;
|
||||||
|
|
|
@ -96,14 +96,6 @@ 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;
|
||||||
|
@ -135,7 +127,7 @@ private:
|
||||||
int _call_size;
|
int _call_size;
|
||||||
int _initial_line;
|
int _initial_line;
|
||||||
bool _static;
|
bool _static;
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::RPCMode rpc_mode;
|
||||||
|
|
||||||
GDScript *_script;
|
GDScript *_script;
|
||||||
|
|
||||||
|
@ -230,7 +222,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_ ScriptInstance::RPCMode get_rpc_mode() const { return rpc_mode; }
|
_FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; }
|
||||||
GDScriptFunction();
|
GDScriptFunction();
|
||||||
~GDScriptFunction();
|
~GDScriptFunction();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::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) {
|
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) {
|
||||||
|
|
||||||
current_export = PropertyInfo();
|
current_export = PropertyInfo();
|
||||||
_set_error("Expected 'var', 'onready', 'remote', 'master', 'slave' or 'sync'.");
|
_set_error("Expected 'var', 'onready', 'remote', 'master', 'slave', 'sync', 'remotesync', 'mastersync', 'slavesync'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3967,7 +3967,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_REMOTE;
|
rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} break;
|
} break;
|
||||||
|
@ -3988,7 +3988,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_MASTER;
|
rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
|
||||||
continue;
|
continue;
|
||||||
} break;
|
} break;
|
||||||
case GDScriptTokenizer::TK_PR_SLAVE: {
|
case GDScriptTokenizer::TK_PR_SLAVE: {
|
||||||
|
@ -4008,9 +4008,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_SLAVE;
|
rpc_mode = MultiplayerAPI::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
|
||||||
|
@ -4023,7 +4024,37 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_SYNC;
|
rpc_mode = MultiplayerAPI::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: {
|
||||||
|
@ -4053,7 +4084,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
|
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
|
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
|
|
||||||
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
|
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
|
||||||
|
|
||||||
|
@ -4478,7 +4509,7 @@ void GDScriptParser::clear() {
|
||||||
current_class = NULL;
|
current_class = NULL;
|
||||||
|
|
||||||
completion_found = false;
|
completion_found = false;
|
||||||
rpc_mode = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
|
|
||||||
current_function = NULL;
|
current_function = NULL;
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
StringName getter;
|
StringName getter;
|
||||||
int line;
|
int line;
|
||||||
Node *expression;
|
Node *expression;
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::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;
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::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 = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ private:
|
||||||
|
|
||||||
PropertyInfo current_export;
|
PropertyInfo current_export;
|
||||||
|
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::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();
|
||||||
|
|
|
@ -110,6 +110,9 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = {
|
||||||
"sync",
|
"sync",
|
||||||
"master",
|
"master",
|
||||||
"slave",
|
"slave",
|
||||||
|
"remotesync",
|
||||||
|
"mastersync",
|
||||||
|
"slavesync",
|
||||||
"'['",
|
"'['",
|
||||||
"']'",
|
"']'",
|
||||||
"'{'",
|
"'{'",
|
||||||
|
@ -201,6 +204,9 @@ 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
|
||||||
|
@ -247,6 +253,9 @@ 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:
|
||||||
|
|
|
@ -115,6 +115,9 @@ 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,
|
||||||
|
|
|
@ -1310,21 +1310,27 @@ bool CSharpInstance::refcount_decremented() {
|
||||||
return ref_dying;
|
return ref_dying;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember *p_member) const {
|
MultiplayerAPI::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 RPC_MODE_REMOTE;
|
return MultiplayerAPI::RPC_MODE_REMOTE;
|
||||||
if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
|
if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
|
||||||
return RPC_MODE_SYNC;
|
return MultiplayerAPI::RPC_MODE_SYNC;
|
||||||
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
|
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
|
||||||
return RPC_MODE_MASTER;
|
return MultiplayerAPI::RPC_MODE_MASTER;
|
||||||
if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
|
if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
|
||||||
return RPC_MODE_SLAVE;
|
return MultiplayerAPI::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 RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
|
||||||
|
|
||||||
GDMonoClass *top = script->script_class;
|
GDMonoClass *top = script->script_class;
|
||||||
|
|
||||||
|
@ -1337,10 +1343,10 @@ ScriptInstance::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method)
|
||||||
top = top->get_parent_class();
|
top = top->get_parent_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const {
|
||||||
|
|
||||||
GDMonoClass *top = script->script_class;
|
GDMonoClass *top = script->script_class;
|
||||||
|
|
||||||
|
@ -1358,7 +1364,7 @@ ScriptInstance::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variab
|
||||||
top = top->get_parent_class();
|
top = top->get_parent_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpInstance::notification(int p_notification) {
|
void CSharpInstance::notification(int p_notification) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
RPCMode _member_get_rpc_mode(GDMonoClassMember *p_member) const;
|
MultiplayerAPI::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 RPCMode get_rpc_mode(const StringName &p_method) const;
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const;
|
virtual MultiplayerAPI::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);
|
||||||
|
|
|
@ -13,4 +13,13 @@ 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 {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,9 @@ 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;
|
||||||
|
|
||||||
|
@ -208,6 +211,9 @@ 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"));
|
||||||
|
|
||||||
|
|
|
@ -1971,11 +1971,11 @@ Ref<Script> VisualScriptInstance::get_script() const {
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
|
MultiplayerAPI::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 RPC_MODE_DISABLED;
|
return MultiplayerAPI::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 @@ ScriptInstance::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
|
||||||
|
|
||||||
return RPC_MODE_DISABLED;
|
return MultiplayerAPI::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) {
|
||||||
|
|
|
@ -433,8 +433,8 @@ public:
|
||||||
|
|
||||||
virtual ScriptLanguage *get_language();
|
virtual ScriptLanguage *get_language();
|
||||||
|
|
||||||
virtual RPCMode get_rpc_mode(const StringName &p_method) const;
|
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||||
virtual RPCMode get_rset_mode(const StringName &p_variable) const;
|
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
|
||||||
|
|
||||||
VisualScriptInstance();
|
VisualScriptInstance();
|
||||||
~VisualScriptInstance();
|
~VisualScriptInstance();
|
||||||
|
|
|
@ -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 = ScriptInstance::RPCMode(int(p_value));
|
rpc_mode = MultiplayerAPI::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(ScriptInstance::RPCMode p_mode) {
|
void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) {
|
||||||
rpc_mode = p_mode;
|
rpc_mode = p_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptInstance::RPCMode VisualScriptFunction::get_rpc_mode() const {
|
MultiplayerAPI::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 = ScriptInstance::RPC_MODE_DISABLED;
|
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualScriptFunction::set_stack_less(bool p_enable) {
|
void VisualScriptFunction::set_stack_less(bool p_enable) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ class VisualScriptFunction : public VisualScriptNode {
|
||||||
|
|
||||||
bool stack_less;
|
bool stack_less;
|
||||||
int stack_size;
|
int stack_size;
|
||||||
ScriptInstance::RPCMode rpc_mode;
|
MultiplayerAPI::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(ScriptInstance::RPCMode p_mode);
|
void set_rpc_mode(MultiplayerAPI::RPCMode p_mode);
|
||||||
ScriptInstance::RPCMode get_rpc_mode() const;
|
MultiplayerAPI::RPCMode get_rpc_mode() const;
|
||||||
|
|
||||||
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);
|
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#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) {
|
||||||
|
|
||||||
|
@ -485,18 +484,18 @@ bool Node::is_network_master() const {
|
||||||
|
|
||||||
/***** RPC CONFIG ********/
|
/***** RPC CONFIG ********/
|
||||||
|
|
||||||
void Node::rpc_config(const StringName &p_method, RPCMode p_mode) {
|
void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
|
||||||
|
|
||||||
if (p_mode == RPC_MODE_DISABLED) {
|
if (p_mode == MultiplayerAPI::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, RPCMode p_mode) {
|
void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
|
||||||
|
|
||||||
if (p_mode == RPC_MODE_DISABLED) {
|
if (p_mode == MultiplayerAPI::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;
|
||||||
|
@ -718,121 +717,14 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
|
||||||
multiplayer = p_multiplayer;
|
multiplayer = p_multiplayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Map<StringName, Node::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) {
|
const Map<StringName, MultiplayerAPI::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, Node::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) {
|
const Map<StringName, MultiplayerAPI::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);
|
||||||
|
@ -2802,12 +2694,6 @@ 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);
|
||||||
|
|
|
@ -65,15 +65,6 @@ 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); }
|
||||||
|
@ -120,8 +111,8 @@ private:
|
||||||
Node *pause_owner;
|
Node *pause_owner;
|
||||||
|
|
||||||
int network_master;
|
int network_master;
|
||||||
Map<StringName, RPCMode> rpc_methods;
|
Map<StringName, MultiplayerAPI::RPCMode> rpc_methods;
|
||||||
Map<StringName, RPCMode> rpc_properties;
|
Map<StringName, MultiplayerAPI::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
|
||||||
|
@ -404,8 +395,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, RPCMode p_mode); // config a local method for RPC
|
void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC
|
||||||
void rset_config(const StringName &p_property, RPCMode p_mode); // config a local property for RPC
|
void rset_config(const StringName &p_property, MultiplayerAPI::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
|
||||||
|
@ -423,11 +414,8 @@ 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, RPCMode>::Element *get_node_rpc_mode(const StringName &p_method);
|
const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method);
|
||||||
const Map<StringName, RPCMode>::Element *get_node_rset_mode(const StringName &p_property);
|
const Map<StringName, MultiplayerAPI::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();
|
||||||
|
|
Loading…
Reference in a new issue