Can only send strings, no support for sending raw bytes
Opened this issue · 5 comments
You must hand the implementation a string instead of a byte buffer, even though the string is converted to a byte buffer immediately.
I can add a function to send a byte array, something like send_lobby_message_as_bytes
but I think most people for lobbies would rather just send a string like it is. If you're planning on doing serious networking with Discord, I'd suggest you fork and try implement the NetworkManager: https://discord.com/developers/docs/game-sdk/networking
Yeah it's not something particularly need, but the option could be nice. I'm making a turn based game so just the lobby networking should be enough but if it isn't I'll be sure to fork.
Yeah it's not something particularly need, but the option could be nice. I'm making a turn based game so just the lobby networking should be enough but if it isn't I'll be sure to fork.
Nice! I only put this together for a godot addon game jam in a couple of days so honestly I'm not sure how solid Discord's service is. Would be cool to see your results.
It seems pretty good, I've been putting together an abstracted network layer to let me easily switch between Godot's built-in stuff and discord API (which would also let me add support for other APIs in the future, like steam or something).
Using the lobby networking is definitely not the fastest but seems pretty performant? I've only tested locally though, I'll post more info when I can test with some other people.
I'll put some info about the abstracted network layer here in case it might help anyone else. The below code should be in an autoload (probably whichever autoload handles networking). Instead of calling rpc("do_thing", input1, input2)
you would call Autoload.custom_rpc("do_thing", self, [input1, input2])
.
Important to note: this implementation has literally no network security. You could remotely call literally any function (even if you didn't put a keyword like puppet
or remotesync
before it). If you're going to use this code in an actual game you're gonna want to add some sort of security.
enum RPC_INPUTS {FUNC_NAME, NODE_PATH, INPUTS, TARGET, SENDER}
enum NET_PROTOCOLS {WEBSOCKET, UDP, DISCORD}
var net_protocol: int = NET_PROTOCOLS.UDP
func custom_rpc(func_name: String, node: Node, inputs: Array) -> void:
var rpc_dict: Dictionary = create_rpc_dict(func_name, node, inputs, rpc_mode)
send_rpc(rpc_dict)
func custom_rpc_id(target_id: int, func_name: String, node: Node, inputs: Array) -> void:
var rpc_dict: Dictionary = create_rpc_dict(func_name, node, inputs, rpc_mode)
rpc_dict[RPC_INPUTS.TARGET] = target_id
send_rpc(rpc_dict)
func send_rpc(rpc_dict: Dictionary) -> void:
var rpc_dict_string: String = var2str(rpc_dict)
match net_protocol:
net_protocols.WEBSOCKET:
rpc("receive_custom_rpc", rpc_dict_string)
net_protocols.UDP:
rpc("receive_custom_rpc", rpc_dict_string)
net_protocols.DISCORD:
# this is where you would tell your discord API to send a message
pass
func create_rpc_dict(func_name: String, node: Node, inputs: Array) -> Dictionary:
var dict: Dictionary = {}
dict[RPC_INPUTS.FUNC_NAME] = func_name
dict[RPC_INPUTS.NODE_PATH] = node.get_path()
dict[RPC_INPUTS.INPUTS] = inputs
dict[RPC_INPUTS.SENDER] = get_my_id()
return dict
remotesync func receive_custom_rpc(rpc_dict_string: String) -> void:
var rpc_dict: Dictionary = str2var(rpc_dict_string)
if RPC_INPUTS.TARGET in rpc_dict:
if get_my_id() != rpc_dict[RPC_INPUTS.TARGET]:
return
rpc_sender_id = rpc_dict[RPC_INPUTS.SENDER]
var node: Node = get_node(rpc_dict[RPC_INPUTS.NODE_PATH])
var func_name: String = rpc_dict[RPC_INPUTS.FUNC_NAME]
var inputs: Array = rpc_dict[RPC_INPUTS.INPUTS]
node.callv(func_name, inputs)