mirror of
https://codeberg.org/sunder/sunder.git
synced 2026-07-15 22:14:33 +00:00
first commit 🎉
This commit is contained in:
commit
6e724f67fe
805 changed files with 62098 additions and 0 deletions
|
|
@ -0,0 +1,58 @@
|
|||
# This file is part of sunder.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class_name HostPanel extends MarginContainer
|
||||
|
||||
@export var host_button:Button
|
||||
@export var menu_button:Button
|
||||
@export var quit_button:Button
|
||||
@export var server_host:LineEdit
|
||||
@export var server_port:LineEdit
|
||||
@export var map_selector:OptionButton
|
||||
@export var mode_selector:OptionButton
|
||||
|
||||
var _host:RegEx = RegEx.new()
|
||||
var _port:RegEx = RegEx.new()
|
||||
|
||||
func _ready() -> void:
|
||||
# see https://datatracker.ietf.org/doc/html/rfc1700
|
||||
_port.compile(r'^(?<port>102[4-9]|10[3-9]\d|1[1-9]\d{2}|[2-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])')
|
||||
# "localhost", wildcard or ipv4|6
|
||||
# @TODO: resolve hostname to ip to accept domain names as valid hosts, because host should be ipv4 or ipv6 (see "set_bind_ip")
|
||||
_host.compile(r'^(?<host>localhost|\*|((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-fA-F]|[a-fA-F][a-fA-F0-9\-]*[a-fA-F0-9])\.)*([A-Fa-f]|[A-Fa-f][A-Fa-f0-9\-]*[A-Fa-f0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))))$')
|
||||
|
||||
## This method gets a validated host as specified in the host panel or returns the default one
|
||||
## from configuration if invalid
|
||||
func get_host() -> String:
|
||||
if server_host.text:
|
||||
var result:RegExMatch = _host.search(server_host.text)
|
||||
if result:
|
||||
return result.get_string("host")
|
||||
return Settings.get_value("server", "host", "localhost")
|
||||
|
||||
## This method gets a validated port as specified in the host panel or returns the default one
|
||||
## from configuration if invalid
|
||||
func get_port() -> int:
|
||||
if server_port.text:
|
||||
var result:RegExMatch = _port.search(server_port.text)
|
||||
if result:
|
||||
var port:int = result.get_string("port").to_int()
|
||||
if port != 0:
|
||||
return port
|
||||
return Settings.get_value("server", "port", 9000)
|
||||
|
||||
## This method gets an array of validated host and port as specified in the host panel or
|
||||
## returns an array of default values from configuration if invalid
|
||||
func get_addr() -> Array:
|
||||
return [get_host(), get_port()]
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bcnltcd1jp8l
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://dv0lqek8bqyv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bcnltcd1jp8l" path="res://scenes/interfaces/menus/boot/multiplayer/host_panel/host_panel.gd" id="1_wnvng"]
|
||||
[ext_resource type="Script" uid="uid://f1xvkf1355ie" path="res://scenes/interfaces/menus/boot/multiplayer/host_panel/map_selector.gd" id="2_kwlr3"]
|
||||
[ext_resource type="Script" uid="uid://f0y6q6ml3lk5" path="res://scenes/interfaces/menus/boot/multiplayer/host_panel/mode_selector.gd" id="3_o6ecq"]
|
||||
|
||||
[node name="HostPanel" type="MarginContainer" node_paths=PackedStringArray("host_button", "menu_button", "quit_button", "server_host", "server_port", "map_selector", "mode_selector")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
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
|
||||
script = ExtResource("1_wnvng")
|
||||
host_button = NodePath("HBoxContainer/LeftBox/Top/Host")
|
||||
menu_button = NodePath("HBoxContainer/LeftBox/Bottom/Menu")
|
||||
quit_button = NodePath("HBoxContainer/LeftBox/Bottom/Quit")
|
||||
server_host = NodePath("HBoxContainer/RightBox/GridContainer/ServerHost")
|
||||
server_port = NodePath("HBoxContainer/RightBox/GridContainer/ServerPort")
|
||||
map_selector = NodePath("HBoxContainer/RightBox/GridContainer/MapSelector")
|
||||
mode_selector = NodePath("HBoxContainer/RightBox/GridContainer/ModeSelector")
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="LeftBox" type="VBoxContainer" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 0.25
|
||||
|
||||
[node name="Top" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 0.25
|
||||
|
||||
[node name="Host" type="Button" parent="HBoxContainer/LeftBox/Top"]
|
||||
layout_mode = 2
|
||||
text = "Host"
|
||||
|
||||
[node name="Bottom" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 10
|
||||
|
||||
[node name="Menu" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Main Menu
|
||||
"
|
||||
|
||||
[node name="Quit" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Quit"
|
||||
|
||||
[node name="RightBox" type="VBoxContainer" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="MapPreview" type="ColorRect" parent="HBoxContainer/RightBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="HBoxContainer/RightBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
columns = 2
|
||||
|
||||
[node name="HostLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
custom_minimum_size = Vector2(120, 0)
|
||||
layout_mode = 2
|
||||
text = "Host"
|
||||
|
||||
[node name="ServerHost" type="LineEdit" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
custom_minimum_size = Vector2(120, 0)
|
||||
layout_mode = 2
|
||||
placeholder_text = "localhost"
|
||||
max_length = 128
|
||||
|
||||
[node name="PortLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
text = "Port"
|
||||
|
||||
[node name="ServerPort" type="LineEdit" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
placeholder_text = "9000"
|
||||
alignment = 2
|
||||
|
||||
[node name="MapLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
text = "Map"
|
||||
|
||||
[node name="MapSelector" type="OptionButton" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
clip_text = true
|
||||
allow_reselect = true
|
||||
script = ExtResource("2_kwlr3")
|
||||
|
||||
[node name="ModeLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
text = "Mode"
|
||||
|
||||
[node name="ModeSelector" type="OptionButton" parent="HBoxContainer/RightBox/GridContainer"]
|
||||
layout_mode = 2
|
||||
script = ExtResource("3_o6ecq")
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# This file is part of sunder.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
extends OptionButton
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
for map:PackedScene in Game.maps:
|
||||
add_item(map._bundled.names[0])
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://f1xvkf1355ie
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# This file is part of sunder.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
extends OptionButton
|
||||
|
||||
func format(enum_key: String) -> String:
|
||||
# split enum value by underscores
|
||||
var words:PackedStringArray = enum_key.split("_")
|
||||
# capitalize first letter of each word
|
||||
for i in range(words.size()):
|
||||
words[i] = words[i].capitalize()
|
||||
# join words with spaces
|
||||
return " ".join(words)
|
||||
|
||||
func _ready() -> void:
|
||||
for mode:Mode in Match.modes:
|
||||
add_item(format(mode.name.to_upper()))
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://f0y6q6ml3lk5
|
||||
Loading…
Add table
Add a link
Reference in a new issue