reinstalling GDUnit from assetlib
Some checks failed
Create tag and build when new code gets to main / Export (push) Failing after 6m41s
Some checks failed
Create tag and build when new code gets to main / Export (push) Failing after 6m41s
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
@tool
|
||||
extends Node
|
||||
|
||||
@onready var _server :GdUnitTcpServer = $TcpServer
|
||||
|
||||
|
||||
@warning_ignore("return_value_discarded")
|
||||
func _ready() -> void:
|
||||
var result := _server.start()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
return
|
||||
var server_port :int = result.value()
|
||||
Engine.set_meta("gdunit_server_port", server_port)
|
||||
_server.client_connected.connect(_on_client_connected)
|
||||
_server.client_disconnected.connect(_on_client_disconnected)
|
||||
_server.rpc_data.connect(_receive_rpc_data)
|
||||
GdUnitCommandHandler.instance().gdunit_runner_stop.connect(_on_gdunit_runner_stop)
|
||||
|
||||
|
||||
func _on_client_connected(client_id: int) -> void:
|
||||
GdUnitSignals.instance().gdunit_client_connected.emit(client_id)
|
||||
|
||||
|
||||
func _on_client_disconnected(client_id: int) -> void:
|
||||
GdUnitSignals.instance().gdunit_client_disconnected.emit(client_id)
|
||||
|
||||
|
||||
func _on_gdunit_runner_stop(client_id: int) -> void:
|
||||
if _server:
|
||||
_server.disconnect_client(client_id)
|
||||
|
||||
|
||||
func _receive_rpc_data(p_rpc: RPC) -> void:
|
||||
if p_rpc is RPCMessage:
|
||||
var rpc_message: RPCMessage = p_rpc
|
||||
GdUnitSignals.instance().gdunit_message.emit(rpc_message.message())
|
||||
return
|
||||
if p_rpc is RPCGdUnitEvent:
|
||||
var rpc_event: RPCGdUnitEvent = p_rpc
|
||||
GdUnitSignals.instance().gdunit_event.emit(rpc_event.event())
|
||||
return
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://2pr0fvtay8vf
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cn5mp3tmi2gb1"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdUnit4/src/network/GdUnitServer.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://addons/gdUnit4/src/network/GdUnitTcpServer.gd" id="2"]
|
||||
|
||||
[node name="Control" type="Node"]
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="TcpServer" type="Node" parent="."]
|
||||
script = ExtResource("2")
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class_name GdUnitServerConstants
|
||||
extends RefCounted
|
||||
|
||||
const DEFAULT_SERVER_START_RETRY_TIMES :int = 5
|
||||
const GD_TEST_SERVER_PORT :int = 31002
|
||||
const JSON_RESPONSE_DELIMITER :String = "<<JRD>>"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://eobp360ofaq5
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
class_name GdUnitTask
|
||||
extends RefCounted
|
||||
|
||||
const TASK_NAME = "task_name"
|
||||
const TASK_ARGS = "task_args"
|
||||
|
||||
var _task_name :String
|
||||
var _fref :Callable
|
||||
|
||||
|
||||
func _init(task_name :String,instance :Object,func_name :String) -> void:
|
||||
_task_name = task_name
|
||||
if not instance.has_method(func_name):
|
||||
push_error("Can't create GdUnitTask, Invalid func name '%s' for instance '%s'" % [instance, func_name])
|
||||
_fref = Callable(instance, func_name)
|
||||
|
||||
|
||||
func name() -> String:
|
||||
return _task_name
|
||||
|
||||
|
||||
func execute(args :Array) -> GdUnitResult:
|
||||
if args.is_empty():
|
||||
return _fref.call()
|
||||
return _fref.callv(args)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://t6wuy7w6nlve
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
class_name GdUnitTcpClient
|
||||
extends GdUnitTcpNode
|
||||
|
||||
signal connection_succeeded(message: String)
|
||||
signal connection_failed(message: String)
|
||||
|
||||
|
||||
var _client_name: String
|
||||
var _debug := false
|
||||
var _host: String
|
||||
var _port: int
|
||||
var _client_id: int
|
||||
var _connected: bool
|
||||
var _stream: StreamPeerTCP
|
||||
|
||||
|
||||
func _init(client_name := "GdUnit4 TCP Client", debug := false) -> void:
|
||||
_client_name = client_name
|
||||
_debug = debug
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_connected = false
|
||||
_stream = StreamPeerTCP.new()
|
||||
#_stream.set_big_endian(true)
|
||||
|
||||
|
||||
func stop() -> void:
|
||||
console("Disconnecting from server")
|
||||
if _stream != null:
|
||||
rpc_send(_stream, RPCClientDisconnect.new().with_id(_client_id))
|
||||
if _stream != null:
|
||||
_stream.disconnect_from_host()
|
||||
_connected = false
|
||||
|
||||
|
||||
func start(host: String, port: int) -> GdUnitResult:
|
||||
_host = host
|
||||
_port = port
|
||||
if _connected:
|
||||
return GdUnitResult.warn("Client already connected ... %s:%d" % [_host, _port])
|
||||
|
||||
# Connect client to server
|
||||
if _stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||
var err := _stream.connect_to_host(host, port)
|
||||
#prints("connect_to_host", host, port, err)
|
||||
if err != OK:
|
||||
return GdUnitResult.error("GdUnit4: Can't establish client, error code: %s" % err)
|
||||
return GdUnitResult.success("GdUnit4: Client connected checked port %d" % port)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
match _stream.get_status():
|
||||
StreamPeerTCP.STATUS_NONE:
|
||||
return
|
||||
|
||||
StreamPeerTCP.STATUS_CONNECTING:
|
||||
set_process(false)
|
||||
# wait until client is connected to server
|
||||
for retry in 10:
|
||||
@warning_ignore("return_value_discarded")
|
||||
_stream.poll()
|
||||
console("Waiting to connect ..")
|
||||
if _stream.get_status() == StreamPeerTCP.STATUS_CONNECTING:
|
||||
await get_tree().create_timer(0.500).timeout
|
||||
if _stream.get_status() == StreamPeerTCP.STATUS_CONNECTED:
|
||||
set_process(true)
|
||||
return
|
||||
set_process(true)
|
||||
_stream.disconnect_from_host()
|
||||
console("Connection failed")
|
||||
connection_failed.emit("Connect to TCP Server %s:%d faild!" % [_host, _port])
|
||||
|
||||
StreamPeerTCP.STATUS_CONNECTED:
|
||||
if not _connected:
|
||||
var rpc_data :RPC = null
|
||||
set_process(false)
|
||||
while rpc_data == null:
|
||||
await get_tree().create_timer(0.500).timeout
|
||||
rpc_data = rpc_receive()
|
||||
set_process(true)
|
||||
_client_id = (rpc_data as RPCClientConnect).client_id()
|
||||
console("Connected to Server: %d" % _client_id)
|
||||
connection_succeeded.emit("Connect to TCP Server %s:%d success." % [_host, _port])
|
||||
_connected = true
|
||||
process_rpc()
|
||||
|
||||
StreamPeerTCP.STATUS_ERROR:
|
||||
console("Connection failed")
|
||||
_stream.disconnect_from_host()
|
||||
connection_failed.emit("Connect to TCP Server %s:%d faild!" % [_host, _port])
|
||||
return
|
||||
|
||||
|
||||
func is_client_connected() -> bool:
|
||||
return _connected
|
||||
|
||||
|
||||
func process_rpc() -> void:
|
||||
if _stream.get_available_bytes() > 0:
|
||||
var rpc_data := rpc_receive()
|
||||
if rpc_data is RPCClientDisconnect:
|
||||
stop()
|
||||
|
||||
|
||||
func send(data: RPC) -> void:
|
||||
rpc_send(_stream, data)
|
||||
|
||||
|
||||
func rpc_receive() -> RPC:
|
||||
return receive_packages(_stream).front()
|
||||
|
||||
|
||||
func console(value: Variant) -> void:
|
||||
if _debug:
|
||||
print(_client_name, ": ", value)
|
||||
|
||||
|
||||
func _on_connection_failed(message: String) -> void:
|
||||
console("Connection faild by: " + message)
|
||||
|
||||
|
||||
func _on_connection_succeeded(message: String) -> void:
|
||||
console("Connected: " + message)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://c5dwxfihc8jwp
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
class_name GdUnitTcpNode
|
||||
extends Node
|
||||
|
||||
|
||||
func rpc_send(stream: StreamPeerTCP, data: RPC) -> void:
|
||||
var package_buffer := StreamPeerBuffer.new()
|
||||
var buffer := data.serialize().to_utf16_buffer()
|
||||
package_buffer.put_u32(0xDEADBEEF)
|
||||
package_buffer.put_u32(buffer.size())
|
||||
var status_code := package_buffer.put_data(buffer)
|
||||
if status_code != OK:
|
||||
push_error("'rpc_send:' Can't put_data(), error: %s" % error_string(status_code))
|
||||
return
|
||||
stream.put_data(package_buffer.data_array)
|
||||
|
||||
|
||||
func receive_packages(stream: StreamPeerTCP, rpc_cb: Callable = noop) -> Array[RPC]:
|
||||
var received_packages: Array[RPC] = []
|
||||
var package_buffer := StreamPeerBuffer.new()
|
||||
if stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||
return received_packages
|
||||
|
||||
while stream.get_status() == StreamPeerTCP.STATUS_CONNECTED and stream.get_available_bytes() > 0:
|
||||
var buffer := stream.get_data(8)
|
||||
var status_code: int = buffer[0]
|
||||
if status_code != OK:
|
||||
push_error("'receive_packages:' Can't get_data(%d) for available_bytes, error: %s"
|
||||
% [stream.get_available_bytes(), error_string(status_code)])
|
||||
return received_packages
|
||||
|
||||
var data_package: PackedByteArray
|
||||
package_buffer.data_array = buffer[1]
|
||||
package_buffer.seek(0)
|
||||
|
||||
if package_buffer.get_u32() == 0xDEADBEEF:
|
||||
var size := package_buffer.get_u32()
|
||||
if stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||
return received_packages
|
||||
if stream.get_available_bytes() < size:
|
||||
prints("size check:",
|
||||
package_buffer.get_size(), ":",
|
||||
package_buffer.get_position(),
|
||||
"to read:",
|
||||
size,
|
||||
"available size:",
|
||||
stream.get_available_bytes())
|
||||
push_error("'receive_packages:' Can't receive data get_data(%d) for package, error: %s" % [size, error_string(status_code)])
|
||||
return received_packages
|
||||
|
||||
buffer = stream.get_data(size)
|
||||
package_buffer.data_array = buffer[1]
|
||||
|
||||
var rpc_data := package_buffer.get_data(size)
|
||||
status_code = rpc_data[0]
|
||||
if status_code != OK:
|
||||
push_error("'receive_packages:' Can't get_data(%d) for package, error: %s" % [size, error_string(status_code)])
|
||||
continue
|
||||
data_package = rpc_data[1]
|
||||
else:
|
||||
data_package = buffer[1]
|
||||
|
||||
var json := data_package.get_string_from_utf16()
|
||||
if json.is_empty():
|
||||
push_warning("json is empty, can't process data")
|
||||
continue
|
||||
var data := RPC.deserialize(json)
|
||||
received_packages.append(data)
|
||||
rpc_cb.call(data)
|
||||
return received_packages
|
||||
|
||||
|
||||
static func noop(_rpc_data: RPC) -> void:
|
||||
pass
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://bcywbsdfcc88k
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
@tool
|
||||
class_name GdUnitTcpServer
|
||||
extends Node
|
||||
|
||||
signal client_connected(client_id: int)
|
||||
signal client_disconnected(client_id: int)
|
||||
@warning_ignore("unused_signal")
|
||||
signal rpc_data(rpc_data: RPC)
|
||||
|
||||
var _server: TCPServer
|
||||
var _server_name: String
|
||||
|
||||
class TcpConnection extends GdUnitTcpNode:
|
||||
var _id: int
|
||||
var _stream: StreamPeerTCP
|
||||
|
||||
|
||||
func _init(tcp_server: TCPServer) -> void:
|
||||
_stream = tcp_server.take_connection()
|
||||
#_stream.set_big_endian(true)
|
||||
_id = _stream.get_instance_id()
|
||||
rpc_send(_stream, RPCClientConnect.new().with_id(_id))
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
server().client_connected.emit(_id)
|
||||
|
||||
|
||||
func close() -> void:
|
||||
if _stream != null and _stream.get_status() == StreamPeerTCP.STATUS_CONNECTED:
|
||||
_stream.disconnect_from_host()
|
||||
queue_free()
|
||||
|
||||
|
||||
func id() -> int:
|
||||
return _id
|
||||
|
||||
|
||||
func server() -> GdUnitTcpServer:
|
||||
return get_parent()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _stream == null or _stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||
return
|
||||
receive_packages(_stream, func(rpc_data: RPC) -> void:
|
||||
server().rpc_data.emit(rpc_data)
|
||||
# is client disconnecting we close the server after a timeout of 1 second
|
||||
if rpc_data is RPCClientDisconnect:
|
||||
close()
|
||||
)
|
||||
|
||||
|
||||
func console(_value: Variant) -> void:
|
||||
#print_debug("TCP Server: ", value)
|
||||
pass
|
||||
|
||||
|
||||
func _init(server_name := "GdUnit4 TCP Server") -> void:
|
||||
_server_name = server_name
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_server = TCPServer.new()
|
||||
client_connected.connect(_on_client_connected)
|
||||
client_disconnected.connect(_on_client_disconnected)
|
||||
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_PREDELETE:
|
||||
stop()
|
||||
|
||||
|
||||
func start(server_port := GdUnitServerConstants.GD_TEST_SERVER_PORT) -> GdUnitResult:
|
||||
var err := OK
|
||||
for retry in GdUnitServerConstants.DEFAULT_SERVER_START_RETRY_TIMES:
|
||||
err = _server.listen(server_port, "127.0.0.1")
|
||||
if err != OK:
|
||||
prints("GdUnit4: Can't establish server checked port: %d, Error: %s" % [server_port, error_string(err)])
|
||||
server_port += 1
|
||||
prints("GdUnit4: Retry (%d) ..." % retry)
|
||||
else:
|
||||
break
|
||||
if err != OK:
|
||||
if err == ERR_ALREADY_IN_USE:
|
||||
return GdUnitResult.error("GdUnit4: Can't establish server, the server is already in use. Error: %s, " % error_string(err))
|
||||
return GdUnitResult.error("GdUnit4: Can't establish server. Error: %s." % error_string(err))
|
||||
console("Successfully started checked port: %d" % server_port)
|
||||
return GdUnitResult.success(server_port)
|
||||
|
||||
|
||||
func stop() -> void:
|
||||
if _server:
|
||||
_server.stop()
|
||||
for connection in get_children():
|
||||
if connection is TcpConnection:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
connection.close()
|
||||
remove_child(connection)
|
||||
_server = null
|
||||
|
||||
|
||||
func disconnect_client(client_id: int) -> void:
|
||||
client_disconnected.emit(client_id)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _server != null and not _server.is_listening():
|
||||
return
|
||||
# check if connection is ready to be used
|
||||
if _server != null and _server.is_connection_available():
|
||||
add_child(TcpConnection.new(_server))
|
||||
|
||||
|
||||
func _on_client_connected(client_id: int) -> void:
|
||||
console("Client connected %d" % client_id)
|
||||
|
||||
|
||||
func _on_client_disconnected(client_id: int) -> void:
|
||||
for connection in get_children():
|
||||
@warning_ignore("unsafe_method_access")
|
||||
if connection is TcpConnection and connection.id() == client_id:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
connection.close()
|
||||
remove_child(connection)
|
||||
|
||||
|
||||
func console(value: Variant) -> void:
|
||||
print(_server_name, ": ", value)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dkxh0mktjia50
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
class_name RPC
|
||||
extends RefCounted
|
||||
|
||||
|
||||
var _data: Dictionary = {}
|
||||
|
||||
|
||||
func _init(obj: Object = null) -> void:
|
||||
if obj != null:
|
||||
if obj.has_method("serialize"):
|
||||
_data = obj.call("serialize")
|
||||
else:
|
||||
_data = inst_to_dict(obj)
|
||||
|
||||
|
||||
func get_data() -> Object:
|
||||
return dict_to_inst(_data)
|
||||
|
||||
|
||||
func serialize() -> String:
|
||||
return JSON.stringify(inst_to_dict(self))
|
||||
|
||||
|
||||
# using untyped version see comments below
|
||||
static func deserialize(json_value: String) -> Object:
|
||||
var json := JSON.new()
|
||||
var err := json.parse(json_value)
|
||||
if err != OK:
|
||||
push_error("Can't deserialize JSON, error at line %d:\n error: %s \n json: '%s'"
|
||||
% [json.get_error_line(), json.get_error_message(), json_value])
|
||||
return null
|
||||
var result: Dictionary = json.get_data()
|
||||
if not typeof(result) == TYPE_DICTIONARY:
|
||||
push_error("Can't deserialize JSON. Expecting dictionary, error at line %d:\n error: %s \n json: '%s'"
|
||||
% [result.error_line, result.error_string, json_value])
|
||||
return null
|
||||
return dict_to_inst(result)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cop588f5ov5ul
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://c0nqfpo3y6lkk
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class_name RPCClientDisconnect
|
||||
extends RPC
|
||||
|
||||
var _client_id: int
|
||||
|
||||
|
||||
func with_id(id: int) -> RPCClientDisconnect:
|
||||
_client_id = id
|
||||
return self
|
||||
|
||||
|
||||
func client_id() -> int:
|
||||
return _client_id
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cos6yegplfqxr
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
class_name RPCGdUnitEvent
|
||||
extends RPC
|
||||
|
||||
|
||||
static func of(p_event: GdUnitEvent) -> RPCGdUnitEvent:
|
||||
return RPCGdUnitEvent.new(p_event)
|
||||
|
||||
|
||||
func event() -> GdUnitEvent:
|
||||
return GdUnitEvent.new().deserialize(_data)
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return "RPCGdUnitEvent: " + str(_data)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://b1ocmn5c833kt
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
class_name RPCMessage
|
||||
extends RPC
|
||||
|
||||
var _message: String
|
||||
|
||||
|
||||
static func of(msg :String) -> RPCMessage:
|
||||
var rpc := RPCMessage.new()
|
||||
rpc._message = msg
|
||||
return rpc
|
||||
|
||||
|
||||
func message() -> String:
|
||||
return _message
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return "RPCMessage: " + _message
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://0mpkrrxtbgao
|
||||
|
||||
Reference in New Issue
Block a user