From 05b5a78a6da453e9cb218558105902cb0e655086 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Thu, 1 Dec 2022 12:13:38 -0500 Subject: [PATCH] Add examples --- .../base_systems/godotwebsocket/README.md | 168 +++++++++++++++++- 1 file changed, 166 insertions(+), 2 deletions(-) diff --git a/evennia/contrib/base_systems/godotwebsocket/README.md b/evennia/contrib/base_systems/godotwebsocket/README.md index 92d7b9c089..b3f6abf99d 100644 --- a/evennia/contrib/base_systems/godotwebsocket/README.md +++ b/evennia/contrib/base_systems/godotwebsocket/README.md @@ -35,8 +35,11 @@ and to implement a minimal client. https://docs.godotengine.org/en/stable/tutorials/networking/websocket.html +The rest of this document will be for Godot 3, an example is left at the bottom +of this readme for Godot 4. -Then at the top of the file you must change the url to point at your mud. + +At the top of the file you must change the url to point at your mud. ``` extends Node @@ -122,4 +125,165 @@ you receive, so you can manage the code better. - Sending SaverDicts and similar objects straight from Evennia .DB will cause issues, cast them to dict() or list() before doing so. -- Background colors are only supported by Godot 4. \ No newline at end of file +- Background colors are only supported by Godot 4. + +## Godot 3 Example + +This is an example of a Script to use in Godot 3. +The script can be attached to the root UI node. + +```gdscript +extends Node + +# The URL to connect to, should be your mud. +export var websocket_url = "ws://127.0.0.1:4008" + +# These are references to controls in the scene +onready var parent = get_parent() +onready var label = parent.get_node("%ChatLog") +onready var txtEdit = parent.get_node("%ChatInput") + +onready var room = get_node("/root/World/Room") + +# Our WebSocketClient instance +var _client = WebSocketClient.new() + +var is_connected = false + +func _ready(): + # Connect base signals to get notified of connection open, close, errors and messages + _client.connect("connection_closed", self, "_closed") + _client.connect("connection_error", self, "_closed") + _client.connect("connection_established", self, "_connected") + _client.connect("data_received", self, "_on_data") + print('Ready') + + # Initiate connection to the given URL. + var err = _client.connect_to_url(websocket_url) + if err != OK: + print("Unable to connect") + set_process(false) + +func _closed(was_clean = false): + # was_clean will tell you if the disconnection was correctly notified + # by the remote peer before closing the socket. + print("Closed, clean: ", was_clean) + set_process(false) + +func _connected(proto = ""): + is_connected = true + print("Connected with protocol: ", proto) + +func _on_data(): + # This is called when Godot receives data from evennia + var data = _client.get_peer(1).get_packet().get_string_from_utf8() + var json_data = JSON.parse(data).result + # Here we have the data from Evennia which is an array. + # The first element will be text if it is a message + # and would be the key of the OOB data you passed otherwise. + if json_data[0] == 'text': + # In this case, we simply append the data as bbcode to our label. + for msg in json_data[1]: + label.append_bbcode(msg) + elif json_data[0] == 'coordinates': + # Dummy signal emitted if we wanted to handle the new coordinates + # elsewhere in the project. + self.emit_signal('updated_coordinates', json_data[1]) + + + # We only print this for easier debugging. + print(data) + +func _process(delta): + # Required for websocket to properly react + _client.poll() + +func _on_button_send(): + # This is called when we press the button in the scene + # with a connected signal, it sends the written message to Evennia. + var msg = txtEdit.text + var msg_arr = ['text', [msg], {}] + var msg_str = JSON.print(msg_arr) + _client.get_peer(1).put_packet(msg_str.to_utf8()) + +func _notification(what): + # This is a special method that allows us to notify Evennia we are closing. + if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: + if is_connected: + var msg_arr = ['text', ['quit'], {}] + var msg_str = JSON.print(msg_arr) + _client.get_peer(1).put_packet(msg_str.to_utf8()) + get_tree().quit() # default behavior + +``` + +## Godot 4 Example + +This is an example of a Script to use in Godot 4. +Note that the version is not final so the code may break. +It requires a WebSocketClientNode as a child of the root node. +The script can be attached to the root UI node. + +```gdscript +extends Control + +# The URL to connect to, should be your mud. +var websocket_url = "ws://127.0.0.1:4008" + +# These are references to controls in the scene +@onready +var label: RichTextLabel = get_node("%ChatLog") +@onready +var txtEdit: TextEdit = get_node("%ChatInput") +@onready +var websocket = get_node("WebSocketClient") + +func _ready(): + # We connect the various signals + websocket.connect('connected_to_server', self._connected) + websocket.connect('connection_closed', self._closed) + websocket.connect('message_received', self._on_data) + + # We attempt to connect and print out the error if we have one. + var result = websocket.connect_to_url(websocket_url) + if result != OK: + print('Could not connect:' + str(result)) + + +func _closed(): + # This emits if the connection was closed by the remote host or unexpectedly + print('Connection closed.') + set_process(false) + +func _connected(): + # This emits when the connection succeeds. + print('Connected!') + +func _on_data(data): + # This is called when Godot receives data from evennia + var json_data = JSON.parse_string(data) + # Here we have the data from Evennia which is an array. + # The first element will be text if it is a message + # and would be the key of the OOB data you passed otherwise. + if json_data[0] == 'text': + # In this case, we simply append the data as bbcode to our label. + for msg in json_data[1]: + # Here we include a newline at every message. + label.append_text("\n" + msg) + elif json_data[0] == 'coordinates': + # Dummy signal emitted if we wanted to handle the new coordinates + # elsewhere in the project. + self.emit_signal('updated_coordinates', json_data[1]) + + # We only print this for easier debugging. + print(data) + +func _on_button_pressed(): + # This is called when we press the button in the scene + # with a connected signal, it sends the written message to Evennia. + var msg = txtEdit.text + var msg_arr = ['text', [msg], {}] + var msg_str = JSON.stringify(msg_arr) + websocket.send(msg_str) + +``` \ No newline at end of file