2022-07-12 23:12:42 +02:00
<?xml version="1.0" encoding="UTF-8" ?>
<class name= "MultiplayerAPIExtension" inherits= "MultiplayerAPI" version= "4.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "../class.xsd" >
<brief_description >
Base class used for extending the [MultiplayerAPI].
</brief_description>
<description >
This class can be used to augment or replace the default [MultiplayerAPI] implementation via script or extensions.
2022-09-30 14:23:36 +02:00
The following example augment the default implementation ([SceneMultiplayer]) by logging every RPC being made, and every object being configured for replication.
2022-07-12 23:12:42 +02:00
[codeblocks]
[gdscript]
extends MultiplayerAPIExtension
class_name LogMultiplayer
# We want to augment the default SceneMultiplayer.
var base_multiplayer = SceneMultiplayer.new()
func _init():
# Just passthourgh base signals (copied to var to avoid cyclic reference)
var cts = connected_to_server
var cf = connection_failed
var pc = peer_connected
var pd = peer_disconnected
base_multiplayer.connected_to_server.connect(func(): cts.emit())
base_multiplayer.connection_failed.connect(func(): cf.emit())
base_multiplayer.peer_connected.connect(func(id): pc.emit(id))
base_multiplayer.peer_disconnected.connect(func(id): pd.emit(id))
# Log RPC being made and forward it to the default multiplayer.
func _rpc(peer: int, object: Object, method: StringName, args: Array) -> int: # Error
print("Got RPC for %d: %s::%s(%s)" % [peer, object, method, args])
return base_multiplayer.rpc(peer, object, method, args)
# Log configuration add. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom.
func _object_configuration_add(object, config: Variant) -> int: # Error
if config is MultiplayerSynchronizer:
print("Adding synchronization configuration for %s. Synchronizer: %s" % [object, config])
elif config is MultiplayerSpawner:
print("Adding node %s to the spawn list. Spawner: %s" % [object, config])
return base_multiplayer.object_configuration_add(object, config)
# Log configuration remove. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom.
func _object_configuration_remove(object, config: Variant) -> int: # Error
if config is MultiplayerSynchronizer:
print("Removing synchronization configuration for %s. Synchronizer: %s" % [object, config])
elif config is MultiplayerSpawner:
print("Removing node %s from the spawn list. Spawner: %s" % [object, config])
return base_multiplayer.object_configuration_remove(object, config)
# These can be optional, but in our case we want to augment SceneMultiplayer, so forward everything.
func _set_multiplayer_peer(p_peer: MultiplayerPeer):
base_multiplayer.multiplayer_peer = p_peer
func _get_multiplayer_peer() -> MultiplayerPeer:
return base_multiplayer.multiplayer_peer
func _get_unique_id() -> int:
return base_multiplayer.get_unique_id()
func _get_peer_ids() -> PackedInt32Array:
return base_multiplayer.get_peers()
[/gdscript]
[/codeblocks]
Then in your main scene or in an autoload call [method SceneTree.set_multiplayer] to start using your custom [MultiplayerAPI]:
[codeblocks]
[gdscript]
# autoload.gd
func _enter_tree():
# Sets our custom multiplayer as the main one in SceneTree.
get_tree().set_multiplayer(LogMultiplayer.new())
[/gdscript]
[/codeblocks]
Native extensions can alternatively use the [method MultiplayerAPI.set_default_interface] method during initialization to configure themselves as the default implementation.
</description>
<tutorials >
</tutorials>
<methods >
<method name= "_get_multiplayer_peer" qualifiers= "virtual" >
<return type= "MultiplayerPeer" />
<description >
Called when the [member MultiplayerAPI.multiplayer_peer] is retrieved.
</description>
</method>
<method name= "_get_peer_ids" qualifiers= "virtual const" >
<return type= "PackedInt32Array" />
<description >
Callback for [method MultiplayerAPI.get_peers].
</description>
</method>
<method name= "_get_remote_sender_id" qualifiers= "virtual const" >
<return type= "int" />
<description >
Callback for [method MultiplayerAPI.get_remote_sender_id].
</description>
</method>
<method name= "_get_unique_id" qualifiers= "virtual const" >
<return type= "int" />
<description >
Callback for [method MultiplayerAPI.get_unique_id].
</description>
</method>
<method name= "_object_configuration_add" qualifiers= "virtual" >
<return type= "int" />
2022-08-06 20:11:48 +02:00
<param index= "0" name= "object" type= "Object" />
<param index= "1" name= "configuration" type= "Variant" />
2022-07-12 23:12:42 +02:00
<description >
Callback for [method MultiplayerAPI.object_configuration_add].
</description>
</method>
<method name= "_object_configuration_remove" qualifiers= "virtual" >
<return type= "int" />
2022-08-06 20:11:48 +02:00
<param index= "0" name= "object" type= "Object" />
<param index= "1" name= "configuration" type= "Variant" />
2022-07-12 23:12:42 +02:00
<description >
Callback for [method MultiplayerAPI.object_configuration_remove].
</description>
</method>
<method name= "_poll" qualifiers= "virtual" >
<return type= "int" />
<description >
Callback for [method MultiplayerAPI.poll].
</description>
</method>
<method name= "_rpc" qualifiers= "virtual" >
<return type= "int" />
2022-08-06 20:11:48 +02:00
<param index= "0" name= "peer" type= "int" />
<param index= "1" name= "object" type= "Object" />
<param index= "2" name= "method" type= "StringName" />
<param index= "3" name= "args" type= "Array" />
2022-07-12 23:12:42 +02:00
<description >
Callback for [method MultiplayerAPI.rpc].
</description>
</method>
<method name= "_set_multiplayer_peer" qualifiers= "virtual" >
<return type= "void" />
2022-08-06 20:11:48 +02:00
<param index= "0" name= "multiplayer_peer" type= "MultiplayerPeer" />
2022-07-12 23:12:42 +02:00
<description >
Called when the [member MultiplayerAPI.multiplayer_peer] is set.
</description>
</method>
</methods>
</class>