Rolling my own ENet mesh network.
This commit is contained in:
parent
ea991ab816
commit
b72ddcbed1
7 changed files with 78 additions and 86 deletions
|
@ -13,25 +13,25 @@ func _accepted():
|
||||||
_dialog.queue_free()
|
_dialog.queue_free()
|
||||||
_result = true
|
_result = true
|
||||||
emit_signal("_dialog_closed")
|
emit_signal("_dialog_closed")
|
||||||
|
|
||||||
|
|
||||||
func _canceled():
|
func _canceled():
|
||||||
_dialog.queue_free()
|
_dialog.queue_free()
|
||||||
_result = false
|
_result = false
|
||||||
emit_signal("_dialog_closed")
|
emit_signal("_dialog_closed")
|
||||||
|
|
||||||
|
|
||||||
func _closed():
|
func _closed():
|
||||||
_dialog.queue_free()
|
_dialog.queue_free()
|
||||||
emit_signal("_dialog_closed")
|
emit_signal("_dialog_closed")
|
||||||
|
|
||||||
|
|
||||||
func _submitted(_text: String):
|
func _submitted(_text: String):
|
||||||
_dialog.queue_free()
|
_dialog.queue_free()
|
||||||
_result = true
|
_result = true
|
||||||
emit_signal("_dialog_closed")
|
emit_signal("_dialog_closed")
|
||||||
|
|
||||||
|
|
||||||
func alert(title: String, text: String, parent: Node = null):
|
func alert(title: String, text: String, parent: Node = null):
|
||||||
_dialog = AcceptDialog.new()
|
_dialog = AcceptDialog.new()
|
||||||
_dialog.dialog_text = text
|
_dialog.dialog_text = text
|
||||||
|
|
|
@ -75,8 +75,8 @@ func start_edge(community: String, key: String, supernode: String, port: int = 7
|
||||||
Engine.get_main_loop().current_scene.add_child(_timer)
|
Engine.get_main_loop().current_scene.add_child(_timer)
|
||||||
_timer.timeout.emit()
|
_timer.timeout.emit()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
func stop_edge():
|
func stop_edge():
|
||||||
if _timer != null:
|
if _timer != null:
|
||||||
_timer.queue_free()
|
_timer.queue_free()
|
||||||
|
|
|
@ -34,6 +34,12 @@ const HELP_ID_MANUAL = 1
|
||||||
var _ip := ""
|
var _ip := ""
|
||||||
|
|
||||||
|
|
||||||
|
func _clear_ui():
|
||||||
|
my_ip_label.text = ""
|
||||||
|
if peers_tree.get_root() != null:
|
||||||
|
peers_tree.clear()
|
||||||
|
|
||||||
|
|
||||||
func _data_recieved(type, data):
|
func _data_recieved(type, data):
|
||||||
#print(type, ": ", data)
|
#print(type, ": ", data)
|
||||||
if type == "info":
|
if type == "info":
|
||||||
|
@ -51,7 +57,7 @@ func _data_recieved(type, data):
|
||||||
var root = peers_tree.create_item()
|
var root = peers_tree.create_item()
|
||||||
for peer in Peers.peerArray:
|
for peer in Peers.peerArray:
|
||||||
var child = peers_tree.create_item(root)
|
var child = peers_tree.create_item(root)
|
||||||
child.set_text(0, peer["user"] + " (" + peer["ip"] + ")")
|
child.set_text(0, peer["user"] + " (" + peer["ip"] + ") " + str(peer["ping"]) + "ms")
|
||||||
# Handle empty peer list.
|
# Handle empty peer list.
|
||||||
if data.size() == 0 and peers_tree.get_root() != null:
|
if data.size() == 0 and peers_tree.get_root() != null:
|
||||||
peers_tree.clear()
|
peers_tree.clear()
|
||||||
|
@ -61,22 +67,21 @@ func _go_offline():
|
||||||
if Peers.is_running():
|
if Peers.is_running():
|
||||||
Peers.stop_server()
|
Peers.stop_server()
|
||||||
Edge.stop_edge()
|
Edge.stop_edge()
|
||||||
my_ip_label.text = ""
|
_clear_ui()
|
||||||
if peers_tree.get_root() != null:
|
|
||||||
peers_tree.clear()
|
|
||||||
|
|
||||||
|
|
||||||
func _network_died():
|
func _network_died():
|
||||||
if Peers.is_running():
|
if Peers.is_running():
|
||||||
Peers.stop_server()
|
Peers.stop_server()
|
||||||
online_check_button.set_pressed_no_signal(false)
|
online_check_button.set_pressed_no_signal(false)
|
||||||
|
_clear_ui()
|
||||||
await Dialog.alert("Error", "The network layer unexpectedly stopped.")
|
await Dialog.alert("Error", "The network layer unexpectedly stopped.")
|
||||||
|
|
||||||
|
|
||||||
func _notification(what):
|
func _notification(what):
|
||||||
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
||||||
_show_exit_dialog()
|
_show_exit_dialog()
|
||||||
|
|
||||||
|
|
||||||
func _on_file_id_pressed(id):
|
func _on_file_id_pressed(id):
|
||||||
match id:
|
match id:
|
||||||
|
|
|
@ -7,7 +7,6 @@ const ENET_SERVICE_EVENT_DATA = 2
|
||||||
const ENET_SERVICE_EVENT_CHANNEL = 3
|
const ENET_SERVICE_EVENT_CHANNEL = 3
|
||||||
|
|
||||||
|
|
||||||
var _enet := ENetMultiplayerPeer.new()
|
|
||||||
var _basePort: int
|
var _basePort: int
|
||||||
var _serverRunning: bool
|
var _serverRunning: bool
|
||||||
|
|
||||||
|
@ -45,20 +44,9 @@ var _userInfo: Dictionary
|
||||||
var peerArray: Array
|
var peerArray: Array
|
||||||
|
|
||||||
|
|
||||||
func _peer_connected(id):
|
|
||||||
print("Peer %d connected" % id)
|
|
||||||
|
|
||||||
|
|
||||||
func _peer_disconnected(id):
|
|
||||||
print("Peer %d disconnected" % id)
|
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if _serverRunning:
|
if _serverRunning:
|
||||||
#_process_enet(_userInfo["enet"], _userInfo["id"])
|
_process_enet(_userInfo["enet"], _userInfo["id"])
|
||||||
for peer in peerArray:
|
|
||||||
_process_enet(peer["enet"], peer["id"])
|
|
||||||
_enet.poll()
|
|
||||||
|
|
||||||
|
|
||||||
func _process_enet(host: ENetConnection, id: int):
|
func _process_enet(host: ENetConnection, id: int):
|
||||||
|
@ -67,87 +55,84 @@ func _process_enet(host: ENetConnection, id: int):
|
||||||
var ret = host.service() # Returns an array of ENET_SERVICE_* items.
|
var ret = host.service() # Returns an array of ENET_SERVICE_* items.
|
||||||
match ret[ENET_SERVICE_EVENT_TYPE]:
|
match ret[ENET_SERVICE_EVENT_TYPE]:
|
||||||
host.EVENT_CONNECT:
|
host.EVENT_CONNECT:
|
||||||
print("Adding host %d" % id)
|
print("Peer connected ", id, " (", host.get_peers().size(), " known peers)")
|
||||||
_enet.add_mesh_peer(id, host)
|
#var enet_peers = host.get_peers()
|
||||||
|
#for enet_peer in enet_peers:
|
||||||
|
|
||||||
host.EVENT_DISCONNECT:
|
host.EVENT_DISCONNECT:
|
||||||
print("Mesh peer disconnected %d" % id)
|
print("Peer disconnected ", id, " (", host.get_peers().size(), " known peers)")
|
||||||
host = null
|
|
||||||
|
|
||||||
host.EVENT_ERROR:
|
host.EVENT_ERROR:
|
||||||
print("Mesh peer error %d" % id)
|
print("Peer error ", id, " (", host.get_peers().size(), " known peers)")
|
||||||
host = null
|
|
||||||
#***TODO*** Attempt disconnect/reconnect
|
#***TODO*** Attempt disconnect/reconnect
|
||||||
|
|
||||||
host.EVENT_NONE:
|
host.EVENT_NONE:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
host.EVENT_RECEIVE:
|
host.EVENT_RECEIVE:
|
||||||
print("Mesh peer recieved data %d" % id)
|
print("Peer recieved data ", id, " (", host.get_peers().size(), " known peers)")
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_serverRunning = false
|
_serverRunning = false
|
||||||
clear()
|
clear()
|
||||||
multiplayer.peer_connected.connect(_peer_connected)
|
|
||||||
multiplayer.peer_disconnected.connect(_peer_disconnected)
|
|
||||||
|
|
||||||
|
|
||||||
func _sort_by_ip(a, b):
|
func _sort_by_ip(a, b):
|
||||||
# Sort numerically.
|
# Sort numerically.
|
||||||
if Util.ip_string_to_int(a["ip"]) < Util.ip_string_to_int(b["ip"]):
|
if Util.ip_string_to_int(a["ip"]) < Util.ip_string_to_int(b["ip"]):
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
func clear():
|
func clear():
|
||||||
peerArray.clear()
|
peerArray.clear()
|
||||||
|
|
||||||
|
|
||||||
func is_running():
|
func is_running():
|
||||||
return _serverRunning
|
return _serverRunning
|
||||||
|
|
||||||
|
|
||||||
func start_server(address, portStart, user, uuid):
|
func start_server(address, portStart, user, uuid):
|
||||||
clear()
|
if !_serverRunning:
|
||||||
_basePort = portStart
|
clear()
|
||||||
_userInfo["ip"] = address
|
_basePort = portStart
|
||||||
_userInfo["user"] = user
|
_userInfo["ip"] = address
|
||||||
_userInfo["uuid"] = uuid
|
_userInfo["user"] = user
|
||||||
_userInfo["id"] = _userInfo["ip"].get_slice(".", 3).to_int() # Use last octet for our ID.
|
_userInfo["uuid"] = uuid
|
||||||
_userInfo["port"] = _basePort + _userInfo["id"]
|
_userInfo["id"] = _userInfo["ip"].get_slice(".", 3).to_int() # Use last octet for our ID.
|
||||||
# Create mesh network.
|
_userInfo["port"] = _basePort + _userInfo["id"]
|
||||||
_enet.create_mesh(_userInfo["id"])
|
# Set up our listening port.
|
||||||
multiplayer.set_multiplayer_peer(_enet)
|
_userInfo["enet"] = ENetConnection.new()
|
||||||
# Set up our listening port.
|
_userInfo["enet"].create_host_bound(_userInfo["ip"], _userInfo["port"], 256, 0)
|
||||||
_userInfo["enet"] = ENetConnection.new()
|
_serverRunning = true
|
||||||
_userInfo["enet"].create_host_bound(_userInfo["ip"], _userInfo["port"], 256, 0)
|
|
||||||
_serverRunning = true
|
|
||||||
|
|
||||||
|
|
||||||
func stop_server():
|
func stop_server():
|
||||||
# Tear down network.
|
if _serverRunning:
|
||||||
_serverRunning = false
|
# Tear down network.
|
||||||
multiplayer.set_multiplayer_peer(null)
|
_serverRunning = false
|
||||||
|
_userInfo["enet"].flush()
|
||||||
|
_userInfo["enet"].destroy()
|
||||||
|
|
||||||
|
|
||||||
func update(peersFromCPP: Array):
|
func update(peersFromCPP: Array):
|
||||||
var found
|
var found
|
||||||
var changed = false
|
var changed = false
|
||||||
var oldArray: Array = []
|
var oldArray: Array = []
|
||||||
|
|
||||||
if !_serverRunning:
|
if !_serverRunning:
|
||||||
return
|
return
|
||||||
|
|
||||||
#print("\nPeers Raw: ", peersFromCPP)
|
#print("\nPeers Raw: ", peersFromCPP)
|
||||||
#print("Peers Before: ", peerArray)
|
#print("Peers Before: ", peerArray)
|
||||||
|
|
||||||
# Remember what we started with.
|
# Remember what we started with.
|
||||||
oldArray = peerArray.duplicate(true)
|
oldArray = peerArray.duplicate(true)
|
||||||
|
|
||||||
# Start a new peer list.
|
# Start a new peer list.
|
||||||
peerArray.clear()
|
peerArray.clear()
|
||||||
|
|
||||||
# Add everyone connected.
|
# Add everyone connected.
|
||||||
for peerCPP in peersFromCPP:
|
for peerCPP in peersFromCPP:
|
||||||
# Get an IP without netmask.
|
# Get an IP without netmask.
|
||||||
|
@ -158,19 +143,22 @@ func update(peersFromCPP: Array):
|
||||||
if oldPeer["ip"] == peerCPP["ip"]:
|
if oldPeer["ip"] == peerCPP["ip"]:
|
||||||
found = true
|
found = true
|
||||||
peerCPP = oldPeer
|
peerCPP = oldPeer
|
||||||
|
# Update peer statistics. ***TODO*** These do not set 'changed' and are not refreshed.
|
||||||
|
if typeof(peerCPP["enet"]) == TYPE_OBJECT:
|
||||||
|
if peerCPP["enet"].get_state() == ENetPacketPeer.STATE_CONNECTED:
|
||||||
|
peerCPP["ping"] = peerCPP["enet"].get_statistic(ENetPacketPeer.PEER_ROUND_TRIP_TIME)
|
||||||
if !found:
|
if !found:
|
||||||
# We didn't have them. Add needed records.
|
# We didn't have them. Add needed records.
|
||||||
peerCPP["user"] = ""
|
peerCPP["user"] = ""
|
||||||
peerCPP["uuid"] = ""
|
peerCPP["uuid"] = ""
|
||||||
peerCPP["online"] = true
|
peerCPP["online"] = true
|
||||||
peerCPP["refresh"] = false
|
peerCPP["refresh"] = false
|
||||||
|
peerCPP["ping"] = 0.0
|
||||||
changed = true
|
changed = true
|
||||||
# Also create the ENet connection to them.
|
# Also create the ENet connection to them.
|
||||||
peerCPP["id"] = peerCPP["ip"].get_slice(".", 3).to_int() # Use last octet for our ID.
|
peerCPP["id"] = peerCPP["ip"].get_slice(".", 3).to_int() # Use last octet for our ID.
|
||||||
peerCPP["port"] = _basePort + peerCPP["ip"].get_slice(".", 3).to_int()
|
peerCPP["port"] = _basePort + peerCPP["ip"].get_slice(".", 3).to_int()
|
||||||
peerCPP["enet"] = ENetConnection.new()
|
peerCPP["enet"] = _userInfo["enet"].connect_to_host(peerCPP["ip"], peerCPP["port"], 0)
|
||||||
peerCPP["enet"].create_host(1)
|
|
||||||
peerCPP["enet"].connect_to_host(peerCPP["ip"], peerCPP["port"], 0)
|
|
||||||
print("Connecting to ", peerCPP["ip"], ":", peerCPP["port"])
|
print("Connecting to ", peerCPP["ip"], ":", peerCPP["port"])
|
||||||
# Sometimes the CPP code will return duplicates. Check.
|
# Sometimes the CPP code will return duplicates. Check.
|
||||||
# Also check if we need to redraw anyone.
|
# Also check if we need to redraw anyone.
|
||||||
|
@ -181,7 +169,7 @@ func update(peersFromCPP: Array):
|
||||||
if peer["refresh"] == true:
|
if peer["refresh"] == true:
|
||||||
peer["refresh"] = false
|
peer["refresh"] = false
|
||||||
changed = true
|
changed = true
|
||||||
|
|
||||||
# Add them to the new list.
|
# Add them to the new list.
|
||||||
peerArray.append(peerCPP)
|
peerArray.append(peerCPP)
|
||||||
|
|
||||||
|
@ -189,5 +177,5 @@ func update(peersFromCPP: Array):
|
||||||
peerArray.sort_custom(_sort_by_ip)
|
peerArray.sort_custom(_sort_by_ip)
|
||||||
|
|
||||||
#print("Peers After: ", peerArray)
|
#print("Peers After: ", peerArray)
|
||||||
|
|
||||||
return changed
|
return changed
|
||||||
|
|
|
@ -28,7 +28,7 @@ func _elevate_unix(program: String, arguments: PackedStringArray):
|
||||||
|
|
||||||
func _elevate_windows(program: String, arguments: PackedStringArray):
|
func _elevate_windows(program: String, arguments: PackedStringArray):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if _udp.is_listening():
|
if _udp.is_listening():
|
||||||
|
@ -49,15 +49,14 @@ func elevate(program: String, arguments: PackedStringArray):
|
||||||
return await _elevate_windows(program, arguments)
|
return await _elevate_windows(program, arguments)
|
||||||
else:
|
else:
|
||||||
return await _elevate_unix(program, arguments)
|
return await _elevate_unix(program, arguments)
|
||||||
|
|
||||||
|
|
||||||
func shutdown():
|
func shutdown():
|
||||||
_udp.stop()
|
_udp.stop()
|
||||||
if FileAccess.file_exists(_ask_pass_script):
|
if FileAccess.file_exists(_ask_pass_script):
|
||||||
print("Removing ", _ask_pass_script)
|
|
||||||
DirAccess.remove_absolute(_ask_pass_script)
|
DirAccess.remove_absolute(_ask_pass_script)
|
||||||
|
|
||||||
|
|
||||||
func startup(port: int = 19999):
|
func startup(port: int = 19999):
|
||||||
_ask_pass_port = port
|
_ask_pass_port = port
|
||||||
_udp.listen(_ask_pass_port, "127.0.0.1")
|
_udp.listen(_ask_pass_port, "127.0.0.1")
|
||||||
|
|
|
@ -55,8 +55,8 @@ func load_settings():
|
||||||
compression_check_button.button_pressed = config.get_value("settings", "compression", true)
|
compression_check_button.button_pressed = config.get_value("settings", "compression", true)
|
||||||
auto_start_check_button.button_pressed = config.get_value("settings", "autoStart", false)
|
auto_start_check_button.button_pressed = config.get_value("settings", "autoStart", false)
|
||||||
uuid = config.get_value("settings", "identity", Uuid.v4())
|
uuid = config.get_value("settings", "identity", Uuid.v4())
|
||||||
|
|
||||||
|
|
||||||
func save_settings():
|
func save_settings():
|
||||||
# Validate IP address, if needed.
|
# Validate IP address, if needed.
|
||||||
if !ip_check_button.button_pressed:
|
if !ip_check_button.button_pressed:
|
||||||
|
@ -90,7 +90,7 @@ func save_settings():
|
||||||
#config.set_value("settings", "position", DisplayServer.window_get_position())
|
#config.set_value("settings", "position", DisplayServer.window_get_position())
|
||||||
config.set_value("settings", "identity", uuid)
|
config.set_value("settings", "identity", uuid)
|
||||||
config.save("user://network.cfg")
|
config.save("user://network.cfg")
|
||||||
|
|
||||||
|
|
||||||
func _on_ip_check_button_toggled(_toggled_on):
|
func _on_ip_check_button_toggled(_toggled_on):
|
||||||
ip_line_edit.editable = !ip_check_button.button_pressed
|
ip_line_edit.editable = !ip_check_button.button_pressed
|
||||||
|
|
|
@ -36,7 +36,7 @@ func _deep_equal_one_way(a, b):
|
||||||
return a == b
|
return a == b
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
func deep_equal(a, b):
|
func deep_equal(a, b):
|
||||||
return _deep_equal_one_way(a, b) && _deep_equal_one_way(b, a)
|
return _deep_equal_one_way(a, b) && _deep_equal_one_way(b, a)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func generate_password(length: int = 16):
|
||||||
for i in range(length):
|
for i in range(length):
|
||||||
password += alpha_num[randi() % len(alpha_num)]
|
password += alpha_num[randi() % len(alpha_num)]
|
||||||
return password
|
return password
|
||||||
|
|
||||||
|
|
||||||
func ip_string_to_int(ip: String):
|
func ip_string_to_int(ip: String):
|
||||||
var result = 0
|
var result = 0
|
||||||
|
|
Loading…
Add table
Reference in a new issue