Inital commit

main
copygirl 4 weeks ago
commit e484ab331b
  1. 16
      README.md
  2. 71
      copySocket.gd
  3. 1
      copySocket.gd.uid
  4. 6
      copySocket.tscn
  5. 1
      description.txt
  6. 34
      send.gd
  7. 1
      send.gd.uid

@ -0,0 +1,16 @@
# copySocket
.. is a simple [SnekStudio] module that hosts a WebSocket server to receive hardcoded commands to affect certain things within SnekStudio from the outside. When added, it hosts a server at `ws://127.0.0.1:13981`.
The included `send.gd` script may be used to send commands if another utility is not available, however it takes a small amount of time to start up. The following example makes the `CameraPositions` mod switch to "Camera 1".
```sh
# --headless - Don't create a window.
# -q/--quiet - Only print errors.
# -s <script> - Run a specific script.
godot --headless -q -s path/to/send.gd -- camera 1
```
If the Godot Editor is not available, the SnekStudio binary can be used in its place.
[SnekStudio]: https://github.com/ExpiredPopsicle/SnekStudio

@ -0,0 +1,71 @@
extends Mod_Base
static var NUMBER_REGEX := RegEx.create_from_string("^\\d+$")
var server: TCPServer
var peers: Dictionary[WebSocketPeer, int]
func _ready() -> void:
server = TCPServer.new()
server.listen(13981, "127.0.0.1")
func _exit_tree() -> void:
server.stop()
for peer in peers:
peer.close()
server = null
peers.clear()
func _process(_delta: float) -> void:
# Accept new connections.
while server.is_connection_available():
var conn := server.take_connection()
if not conn: break
var socket := WebSocketPeer.new()
# socket.supported_protocols = []
socket.accept_stream(conn)
socket.set_no_delay(true)
peers.set(socket, Time.get_ticks_msec())
var to_remove: Array[WebSocketPeer]
for peer in peers:
peer.poll()
# Receive messages.
while peer.get_available_packet_count():
var packet := peer.get_packet()
if not peer.was_string_packet(): continue # ignore binary packets
var message := packet.get_string_from_utf8()
_on_websocket_message(peer, message)
# Remove the peer if it's disconnected.
if peer.get_ready_state() != WebSocketPeer.STATE_OPEN:
to_remove.append(peer)
# Remove the peer if it's been around for over 0.5 seconds.
if Time.get_ticks_msec() - peers[peer] > 500:
to_remove.append(peer)
# Clear out disconnected peers.
for peer in to_remove:
peers.erase(peer)
func _on_websocket_message(peer: WebSocketPeer, message: String) -> void:
if message.begins_with("camera "):
var index := message.substr("camera ".length())
if NUMBER_REGEX.search(index) and int(index):
var camera_mod := get_node("../CameraPositions")
if camera_mod:
camera_mod._load_camera_position("Camera " + index);
else:
print_log("mod with index 'CameraPositions' not found")
else:
print_log("invalid camera index: " + index)
else:
print_log("unknown command: " + message)
# Process only one message, then disconnect.
peer.close()

@ -0,0 +1 @@
uid://dme7c7r7w85pq

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://0lluarde7l2e"]
[ext_resource type="Script" uid="uid://dme7c7r7w85pq" path="res://Mods/copySocket/copySocket.gd" id="1_yclwn"]
[node name="copySocket" type="Node3D"]
script = ExtResource("1_yclwn")

@ -0,0 +1 @@
Hosts a WebSocket server to receive commands.

@ -0,0 +1,34 @@
extends SceneTree
func _init() -> void:
var socket = WebSocketPeer.new()
# socket.supported_protocols = []
socket.connect_to_url("ws://127.0.0.1:13981")
socket.set_no_delay(true)
# Wait up to 1 second for the socket to connect.
_wait_until_not(socket, WebSocketPeer.STATE_CONNECTING)
if socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
push_error("could not connect"); quit(1); return
var message := ""
for arg in OS.get_cmdline_user_args():
if not message.is_empty(): message += " "
# TODO: Escape (and handle) quote characters?
# Surround empty string and those that contain spaces with quotes.
if arg.is_empty() or arg.contains(" "): arg = "\"" + arg + "\""
message += arg
socket.send_text(message)
# Wait up to 1 second for the socket to close.
# This ensures the message makes it through.
_wait_until_not(socket, WebSocketPeer.STATE_OPEN)
quit()
## Waits up to the specified amount for the socket to NOT be in the given state any longer.
func _wait_until_not(socket: WebSocketPeer, state: int, msec := 1000) -> void:
var start := Time.get_ticks_msec()
while socket.get_ready_state() == state:
if Time.get_ticks_msec() - start > msec: return
socket.poll() # Update websocket state.

@ -0,0 +1 @@
uid://bdcatr7rg0gld
Loading…
Cancel
Save