Start of added (more than just a VPN) features.

This commit is contained in:
Scott Duensing 2023-08-27 20:17:49 -05:00
parent 619a7cfdd6
commit 56ddb29c56
8 changed files with 235 additions and 29 deletions

3
.gitignore vendored
View file

@ -1 +1,4 @@
*~
output.log
bin/
hamncheese/export_presets.cfg

3
edit.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
sudo godot/bin/godot.linuxbsd.editor.x86_64 --editor --path hamncheese | tee output.log

View file

@ -1,6 +1,8 @@
extends Control
const SERVER_PORT = 10042
const FILE_ID_SETTINGS = 0
const FILE_ID_EXIT = 2
@ -10,6 +12,7 @@ const HELP_ID_MANUAL = 1
@onready var online_check_button = %OnlineCheckButton
@onready var my_ip_label = %MyIPLabel
@onready var peers_tree = %PeersTree
@onready var settings_window = %SettingsWindow
@onready var user_name_line_edit = %UserNameLineEdit
@ -30,6 +33,45 @@ const HELP_ID_MANUAL = 1
var net;
func _go_offline():
#***TODO*** This can take some time. Show a message.
Peers.stop_server()
net.stop_network()
Peers.clear()
peers_tree.clear()
func _go_online():
net.reset_configuration()
net.set_addresses("" if ip_check_button.button_pressed else ip_line_edit.text, "" if mac_check_button.button_pressed else mac_line_edit.text)
net.set_compression(compression_check_button.button_pressed)
net.set_network(user_name_line_edit.text, network_name_line_edit.text, network_password_line_edit.text)
net.set_supernode(server_line_edit.text, server_port_spin_box.value)
var result = net.start_network()
if result < 0:
# Something is wrong. Cancel starting network.
online_check_button.set_pressed_no_signal(false)
# Tell them what happened.
var message = "An unknown error occurred. Code: " + str(result)
match result:
-1:
message = "Invalid edge confguration."
-2:
message = "Failed to create interface. Are you running as "
if OS.get_name() == "Windows":
message = message + "Administrator?"
else:
message = message + "root?"
-3:
message = "Failed to initialize edge node."
Dialog.alert("Error Starting Network", message)
else:
# Successful connection.
var userInfo = {}
userInfo["user"] = user_name_line_edit.text
Peers.start_server(net.get_ip(), SERVER_PORT, userInfo)
func _notification(what):
# Window manager requested app close.
if what == NOTIFICATION_WM_CLOSE_REQUEST:
@ -52,8 +94,6 @@ func _on_file_id_pressed(id):
FILE_ID_EXIT:
_show_exit_dialog()
#get_tree().root.propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST)
#SceneTree.quit()
func _on_help_id_pressed(id):
@ -78,19 +118,9 @@ func _on_manual_window_close_requested():
func _on_online_check_button_toggled(button_pressed):
# Go online or offline.
if button_pressed:
net.reset_configuration()
net.set_addresses("" if ip_check_button.button_pressed else ip_line_edit.text, "" if mac_check_button.button_pressed else mac_line_edit.text)
net.set_compression(compression_check_button.button_pressed)
net.set_network(user_name_line_edit.text, network_name_line_edit.text, network_password_line_edit.text)
net.set_supernode(server_line_edit.text, server_port_spin_box.value)
var result = net.start_network()
if result < 0:
# Something is wrong. Cancel starting network.
online_check_button.set_pressed_no_signal(false)
# Tell them what happened.
_go_online()
else:
net.stop_network()
_go_offline()
func _on_save_settings_button_pressed():
@ -122,13 +152,17 @@ func _on_timer_timeout():
my_ip_label.text = net.get_ip()
# Update list of known peers.
var peers = net.get_peers()
#for peer in peers:
# print_debug("Type: ", peer["type"], " IP: ", peer["ip"])
if Peers.update(peers):
# Redraw peer tree.
peers_tree.clear()
for peer in Peers.peerArray:
var child = peers_tree.create_item(peers_tree.get_root())
child.set_text(0, peer["user"] + " (" + peer["ip"] + ")")
else:
# Clear network information.
my_ip_label.text = ""
func _ready():
# Get our network object.
net = N2NVPN.new()
@ -175,9 +209,9 @@ func _show_exit_dialog():
var message = "Are you sure you wish to exit?"
if online_check_button.button_pressed:
message = message + "\n\nThis will disconnect you from the network!\n"
var result = await Global.confirm("Exit", message)
var result = await Dialog.confirm("Exit", message)
if result:
if online_check_button.button_pressed:
net.stop_network()
get_tree().quit()
_go_offline()
Engine.get_main_loop().quit()

View file

@ -13,9 +13,11 @@ script = ExtResource("1_ojpam")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 10
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
metadata/_edit_use_anchors_ = true
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
@ -24,6 +26,7 @@ size_flags_vertical = 0
[node name="MenuBar" type="MenuBar" parent="VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 0
[node name="File" type="PopupMenu" parent="VBoxContainer/HBoxContainer/MenuBar"]
@ -43,18 +46,32 @@ item_0/id = 0
item_1/text = "Manual..."
item_1/id = 1
[node name="MyIPLabel" type="Label" parent="VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
horizontal_alignment = 1
[node name="OnlineCheckButton" type="CheckButton" parent="VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
text = "Online"
[node name="MyIPLabel" type="Label" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
horizontal_alignment = 1
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="PeersTree" type="Tree" parent="VBoxContainer/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
hide_folding = true
hide_root = true
[node name="SettingsWindow" type="Window" parent="."]
unique_name_in_owner = true
title = "Settings"

140
hamncheese/peers.gd Normal file
View file

@ -0,0 +1,140 @@
extends Node
var _server := UDPServer.new()
var _userInfo: Dictionary
var _pendingPackets: Array
var _metadataTimer: Timer
# This array is of dictionary elements that contain:
# "online": Will be true except when used to update the array.
# "type": Either "pending" or "known", which is confusing.
# "ip": IP address of this peer.
# "user": User name on this IP.
# "refresh": Do we need to redraw this entry?
var peerArray: Array
func _metadataTimerTimeout():
if _server.is_listening():
var method = {}
# Request updated metadata from everyone on the network.
method["method"] = "query"
for peer in peerArray:
_sendTo(peer["ip"], method)
func _process(_delta):
if _server.is_listening():
# Handle incoming data.
_server.poll()
if _server.is_connection_available():
var client: PacketPeerUDP = _server.take_connection()
var packet = client.get_packet()
var clientIP = client.get_packet_ip()
var raw = packet.get_string_from_utf8()
var jsonIn = JSON.new()
var error = jsonIn.parse(raw)
if error == OK:
# Remote node wants our information.
if jsonIn.data["method"] == "query":
var payload = {}
payload["method"] = "queryResponse"
payload["user"] = _userInfo["user"]
client.put_packet(JSON.stringify(payload).to_utf8_buffer())
# Remote node replied to our query.
if jsonIn.data["method"] == "queryResponse":
for i in range(0, peerArray.size() - 1):
if peerArray[i]["ip"] == clientIP:
peerArray[i]["user"] = jsonIn.data["user"]
peerArray[i]["refresh"] = true
break
client.close()
# Handle outgoing data.
for outbound in _pendingPackets:
var destination := PacketPeerUDP.new()
destination.connect_to_host(outbound["ip"], _server.get_local_port())
destination.put_packet(JSON.stringify(outbound["message"]).to_utf8_buffer())
destination.close()
_pendingPackets.clear()
func _ready():
clear()
_metadataTimer = Timer.new()
_metadataTimer.timeout.connect(_metadataTimerTimeout)
Engine.get_main_loop().current_scene.add_child(_metadataTimer)
_metadataTimer.start(5)
func _sendTo(ipAddress, message):
var pending = {}
pending["ip"] = ipAddress
pending["message"] = message
_pendingPackets.append(pending)
func clear():
peerArray.clear()
func start_server(address, port, userInfo):
_userInfo = userInfo
if !_server.is_listening():
_server.listen(port, address)
_pendingPackets.clear()
func stop_server():
if _server.is_listening():
_server.stop()
func update(peers: Array):
var changed = false
var found
# Mark everyone as offline.
for i in range(0, peerArray.size() - 1):
peerArray[i]["online"] = false
# Now go through everyone we know is connected and mark them online and update their type.
for peerEntry in peers:
found = false
for i in range(0, peerArray.size() - 1):
if peerEntry["ip"] == peerArray[i]["ip"]:
peerArray[i]["online"] = true
if peerArray[i]["type"] != peerEntry["type"]:
peerArray[i]["type"] = peerEntry["type"]
changed = true
found = true
break
# Is this a new entry?
if !found:
var newPeer = peerEntry
# Add all dictionary elements except "ip" and "type".
newPeer["user"] = ""
newPeer["online"] = true
newPeer["refresh"] = false
peerArray.append(newPeer)
changed = true
# Delete everyone that is offline.
found = true
while found:
found = false
for i in range(0, peerArray.size() - 1):
if peerArray[i]["online"] == false:
found = true
peerArray.remove_at(i)
changed = true
break
# Do we need to redraw the list?
for i in range(0, peerArray.size() - 1):
if peerArray[i]["refresh"] == true:
peerArray[i]["refresh"] = false
changed = true
# Did the array change?
return changed

View file

@ -20,7 +20,9 @@ config/icon="res://icon.svg"
[autoload]
Global="*res://global.gd"
Dialog="*res://dialog.gd"
Util="*res://util.gd"
Peers="*res://peers.gd"
[display]

7
hamncheese/util.gd Normal file
View file

@ -0,0 +1,7 @@
extends Node
func delete_children(node):
for n in node.get_children():
node.remove_child(n)
n.queue_free()