hamncheese/hamncheese/Scripts/main.gd
2023-09-30 19:40:07 -05:00

198 lines
5.7 KiB
GDScript

#
# Ham'n'Cheese
# Copyright (C) 2023-2024 Scott Duensing <scott@kangaroopunch.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
#
# Things to do:
# - Get the rest of the edge settings into the dialog.
# - Rearrange settings dialog into simple/advanced.
# - Find non-sleazy way to handle registry editing for file access on Windows.
# - Crazy amount of other stuff.
#
# Issues to watch:
# - https://github.com/ntop/n2n/issues/1090 (P2P connections still occupy server traffic)
# - https://github.com/ntop/n2n/issues/1087 (Slow shutdown on Windows)
# - https://github.com/ntop/n2n/issues/1082 (A large ping value every 20 seconds)
# - https://github.com/ntop/n2n/issues/610 (n2nGaming Application?)
# - https://github.com/ntop/n2n/issues/934 (Upnp is missing)
#
extends Control
const FILE_ID_SETTINGS = 0
const FILE_ID_EXIT = 2
const HELP_ID_ABOUT = 0
const HELP_ID_MANUAL = 1
const BUTTON_CHAT = 1
@onready var online_check_button = %OnlineCheckButton
@onready var my_ip_label = %MyIPLabel
@onready var peers_tree = %PeersTree
var _ip := ""
func _clear_ui():
my_ip_label.text = ""
if peers_tree.get_root() != null:
peers_tree.clear()
func _data_recieved(type, data):
#print(type, ": ", data)
if type == "info":
_ip = data[0]["ip4addr"]
my_ip_label.text = _ip
if !Peers.is_running():
Peers.start_server(_ip, Settings.mesh_port_spin_box.value, Settings.user_name_line_edit.text, Settings.uuid)
if type == "edges":
if Peers.update(data):
_draw_tree()
# Handle empty peer list.
if data.size() == 0 and peers_tree.get_root() != null:
peers_tree.clear()
func _draw_tree():
# Redraw peer tree.
var icon_chat = load("res://Art/chat-circle-dots-fill.svg")
peers_tree.clear()
peers_tree.columns = 1
var root = peers_tree.create_item()
for peer in Peers.peerArray:
if peer["online"] or true:
var debug = str(peer["online"]) + " "
if peer["tcp"] == null:
debug = debug + "NULL"
else:
match peer["tcp"].get_status():
StreamPeerTCP.STATUS_NONE:
debug = debug + "None"
StreamPeerTCP.STATUS_CONNECTING:
debug = debug + "Connecting"
StreamPeerTCP.STATUS_CONNECTED:
debug = debug + "Connected " + peer["tcp"].get_connected_host()
StreamPeerTCP.STATUS_ERROR:
debug = debug + "Error"
_:
debug = debug + "Unknown"
var child = peers_tree.create_item(root)
child.set_meta("peer", peer["uuid"])
child.set_text(0, peer["user"] + " (" + peer["ip"] + ") " + debug)
child.add_button(0, icon_chat, BUTTON_CHAT)
func _go_offline():
if Peers.is_running():
Peers.stop_server()
Edge.stop_edge()
_clear_ui()
func _network_died():
if Peers.is_running():
Peers.stop_server()
online_check_button.set_pressed_no_signal(false)
_clear_ui()
await Dialog.alert("Error", "The network layer unexpectedly stopped.")
func _notification(what):
if what == NOTIFICATION_WM_CLOSE_REQUEST:
_show_exit_dialog()
func _on_file_id_pressed(id):
match id:
FILE_ID_SETTINGS:
Settings.settings_window.visible = true
Settings.settings_window.move_to_foreground()
FILE_ID_EXIT:
_show_exit_dialog()
func _on_help_id_pressed(id):
match id:
HELP_ID_MANUAL:
Manual.manual_window.visible = true
Manual.manual_window.move_to_foreground()
HELP_ID_ABOUT:
About.about_window.visible = true
About.about_window.move_to_foreground()
func _on_online_check_button_toggled(toggled_on):
if toggled_on:
Edge.bind("" if Settings.vpn_bind_check_button.is_pressed else Settings.vpn_bind_line_edit.text, Settings.listening_port_spin_box.value)
Edge.set_network(Settings.network_name_line_edit.text, Settings.network_password_line_edit.text)
Edge.set_supernode(Settings.server_line_edit.text, Settings.server_port_spin_box.value)
Edge.set_management(Settings.management_port_spin_box.value, Settings.management_port_spin_box.value + 1)
if await Edge.start_edge() == false:
online_check_button.set_pressed_no_signal(false)
else:
_go_offline()
func _on_peers_tree_button_clicked(item, _column, id, mouse_button_index):
# Handle left click.
if mouse_button_index == 1:
if id == BUTTON_CHAT:
Chat.open(item.get_meta("peer"))
func _ready():
About.about_window.visible = false
Manual.manual_window.visible = false
Settings.startup()
Process.startup(Settings.management_port_spin_box.value + 2)
Peers.startup()
Chat.startup()
# If we're on Windows, be sure we're running as Administrator.
# This is going to bork up network shares later.
if OS.get_name() == "Windows":
if !Process.is_elevated():
Process.elevate(OS.get_executable_path())
_shutdown()
Edge.startup()
Edge.data_recieved.connect(_data_recieved)
Edge.network_died.connect(_network_died)
Chat.open(null) # Debug
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 Dialog.confirm("Exit", message)
if result:
_shutdown()
func _shutdown():
if online_check_button.button_pressed:
_go_offline()
Process.shutdown()
Edge.shutdown()
Engine.get_main_loop().quit()