1 /** 2 High-level multiplayer API. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.multiplayerapi; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.reference; 25 import godot.networkedmultiplayerpeer; 26 import godot.node; 27 /** 28 High-level multiplayer API. 29 30 This class implements most of the logic behind the high-level multiplayer API. See also $(D NetworkedMultiplayerPeer). 31 By default, $(D SceneTree) has a reference to this class that is used to provide multiplayer capabilities (i.e. RPC/RSET) across the whole scene. 32 It is possible to override the MultiplayerAPI instance used by specific Nodes by setting the $(D Node.customMultiplayer) property, effectively allowing to run both client and server in the same scene. 33 $(B Note:) The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. 34 */ 35 @GodotBaseClass struct MultiplayerAPI 36 { 37 package(godot) enum string _GODOT_internal_name = "MultiplayerAPI"; 38 public: 39 @nogc nothrow: 40 union { /** */ godot_object _godot_object; /** */ Reference _GODOT_base; } 41 alias _GODOT_base this; 42 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 43 package(godot) __gshared bool _classBindingInitialized = false; 44 package(godot) static struct GDNativeClassBinding 45 { 46 __gshared: 47 @GodotName("_add_peer") GodotMethod!(void, long) _addPeer; 48 @GodotName("_connected_to_server") GodotMethod!(void) _connectedToServer; 49 @GodotName("_connection_failed") GodotMethod!(void) _connectionFailed; 50 @GodotName("_del_peer") GodotMethod!(void, long) _delPeer; 51 @GodotName("_server_disconnected") GodotMethod!(void) _serverDisconnected; 52 @GodotName("clear") GodotMethod!(void) clear; 53 @GodotName("get_network_connected_peers") GodotMethod!(PoolIntArray) getNetworkConnectedPeers; 54 @GodotName("get_network_peer") GodotMethod!(NetworkedMultiplayerPeer) getNetworkPeer; 55 @GodotName("get_network_unique_id") GodotMethod!(long) getNetworkUniqueId; 56 @GodotName("get_root_node") GodotMethod!(Node) getRootNode; 57 @GodotName("get_rpc_sender_id") GodotMethod!(long) getRpcSenderId; 58 @GodotName("has_network_peer") GodotMethod!(bool) hasNetworkPeer; 59 @GodotName("is_network_server") GodotMethod!(bool) isNetworkServer; 60 @GodotName("is_object_decoding_allowed") GodotMethod!(bool) isObjectDecodingAllowed; 61 @GodotName("is_refusing_new_network_connections") GodotMethod!(bool) isRefusingNewNetworkConnections; 62 @GodotName("poll") GodotMethod!(void) poll; 63 @GodotName("send_bytes") GodotMethod!(GodotError, PoolByteArray, long, long) sendBytes; 64 @GodotName("set_allow_object_decoding") GodotMethod!(void, bool) setAllowObjectDecoding; 65 @GodotName("set_network_peer") GodotMethod!(void, NetworkedMultiplayerPeer) setNetworkPeer; 66 @GodotName("set_refuse_new_network_connections") GodotMethod!(void, bool) setRefuseNewNetworkConnections; 67 @GodotName("set_root_node") GodotMethod!(void, Node) setRootNode; 68 } 69 /// 70 pragma(inline, true) bool opEquals(in MultiplayerAPI other) const 71 { return _godot_object.ptr is other._godot_object.ptr; } 72 /// 73 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 74 { _godot_object.ptr = n; return null; } 75 /// 76 pragma(inline, true) bool opEquals(typeof(null) n) const 77 { return _godot_object.ptr is n; } 78 /// 79 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 80 mixin baseCasts; 81 /// Construct a new instance of MultiplayerAPI. 82 /// Note: use `memnew!MultiplayerAPI` instead. 83 static MultiplayerAPI _new() 84 { 85 static godot_class_constructor constructor; 86 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("MultiplayerAPI"); 87 if(constructor is null) return typeof(this).init; 88 return cast(MultiplayerAPI)(constructor()); 89 } 90 @disable new(size_t s); 91 /// 92 enum RPCMode : int 93 { 94 /** 95 Used with $(D Node.rpcConfig) or $(D Node.rsetConfig) to disable a method or property for all RPC calls, making it unavailable. Default for all methods. 96 */ 97 rpcModeDisabled = 0, 98 /** 99 Used with $(D Node.rpcConfig) or $(D Node.rsetConfig) to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the `remote` keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets. 100 */ 101 rpcModeRemote = 1, 102 /** 103 Used with $(D Node.rpcConfig) or $(D Node.rsetConfig) to set a method to be called or a property to be changed only on the network master for this node. Analogous to the `master` keyword. Only accepts calls or property changes from the node's network puppets, see $(D Node.setNetworkMaster). 104 */ 105 rpcModeMaster = 2, 106 /** 107 Used with $(D Node.rpcConfig) or $(D Node.rsetConfig) to set a method to be called or a property to be changed only on puppets for this node. Analogous to the `puppet` keyword. Only accepts calls or property changes from the node's network master, see $(D Node.setNetworkMaster). 108 */ 109 rpcModePuppet = 3, 110 /** 111 $(I Deprecated.) Use $(D constant RPC_MODE_PUPPET) instead. Analogous to the `slave` keyword. 112 */ 113 rpcModeSlave = 3, 114 /** 115 $(I Deprecated.) Use $(D constant RPC_MODE_REMOTESYNC) instead. Analogous to the `sync` keyword. 116 */ 117 rpcModeSync = 4, 118 /** 119 Behave like $(D constant RPC_MODE_REMOTE) but also make the call or property change locally. Analogous to the `remotesync` keyword. 120 */ 121 rpcModeRemotesync = 4, 122 /** 123 Behave like $(D constant RPC_MODE_MASTER) but also make the call or property change locally. Analogous to the `mastersync` keyword. 124 */ 125 rpcModeMastersync = 5, 126 /** 127 Behave like $(D constant RPC_MODE_PUPPET) but also make the call or property change locally. Analogous to the `puppetsync` keyword. 128 */ 129 rpcModePuppetsync = 6, 130 } 131 /// 132 enum Constants : int 133 { 134 rpcModeDisabled = 0, 135 rpcModeRemote = 1, 136 rpcModeMaster = 2, 137 rpcModePuppet = 3, 138 rpcModeSlave = 3, 139 rpcModeSync = 4, 140 rpcModeRemotesync = 4, 141 rpcModeMastersync = 5, 142 rpcModePuppetsync = 6, 143 } 144 /** 145 146 */ 147 void _addPeer(in long id) 148 { 149 Array _GODOT_args = Array.make(); 150 _GODOT_args.append(id); 151 String _GODOT_method_name = String("_add_peer"); 152 this.callv(_GODOT_method_name, _GODOT_args); 153 } 154 /** 155 156 */ 157 void _connectedToServer() 158 { 159 Array _GODOT_args = Array.make(); 160 String _GODOT_method_name = String("_connected_to_server"); 161 this.callv(_GODOT_method_name, _GODOT_args); 162 } 163 /** 164 165 */ 166 void _connectionFailed() 167 { 168 Array _GODOT_args = Array.make(); 169 String _GODOT_method_name = String("_connection_failed"); 170 this.callv(_GODOT_method_name, _GODOT_args); 171 } 172 /** 173 174 */ 175 void _delPeer(in long id) 176 { 177 Array _GODOT_args = Array.make(); 178 _GODOT_args.append(id); 179 String _GODOT_method_name = String("_del_peer"); 180 this.callv(_GODOT_method_name, _GODOT_args); 181 } 182 /** 183 184 */ 185 void _serverDisconnected() 186 { 187 Array _GODOT_args = Array.make(); 188 String _GODOT_method_name = String("_server_disconnected"); 189 this.callv(_GODOT_method_name, _GODOT_args); 190 } 191 /** 192 Clears the current MultiplayerAPI network state (you shouldn't call this unless you know what you are doing). 193 */ 194 void clear() 195 { 196 checkClassBinding!(typeof(this))(); 197 ptrcall!(void)(GDNativeClassBinding.clear, _godot_object); 198 } 199 /** 200 Returns the peer IDs of all connected peers of this MultiplayerAPI's $(D networkPeer). 201 */ 202 PoolIntArray getNetworkConnectedPeers() const 203 { 204 checkClassBinding!(typeof(this))(); 205 return ptrcall!(PoolIntArray)(GDNativeClassBinding.getNetworkConnectedPeers, _godot_object); 206 } 207 /** 208 209 */ 210 Ref!NetworkedMultiplayerPeer getNetworkPeer() const 211 { 212 checkClassBinding!(typeof(this))(); 213 return ptrcall!(NetworkedMultiplayerPeer)(GDNativeClassBinding.getNetworkPeer, _godot_object); 214 } 215 /** 216 Returns the unique peer ID of this MultiplayerAPI's $(D networkPeer). 217 */ 218 long getNetworkUniqueId() const 219 { 220 checkClassBinding!(typeof(this))(); 221 return ptrcall!(long)(GDNativeClassBinding.getNetworkUniqueId, _godot_object); 222 } 223 /** 224 225 */ 226 Node getRootNode() 227 { 228 checkClassBinding!(typeof(this))(); 229 return ptrcall!(Node)(GDNativeClassBinding.getRootNode, _godot_object); 230 } 231 /** 232 Returns the sender's peer ID for the RPC currently being executed. 233 $(B Note:) If not inside an RPC this method will return 0. 234 */ 235 long getRpcSenderId() const 236 { 237 checkClassBinding!(typeof(this))(); 238 return ptrcall!(long)(GDNativeClassBinding.getRpcSenderId, _godot_object); 239 } 240 /** 241 Returns `true` if there is a $(D networkPeer) set. 242 */ 243 bool hasNetworkPeer() const 244 { 245 checkClassBinding!(typeof(this))(); 246 return ptrcall!(bool)(GDNativeClassBinding.hasNetworkPeer, _godot_object); 247 } 248 /** 249 Returns `true` if this MultiplayerAPI's $(D networkPeer) is in server mode (listening for connections). 250 */ 251 bool isNetworkServer() const 252 { 253 checkClassBinding!(typeof(this))(); 254 return ptrcall!(bool)(GDNativeClassBinding.isNetworkServer, _godot_object); 255 } 256 /** 257 258 */ 259 bool isObjectDecodingAllowed() const 260 { 261 checkClassBinding!(typeof(this))(); 262 return ptrcall!(bool)(GDNativeClassBinding.isObjectDecodingAllowed, _godot_object); 263 } 264 /** 265 266 */ 267 bool isRefusingNewNetworkConnections() const 268 { 269 checkClassBinding!(typeof(this))(); 270 return ptrcall!(bool)(GDNativeClassBinding.isRefusingNewNetworkConnections, _godot_object); 271 } 272 /** 273 Method used for polling the MultiplayerAPI. You only need to worry about this if you are using $(D Node.customMultiplayer) override or you set $(D SceneTree.multiplayerPoll) to `false`. By default, $(D SceneTree) will poll its MultiplayerAPI for you. 274 $(B Note:) This method results in RPCs and RSETs being called, so they will be executed in the same context of this function (e.g. `_process`, `physics`, $(D Thread)). 275 */ 276 void poll() 277 { 278 checkClassBinding!(typeof(this))(); 279 ptrcall!(void)(GDNativeClassBinding.poll, _godot_object); 280 } 281 /** 282 Sends the given raw `bytes` to a specific peer identified by `id` (see $(D NetworkedMultiplayerPeer.setTargetPeer)). Default ID is `0`, i.e. broadcast to all peers. 283 */ 284 GodotError sendBytes(in PoolByteArray bytes, in long id = 0, in long mode = 2) 285 { 286 checkClassBinding!(typeof(this))(); 287 return ptrcall!(GodotError)(GDNativeClassBinding.sendBytes, _godot_object, bytes, id, mode); 288 } 289 /** 290 291 */ 292 void setAllowObjectDecoding(in bool enable) 293 { 294 checkClassBinding!(typeof(this))(); 295 ptrcall!(void)(GDNativeClassBinding.setAllowObjectDecoding, _godot_object, enable); 296 } 297 /** 298 299 */ 300 void setNetworkPeer(NetworkedMultiplayerPeer peer) 301 { 302 checkClassBinding!(typeof(this))(); 303 ptrcall!(void)(GDNativeClassBinding.setNetworkPeer, _godot_object, peer); 304 } 305 /** 306 307 */ 308 void setRefuseNewNetworkConnections(in bool refuse) 309 { 310 checkClassBinding!(typeof(this))(); 311 ptrcall!(void)(GDNativeClassBinding.setRefuseNewNetworkConnections, _godot_object, refuse); 312 } 313 /** 314 315 */ 316 void setRootNode(Node node) 317 { 318 checkClassBinding!(typeof(this))(); 319 ptrcall!(void)(GDNativeClassBinding.setRootNode, _godot_object, node); 320 } 321 /** 322 If `true` (or if the $(D networkPeer) has $(D PacketPeer.allowObjectDecoding) set to `true`), the MultiplayerAPI will allow encoding and decoding of object during RPCs/RSETs. 323 $(B Warning:) Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats such as remote code execution. 324 */ 325 @property bool allowObjectDecoding() 326 { 327 return isObjectDecodingAllowed(); 328 } 329 /// ditto 330 @property void allowObjectDecoding(bool v) 331 { 332 setAllowObjectDecoding(v); 333 } 334 /** 335 The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with $(D isNetworkServer)) and will set root node's network mode to master, or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. 336 */ 337 @property NetworkedMultiplayerPeer networkPeer() 338 { 339 return getNetworkPeer(); 340 } 341 /// ditto 342 @property void networkPeer(NetworkedMultiplayerPeer v) 343 { 344 setNetworkPeer(v); 345 } 346 /** 347 If `true`, the MultiplayerAPI's $(D networkPeer) refuses new incoming connections. 348 */ 349 @property bool refuseNewNetworkConnections() 350 { 351 return isRefusingNewNetworkConnections(); 352 } 353 /// ditto 354 @property void refuseNewNetworkConnections(bool v) 355 { 356 setRefuseNewNetworkConnections(v); 357 } 358 /** 359 The root node to use for RPCs. Instead of an absolute path, a relative path will be used to find the node upon which the RPC should be executed. 360 This effectively allows to have different branches of the scene tree to be managed by different MultiplayerAPI, allowing for example to run both client and server in the same scene. 361 */ 362 @property Node rootNode() 363 { 364 return getRootNode(); 365 } 366 /// ditto 367 @property void rootNode(Node v) 368 { 369 setRootNode(v); 370 } 371 }