diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/.gdignore b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/.gdignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/.gdignore @@ -0,0 +1 @@ + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.md5 b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.md5 new file mode 100644 index 0000000..c9de266 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.md5 @@ -0,0 +1,3 @@ +source_md5="79d2b9a5284e50d91a97c2dd565f2fa4" +dest_md5="41051ec7a940540d8c9badbd43d2180f" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.stex b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.stex new file mode 100644 index 0000000..2c93d01 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.stex differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.md5 b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.md5 new file mode 100644 index 0000000..f561f81 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.md5 @@ -0,0 +1,3 @@ +source_md5="13a1e728def8fb06bd8e797fcc392604" +dest_md5="254ea3ed3a62b36ab206f320d0c51637" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.stex b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.stex new file mode 100644 index 0000000..1b1d9c3 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.stex differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.md5 b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.md5 new file mode 100644 index 0000000..e5616f9 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.md5 @@ -0,0 +1,3 @@ +source_md5="266f789a4e895911161321092c2c2429" +dest_md5="505d2398da99764a2e0cc067ba291aa1" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.stex b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.stex new file mode 100644 index 0000000..f3be71b Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-bf78baa5e40d24f1836aa08964398dec.stex differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.md5 b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.md5 new file mode 100644 index 0000000..e5616f9 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.md5 @@ -0,0 +1,3 @@ +source_md5="266f789a4e895911161321092c2c2429" +dest_md5="505d2398da99764a2e0cc067ba291aa1" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.stex b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.stex new file mode 100644 index 0000000..f3be71b Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.stex differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 new file mode 100644 index 0000000..5328bc7 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 @@ -0,0 +1,3 @@ +source_md5="47313fa4c47a9963fddd764e1ec6e4a8" +dest_md5="26ea799ea0a3da9e753b3ebe822e0570" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex new file mode 100644 index 0000000..71f6913 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.gd new file mode 100644 index 0000000..bb9bd06 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.gd @@ -0,0 +1,16 @@ +extends Control + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# pass diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.tscn new file mode 100644 index 0000000..8bbe135 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/MenuScreen.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://userInterface/But_Quit.tscn" type="PackedScene" id=1] +[ext_resource path="res://userInterface/But_ChangeScene.tscn" type="PackedScene" id=2] + +[node name="MenuScreen" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="Background" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -119.0 +margin_top = -152.0 +margin_right = 65.0 +margin_bottom = -91.0 +rect_scale = Vector2( 1.04675, 1.07389 ) + +[node name="But_ChangeScene" parent="VBoxContainer" instance=ExtResource( 2 )] +margin_right = 184.0 +margin_bottom = 37.0 +text = "Test Postgres" +next_scene_path = "res://screens/DBTest_Postgres.tscn" + +[node name="But_Quit" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 41.0 +margin_right = 184.0 +margin_bottom = 61.0 + +[node name="Version" type="Label" parent="."] +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = -177.0 +margin_top = -44.0 +margin_right = -5.0 +margin_bottom = -6.0 +text = "Version: 0.0.0" +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png new file mode 100644 index 0000000..85723f8 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png.import b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png.import new file mode 100644 index 0000000..d4f170f --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_black.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Backgrounds/Background_black.png" +dest_files=[ "res://.import/Background_black.png-56039c85507f66e5b636dc3622fcd7f0.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png new file mode 100644 index 0000000..62c3a55 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png.import b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png.import new file mode 100644 index 0000000..5619f68 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/Background_white.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Backgrounds/Background_white.png" +dest_files=[ "res://.import/Background_white.png-90278c2837a8c1d366dff638eb6d5498.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png new file mode 100644 index 0000000..1ac5ed2 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png.import b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png.import new file mode 100644 index 0000000..a337825 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Backgrounds/background_demo.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Backgrounds/background_demo.png" +dest_files=[ "res://.import/background_demo.png-e30ac367b3596013bad15f6d4bbea075.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Bold.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Bold.ttf new file mode 100644 index 0000000..db3d6f3 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Bold.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-BoldItalic.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-BoldItalic.ttf new file mode 100644 index 0000000..8b21277 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-BoldItalic.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Italic.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Italic.ttf new file mode 100644 index 0000000..768b833 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Italic.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Regular.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Regular.ttf new file mode 100644 index 0000000..6fa9a59 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/LiberationSerif-Regular.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/l_10646.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/l_10646.ttf new file mode 100644 index 0000000..afb1c60 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/Fonts_source/l_10646.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicFont_BIG.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicFont_BIG.tres new file mode 100644 index 0000000..a2e2de7 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicFont_BIG.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/l_10646.ttf" type="DynamicFontData" id=1] + +[resource] +size = 42 +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont.tres new file mode 100644 index 0000000..63243b4 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/l_10646.ttf" type="DynamicFontData" id=1] + +[resource] +size = 24 +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont_16.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont_16.tres new file mode 100644 index 0000000..f9acb20 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/base_dynamicfont_16.tres @@ -0,0 +1,6 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/l_10646.ttf" type="DynamicFontData" id=1] + +[resource] +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/l_10646.ttf b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/l_10646.ttf new file mode 100644 index 0000000..afb1c60 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/l_10646.ttf differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif.tres new file mode 100644 index 0000000..051bc09 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif.tres @@ -0,0 +1,6 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/Fonts_source/LiberationSerif-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_20pt.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_20pt.tres new file mode 100644 index 0000000..2953618 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_20pt.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/Fonts_source/LiberationSerif-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 20 +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_30pt.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_30pt.tres new file mode 100644 index 0000000..6297862 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_30pt.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/Fonts_source/LiberationSerif-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 30 +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_40pt.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_40pt.tres new file mode 100644 index 0000000..229621e --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/liberation_serif_40pt.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://assets/Fonts_source/LiberationSerif-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 40 +font_data = ExtResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_black.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_black.tres new file mode 100644 index 0000000..859abe4 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_black.tres @@ -0,0 +1,9 @@ +[gd_resource type="StyleBoxFlat" format=2] + +[resource] +bg_color = Color( 0, 0, 0, 1 ) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color( 0, 0, 0, 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_white.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_white.tres new file mode 100644 index 0000000..418e195 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/sbf_white.tres @@ -0,0 +1,9 @@ +[gd_resource type="StyleBoxFlat" format=2] + +[resource] +bg_color = Color( 1, 1, 1, 1 ) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color( 1, 1, 1, 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_dark_theme.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_dark_theme.tres new file mode 100644 index 0000000..38a6ae1 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_dark_theme.tres @@ -0,0 +1,120 @@ +[gd_resource type="Theme" load_steps=5 format=2] + +[ext_resource path="res://assets/sbf_black.tres" type="StyleBox" id=1] +[ext_resource path="res://assets/liberation_serif_30pt.tres" type="DynamicFont" id=2] +[ext_resource path="res://assets/liberation_serif_20pt.tres" type="DynamicFont" id=3] +[ext_resource path="res://assets/liberation_serif.tres" type="DynamicFont" id=4] + +[resource] +Button/colors/font_color = Color( 1, 1, 1, 1 ) +Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Button/colors/font_color_hover = Color( 0.94, 0.94, 0.94, 1 ) +Button/colors/font_color_pressed = Color( 1, 1, 1, 1 ) +Button/constants/hseparation = 2 +Button/fonts/font = ExtResource( 2 ) +Button/styles/disabled = null +Button/styles/focus = null +Button/styles/hover = null +Button/styles/normal = ExtResource( 1 ) +Button/styles/pressed = ExtResource( 1 ) +ItemList/colors/font_color = Color( 1, 1, 1, 1 ) +ItemList/colors/font_color_selected = Color( 1, 1, 1, 1 ) +ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 ) +ItemList/constants/hseparation = 4 +ItemList/constants/icon_margin = 4 +ItemList/constants/line_separation = 2 +ItemList/constants/vseparation = 2 +ItemList/fonts/font = ExtResource( 3 ) +ItemList/styles/bg = ExtResource( 1 ) +ItemList/styles/bg_focus = ExtResource( 1 ) +ItemList/styles/cursor = null +ItemList/styles/cursor_unfocused = ExtResource( 1 ) +ItemList/styles/selected = null +ItemList/styles/selected_focus = null +Label/colors/font_color = Color( 1, 1, 1, 1 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 0 ) +Label/colors/font_outline_modulate = Color( 1, 1, 1, 1 ) +Label/constants/line_spacing = 3 +Label/constants/shadow_as_outline = 0 +Label/constants/shadow_offset_x = 1 +Label/constants/shadow_offset_y = 1 +Label/fonts/font = ExtResource( 3 ) +Label/styles/normal = ExtResource( 1 ) +LineEdit/colors/clear_button_color = Color( 0.88, 0.88, 0.88, 1 ) +LineEdit/colors/clear_button_color_pressed = Color( 1, 1, 1, 1 ) +LineEdit/colors/cursor_color = Color( 0.94, 0.94, 0.94, 1 ) +LineEdit/colors/font_color = Color( 1, 1, 1, 1 ) +LineEdit/colors/font_color_selected = Color( 1, 1, 1, 1 ) +LineEdit/colors/font_color_uneditable = Color( 0.88, 0.88, 0.88, 0.5 ) +LineEdit/colors/selection_color = Color( 0.49, 0.49, 0.49, 1 ) +LineEdit/constants/minimum_spaces = 12 +LineEdit/fonts/font = null +LineEdit/icons/clear = null +LineEdit/styles/focus = null +LineEdit/styles/normal = ExtResource( 1 ) +LineEdit/styles/read_only = null +MarginContainer/constants/margin_bottom = 0 +MarginContainer/constants/margin_left = 0 +MarginContainer/constants/margin_right = 0 +MarginContainer/constants/margin_top = 0 +Panel/styles/panel = ExtResource( 1 ) +PanelContainer/styles/panel = ExtResource( 1 ) +Tabs/colors/font_color_bg = Color( 1, 1, 1, 1 ) +Tabs/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Tabs/colors/font_color_fg = Color( 1, 1, 1, 1 ) +Tabs/constants/hseparation = 4 +Tabs/constants/label_valign_bg = 2 +Tabs/constants/label_valign_fg = 0 +Tabs/constants/top_margin = 24 +Tabs/fonts/font = ExtResource( 3 ) +Tabs/icons/close = null +Tabs/icons/decrement = null +Tabs/icons/decrement_highlight = null +Tabs/icons/increment = null +Tabs/icons/increment_highlight = null +Tabs/styles/button = ExtResource( 1 ) +Tabs/styles/button_pressed = null +Tabs/styles/panel = ExtResource( 1 ) +Tabs/styles/tab_bg = ExtResource( 1 ) +Tabs/styles/tab_disabled = null +Tabs/styles/tab_fg = ExtResource( 1 ) +TextEdit/colors/background_color = Color( 1, 1, 1, 1 ) +TextEdit/colors/bookmark_color = Color( 0.08, 0.49, 0.98, 1 ) +TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 ) +TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 ) +TextEdit/colors/caret_background_color = Color( 0, 0, 0, 1 ) +TextEdit/colors/caret_color = Color( 0.88, 0.88, 0.88, 1 ) +TextEdit/colors/code_folding_color = Color( 0.8, 0.8, 0.8, 0.8 ) +TextEdit/colors/completion_background_color = Color( 0.17, 0.16, 0.2, 1 ) +TextEdit/colors/completion_existing_color = Color( 0.87, 0.87, 0.87, 0.13 ) +TextEdit/colors/completion_font_color = Color( 0.67, 0.67, 0.67, 1 ) +TextEdit/colors/completion_scroll_color = Color( 1, 1, 1, 1 ) +TextEdit/colors/completion_selected_color = Color( 0.26, 0.26, 0.27, 1 ) +TextEdit/colors/current_line_color = Color( 0.25, 0.25, 0.26, 0.8 ) +TextEdit/colors/executing_line_color = Color( 0.2, 0.8, 0.2, 0.4 ) +TextEdit/colors/font_color = Color( 1, 1, 1, 1 ) +TextEdit/colors/font_color_readonly = Color( 0.933333, 0.933333, 0.933333, 0.501961 ) +TextEdit/colors/font_color_selected = Color( 1, 1, 1, 1 ) +TextEdit/colors/function_color = Color( 0.4, 0.64, 0.81, 1 ) +TextEdit/colors/line_number_color = Color( 0.67, 0.67, 0.67, 0.4 ) +TextEdit/colors/mark_color = Color( 1, 0.4, 0.4, 0.4 ) +TextEdit/colors/member_variable_color = Color( 0.9, 0.31, 0.35, 1 ) +TextEdit/colors/number_color = Color( 0.92, 0.58, 0.2, 1 ) +TextEdit/colors/safe_line_number_color = Color( 0.67, 0.78, 0.67, 0.6 ) +TextEdit/colors/selection_color = Color( 0.49, 0.49, 0.49, 1 ) +TextEdit/colors/symbol_color = Color( 0.94, 0.94, 0.94, 1 ) +TextEdit/colors/word_highlighted_color = Color( 0.8, 0.9, 0.9, 0.15 ) +TextEdit/constants/completion_lines = 7 +TextEdit/constants/completion_max_width = 50 +TextEdit/constants/completion_scroll_width = 3 +TextEdit/constants/line_spacing = 4 +TextEdit/fonts/font = ExtResource( 4 ) +TextEdit/icons/fold = null +TextEdit/icons/folded = null +TextEdit/icons/space = null +TextEdit/icons/tab = null +TextEdit/styles/completion = ExtResource( 1 ) +TextEdit/styles/focus = ExtResource( 1 ) +TextEdit/styles/normal = ExtResource( 1 ) +TextEdit/styles/read_only = ExtResource( 1 ) +VBoxContainer/constants/separation = 4 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_light_theme.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_light_theme.tres new file mode 100644 index 0000000..7fcfd40 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/assets/ui_controlNode_light_theme.tres @@ -0,0 +1,120 @@ +[gd_resource type="Theme" load_steps=5 format=2] + +[ext_resource path="res://assets/sbf_white.tres" type="StyleBox" id=1] +[ext_resource path="res://assets/liberation_serif_30pt.tres" type="DynamicFont" id=2] +[ext_resource path="res://assets/liberation_serif_20pt.tres" type="DynamicFont" id=3] +[ext_resource path="res://assets/liberation_serif.tres" type="DynamicFont" id=4] + +[resource] +Button/colors/font_color = Color( 0, 0, 0, 1 ) +Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Button/colors/font_color_hover = Color( 0.94, 0.94, 0.94, 1 ) +Button/colors/font_color_pressed = Color( 1, 1, 1, 1 ) +Button/constants/hseparation = 2 +Button/fonts/font = ExtResource( 2 ) +Button/styles/disabled = null +Button/styles/focus = null +Button/styles/hover = null +Button/styles/normal = ExtResource( 1 ) +Button/styles/pressed = ExtResource( 1 ) +ItemList/colors/font_color = Color( 0, 0, 0, 1 ) +ItemList/colors/font_color_selected = Color( 1, 1, 1, 1 ) +ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 ) +ItemList/constants/hseparation = 4 +ItemList/constants/icon_margin = 4 +ItemList/constants/line_separation = 2 +ItemList/constants/vseparation = 2 +ItemList/fonts/font = null +ItemList/styles/bg = ExtResource( 1 ) +ItemList/styles/bg_focus = ExtResource( 1 ) +ItemList/styles/cursor = null +ItemList/styles/cursor_unfocused = ExtResource( 1 ) +ItemList/styles/selected = null +ItemList/styles/selected_focus = null +Label/colors/font_color = Color( 0, 0, 0, 1 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 0 ) +Label/colors/font_outline_modulate = Color( 1, 1, 1, 1 ) +Label/constants/line_spacing = 3 +Label/constants/shadow_as_outline = 0 +Label/constants/shadow_offset_x = 1 +Label/constants/shadow_offset_y = 1 +Label/fonts/font = ExtResource( 3 ) +Label/styles/normal = ExtResource( 1 ) +LineEdit/colors/clear_button_color = Color( 0.88, 0.88, 0.88, 1 ) +LineEdit/colors/clear_button_color_pressed = Color( 1, 1, 1, 1 ) +LineEdit/colors/cursor_color = Color( 0.94, 0.94, 0.94, 1 ) +LineEdit/colors/font_color = Color( 0, 0, 0, 1 ) +LineEdit/colors/font_color_selected = Color( 0, 0, 0, 1 ) +LineEdit/colors/font_color_uneditable = Color( 0.88, 0.88, 0.88, 0.5 ) +LineEdit/colors/selection_color = Color( 0.49, 0.49, 0.49, 1 ) +LineEdit/constants/minimum_spaces = 12 +LineEdit/fonts/font = null +LineEdit/icons/clear = null +LineEdit/styles/focus = null +LineEdit/styles/normal = ExtResource( 1 ) +LineEdit/styles/read_only = null +MarginContainer/constants/margin_bottom = 0 +MarginContainer/constants/margin_left = 0 +MarginContainer/constants/margin_right = 0 +MarginContainer/constants/margin_top = 0 +Panel/styles/panel = ExtResource( 1 ) +PanelContainer/styles/panel = ExtResource( 1 ) +Tabs/colors/font_color_bg = Color( 0, 0, 0, 1 ) +Tabs/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Tabs/colors/font_color_fg = Color( 0, 0, 0, 1 ) +Tabs/constants/hseparation = 4 +Tabs/constants/label_valign_bg = 2 +Tabs/constants/label_valign_fg = 0 +Tabs/constants/top_margin = 24 +Tabs/fonts/font = ExtResource( 3 ) +Tabs/icons/close = null +Tabs/icons/decrement = null +Tabs/icons/decrement_highlight = null +Tabs/icons/increment = null +Tabs/icons/increment_highlight = null +Tabs/styles/button = ExtResource( 1 ) +Tabs/styles/button_pressed = null +Tabs/styles/panel = ExtResource( 1 ) +Tabs/styles/tab_bg = ExtResource( 1 ) +Tabs/styles/tab_disabled = null +Tabs/styles/tab_fg = ExtResource( 1 ) +TextEdit/colors/background_color = Color( 1, 1, 1, 1 ) +TextEdit/colors/bookmark_color = Color( 0.08, 0.49, 0.98, 1 ) +TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 ) +TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 ) +TextEdit/colors/caret_background_color = Color( 0, 0, 0, 1 ) +TextEdit/colors/caret_color = Color( 0.88, 0.88, 0.88, 1 ) +TextEdit/colors/code_folding_color = Color( 0.8, 0.8, 0.8, 0.8 ) +TextEdit/colors/completion_background_color = Color( 0.17, 0.16, 0.2, 1 ) +TextEdit/colors/completion_existing_color = Color( 0.87, 0.87, 0.87, 0.13 ) +TextEdit/colors/completion_font_color = Color( 0.67, 0.67, 0.67, 1 ) +TextEdit/colors/completion_scroll_color = Color( 1, 1, 1, 1 ) +TextEdit/colors/completion_selected_color = Color( 0.26, 0.26, 0.27, 1 ) +TextEdit/colors/current_line_color = Color( 0.25, 0.25, 0.26, 0.8 ) +TextEdit/colors/executing_line_color = Color( 0.2, 0.8, 0.2, 0.4 ) +TextEdit/colors/font_color = Color( 0.00392157, 0.00392157, 0.00392157, 1 ) +TextEdit/colors/font_color_readonly = Color( 0.0588235, 0.0588235, 0.0588235, 0.501961 ) +TextEdit/colors/font_color_selected = Color( 0, 0, 0, 1 ) +TextEdit/colors/function_color = Color( 0.4, 0.64, 0.81, 1 ) +TextEdit/colors/line_number_color = Color( 0.67, 0.67, 0.67, 0.4 ) +TextEdit/colors/mark_color = Color( 1, 0.4, 0.4, 0.4 ) +TextEdit/colors/member_variable_color = Color( 0.9, 0.31, 0.35, 1 ) +TextEdit/colors/number_color = Color( 0.92, 0.58, 0.2, 1 ) +TextEdit/colors/safe_line_number_color = Color( 0.67, 0.78, 0.67, 0.6 ) +TextEdit/colors/selection_color = Color( 0.49, 0.49, 0.49, 1 ) +TextEdit/colors/symbol_color = Color( 0.94, 0.94, 0.94, 1 ) +TextEdit/colors/word_highlighted_color = Color( 0.8, 0.9, 0.9, 0.15 ) +TextEdit/constants/completion_lines = 7 +TextEdit/constants/completion_max_width = 50 +TextEdit/constants/completion_scroll_width = 3 +TextEdit/constants/line_spacing = 4 +TextEdit/fonts/font = ExtResource( 4 ) +TextEdit/icons/fold = null +TextEdit/icons/folded = null +TextEdit/icons/space = null +TextEdit/icons/tab = null +TextEdit/styles/completion = ExtResource( 1 ) +TextEdit/styles/focus = ExtResource( 1 ) +TextEdit/styles/normal = ExtResource( 1 ) +TextEdit/styles/read_only = ExtResource( 1 ) +VBoxContainer/constants/separation = 4 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/default_env.tres b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="ProceduralSky" id=1] + +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/export_presets.cfg b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/export_presets.cfg new file mode 100644 index 0000000..da2c105 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/export_presets.cfg @@ -0,0 +1,34 @@ +[preset.0] + +name="HTML5" +platform="HTML5" +runnable=true +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="../../Godot_Outputs/Godot_35_Outputs/Web/BaseTest/index.html" +script_export_mode=1 +script_encryption_key="" + +[preset.0.options] + +custom_template/debug="" +custom_template/release="" +variant/export_type=0 +vram_texture_compression/for_desktop=true +vram_texture_compression/for_mobile=false +html/export_icon=true +html/custom_html_shell="" +html/head_include="" +html/canvas_resize_policy=2 +html/focus_canvas_on_start=true +html/experimental_virtual_keyboard=false +progressive_web_app/enabled=false +progressive_web_app/offline_page="" +progressive_web_app/display=1 +progressive_web_app/orientation=0 +progressive_web_app/icon_144x144="" +progressive_web_app/icon_180x180="" +progressive_web_app/icon_512x512="" +progressive_web_app/background_color=Color( 0, 0, 0, 1 ) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png new file mode 100644 index 0000000..c98fbb6 Binary files /dev/null and b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png differ diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png.import b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png.import new file mode 100644 index 0000000..a4c02e6 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/icon.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/project.godot b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/project.godot new file mode 100644 index 0000000..150b594 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/project.godot @@ -0,0 +1,46 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ { +"base": "PanelContainer", +"class": "Locale", +"language": "GDScript", +"path": "res://userInterface/Locale.gd" +}, { +"base": "Object", +"class": "PostgreSQLClient", +"language": "GDScript", +"path": "res://screens/PostgreSQLClient.gd" +} ] +_global_script_class_icons={ +"Locale": "", +"PostgreSQLClient": "" +} + +[application] + +config/name="Database_Testing" +run/main_scene="res://MenuScreen.tscn" +config/icon="res://icon.png" + +[gui] + +common/drop_mouse_on_gui_input_disabled=true + +[physics] + +common/enable_pause_aware_picking=true + +[rendering] + +quality/driver/driver_name="GLES2" +vram_compression/import_etc=true +vram_compression/import_etc2=false +environment/default_environment="res://default_env.tres" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/But_HistoryPager.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/But_HistoryPager.gd new file mode 100644 index 0000000..a5e1b2f --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/But_HistoryPager.gd @@ -0,0 +1,13 @@ +#BUT_HISTORYPAGER: +# Iterates the page number and calls HistoryViewer script to display +# stored page and response fro the history array +# + +extends Button + +onready var historyViewerScript = get_node("/root/HistoryViewer") + +#DKM TEMP: this needs refactoring -- too much being calculated as needed/repeated +func _on_But_HistoryPager_button_up() -> void: + historyViewerScript.update_pager() + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.gd new file mode 100644 index 0000000..bc9d1b2 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.gd @@ -0,0 +1,22 @@ +#CHARACTER_ADD: +# Script for adding a new character and both saving it to file and loading +# it into the character object + +extends Control + +onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance + +func _ready() -> void: + theme=load(settings.themeFile) + $Title/But_SaveChar.grab_focus() + +func _on_But_SaveChar_pressed() -> void: + $Title/FileDialog.popup() + +#DKM TEMP: just text for now from text edit +func _on_FileDialog_file_selected(path: String) -> void: + var pc = get_node("/root/PlayerCharacter") + var newCharFile = File.new() + newCharFile.open(path, 2) + newCharFile.store_string($TextEdit.text) + pc.playerCharacterSingleton.pcText = $TextEdit.text diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.tscn new file mode 100644 index 0000000..96473c7 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Add.tscn @@ -0,0 +1,171 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://userInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://userInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/Character_Add.gd" type="Script" id=3] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="TextEdit" type="TextEdit" parent="."] +margin_left = 215.0 +margin_top = 23.0 +margin_right = 997.0 +margin_bottom = 447.0 + +[node name="Title" parent="." instance=ExtResource( 1 )] +anchor_left = 0.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 0.0 +margin_top = 0.0 +margin_right = 0.0 +margin_bottom = 0.0 +text = "Create Character (temp)" + +[node name="But_SaveChar" type="Button" parent="Title"] +margin_right = 12.0 +margin_bottom = 20.0 +text = "Save Character" + +[node name="But_ChangeScene" parent="Title" instance=ExtResource( 2 )] +margin_left = -1.0 +margin_top = 48.0 +margin_right = 142.0 +margin_bottom = 72.0 +text = "Temp: Main Menu" +next_scene_path = "res://screens/MenuScreen.tscn" + +[node name="But_StartNewGame" parent="Title" instance=ExtResource( 2 )] +margin_top = 98.0 +margin_right = 159.0 +margin_bottom = 122.0 +text = "Temp: Start New Game" + +[node name="FileDialog" type="FileDialog" parent="Title"] +margin_left = 164.0 +margin_top = 35.0 +margin_right = 741.0 +margin_bottom = 426.0 +rect_min_size = Vector2( 400, 140 ) +access = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="Title"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -20.0 +margin_top = 50.0 +margin_right = 20.0 +margin_bottom = 140.0 + +[node name="LabelName" type="Label" parent="Title/VBoxContainer"] +margin_right = 81.0 +margin_bottom = 31.0 +text = "NAME +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelName"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelProfession" type="Label" parent="Title/VBoxContainer"] +margin_top = 35.0 +margin_right = 81.0 +margin_bottom = 66.0 +text = "PROFESSION +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelProfession"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelStrength" type="Label" parent="Title/VBoxContainer"] +margin_top = 70.0 +margin_right = 81.0 +margin_bottom = 101.0 +text = "STRENGTH +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelStrength"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelIntellect" type="Label" parent="Title/VBoxContainer"] +margin_top = 105.0 +margin_right = 81.0 +margin_bottom = 136.0 +text = "INTELLECT +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelIntellect"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelWillpower" type="Label" parent="Title/VBoxContainer"] +margin_top = 140.0 +margin_right = 81.0 +margin_bottom = 171.0 +text = "WILLPOWER +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelWillpower"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelCharm" type="Label" parent="Title/VBoxContainer"] +margin_top = 175.0 +margin_right = 81.0 +margin_bottom = 189.0 +text = "CHARM" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelCharm"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelWeapon" type="Label" parent="Title/VBoxContainer"] +margin_top = 193.0 +margin_right = 81.0 +margin_bottom = 224.0 +text = "WEAPON +" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelWeapon"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelArmor" type="Label" parent="Title/VBoxContainer"] +margin_top = 228.0 +margin_right = 81.0 +margin_bottom = 242.0 +text = "ARMOR" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelArmor"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[node name="LabelQuote" type="Label" parent="Title/VBoxContainer"] +margin_top = 246.0 +margin_right = 81.0 +margin_bottom = 260.0 +text = "QUOTE" + +[node name="LineEdit" type="LineEdit" parent="Title/VBoxContainer/LabelQuote"] +margin_top = 15.0 +margin_right = 58.0 +margin_bottom = 24.0 + +[connection signal="pressed" from="Title/But_SaveChar" to="." method="_on_But_SaveChar_pressed"] +[connection signal="file_selected" from="Title/FileDialog" to="." method="_on_FileDialog_file_selected"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.gd new file mode 100644 index 0000000..ad6681d --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.gd @@ -0,0 +1,24 @@ +#CHARACTER_LOAD: +# Script for loading a character file into the character object from file + +extends Control + +onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance + +func _ready() -> void: + theme=load(settings.themeFile) + $Title/But_loadCharacter.grab_focus() + + +func _on_But_loadCharacter_pressed() -> void: + $LoadCharacter_FileDialog.popup() + + +#DKM TEMP: we need to load the character item, not display to field +func _on_LoadCharacter_FileDialog_file_selected(path: String) -> void: + print(path) + var charFile = File.new() + charFile.open(path, 1) + var pc = get_node("/root/PlayerCharacter") + pc.playerCharacterSingleton.pcText = charFile.get_as_text() + $TextEdit.text = pc.playerCharacterSingleton.pcText diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.tscn new file mode 100644 index 0000000..38038a2 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Character_Load.tscn @@ -0,0 +1,70 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://userInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://userInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/Character_Load.gd" type="Script" id=3] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="TextEdit" type="TextEdit" parent="."] +margin_left = 189.0 +margin_top = 18.0 +margin_right = 989.0 +margin_bottom = 461.0 +readonly = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" parent="." instance=ExtResource( 1 )] +anchor_left = 0.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 0.0 +margin_top = 0.0 +margin_right = 0.0 +margin_bottom = 0.0 +text = "Load Character (temp)" + +[node name="But_loadCharacter" type="Button" parent="Title"] +margin_left = 22.0 +margin_top = 34.0 +margin_right = 155.0 +margin_bottom = 54.0 +text = "Load Character File" + +[node name="But_StartNewGame" parent="Title" instance=ExtResource( 2 )] +margin_left = 22.0 +margin_top = 71.0 +margin_right = 181.0 +margin_bottom = 95.0 +text = "Temp: Start New Game" + +[node name="But_ChangeScene" parent="Title" instance=ExtResource( 2 )] +margin_left = 21.0 +margin_top = 109.0 +margin_right = 164.0 +margin_bottom = 133.0 +text = "Temp: Main Menu " + +[node name="LoadCharacter_FileDialog" type="FileDialog" parent="."] +margin_left = 193.0 +margin_top = 33.0 +margin_right = 862.0 +margin_bottom = 409.0 +rect_min_size = Vector2( 400, 140 ) +window_title = "Open a File" +mode = 0 +access = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="pressed" from="Title/But_loadCharacter" to="." method="_on_But_loadCharacter_pressed"] +[connection signal="file_selected" from="LoadCharacter_FileDialog" to="." method="_on_LoadCharacter_FileDialog_file_selected"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.gd new file mode 100644 index 0000000..a45394c --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.gd @@ -0,0 +1,82 @@ +extends Node + +var database := PostgreSQLClient.new() + +#TODO: ADD RELEVANT VALUES BELOW FOR TESTING! +const USER = ''#"postgres" +const PASSWORD = '' +const HOST = ''#"localhost" +const PORT = 5432 # Default postgres port +const DATABASE = ''#"postgres" + + + +func _ready() -> void: + print("Test is running") + +func _init() -> void: + print("Init running") + var _error := database.connect("connection_established", self, "_executer") + _error = database.connect("authentication_error", self, "_authentication_error") + _error = database.connect("connection_closed", self, "_close") + + #Connection to the database + _error = database.connect_to_host("postgresql://%s:%s@%s:%d/%s" % [USER, PASSWORD, HOST, PORT, DATABASE]) + + +func _physics_process(_delta: float) -> void: + print("Physics running") + database.poll() + + +func _authentication_error(error_object: Dictionary) -> void: + prints("Error connection to database:", error_object["message"]) + + +func _executer() -> void: + print("Executor running") + print(database.parameter_status) + +# var datas := database.execute(""" +# BEGIN; +# /*Helloworld*/ +# SELECT concat('Hello', 'World'); +# COMMIT; +# """) + + var datas := database.execute(""" + BEGIN; + SELECT * FROM characters; + COMMIT; + """) + + + + #The datas variable contains an array of PostgreSQLQueryResult object. + for data in datas: + #Specifies the number of fields in a row (can be zero). + print(data.number_of_fields_in_a_row) + + # This is usually a single word that identifies which SQL command was completed. + # note: the "BEGIN" and "COMMIT" commands return empty values + print(data.command_tag) + + print(data.row_description) + + print(data.data_row) + + prints("Notice:", data.notice) + + if not database.error_object.empty(): + prints("Error:", database.error_object) + + database.close() + + +func _close(clean_closure := true) -> void: + prints("DB CLOSE,", "Clean closure:", clean_closure) + + +func _exit_tree() -> void: + print("Exit running") + database.close() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.tscn new file mode 100644 index 0000000..e54e935 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/DBTest_Postgres.tscn @@ -0,0 +1,38 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=1] +[ext_resource path="res://screens/DBTest_Postgres.gd" type="Script" id=2] + +[node name="Control" type="Node2D"] +script = ExtResource( 2 ) + +[node name="Background" type="Panel" parent="."] +margin_right = 1024.0 +margin_bottom = 600.0 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = 415.0 +margin_top = 133.0 +margin_right = 653.0 +margin_bottom = 233.0 + +[node name="But_MainMenu" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_right = 238.0 +margin_bottom = 100.0 +text = "Main Menu" +next_scene_path = "res://MenuScreen.tscn" + +[node name="Version" type="Label" parent="."] +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 846.0 +margin_top = 554.0 +margin_right = 1018.0 +margin_bottom = 592.0 +text = "Version: 0.0.0" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.gd new file mode 100644 index 0000000..843b361 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.gd @@ -0,0 +1,49 @@ +#HISTORY_VIEWER: +# Controls output space -- will display the appropriate history array page. +# DKM TEMP: 5/15/22: what's here is replicated from the Game script for starting +# purposes. I have this working in experimental version -- will add this back +# next. + +extends Control + +onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance +onready var history_source = get_node("/root/History").historyScreensSingleton +onready var current_history = $Background/MarginContainer/Rows/GameInfo/CurrentHistory +#For zero-indexed array position: +onready var current_history_page_no = 0 +onready var page_displayer = $Background/MarginContainer/Rows/ItemList/Page_Display + +#Abstract class we instance when wanted in game as child of HistoryReference +const TextOutput = preload("res://UserInterface/Response.tscn") +const InputResponse = preload("res://UserInterface/InputResponse.tscn") + + +func _ready() -> void: + theme=load(settings.themeFile) + + print("Loaded history array size is: " + str(history_source.output_history_array.size())) + update_pager() + #DKM TEMP: +# page_displayer.text = "1" +# if(current_history.get_child_count() > 0): +# current_history.remove_child(current_history.get_child(0)) +# var opening_res = history_source.output_history_array[0] +# current_history.add_child(opening_res) + +#Copies the response output to add to both current game output, and the +# history array. +func add_display_to_game(response: Control): + if(current_history.get_child_count() > 0): + current_history.remove_child(current_history.get_child(0)) + current_history.add_child(response) + +func update_pager(): + if(current_history_page_no >= history_source.output_history_array.size()): + current_history_page_no = 0 + print("Current page: " + str(current_history_page_no)) + add_display_to_game(history_source.output_history_array[current_history_page_no]) + current_history_page_no = current_history_page_no +1 + page_displayer.text = str(current_history_page_no) + + + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.tscn new file mode 100644 index 0000000..a5ff472 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/HistoryViewer.tscn @@ -0,0 +1,100 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://screens/HistoryViewer.gd" type="Script" id=1] +[ext_resource path="res://userInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://assets/ui_controlNode_dark_theme.tres" type="Theme" id=3] +[ext_resource path="res://screens/But_HistoryPager.gd" type="Script" id=4] + +[node name="HistoryViewer" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 3 ) +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Background" type="PanelContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarginContainer" type="MarginContainer" parent="Background"] +margin_left = 1.0 +margin_top = 1.0 +margin_right = 1023.0 +margin_bottom = 599.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 10 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 + +[node name="Rows" type="VBoxContainer" parent="Background/MarginContainer"] +margin_left = 20.0 +margin_top = 10.0 +margin_right = 1002.0 +margin_bottom = 578.0 +custom_constants/separation = 10 + +[node name="ItemList" type="ItemList" parent="Background/MarginContainer/Rows"] +margin_right = 982.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 0, 40 ) + +[node name="But_ChangeScene" parent="Background/MarginContainer/Rows/ItemList" instance=ExtResource( 2 )] +margin_right = 200.0 +margin_bottom = 36.0 +text = "More Options" +next_scene_path = "res://screens/MoreOptions.tscn" + +[node name="But_HistoryPager" type="Button" parent="Background/MarginContainer/Rows/ItemList"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -84.0 +margin_right = 115.0 +margin_bottom = 36.0 +text = "History Pager" +script = ExtResource( 4 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label" type="Label" parent="Background/MarginContainer/Rows/ItemList"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -194.94 +margin_top = -1.12247 +margin_right = -81.9397 +margin_bottom = 23.8775 +text = "History Page:" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Page_Display" type="Label" parent="Background/MarginContainer/Rows/ItemList"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -40.0 +margin_bottom = 25.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="GameInfo" type="PanelContainer" parent="Background/MarginContainer/Rows"] +margin_top = 50.0 +margin_right = 982.0 +margin_bottom = 568.0 +size_flags_vertical = 3 + +[node name="CurrentHistory" type="VBoxContainer" parent="Background/MarginContainer/Rows/GameInfo"] +margin_left = 1.0 +margin_top = 1.0 +margin_right = 981.0 +margin_bottom = 517.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +custom_constants/separation = 20 + +[connection signal="button_up" from="Background/MarginContainer/Rows/ItemList/But_HistoryPager" to="Background/MarginContainer/Rows/ItemList/But_HistoryPager" method="_on_But_HistoryPager_button_up"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.gd new file mode 100644 index 0000000..3a17978 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.gd @@ -0,0 +1,48 @@ +#GRAB FOCUS: simple script for temp files to grab focus +# Expanded for Import Character option + +extends Control + +onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance +onready var pSingleton = get_node("/root/PlayerCharacter").pc + +var charFilePath +var a + + +func _ready() -> void: + theme=load(settings.themeFile) + +func _on_Button_pressed(): + $FileDialog.popup() + +#this is going to take information from the file the player chose and put the individul parts into textboxes so it can be edited and then saved +func _on_FileDialog_file_selected(path): + var file = File.new() + #read the text in the file, save it in the variable a + file.open(path, File.READ) + + #split by the spaces so the individual pieces can be separated into textboxes + while file.eof_reached() == false: + var csvStrArray = file.get_csv_line() + var i = 0 + var isLabel = true + while i < csvStrArray.size(): + var csvStr = csvStrArray[i] + if(isLabel): + #make a new textbox for each piece of information + var textLine = Label.new() + $ScrollContainer/VBoxContainer.add_child(textLine) + textLine.text = csvStr.to_upper() + isLabel = false + #DKM TEMP: save this unformatted to the singleton text string + pSingleton.pcText += csvStr.to_upper() + ": " + else: + isLabel = true + var textBox = LineEdit.new() + $ScrollContainer/VBoxContainer.add_child(textBox) + textBox.text = csvStr + #DKM TEMP: save this unformatted to the singleton text string + pSingleton.pcText += csvStr + "\n" + i += 1 + file.close() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.tscn new file mode 100644 index 0000000..3ba6357 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/ImportCharacter.tscn @@ -0,0 +1,127 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://UserInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/ImportCharacter.gd" type="Script" id=3] +[ext_resource path="res://userInterface/But_PlayButton.gd" type="Script" id=4] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="PopupDialog" type="PopupDialog" parent="."] +anchor_top = 0.5 +anchor_bottom = 0.5 + +[node name="WarnText" type="Label" parent="PopupDialog"] +margin_right = 40.0 +margin_bottom = 14.0 +text = "Example" + +[node name="Background" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="FileDialog" type="FileDialog" parent="."] +margin_left = 113.0 +margin_top = 24.0 +margin_right = 886.0 +margin_bottom = 480.0 +window_title = "Open a File" +mode = 0 +access = 2 +current_dir = "/ProgramData/CS_Working/RPGR/Godot_projects/bcirpg_mergedDemo_20220911A" +current_file = "_userData/characterFiles" +current_path = "/ProgramData/CS_Working/RPGR/Godot_projects/bcirpg_mergedDemo_20220911A/_userData/characterFiles" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" parent="." instance=ExtResource( 1 )] +margin_left = -164.0 +margin_top = 0.0 +margin_right = 164.0 +margin_bottom = 14.0 +text = "Import Character" + +[node name="But_Play" parent="." instance=ExtResource( 2 )] +margin_left = 1.0 +margin_top = 34.0 +margin_right = 152.0 +margin_bottom = 71.0 +text = "Start Game" +script = ExtResource( 4 ) +next_scene_path = "res://gamePlay/Game.tscn" + +[node name="But_Cancel" parent="." instance=ExtResource( 2 )] +margin_left = 1.0 +margin_top = 78.0 +margin_right = 152.0 +margin_bottom = 115.0 +text = "Back" +next_scene_path = "res://Screens/MenuScreen.tscn" + +[node name="VBoxContainer2" type="VBoxContainer" parent="."] +anchor_left = 0.0634766 +anchor_top = 0.0583333 +anchor_right = 0.103516 +anchor_bottom = 0.0583333 +margin_left = 107.0 +margin_right = 435.0 +margin_bottom = 44.0 +alignment = 1 +__meta__ = { +"_edit_use_anchors_": true +} + +[node name="But_OpenFile" type="Button" parent="VBoxContainer2"] +margin_right = 369.0 +margin_bottom = 20.0 +text = "Open Character File" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Save_Button" type="Button" parent="VBoxContainer2"] +margin_top = 24.0 +margin_right = 369.0 +margin_bottom = 44.0 +text = "Save" + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -341.0 +margin_top = -175.0 +margin_right = 427.0 +margin_bottom = 284.0 +follow_focus = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="NameLabel" type="Label" parent="ScrollContainer/VBoxContainer"] +visible = false +margin_bottom = 14.0 + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/VBoxContainer"] +visible = false +margin_right = 58.0 +margin_bottom = 24.0 + +[connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"] +[connection signal="pressed" from="VBoxContainer2/But_OpenFile" to="." method="_on_Button_pressed"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/LoadGame_temp.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/LoadGame_temp.tscn new file mode 100644 index 0000000..c843e61 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/LoadGame_temp.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://UserInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/grabFocus.gd" type="Script" id=3] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" parent="." instance=ExtResource( 1 )] +anchor_left = 0.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 0.0 +margin_top = 0.0 +margin_right = 0.0 +margin_bottom = 0.0 +text = "Multiplayer (temp)" + +[node name="But_ChangeScene" parent="Title" instance=ExtResource( 2 )] +text = "Temp: back to menu" +next_scene_path = "res://Screens/MenuScreen.tscn" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.gd new file mode 100644 index 0000000..b9d754a --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.gd @@ -0,0 +1,11 @@ +#MENUSCREEN: +# Script purely to grab focus for tabbing control + +extends Control + +#onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + #theme=load(settings.themeFile) + $VBoxContainer/But_NewGame.grab_focus() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.tscn new file mode 100644 index 0000000..56874a4 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MenuScreen.tscn @@ -0,0 +1,102 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=1] +[ext_resource path="res://Screens/MenuScreen.gd" type="Script" id=2] +[ext_resource path="res://assets/liberation_serif_40pt.tres" type="DynamicFont" id=3] +[ext_resource path="res://UserInterface/Title.tscn" type="PackedScene" id=5] +[ext_resource path="res://assets/ui_controlNode_dark_theme.tres" type="Theme" id=6] +[ext_resource path="res://UserInterface/But_Quit.tscn" type="PackedScene" id=10] + +[node name="MenuScreen" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 6 ) +script = ExtResource( 2 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Background" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" parent="." instance=ExtResource( 5 )] +margin_top = 51.8676 +margin_bottom = 117.868 +custom_fonts/font = ExtResource( 3 ) + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -119.0 +margin_top = -152.0 +margin_right = 119.0 +margin_bottom = 152.0 +rect_scale = Vector2( 1.04675, 1.07389 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="But_NewGame" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_right = 238.0 +margin_bottom = 40.0 +next_scene_path = "res://screens/PlayerSelection.tscn" + +[node name="But_LoadGame" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 44.0 +margin_right = 238.0 +margin_bottom = 85.0 +text = "Load Game" +next_scene_path = "res://screens/LoadGame_temp.tscn" + +[node name="But_Multiplayer" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 89.0 +margin_right = 238.0 +margin_bottom = 130.0 +text = "Multiplayer" +next_scene_path = "res://Screens/Multiplayer_temp.tscn" + +[node name="But_AddChar" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 134.0 +margin_right = 238.0 +margin_bottom = 174.0 +text = "Add Character" +next_scene_path = "res://Screens/Character_Add.tscn" + +[node name="But_ImportChar2" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 178.0 +margin_right = 238.0 +margin_bottom = 219.0 +text = "Import Character" +next_scene_path = "res://Screens/ImportCharacter.tscn" + +[node name="But_Settings" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 223.0 +margin_right = 238.0 +margin_bottom = 264.0 +text = "Settings" +next_scene_path = "res://Screens/SettingsMenuControl.tscn" + +[node name="But_Quit" parent="VBoxContainer" instance=ExtResource( 10 )] +margin_top = 268.0 +margin_right = 238.0 +margin_bottom = 304.0 + +[node name="Version" type="Label" parent="."] +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = -177.0 +margin_top = -44.0 +margin_right = -5.0 +margin_bottom = -6.0 +text = "Version: 0.0.0" +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.gd new file mode 100644 index 0000000..8bbdbe1 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.gd @@ -0,0 +1,11 @@ +#MOREOPTIONS: +# Script purely to grab focus for tabbing control + +extends Control + +#onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + #theme=load(settings.themeFile) + $VBoxContainer/But_ResumeGame.grab_focus() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.tscn new file mode 100644 index 0000000..8111327 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/MoreOptions.tscn @@ -0,0 +1,79 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=1] +[ext_resource path="res://screens/MoreOptions.gd" type="Script" id=2] +[ext_resource path="res://userInterface/But_ResumeGame.gd" type="Script" id=3] +[ext_resource path="res://assets/ui_controlNode_dark_theme.tres" type="Theme" id=6] + +[node name="MoreOptions" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 6 ) +script = ExtResource( 2 ) + +[node name="Background" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -119.0 +margin_top = -152.0 +margin_right = 119.0 +margin_bottom = 152.0 +rect_scale = Vector2( 1.04675, 1.07389 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="But_ResumeGame" type="Button" parent="VBoxContainer"] +margin_right = 238.0 +margin_bottom = 36.0 +text = "Resume Game" +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="But_ShowHistory" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 40.0 +margin_right = 238.0 +margin_bottom = 125.0 +text = "Show History" +next_scene_path = "res://screens/HistoryViewer.tscn" + +[node name="But_Chat" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 129.0 +margin_right = 238.0 +margin_bottom = 214.0 +text = "Chat" +next_scene_path = "res://screens/MenuScreen.tscn" + +[node name="But_MainMenu" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 218.0 +margin_right = 238.0 +margin_bottom = 304.0 +text = "Main Menu" +next_scene_path = "res://Screens/MenuScreen.tscn" + +[node name="Version" type="Label" parent="."] +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = -177.0 +margin_top = -44.0 +margin_right = -5.0 +margin_bottom = -6.0 +text = "Version: 0.0.0" +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="button_up" from="VBoxContainer/But_ResumeGame" to="VBoxContainer/But_ResumeGame" method="_on_But_ResumeGame_button_up"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Multiplayer_temp.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Multiplayer_temp.tscn new file mode 100644 index 0000000..a693767 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Multiplayer_temp.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://UserInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/grabFocus.gd" type="Script" id=3] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) + +[node name="Title" parent="." instance=ExtResource( 1 )] +anchor_left = 0.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 0.0 +margin_top = 0.0 +margin_right = 0.0 +margin_bottom = 0.0 +text = "Multiplayer (temp)" + +[node name="But_ChangeScene" parent="Title" instance=ExtResource( 2 )] +text = "Temp: back to menu" +next_scene_path = "res://Screens/MenuScreen.tscn" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/NewGame_temp.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/NewGame_temp.tscn new file mode 100644 index 0000000..c843e61 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/NewGame_temp.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://UserInterface/Title.tscn" type="PackedScene" id=1] +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=2] +[ext_resource path="res://screens/grabFocus.gd" type="Script" id=3] + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" parent="." instance=ExtResource( 1 )] +anchor_left = 0.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 0.0 +margin_top = 0.0 +margin_right = 0.0 +margin_bottom = 0.0 +text = "Multiplayer (temp)" + +[node name="But_ChangeScene" parent="Title" instance=ExtResource( 2 )] +text = "Temp: back to menu" +next_scene_path = "res://Screens/MenuScreen.tscn" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.gd new file mode 100644 index 0000000..6aa9b23 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.gd @@ -0,0 +1,11 @@ +#PLAYERSELECTION: +# Script purely to grab focus for tabbing control + +extends Control + +onready var settings = get_node("/root/GlobalSaveInstance").settingsInstance + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + theme=load(settings.themeFile) + $VBoxContainer/But_ChoosePlayer.grab_focus() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.tscn new file mode 100644 index 0000000..aba2136 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PlayerSelection.tscn @@ -0,0 +1,69 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://UserInterface/But_ChangeScene.tscn" type="PackedScene" id=1] +[ext_resource path="res://screens/PlayerSelection.gd" type="Script" id=2] +[ext_resource path="res://assets/ui_controlNode_dark_theme.tres" type="Theme" id=6] + +[node name="PlayerSelection" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 6 ) +script = ExtResource( 2 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Background" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -119.0 +margin_top = -152.0 +margin_right = 119.0 +margin_bottom = 152.0 +rect_scale = Vector2( 1.04675, 1.07389 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="But_ChoosePlayer" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_right = 238.0 +margin_bottom = 98.0 +text = "Import Character" +next_scene_path = "res://screens/ImportCharacter.tscn" + +[node name="But_AddChar" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 102.0 +margin_right = 238.0 +margin_bottom = 201.0 +text = "Create Character" +next_scene_path = "res://Screens/Character_Add.tscn" + +[node name="But_MainMenu" parent="VBoxContainer" instance=ExtResource( 1 )] +margin_top = 205.0 +margin_right = 238.0 +margin_bottom = 304.0 +text = "Main Menu" +next_scene_path = "res://Screens/MenuScreen.tscn" + +[node name="Version" type="Label" parent="."] +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = -177.0 +margin_top = -44.0 +margin_right = -5.0 +margin_bottom = -6.0 +text = "Version: 0.0.0" +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PostgreSQLClient.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PostgreSQLClient.gd new file mode 100644 index 0000000..8a647e0 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/PostgreSQLClient.gd @@ -0,0 +1,1911 @@ +# Lience MIT +# Written by Samuel MARZIN +# Detailed documentation: https://github.com/Marzin-bot/PostgreSQLClient/wiki/Documentation +extends Object + + +## Godot PostgreSQL Client is a GDscript script/class that allows you to connect to a Postgres backend and run SQL commands there. +## It is able to send data and receive it from the backend. Useful for managing player user data on a multiplayer game, by saving a large amount of data on a dedicated Postgres server from GDscript. +## The class is written in pure GDScript which allows it not to depend on GDNative. This makes it ultra portable for many platforms. +class_name PostgreSQLClient + + +## Version number (minor.major) of the PostgreSQL protocol used when connecting to the backend. +const PROTOCOL_VERSION := 3.0 + + +## Backend runtime parameters +## A dictionary that contains various information about the state of the server. +## For security reasons the dictionary is always empty if the frontend is disconnected from the backend and updates once the connection is established. +var parameter_status := {} + + +## Enemeration the statuts of the connection. +enum Status { + STATUS_DISCONNECTED, ## A status representing a PostgreSQLClient that is disconnected. + STATUS_CONNECTING, ## A status representing a PostgreSQLClient that is connecting to a host. + STATUS_CONNECTED, ## A status representing a PostgreSQLClient that is connected to a host. + STATUS_ERROR ## A status representing a PostgreSQLClient in error state. +} + +# The statut of the connection. +var status = Status.STATUS_DISCONNECTED setget set_status, get_status + +## Returns the status of the connection (see the Status enumeration). +func get_status() -> int: + return status + +func set_status(_value) -> void: + # The value of the "status" variable can only be modified locally. + pass + + +var password_global: String +var user_global: String + +var client := StreamPeerTCP.new() +var peerstream := PacketPeerStream.new() +var stream_peer_ssl = StreamPeerSSL.new() + +var peer: StreamPeer +func _init() -> void: + peerstream.set_stream_peer(client) + peer = peerstream.stream_peer + + +## Fires when the connection to the backend closes. +## was_clean_close is true if the connection was closed correctly otherwise false. +signal connection_closed(was_clean_close) + +# No use +#signal connection_error() # del /!\ + +## Triggered when the authentication process failed during contact with the target backend. +## The error_object parameter is a dictionary that contains various information during the nature of the error. +signal authentication_error(error_object) + + +## Trigger when the connection between the frontend and the backend is established. +## This is usually a good time to start making requests to the backend with execute (). +signal connection_established + +#signal data_received + +################## No use at the moment ############### +## The process ID of this backend. +var process_backend_id: int + +################## No use at the moment ############### +## The secret key of this backend. +var process_backend_secret_key: int + +var status_ssl = 0 + +var global_url = "" +var startup_message: PoolByteArray +var next_etape := false +var con_ssl: bool + +## Allows you to connect to a Postgresql backend at the specified url. +func connect_to_host(url: String, ssl := false, connect_timeout := 30) -> int: + global_url = url + con_ssl = ssl + var error := 1 + + # If the fontend was already connected to the backend, we disconnect it before reconnecting. + if status == Status.STATUS_CONNECTED: + close(false) + + var regex = RegEx.new() + # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + regex.compile("^(?:postgresql|postgres)://(.+):(.+)@(.+):(\\d*)/(.+)") + + var result = regex.search(url) + + if result: + ### StartupMessage ### + + # "postgres" is the database and user by default. + startup_message = request("", "user".to_ascii() + PoolByteArray([0]) + result.strings[1].to_utf8() + PoolByteArray([0]) + "database".to_ascii() + PoolByteArray([0]) + result.strings[5].to_utf8() + PoolByteArray([0, 0])) + + password_global = result.strings[2] + user_global = result.strings[1] + + # The default port for postgresql. + var port = 5432 + + if result.strings[4]: + port = int(result.strings[4]) + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.put_data(startup_message) + else: + if not client.is_connected_to_host() and client.get_status() == StreamPeerTCP.STATUS_NONE: + error = client.connect_to_host(result.strings[3], port) + + #if (error == OK) + # Get the fist message of server. + if error == OK: + next_etape = true + else: + print("[PostgreSQLClient:%d] Invalid host Postgres." % [get_instance_id()]) + else: + status = Status.STATUS_ERROR + + push_error("[PostgreSQLClient:%d] Invalid Postgres URL." % [get_instance_id()]) + + return error + + +## A dictionary which contains various information on the execution errors of the last requests made on the backend (usually after using the execute() method). +## If the dictionary is empty, it means that the backend did not detect any error in the query. +## Should be used ideally after each use of the execute() method. +## For security reasons, the dictionary is empty when the frontend is not connected to the backend. +var error_object := {} + + +## Allows you to close the connection with the backend. +## If clean_closure is true, the frontend will notify the backend that it requests to close the connection. +## If false, the frontend forcibly closes the connection without notifying the backend (not recommended sof in exceptional cases). +## Has no effect if the frontend is not already connected to the backend. +func close(clean_closure := true) -> void: + if status == Status.STATUS_CONNECTED: + ### Terminate ### + + # Identifies the message as a termination. + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_HANDSHAKING or stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + # Deconnection ssl + if clean_closure: + stream_peer_ssl.put_data(request('X', PoolByteArray())) + + stream_peer_ssl.disconnect_from_stream() + else: + if clean_closure: + var _unused = peer.put_data(request('X', PoolByteArray())) + + client.disconnect_from_host() + + # For security reasons, the dictionary is empty when the frontend is not connected to the backend. + parameter_status = {} + + # For security reasons, the dictionary is empty when the frontend is not connected to the backend. + error_object = {} + + status = Status.STATUS_DISCONNECTED + next_etape = false + status_ssl = 0 + + emit_signal("connection_closed", clean_closure) + else: + push_warning("[PostgreSQLClient:%d] The fontend was already disconnected from the backend when calling close()." % [get_instance_id()]) + + +## Allows to send an SQL string to the backend that should run. +## The sql parameter can contain one or more valid SQL statements. +## Returns an Array of PostgreSQLQueryResult. (Can be empty) +## There are as many PostgreSQLQueryResult elements in the array as there are SQL statements in sql (sof in exceptional cases). +func execute(sql: String) -> Array: + if status == Status.STATUS_CONNECTED: + var _unused + var request := request('Q', sql.to_utf8() + PoolByteArray([0])) + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.put_data(request) + else: + _unused = peer.put_data(request) + + while client.is_connected_to_host() and client.get_status() == StreamPeerTCP.STATUS_CONNECTED and status == Status.STATUS_CONNECTED: + var reponce := [OK, PoolByteArray()] + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.poll() + if stream_peer_ssl.get_available_bytes(): + reponce = stream_peer_ssl.get_data(stream_peer_ssl.get_available_bytes()) # I don't know why it crashes when this value (stream_peer_ssl.get_available_bytes()) is equal to 0 so I pass it a condition. It is probably a Godot bug. + else: + continue + else: + reponce = peer.get_data(peer.get_available_bytes()) + + if reponce[0] == OK: + var result = reponce_parser(reponce[1]) + if result != null: + return result + else: + push_warning("[PostgreSQLClient:%d] The backend did not send any data or there must have been a problem while the backend sent a response to the request." % [get_instance_id()]) + else: + push_error("[PostgreSQLClient:%d] The frontend is not connected to backend." % [get_instance_id()]) + + return [] + + +## Upgrade the connexion to SSL. +func set_ssl_connection() -> void: + var _unused + + if stream_peer_ssl.get_status() == StreamPeerSSL.STATUS_HANDSHAKING or stream_peer_ssl.get_status() == StreamPeerSSL.STATUS_CONNECTED: + push_warning("[PostgreSQLClient:%d] The connection is already secured with TLS/SSL." % [get_instance_id()]) + elif client.get_status() == StreamPeerTCP.STATUS_CONNECTED: + ### SSLRequest ### + + var buffer := StreamPeerBuffer.new() + + # Length of message contents in bytes, including self. + _unused = buffer.put_data(get_32byte_invert(8, true)) + + # The SSL request code. + # The value is chosen to contain 1234 in the most significant 16 bits, and 5679 in the least significant 16 bits. (To avoid confusion, this code must not be the same as any protocol version number.) + _unused = buffer.put_data(get_32byte_invert(80877103)) + + _unused = peer.put_data(buffer.data_array) + + status_ssl = 1 + else: + push_error("[PostgreSQLClient:%d] The frontend is not connected to backend." % [get_instance_id()]) + + +##### No use ##### +## Upgrade the connexion to GSSAPI. +func set_gssapi_connection() -> void: + var _unused + + if client.get_status() == StreamPeerTCP.STATUS_CONNECTED: + ### GSSENCRequest ### + + var buffer := StreamPeerBuffer.new() + + # Length of message contents in bytes, including self. + _unused = buffer.put_data(get_32byte_invert(8, true)) + + # The GSSAPI Encryption request code. + # The value is chosen to contain 1234 in the most significant 16 bits, and 5680 in the least significant 16 bits. (To avoid confusion, this code must not be the same as any protocol version number.) + _unused = buffer.put_data(get_32byte_invert(80877104)) + + _unused = peer.put_data(buffer.data_array) + else: + push_error("[PostgreSQLClient:%d] The frontend is not connected to backend." % [get_instance_id()]) + + +## This function undoes all changes made to the database since the last Commit. +func rollback(process_id: int, process_key: int) -> void: + ### CancelRequest ### + var _unused + if status == Status.STATUS_CONNECTED: + var buffer := StreamPeerBuffer.new() + + # Length of message contents in bytes, including self. + buffer.put_u32(16) + + var message_length := buffer.data_array + + message_length.invert() + + _unused = buffer.put_data(message_length) + + # The cancel request code. + # The value is chosen to contain 1234 in the most significant 16 bits, and 5678 in the least 16 significant bits. (To avoid confusion, this code must not be the same as any protocol version number.) + _unused = buffer.put_data(get_32byte_invert(80877102)) + + # The process ID of the target backend. + buffer.put_u32(process_id) + + # The secret key for the target backend. + buffer.put_u32(process_key) + + + _unused = peer.put_data(buffer.data_array.subarray(4, -1)) + else: + push_error("[PostgreSQLClient:%d] The frontend is not connected to backend." % [get_instance_id()]) + + +## Poll the connection to check for incoming messages. +## Ideally, it should be called before PostgreSQLClient.execute() for it to work properly and called frequently in a loop. +func poll() -> void: + var _unused + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_HANDSHAKING or stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.poll() + + if client.is_connected_to_host(): + if client.get_status() == StreamPeerTCP.STATUS_CONNECTED: + if next_etape: + if con_ssl: + ### SSLRequest ### + + set_ssl_connection() + else: + _unused = peer.put_data(startup_message) + startup_message = PoolByteArray() + + next_etape = false + + if status_ssl == 1: + var response = peer.get_data(peer.get_available_bytes()) + if response[0] == OK: + if not response[1].empty(): + match char(response[1][0]): + 'S': + #var crypto = Crypto.new() + #var ssl_key = crypto.generate_rsa(4096) + #var ssl_cert = crypto.generate_self_signed_certificate(ssl_key) + stream_peer_ssl.connect_to_stream(peer) + # stream_peer_ssl.blocking_handshake = false + status_ssl = 2 + 'N': + status = Status.STATUS_ERROR + + push_error("[PostgreSQLClient:%d] The connection attempt failed. The backend does not want to establish a secure SSL/TLS connection." % [get_instance_id()]) + + close(false) + var value: + status = Status.STATUS_ERROR + + push_error("[PostgreSQLClient:%d] The backend sent an unknown response to the request to establish a secure connection. Response is not recognized: '%c'." % [get_instance_id(), value]) + + close(false) + else: + push_warning("[PostgreSQLClient:%d] The backend did not send any data or there must have been a problem while the backend sent a response to the request." % [get_instance_id()]) + + + if status_ssl == 2 and stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + _unused = connect_to_host(global_url, false) + status_ssl = 3 + + + if status_ssl != 1 and status_ssl != 2 and not status == Status.STATUS_CONNECTED and client.get_status() == StreamPeerTCP.STATUS_CONNECTED: + var reponce: Array + + if status_ssl == 0: + reponce = peer.get_data(peer.get_available_bytes()) + else: + reponce = stream_peer_ssl.get_data(stream_peer_ssl.get_available_bytes()) + + if reponce[0] == OK and reponce[1].size(): + var servire = reponce_parser(reponce[1]) + + if servire: + if status_ssl == 0: + _unused = peer.put_data(servire) + else: + stream_peer_ssl.put_data(servire) + + +func request(type_message: String, message := PoolByteArray()) -> PoolByteArray: + var _unused + # Get the size of message. + var buffer := StreamPeerBuffer.new() + + buffer.put_u32(message.size() + (4 if type_message else 8)) + + var message_length := buffer.data_array + + message_length.invert() + + # If the message is not StartupMessage... + if type_message: + buffer.put_u8(ord(type_message)) + + _unused = buffer.put_data(message_length) + + # If the message is StartupMessage... + if not type_message: + # Version parsing + var protocol_major_version = int(PROTOCOL_VERSION) + var protocol_minor_version = protocol_major_version - PROTOCOL_VERSION + + for char_number in str(protocol_major_version).pad_zeros(2) + str(protocol_minor_version).pad_zeros(2): + _unused = buffer.put_data(PoolByteArray([int(char_number)])) + + _unused = buffer.put_data(message) + + error_object = {} + + return buffer.data_array.subarray(4, -1) + + +static func get_32byte_invert(integer: int, unsigned := false) -> PoolByteArray: + var buffer := StreamPeerBuffer.new() + + if unsigned: + buffer.put_u32(integer) + else: + buffer.put_32(integer) + + var bytes := buffer.data_array + bytes.invert() + + return bytes + + +static func split_pool_byte_array(pool_byte_array: PoolByteArray, delimiter: int) -> Array: + var array := [] + var from := 0 + var to := 0 + + for byte in pool_byte_array: + if byte == delimiter: + array.append(pool_byte_array.subarray(from, to)) + from = to + 1 + + to += 1 + + return array + + +static func pbkdf2(hash_type: int, password: PoolByteArray, salt: PoolByteArray, iterations := 4096, length := 0) -> PoolByteArray: + var crypto := Crypto.new() + var hash_length := len(crypto.hmac_digest(hash_type, salt, password)) + if length == 0: + length = hash_length + + var output := PoolByteArray() + var block_count := ceil(float(length) / hash_length) + + var buffer := PoolByteArray() + buffer.resize(4) + + var block := 1 + while block <= block_count: + buffer[0] = (block >> 24) & 0xFF + buffer[1] = (block >> 16) & 0xFF + buffer[2] = (block >> 8) & 0xFF + buffer[3] = block & 0xFF + + var key_1 := crypto.hmac_digest(hash_type, password, salt + buffer) + var key_2 := key_1 + + for _index in iterations - 1: + key_1 = crypto.hmac_digest(hash_type, password, key_1) + + for index in key_1.size(): + key_2[index] ^= key_1[index] + + output += key_2 + + block += 1 + + return output.subarray(0, hash_length - 1) + + +enum DataTypePostgreSQL { + BOOLEAN = 16, + SMALLINT = 21, + INTEGER = 23, + BIGINT = 20, + REAL = 700, + DOUBLE_PRECISION = 701, + TEXT = 25, + CHARACTER = 1042, # Alias CHAR. + CHARACTER_VARYING = 1043, # Alias VARCHAR. + JSON = 114, + JSONB = 3802, + XML = 142, + BITEA = 17, + CIDR = 650, + INET = 869, + MACADDR = 829, + MACADDR8 = 774, + BIT = 1560, + BIT_VARYING = 1562, + UUID = 2950, + POINT = 600, + BOX = 603, + LSEG = 601, + LINE = 628, + CIRCLE = 718, + DATE = 1082, + TIME = 1266 +} + + +## The PostgreSQLQueryResult class is a subclass of PostgreSQLClient which is not intended to be created manually. +## It represents the result of an SQL query and provides an information and method report to use the result of the query. +## It is usually returned by the PostgreSQLClient.execute() method in an array of PostgreSQLQueryResult. +class PostgreSQLQueryResult: + ## Specifies the number of fields in a row (can be zero). + var number_of_fields_in_a_row := 0 + + ## An array that contains dictionaries. + ## These dictionaries represent the description of the rows where the query was executed. + ## The number of dictionary depends on the number of fields resulting from the result of the query which was executed. + var row_description := [] + + ## An Array that contains sub-arrays. + ## These sub-arrays represent for most of the queries the rows of the table where the query was executed. + ## The number of sub-tables depends on the query that has been made. + ## These sub-arrays contain as many elements as number_of_fields_in_a_row. + ## These elements are native GDscript types that represent the data resulting from the query. + var data_row := [] + + ## An Array that contains sub-arrays. + ## These sub-arrays represent for most of the queries the rows of the table where the query was executed. + ## The number of sub-tables depends on the query that has been made. + ## These sub-arrays contain as many elements as number_of_fields_in_a_row. + var raw_data_row := [] + + ## This is usually a single word that identifies which SQL command was completed. + var command_tag: String + + ## Represents various information about the execution status of the query notified by the backend. Can be empty. + var notice := {} + + ## Returns all the values of a field. + ## field_name is the name of the field on which we get the values. + ## Can be empty if the field name is unknown. + ## The field_name parameter is case sensitive. + func get_field_values(field_name: String) -> Array: + var values := [] + + var fields_index: int + + for i in number_of_fields_in_a_row: + if row_description[i]["field_name"] == field_name: + fields_index = i + + break + + if fields_index == null: + return values + + for data in data_row: + values.append(data[fields_index]) + + return values + + + ## Returns the object ID of the data type of the field. + ## field_name is the name of the field whose type we get. + ## Can return -1 if the field name is unknown. + ## The field_name parameter is case sensitive. + func field_data_type(field_name: String) -> int: + for i in number_of_fields_in_a_row: + if row_description[i]["field_name"] == field_name: + return row_description[i]["type_object_id"] + + return -1 + + +var postgresql_query_result_instance := PostgreSQLQueryResult.new() + +var datas_command_sql := [] + +var response_buffer: PoolByteArray + +var client_first_message: String # Authentication SASL +var salted_password: PoolByteArray # Authentication SASL +var auth_message: String # Authentication SASL + +func reponce_parser(response: PoolByteArray): + var _unused + response_buffer += response + + while response_buffer.size() > 4: + # Get the length of the response. + var data_length = response_buffer.subarray(1, 4) + data_length.invert() + + var buffer := StreamPeerBuffer.new() + _unused = buffer.put_data(data_length) + buffer.seek(0) + + # Message length. + var message_length = buffer.get_u32() + + # If the size of the buffer is not equal to the length of the message, the request is not processed immediately. + # The server may send a fragmented response. + # We must therefore wait to receive the full response. + if response_buffer.size() < message_length + 1: + break + + # Message type. + match char(response_buffer[0]): + 'A': + ### NotificationResponse ### + + # Get the process ID of the notifying backend process. + var process_id = response_buffer.subarray(5, 8) + process_id.invert() + + _unused = buffer.put_data(process_id) + buffer.seek(4) + + process_id = buffer.get_32() + + # We get the following parameters. + var situation_report_data := split_pool_byte_array(response_buffer.subarray(5, message_length), 0) + + # Get the name of the channel that the notify has been raised on. + var name_of_channel: String = situation_report_data[0].get_string_from_utf8() + + # Get the "payload" string passed from the notifying process. + var payload: String = situation_report_data[1].get_string_from_utf8() + + # The result. + prints(process_id, name_of_channel, payload) + 'C': + ### CommandComplete ### + + # Identifies the message as a command-completed response. + + # Get the command tag. This is usually a single word that identifies which SQL command was completed. + var command_tag = response_buffer.subarray(5, message_length).get_string_from_ascii() + + # The result. + postgresql_query_result_instance.command_tag = command_tag + + datas_command_sql.append(postgresql_query_result_instance) + + # Now is a good time to create a new return object for a possible next request. + postgresql_query_result_instance = PostgreSQLQueryResult.new() + 'D': + ### DataRow ### + + # Identifies the message as a data row. + + # Number of column values ​​that follow (can be zero). + var number_of_columns = response_buffer.subarray(5, 6) + number_of_columns.invert() + + _unused = buffer.put_data(number_of_columns) + buffer.seek(4) + + number_of_columns = buffer.get_16() + + var cursor := 0 + var row := [] + var raw_row := [] + + # Next, the following pair of fields appear for each column. + for i in number_of_columns: + var value_length = response_buffer.subarray(cursor + 7, cursor + 10) + value_length.invert() + + buffer = StreamPeerBuffer.new() + _unused = buffer.put_data(value_length) + buffer.seek(0) + + value_length = buffer.get_32() + + if value_length == -1: + ### NULL ### + + # The result. + row.append(null) + + match postgresql_query_result_instance.row_description[i].format_code: + 0: + raw_row.append("") + 1: + raw_row.append(PoolByteArray()) + _: + print("error") + + value_length = 0 + else: + var value_data := response_buffer.subarray(cursor + 11, cursor + value_length + 10) + + match postgresql_query_result_instance.row_description[i].format_code: + 0: + raw_row.append(value_data.get_string_from_ascii()) + 1: + raw_row.append(value_data) + _: + print("error") + + var error: int + + match postgresql_query_result_instance.row_description[i].type_object_id: + DataTypePostgreSQL.BOOLEAN: + ### BOOLEAN ### + + # The type returned is bool. + match char(value_data[0]): + 't': + ### TRUE ### + + # The result. + row.append(true) + 'f': + ### FALSE ### + + # The result. + row.append(false) + var value_column: + push_error("[PostgreSQLClient:%d] The backend sent an invalid BOOLEAN object. Column value is not recognized: '%c'." % [get_instance_id(), value_column]) + + close(false) + return + DataTypePostgreSQL.SMALLINT: + ### SMALLINT ### + + # The type returned is int. + # The result. + row.append(int(value_data.get_string_from_ascii())) + DataTypePostgreSQL.INTEGER: + ### INTEGER ### + + # The type returned is int. + # The result. + row.append(int(value_data.get_string_from_ascii())) + DataTypePostgreSQL.BIGINT: + ### BIGINT ### + + # The type returned is int. + # The result. + row.append(int(value_data.get_string_from_ascii())) + DataTypePostgreSQL.REAL: + ### REAL ### + + # The type returned is float. + # The result. + row.append(float(value_data.get_string_from_ascii())) + DataTypePostgreSQL.DOUBLE_PRECISION: + ### DOUBLE PRECISION ### + + # The type returned is float. + # The result. + row.append(float(value_data.get_string_from_ascii())) + DataTypePostgreSQL.TEXT: + ### TEXT ### + + # The type returned is String. + # The result. + row.append(value_data.get_string_from_utf8()) + DataTypePostgreSQL.CHARACTER: + ### CHARACTER ### + + # The type returned is String. + # The result. + row.append(value_data.get_string_from_utf8()) + DataTypePostgreSQL.CHARACTER_VARYING: + ### CHARACTER_VARYING ### + + # The type returned is String. + # The result. + row.append(value_data.get_string_from_utf8()) + "tsvector": + ### TSVECTOR ### + + pass + "tsquery": + ### TSQUERY ### + + pass + DataTypePostgreSQL.XML: + ### XML ### + + # The type returned is String. + var xml := XMLParser.new() + + error = xml.open_buffer(value_data) + if error == OK: + # The result. + row.append(value_data.get_string_from_utf8()) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid XML object. (Error: %d)" % [get_instance_id(), error]) + + close(false) + + response_buffer = PoolByteArray() + return + DataTypePostgreSQL.JSON: + ### JSON ### + + # The type returned is String. + var json = value_data.get_string_from_utf8() + + var json_error := validate_json(json) + + if json_error: + push_error("[PostgreSQLClient:%d] The backend sent an invalid JSON object: (Error: %d)" % [get_instance_id(), json_error]) + + close(false) + response_buffer = PoolByteArray() + return + else: + # The result. + row.append(json) + DataTypePostgreSQL.JSONB: + ### JSONB ### + + # The type returned is String. + var json = value_data.get_string_from_utf8() + + var json_error := validate_json(json) + + if json_error: + push_error("[PostgreSQLClient:%d] The backend sent an invalid JSONB object: (Error: %d)" % [get_instance_id(), json_error]) + + close(false) + response_buffer = PoolByteArray() + return + else: + # The result. + row.append(json) + DataTypePostgreSQL.BIT: + ### BIT ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.BIT_VARYING: + ### BIT VARYING ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.BITEA: + ### BITEA ### + + # /!\ Support not complet (not end). /!\ + + # The type returned is PoolByteArray. + var bitea_data := value_data.get_string_from_ascii() + + if bitea_data.substr(2).is_valid_hex_number(): + var bitea := PoolByteArray() + + for i_hex in value_data.size() * 0.5 - 1: + bitea.append(("0x" + bitea_data[i_hex + 2] + bitea_data[i_hex + 2]).hex_to_int()) + + # The result. + row.append(bitea) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid BITEA object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + "timestamp": + ### TIMESTAMP ### + + pass + "date": + ### DATE ### + + pass + "interval": + ### INTERVAL ### + + pass + DataTypePostgreSQL.UUID: + ### UUID ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.CIDR: + ### CIDR ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend with the line if below... + #value_data.get_string_from_ascii().is_valid_ip_address() + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.INET: + ### INET ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend with the line if below... + #value_data.get_string_from_ascii().is_valid_ip_address() + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.MACADDR: + ### MACADDR ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.MACADDR8: + ### MACADDR8 ### + + # The type returned is String. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.POINT: + ### POINT ### + + # The type returned is Vector2. + var regex = RegEx.new() + + error = regex.compile("^\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\)") + if error: + push_error("[PostgreSQLClient:%d] RegEx compilation of POINT object failed. (Error: %d)" % [get_instance_id(), error]) + + close(false) + response_buffer = PoolByteArray() + return + + var result = regex.search(value_data.get_string_from_ascii()) + + if result: + # The result. + row.append(Vector2(float(result.strings[1]), float(result.strings[2]))) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid POINT object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + DataTypePostgreSQL.BOX: + ### BOX ### + + # The type returned is Rect2. + var regex = RegEx.new() + + error = regex.compile("^\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\),\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\)") + if error: + push_error("[PostgreSQLClient:%d] RegEx compilation of BOX object failed. (Error: %d)" % [get_instance_id(), error]) + + close(false) + response_buffer = PoolByteArray() + return + + var result = regex.search(value_data.get_string_from_ascii()) + if result: + # The result. + row.append(Rect2(float(result.strings[3]), float(result.strings[4]), float(result.strings[1]), float(result.strings[2]))) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid BOX object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + DataTypePostgreSQL.LSEG: + ### LSEG ### + + # The type returned is PoolVector2Array. + var regex = RegEx.new() + + error = regex.compile("^\\[\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\),\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\)\\]") + if error: + push_error("[PostgreSQLClient:%d] RegEx compilation of LSEG object failed. (Error: %d)" % [get_instance_id(), error]) + + close(false) + response_buffer = PoolByteArray() + return + + var result = regex.search(value_data.get_string_from_ascii()) + if result: + # The result. + row.append(PoolVector2Array([ + Vector2(float(result.strings[1]), float(result.strings[2])), + Vector2(float(result.strings[3]), float(result.strings[4])) + ])) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid LSEG object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + "polygon": + ### POLYGON ### + + # The type returned is PoolVector2Array. + row.append(PoolVector2Array()) + "path": + ### PATH ### + + # The type returned is PoolVector2Array. + row.append(PoolVector2Array()) + DataTypePostgreSQL.LINE: + ### LINE ### + + # The type returned is Vector3. + var regex = RegEx.new() + + error = regex.compile("^\\{(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\}") + if error: + push_error("[PostgreSQLClient:%d] RegEx compilation of LINE object failed. (Error: %d)" % [get_instance_id(), error]) + + close(false) + response_buffer = PoolByteArray() + return + + var result = regex.search(value_data.get_string_from_ascii()) + + if result: + # The result. + row.append(Vector3(float(result.strings[1]), float(result.strings[2]), float(result.strings[3]))) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid LINE object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + DataTypePostgreSQL.CIRCLE: + ### CIRCLE ### + + # The type returned is Vector3. + var regex = RegEx.new() + + error = regex.compile("^<\\((-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)\\),(\\d+(\\.\\d+)?)>") + if error: + push_error("[PostgreSQLClient:%d] RegEx compilation of CIRCLE object failed. (Error: %d)" % [get_instance_id(), error]) + + close(false) + response_buffer = PoolByteArray() + return + + var result = regex.search(value_data.get_string_from_ascii()) + if result: + # The result. + row.append(Vector3(float(result.strings[1]), float(result.strings[2]), float(result.strings[3]))) + else: + push_error("[PostgreSQLClient:%d] The backend sent an invalid CIRCLE object." % [get_instance_id()]) + + close(false) + response_buffer = PoolByteArray() + return + DataTypePostgreSQL.DATE: + ### DATE ### + + # The type returned is Date. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + DataTypePostgreSQL.TIME: + ### TIME ### + + # The type returned is Time. + + # Ideally we should validate the value sent by the backend... + + # The result. + row.append(value_data.get_string_from_ascii()) + _: + # The type returned is PoolByteArray. + row.append(value_data) + + cursor += value_length + 4 + + # The result. + postgresql_query_result_instance.data_row.append(row) + postgresql_query_result_instance.raw_data_row.append(raw_row) + 'E': + ### ErrorResponse ### + + # Identifies the message as an error. + + # The message body consists of one or more identified fields, followed by a zero byte as a terminator. + # Fields can appear in any order. For each field there is the following: + for champ_data in split_pool_byte_array(response_buffer.subarray(5, message_length - 1), 0): + var champ: String = champ_data.get_string_from_ascii() + + # A code identifying the field type; if zero, this is the message terminator and no string follows. + var field_type_code := champ[0] + + # The field value. + var value := champ.trim_prefix(field_type_code) + + match field_type_code: + 'S': + if value == "FATAL": + # For security reasons, the dictionary is empty when the frontend is not connected to the backend. + parameter_status = {} + + # For security reasons, the dictionary is empty when the frontend is not connected to the backend. + error_object = {} + + status = Status.STATUS_DISCONNECTED + + status_ssl = 0 + + emit_signal("connection_closed", true) + + error_object["severity"] = value + 'V': + error_object["severity_no_localized"] = value + 'C': + error_object["SQLSTATE_code"] = value + 'M': + error_object["message"] = value + + push_error("[PostgreSQLClient:%d] %s" % [get_instance_id(), value]) + 'D': + error_object["detail"] = value + 'H': + error_object["hint"] = value + 'P': + error_object["position"] = value + 'p': + error_object["internal_position"] = value + 'q': + error_object["internal_query"] = value + 'W': + error_object["where"] = value + 's': + error_object["schema_name"] = value + 't': + error_object["table_name"] = value + 'c': + error_object["column_name"] = value + 'd': + error_object["constraint_name"] = value + 'n': + error_object["constraint_name"] = value + 'F': + error_object["file"] = value + 'L': + error_object["line"] = value + 'R': + error_object["routine"] = value + _: + # Since more field types might be added in future, frontends should silently ignore fields of unrecognized type. + pass + + if error_object["severity"] == "FATAL": + status = Status.STATUS_ERROR + + if status != Status.STATUS_CONNECTED: + emit_signal("authentication_error", error_object.duplicate()) + 'G': + ### CopyInResponse ### + + # The message "CopyInResponse" identifies the message as a Start Copy In response. The frontend must now send copy-in data (if not prepared to do so, send a CopyFail message). + + buffer = StreamPeerBuffer.new() + + # Get overall copy format code. + # 0 indicates the overall COPY format is textual (rows separated by newlines, columns separated by separator characters, etc). 1 indicates the overall copy format is binary (similar to DataRow format). See COPY for more information. + var overall_copy_format_code = response_buffer.subarray(5, 6) + overall_copy_format_code.invert() + + _unused = buffer.put_data(overall_copy_format_code) + buffer.seek(0) + + overall_copy_format_code = buffer.get_u8() + + # Get the number of columns in the data to be copied. + var number_of_columns = response_buffer.subarray(7, 9) + number_of_columns.invert() + + _unused = buffer.put_data(number_of_columns) + buffer.seek(1) + + number_of_columns = buffer.get_u16() + + # Get the format codes to be used for each column. + # Each must presently be zero (text) or one (binary). All must be zero if the overall copy format is textual. + for index in number_of_columns: + var format_code = response_buffer.subarray(10, 12) + format_code.invert() + + _unused = buffer.put_data(format_code) + buffer.seek(2 * index + 3) + + format_code = buffer.get_u16() + + # The result. + print(format_code) + + push_warning("[PostgreSQLClient:%d] CopyInResponse, no support." % [get_instance_id()]) + 'H': + ### CopyOutResponse ### + + # The message "CopyOutResponse" identifies the message as a Start Copy Out response. This message will be followed by copy-out data. + + buffer = StreamPeerBuffer.new() + + # Get overall copy format code. + # 0 indicates the overall COPY format is textual (rows separated by newlines, columns separated by separator characters, etc). 1 indicates the overall copy format is binary (similar to DataRow format). See COPY for more information. + var overall_copy_format_code = response_buffer.subarray(5, 6) + overall_copy_format_code.invert() + + _unused = buffer.put_data(overall_copy_format_code) + buffer.seek(0) + + overall_copy_format_code = buffer.get_8() + + # Get the number of columns in the data to be copied. + var number_of_columns = response_buffer.subarray(7, 9) + number_of_columns.invert() + + _unused = buffer.put_data(number_of_columns) + buffer.seek(1) + + number_of_columns = buffer.get_16() + + # Get the format codes to be used for each column. + # Each must presently be zero (text) or one (binary). All must be zero if the overall copy format is textual. + for index in number_of_columns: + var format_code = response_buffer.subarray(10, 12) + format_code.invert() + + _unused = buffer.put_data(format_code) + buffer.seek(2 * index + 3) + + format_code = buffer.get_16() + + # The result. + print(format_code) + + push_warning("[PostgreSQLClient:%d] CopyOutResponse, no support." % [get_instance_id()]) + 'N': + ### NoticeResponse ### + + # Identifies the message as a notice. + + var notice_object := {} + + # The message body consists of one or more identified fields, followed by a zero byte as a terminator. + # Fields can appear in any order. + # For each field there is the following: + for champ_data in split_pool_byte_array(response_buffer.subarray(5, message_length - 1), 0): + var champ: String = champ_data.get_string_from_ascii() + + # A code identifying the field type; if zero, this is the message terminator and no string follows. + var field_type_code := champ[0] + + # The field value. + var value := champ.trim_prefix(field_type_code) + + match field_type_code: + 'S': + notice_object["severity"] = value + 'V': + notice_object["severity_no_localized"] = value + 'C': + notice_object["SQLSTATE_code"] = value + 'M': + notice_object["message"] = value + 'D': + notice_object["detail"] = value + 'H': + notice_object["hint"] = value + 'P': + notice_object["position"] = value + 'p': + notice_object["internal_position"] = value + 'q': + notice_object["internal_query"] = value + 'W': + notice_object["where"] = value + 's': + notice_object["schema_name"] = value + 't': + notice_object["table_name"] = value + 'c': + notice_object["column_name"] = value + 'd': + notice_object["constraint_name"] = value + 'n': + notice_object["constraint_name"] = value + 'F': + notice_object["file"] = value + 'L': + notice_object["line"] = value + 'R': + notice_object["routine"] = value + _: + # Since more field types might be added in future, frontends should silently ignore fields of unrecognized type. + pass + + var last_datas_command_sql = datas_command_sql.back() + + if last_datas_command_sql: + last_datas_command_sql.notice = notice_object + 'I': + ### EmptyQueryResponse ### + + # Identifies the message as a response to an empty query string. (This substitutes for CommandComplete.) + pass + 'K': + ### BackendKeyData #### + + # Identifies the message as cancellation key data. The frontend must save these values if it wishes to be able to issue CancelRequest messages later. + + # Get the process ID of this backend. + var process_backend_id_buffer = response_buffer.subarray(5, 8) + process_backend_id_buffer.invert() + + _unused = buffer.put_data(process_backend_id_buffer) + buffer.seek(4) + + # The result. + process_backend_id = buffer.get_u32() + + # Get the secret key of this backend. + var process_backend_secret_key_buffer = response_buffer.subarray(9, message_length) + process_backend_secret_key_buffer.invert() + + _unused = buffer.put_data(process_backend_secret_key_buffer) + buffer.seek(8) + + # The result. + process_backend_secret_key = buffer.get_u32() + 'R': + ### Authentication ### + + # Identifies the message as an authentication request. + + var authentication_type_data := response_buffer.subarray(5, 8) + + authentication_type_data.invert() + + _unused = buffer.put_data(authentication_type_data) + buffer.seek(4) + + var authentication_type := buffer.get_32() + + match authentication_type: + 0: + ### AuthenticationOk ### + + # Specifies that the authentication was successful. + + status = Status.STATUS_CONNECTING + 2: + ### AuthenticationKerberosV5 ### + + # Specifies that Kerberos V5 authentication is required. + + # rfc4120 + # No support + push_error("AuthenticationKerberosV5 No support") + close(false) + + response_buffer = PoolByteArray() + return + 3: + ### AuthenticationCleartextPassword ### + + # Specifies that a clear-text password is required. + + response_buffer = PoolByteArray() + return request('p', password_global.to_utf8()) + 5: + ### AuthentificationMD5Password ### + + # Specifies that an MD5-encrypted password is required. + + var hashing_context = HashingContext.new() + hashing_context.start(HashingContext.HASH_MD5) + hashing_context.update((password_global + user_global).md5_buffer().hex_encode().to_ascii() + response_buffer.subarray(9, 12)) + + response_buffer = PoolByteArray() + return request('p', ("md5" + hashing_context.finish().hex_encode()).to_ascii() + PoolByteArray([0])) + 6: + ### AuthenticationSCMCredential ### + + # Specifies that an SCM credentials message is required. + # No support + push_error("AuthenticationSCMCredential No support") + close(false) + + response_buffer = PoolByteArray() + return + 7: + ### AuthenticationGSS ### + + # Specifies that GSSAPI authentication is required. + # No support + push_error("AuthenticationGSS No support") + close(false) + + response_buffer = PoolByteArray() + return + 8: + ### AuthenticationGSSContinue ### + + # Specifies that this message contains GSSAPI or SSPI data. + # No support + push_error("AuthenticationGSSContinue No support") + close(false) + + response_buffer = PoolByteArray() + return + 9: + ### AuthenticationSSPI ### + + # Specifies that SSPI authentication is required. + + # No support + push_error("AuthenticationSSPI No support") + close(false) + + response_buffer = PoolByteArray() + return + 10: + ### AuthenticationSASL ### + + # Specifies that SASL authentication is required. + + # Get the message body is a list of SASL authentication mechanisms, in the server's order of preference. A zero byte is required as terminator after the last authentication mechanism name. + # For each mechanism, there is the following: + for name_sasl_authentication_mechanism in split_pool_byte_array(response_buffer.subarray(9, message_length - 1), 0): + match name_sasl_authentication_mechanism.get_string_from_ascii(): + "SCRAM-SHA-256": + ### SASLInitialResponse ### + + # Identifies the message as an initial SASL response. Note that this is also used for GSSAPI, SSPI and password response messages. The exact message type is deduced from the context. + + var crypto := Crypto.new() + + var nonce = Marshalls.raw_to_base64(crypto.generate_random_bytes(24)) + + client_first_message = "%c,,n=%s,r=%s" % ['n', "", nonce] # When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name that the client sends in the client-first-message. The user name that was already sent in the startup message is used instead. + + var len_client_first_message := get_32byte_invert(len(client_first_message), true) + + var sasl_initial_response := request('p', "SCRAM-SHA-256".to_ascii() + PoolByteArray([0]) + len_client_first_message + client_first_message.to_utf8()) + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.put_data(sasl_initial_response) + else: + _unused = peer.put_data(sasl_initial_response) + + response_buffer = PoolByteArray() + return + "SCRAM-SHA-256-PLUS": + continue # I'm still not done implementing SCRAM-SHA-256-PLUS, so we'll skip it for now. + + # /!\ Not end /!\ + + ### SASLInitialResponse ### + + # Identifies the message as an initial SASL response. Note that this is also used for GSSAPI, SSPI and password response messages. The exact message type is deduced from the context. + + var crypto := Crypto.new() + + var nonce = Marshalls.raw_to_base64(crypto.generate_random_bytes(24)) + + client_first_message = "%c,,n=%s,r=%s" % ['y', "", nonce] # When SCRAM-SHA-256-PLUS is used in PostgreSQL, the server will ignore the user name that the client sends in the client-first-message. The user name that was already sent in the startup message is used instead. + + var len_client_first_message := get_32byte_invert(len(client_first_message), true) + + var sasl_initial_response := request('p', "SCRAM-SHA-256-PLUS".to_ascii() + PoolByteArray([0]) + len_client_first_message + client_first_message.to_utf8()) + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.put_data(sasl_initial_response) + else: + _unused = peer.put_data(sasl_initial_response) + + response_buffer = PoolByteArray() + return + "SCRAM-SHA-1": + # No implemented. + pass + "SCRAM-SHA-1-PLUS": + # No implemented. + pass + "CRAM-MD5": + # No implemented. + pass + "CRAM-MD5-PLUS": + # No implemented. + pass + + push_error("[PostgreSQLClient:%d] No SASL mechanism offered by the backend is supported by the frontend for SASL authentication." % [get_instance_id()]) + + close(false) + + response_buffer = PoolByteArray() + return + 11: + ### AuthenticationSASLContinue ### + + # Specifies that this message contains a SASL challenge. + + # SCRAM-SHA-256 + var server_first_message = response_buffer.subarray(9, message_length).get_string_from_ascii() + + var server_nonce = server_first_message.split(',')[0].substr(2) + var server_salt = Marshalls.base64_to_raw(server_first_message.split(',')[1].substr(2)) + var server_iterations := int(server_first_message.split(',')[2].substr(2)) + + var client_final_message := "c=biws,r=%s" % [server_nonce] + + # On devrait passer le mot de passe (password_global) dans la fonction SASLprep (rfc7613) (or SASLprep, rfc4013) non implémenté si desous... + salted_password = pbkdf2(HashingContext.HASH_SHA256, password_global.to_utf8(), server_salt, server_iterations) + + var crypto = Crypto.new() + + var client_key = crypto.hmac_digest(HashingContext.HASH_SHA256, salted_password, "Client Key".to_ascii()) + + var hashing_context = HashingContext.new() + hashing_context.start(HashingContext.HASH_SHA256) + hashing_context.update(client_key) + var stored_key = hashing_context.finish() + + # AuthMessage is just a concatenation of the initial client message, server challenge, and client response (without ClientProof). + var client_first_message_bare = client_first_message.substr(3) + + client_first_message = "" + + auth_message = client_first_message_bare + ',' + server_first_message + ',' + client_final_message + var client_signature = crypto.hmac_digest(HashingContext.HASH_SHA256, stored_key, auth_message.to_utf8()) + + var client_proof_buffer := PoolByteArray() + for index in client_key.size(): + client_proof_buffer.append(client_key[index] ^ client_signature[index]) + + var client_proof := Marshalls.raw_to_base64(client_proof_buffer) + + client_final_message += ",p=" + client_proof + + var authentication_sasl_continue := request('p', client_final_message.to_ascii()) + + if stream_peer_ssl.get_status() == stream_peer_ssl.STATUS_CONNECTED: + stream_peer_ssl.put_data(authentication_sasl_continue) + else: + _unused = peer.put_data(authentication_sasl_continue) + 12: + ### AuthenticationSASLFinal ### + + # Specifies that SASL authentication has completed. + + var server_final_message = response_buffer.subarray(9, message_length).get_string_from_ascii() + + # The client verifies the proof from the server by calculating the ServerKey and the ServerSignature, then comparing its ServerSignature to that received from the server. + # If they are the same, the client has proof that the server has access to the ServerKey. + + var crypto = Crypto.new() + + var server_key = crypto.hmac_digest(HashingContext.HASH_SHA256, salted_password, "Server Key".to_ascii()) + + salted_password = PoolByteArray() + + var server_signature = crypto.hmac_digest(HashingContext.HASH_SHA256, server_key, auth_message.to_utf8()) + + auth_message = "" + + var server_proof := PoolByteArray() + for index in server_key.size(): + server_proof.append(server_key[index] ^ server_signature[index]) + + # Get server proof response + var server_proof_response = server_final_message.substr(2) + + if server_proof_response != Marshalls.raw_to_base64(server_signature): + # /!\ We should normally trigger the "authentication_error" signal but it is still not implemented... /!\ + push_error("[PostgreSQLClient:%d] An error occurred during SASL authentication. The SCRAM dialogue between the frontend and the backend does not end as expected. The server could not prove that it was in possession of ServerKey. The backend does not seem reliable for the frontend. The authentication attempt failed. Connection between frontend and backend interrupted." % [get_instance_id()]) + + close(false) + + response_buffer = PoolByteArray() + return + _: + push_error("[PostgreSQLClient:%d] The backend requires the frontend to use an authentication method that it does not support. Unknown authentication code." % [get_instance_id()]) + + close(false) + + response_buffer = PoolByteArray() + return + 'S': + ### ParameterStatus ### + + # Identifies the message as a run-time parameter status report. + var situation_report_data := split_pool_byte_array(response_buffer.subarray(5, message_length), 0) + + # Get the name of the run-time parameter being reported. + var parameter: String = situation_report_data[0].get_string_from_utf8() + + # Get the current value of the parameter. + var value: String = situation_report_data[1].get_string_from_utf8() + + # The result + parameter_status[parameter] = value + 'T': + ### RowDescription ### + + # Get the number of fields in a row (can be zero). + var number_of_fields_in_a_row := response_buffer.subarray(5, 6) + number_of_fields_in_a_row.invert() + + _unused = buffer.put_data(number_of_fields_in_a_row) + buffer.seek(4) + + postgresql_query_result_instance.number_of_fields_in_a_row = buffer.get_u16() + + # Then, for each field... + var cursor := 7 + for _index in postgresql_query_result_instance.number_of_fields_in_a_row: + # Get the field name. + var field_name := "" + + for octet in response_buffer.subarray(cursor, message_length): + field_name += char(octet) + + # If we get to the end of the chain, we get out of the loop. + if not octet: + break + + cursor += len(field_name) + + buffer = StreamPeerBuffer.new() + + # Get the object ID of the table. + # If the field can be identified as a column of a specific table, the object ID of the table; otherwise zero. + var table_object_id = response_buffer.subarray(cursor, cursor + 4) + table_object_id.invert() + + _unused = buffer.put_data(table_object_id) + buffer.seek(0) + + table_object_id = buffer.get_u32() + + # Get the attribute number of the column. + # If the field can be identified as a column of a specific table, the attribute number of the column; otherwise zero. + var column_index = response_buffer.subarray(cursor + 5, cursor + 6) + column_index.invert() + + _unused = buffer.put_data(column_index) + buffer.seek(4) + + column_index = buffer.get_u16() + + # Get the object ID of the field's data type. + var type_object_id = response_buffer.subarray(cursor + 7, cursor + 10) + type_object_id.invert() + + _unused = buffer.put_data(type_object_id) + buffer.seek(6) + + type_object_id = buffer.get_u32() + + # Get the data type size (see pg_type.typlen). + # Note that negative values denote variable-width types. + var data_type_size = response_buffer.subarray(cursor + 11, cursor + 12) + data_type_size.invert() + + _unused = buffer.put_data(data_type_size) + buffer.seek(10) + + data_type_size = buffer.get_u16() + + # Get the type modifier (see pg_attribute.atttypmod). + # The meaning of the modifier is type-specific. + var type_modifier = response_buffer.subarray(cursor + 13, cursor + 16) + type_modifier.invert() + + _unused = buffer.put_data(type_modifier) + buffer.seek(12) + + type_modifier = buffer.get_u32() + + # Get the format code being used for the field. + # Currently will be zero (text) or one (binary). + # In a RowDescription returned from the statement variant of Describe, the format code is not yet known and will always be zero. + var format_code = response_buffer.subarray(cursor + 17, cursor + 18) + format_code.invert() + + _unused = buffer.put_data(format_code) + buffer.seek(16) + + format_code = buffer.get_u16() + + cursor += 19 + + # The result. + postgresql_query_result_instance.row_description.append({ + "field_name": field_name, + "table_object_id": table_object_id, + "column_index": column_index, + "type_object_id": type_object_id, + "data_type_size": data_type_size, + "type_modifier": type_modifier, + "format_code": format_code + }) + 'V': + ### FunctionCallResponse ### + + # Identifies the message as a function call result. + push_error("FunctionCallResponse no implemented.") + 'W': + ### CopyBothResponse ### + + # The message "CopyBothResponse" identifies the message as a Start Copy Both response. This message is used only for Streaming Replication. + + buffer = StreamPeerBuffer.new() + + # Get overall copy format code. + # 0 indicates the overall COPY format is textual (rows separated by newlines, columns separated by separator characters, etc). 1 indicates the overall copy format is binary (similar to DataRow format). See COPY for more information. + var overall_copy_format_code = response_buffer.subarray(5, 6) + overall_copy_format_code.invert() + + _unused = buffer.put_data(overall_copy_format_code) + buffer.seek(0) + + overall_copy_format_code = buffer.get_8() + + # Get the number of columns in the data to be copied. + var number_of_columns = response_buffer.subarray(7, 9) + number_of_columns.invert() + + _unused = buffer.put_data(number_of_columns) + buffer.seek(1) + + number_of_columns = buffer.get_16() + + # Get the format codes to be used for each column. + # Each must presently be zero (text) or one (binary). All must be zero if the overall copy format is textual. + for index in number_of_columns: + var format_code = response_buffer.subarray(10, 12) + format_code.invert() + + _unused = buffer.put_data(format_code) + buffer.seek(2 * index + 3) + + format_code = buffer.get_16() + + # The result. + print(format_code) + + push_warning("[PostgreSQLClient:%d] CopyBothResponse, no support." % [get_instance_id()]) + 'Z': + ### ReadyForQuery ### + + # Identifies the message type. ReadyForQuery is sent whenever the backend is ready for a new query cycle. + + # Get current backend transaction status indicator. + match char(response_buffer[message_length]): + 'I': + # If idle (if not in a transaction block). + prints("Not in a transaction block.") + 'T': + # If in a transaction block. + prints("In a transaction block.") + 'E': + # If in a failed transaction block (queries will be rejected until block is ended). + prints("In a failed transaction block.") + _: + # We close the connection with the backend if current backend transaction status indicator is not recognized. + close(false) + + var data_returned := datas_command_sql + + datas_command_sql = [] + response_buffer = PoolByteArray() + + + if status == Status.STATUS_CONNECTING: + status = Status.STATUS_CONNECTED + + # Once logged in, the database password and username are deleted from memory for security reasons. + password_global = "" + user_global = "" + + emit_signal("connection_established") + + return data_returned + 'c': + ### CopyDone ### + + # Identifies the message as a COPY-complete indicator. + print("CopyDone") + 'd': + ### CopyData ### + + # Identifies the message as COPY data. + + # Get data that forms part of a COPY data stream. Messages sent from the backend will always correspond to single data rows. + var data := response_buffer.subarray(5, message_length) + + # The result + print(data) + 'n': + ### NoData ### + + # Identifies the message as a no-data indicator. + pass + 's': + ### ReadyForQuery ### + + #Identifies the message as a portal-suspended indicator. Note this only appears if an Execute message's row-count limit was reached. + pass + 't': + ### ParameterDescription ### + + # Identifies the message as a parameter description. + + # Get the number of parameters used by the statement (can be zero). + var number_of_parameters = response_buffer.subarray(5, 6) + number_of_parameters.invert() + + _unused = buffer.put_data(number_of_parameters) + buffer.seek(4) + + number_of_parameters = buffer.get_16() + + # Then, for each parameter, there is the following: + var data_types = [] + var cursor := 7 + for index in number_of_parameters: + # Get the object ID of the parameter data type. + var object_id = response_buffer.subarray(cursor, cursor + 4) + object_id.invert() + + _unused = buffer.put_data(object_id) + buffer.seek(cursor + index - 1) + + data_types.append(buffer.get_32()) + + cursor += 5 + + # The result. + print(data_types) + 'v': + ### NegotiateProtocolVersion ### + + # Identifies the message as a protocol version negotiation message. + + # Get newest minor protocol version supported by the server for the major protocol version requested by the client. + var minor_protocol_version = response_buffer.subarray(5, 8) + minor_protocol_version.invert() + + _unused = buffer.put_data(minor_protocol_version) + buffer.seek(4) + + minor_protocol_version = buffer.get_u32() + + # Get the number of protocol options not recognized by the server. + var number_of_options = response_buffer.subarray(9, 13) + number_of_options.invert() + + _unused = buffer.put_data(number_of_options) + buffer.seek(8) + + number_of_options = buffer.get_u32() + + # Then, for each protocol option not recognized by the server... + var _cursor := 0 + for _index in number_of_options: + # Get the option name. + pass + + # The result. + prints(minor_protocol_version) + '1': + ### ParseComplete ### + + # Identifies the message as a Parse-complete indicator. + pass + '2': + ### BindComplete ### + + # Identifies the message as a Bind-complete indicator. + pass + '3': + ### CloseComplete ### + + # Identifies the message as a Close-complete indicator. + pass + var message_type: + # We close the connection with the backend if the type of message is not recognized. + + status = Status.STATUS_ERROR + + push_error("[PostgreSQLClient:%d] The type of message sent by the backend is not recognized (%c)." % [get_instance_id(), message_type]) + + close(false) + + # The response from the server can contain several messages, we read the message then delete the message to be processed to read the next one in the loop. + if response_buffer.size() != message_length + 1: + response_buffer = response_buffer.subarray(message_length + 1, -1) + else: + response_buffer.resize(0) + + if client.get_status() != StreamPeerTCP.STATUS_CONNECTED: + break diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuConfig.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuConfig.gd new file mode 100644 index 0000000..6f5bfbd --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuConfig.gd @@ -0,0 +1,134 @@ +extends Control + + +# https://stackoverflow.com/a/65774028 +# Be Sure to make these Vars as OnReadys; you can read up on it here. + +# Items to Fill the dropdown Lists +onready var keyboardContents = ["Qwerty", "Dvorak", "Alphabetical"] + +onready var themeContents = ["White on Black", "Black on White"] + +onready var saveObject = get_node('/root/GlobalSaveInstance') + + +#res://SettingsMenuControl.tscn + +# Vars For UI Widgets +onready var NameVar = get_node('Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/DisplayNameLineEdit') + +onready var NRiskVar = get_node('Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/VBoxRiskFactor/RiskSlider') + +onready var FontVar = get_node("Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox/FontSizeSlider") + +onready var BrightnessVar = get_node('Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox/BrightnessSlider') + +onready var VolumeVar = get_node("Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/VolumeSlider") + +onready var ClosedCaptionsVar = get_node('Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxClosedCaptions/ClosedCaptionsCheckBox') + +onready var ConsoleCommandVar = get_node('Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxDevConsole/DevConsoleCheckbox') + +onready var saveButton = get_node("Panel/HBoxBottomRow/SaveButton") + +onready var bKeyboardEnabled = get_node("Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/HBoxVirtualKeyboardEnabled/VisualKeyboardCheckBox") + +onready var keyboardLayoutList = get_node('Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/LayoutItemList') + +onready var themeChoiceList = get_node('Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/ThemeItemList') + + +var iniFile = ConfigFile.new() + +func saveToInstance(): + #Save to Singleton, so saveFile does not need to be constantly read + saveObject.settingsInstance.inputName = NameVar.text + saveObject.settingsInstance.riskFactor = NRiskVar.value + saveObject.settingsInstance.fontSize = FontVar.value + saveObject.settingsInstance.volume = VolumeVar.value + saveObject.settingsInstance.bClosedCaptions = ClosedCaptionsVar.is_pressed() + saveObject.settingsInstance.bdevConsole = ConsoleCommandVar.is_pressed() + saveObject.settingsInstance.bVirtualKeyboard = bKeyboardEnabled.is_pressed() + var savedKeyboardItems = keyboardLayoutList.get_selected_items() + var keyboardSelection = savedKeyboardItems[0] + saveObject.settingsInstance.visualKeyboardLayout = keyboardSelection + var savedThemeItems = themeChoiceList.get_selected_items() + var themeSelection = savedThemeItems[0] + saveObject.settingsInstance.themeChoiceInt = themeSelection + #Trigger re-load of the file name + saveObject.load_settings_file() + theme=load(saveObject.settingsInstance.themeFile) + + +func saveFile(): + iniFile.set_value("player_preferences", "player_name", NameVar.text) + iniFile.set_value("player_preferences", "risk_threshold", NRiskVar.value) + iniFile.set_value("visual_controls", "font_size", FontVar.value) + iniFile.set_value("visual_controls", "brightness", BrightnessVar.value) + + iniFile.set_value("general_settings", "volume", VolumeVar.value) + iniFile.set_value("general_settings", "closed_captions", ClosedCaptionsVar.is_pressed()) + iniFile.set_value("general_settings", "dev_console", ConsoleCommandVar.is_pressed()) + + print(keyboardLayoutList.get_selected_items()) + + var savedKeyboardItems = keyboardLayoutList.get_selected_items() + + var keyboardSelection = savedKeyboardItems[0] + + var savedThemeItems = themeChoiceList.get_selected_items() + + var themeSelection = savedThemeItems[0] + + print(typeof(keyboardSelection)) + + iniFile.set_value("virtual_keyboard", "keyboard_layout", keyboardSelection) + + iniFile.set_value("theme", "theme_selection", themeSelection) + + iniFile.save("res://_userFiles/PlayerPreferences.cfg") + +#DKM TEMP: can this be done at singleton, initial load level instead of here? +func loadFile(): + pass + +func _process(delta): + if saveButton.pressed == true: + if NameVar.text == "": + print("Please input a name") + + if NameVar.text != "": + # Save to the template instance + saveToInstance() + + saveFile() + print('saveFileRan') + +func _ready(): + #Get the singleton's values for initial settings: + NameVar.text = saveObject.settingsInstance.inputName + NRiskVar.value = saveObject.settingsInstance.riskFactor + FontVar.value = saveObject.settingsInstance.fontSize + ClosedCaptionsVar.pressed = saveObject.settingsInstance.bClosedCaptions + ConsoleCommandVar.pressed = saveObject.settingsInstance.bdevConsole + bKeyboardEnabled.pressed = saveObject.settingsInstance.bVirtualKeyboard + + print(NameVar.get_path()) + +# Init Keyboard Layout List + for i in range(3): + keyboardLayoutList.add_item(keyboardContents[i],null,true) + + keyboardLayoutList.select(0,true) + +# Init Theme Choice List + + for i in range(2): + themeChoiceList.add_item(themeContents[i],null,true) + + keyboardLayoutList.select(saveObject.settingsInstance.visualKeyboardLayout,true) + + themeChoiceList.select(saveObject.settingsInstance.themeChoiceInt,true) + + #Load selected theme: + theme=load(saveObject.settingsInstance.themeFile) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuControl.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuControl.tscn new file mode 100644 index 0000000..fce3461 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/SettingsMenuControl.tscn @@ -0,0 +1,322 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://screens/SettingsMenuConfig.gd" type="Script" id=1] +[ext_resource path="res://assets/liberation_serif.tres" type="DynamicFont" id=2] +[ext_resource path="res://userInterface/But_ChangeScene.tscn" type="PackedScene" id=3] + +[sub_resource type="Theme" id=1] +default_font = ExtResource( 2 ) + +[node name="Control" type="Control"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -512.0 +margin_top = -300.0 +margin_right = 512.0 +margin_bottom = 300.0 +theme = SubResource( 1 ) +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Panel" type="Panel" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -512.0 +margin_top = -302.0 +margin_right = 512.0 +margin_bottom = 298.0 +rect_pivot_offset = Vector2( -276, 469 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxContainer" type="HBoxContainer" parent="Panel"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -298.5 +margin_right = 298.5 +margin_bottom = 19.0 +custom_constants/separation = 60 +alignment = 1 + +[node name="RootVboxVisualControls" type="VBoxContainer" parent="Panel/HBoxContainer"] +margin_right = 98.0 +margin_bottom = 19.0 + +[node name="VisualControlsLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls"] +margin_right = 98.0 +margin_bottom = 19.0 +text = "Visual Controls" + +[node name="VisualControlsVBox" type="VBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -77.5 +margin_top = 30.0 +margin_right = 77.5 +margin_bottom = 52.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxFontSize" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox"] +margin_right = 155.0 +margin_bottom = 19.0 + +[node name="FontLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox/HBoxFontSize"] +margin_right = 64.0 +margin_bottom = 19.0 +text = "Font Size:" + +[node name="FontSizeSlider" type="HSlider" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox"] +margin_top = 23.0 +margin_right = 155.0 +margin_bottom = 39.0 +min_value = 1.0 +max_value = 5.0 +value = 5.0 +rounded = true +tick_count = 10 +ticks_on_borders = true + +[node name="BrightnessLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox"] +margin_top = 43.0 +margin_right = 155.0 +margin_bottom = 62.0 +text = "Brightness:" + +[node name="BrightnessSlider" type="HSlider" parent="Panel/HBoxContainer/RootVboxVisualControls/VisualControlsLabel/VisualControlsVBox"] +margin_top = 66.0 +margin_right = 155.0 +margin_bottom = 82.0 +min_value = 1.0 +max_value = 5.0 +value = 5.0 +rounded = true +tick_count = 10 +ticks_on_borders = true + +[node name="RootVboxPlayerPreferences" type="VBoxContainer" parent="Panel/HBoxContainer"] +margin_left = 158.0 +margin_right = 275.0 +margin_bottom = 19.0 + +[node name="Label" type="Label" parent="Panel/HBoxContainer/RootVboxPlayerPreferences"] +margin_right = 117.0 +margin_bottom = 19.0 +text = "Player Preferances" + +[node name="VBoxPlayerPreferances" type="VBoxContainer" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label"] +margin_left = -18.5 +margin_top = 30.0 +margin_right = 126.5 +margin_bottom = 125.0 + +[node name="HBoxDisplayName" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances"] +margin_right = 145.0 +margin_bottom = 19.0 + +[node name="DisplayNameLabel" type="Label" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/HBoxDisplayName"] +margin_right = 95.0 +margin_bottom = 19.0 +text = "Display Name:" + +[node name="DisplayNameLineEdit" type="LineEdit" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances"] +margin_top = 23.0 +margin_right = 145.0 +margin_bottom = 52.0 + +[node name="VBoxRiskFactor" type="VBoxContainer" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances"] +margin_top = 56.0 +margin_right = 145.0 +margin_bottom = 95.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxRiskFactor" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/VBoxRiskFactor"] +margin_right = 145.0 +margin_bottom = 19.0 + +[node name="RiskFactorLabel" type="Label" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/VBoxRiskFactor/HBoxRiskFactor"] +margin_right = 145.0 +margin_bottom = 19.0 +text = "Risk Factor Threshold:" + +[node name="RiskSlider" type="HSlider" parent="Panel/HBoxContainer/RootVboxPlayerPreferences/Label/VBoxPlayerPreferances/VBoxRiskFactor"] +margin_top = 23.0 +margin_right = 145.0 +margin_bottom = 39.0 +min_value = 1.0 +max_value = 5.0 +value = 5.0 +rounded = true +tick_count = 10 +ticks_on_borders = true + +[node name="RootVboxGeneralSettings" type="VBoxContainer" parent="Panel/HBoxContainer"] +margin_left = 335.0 +margin_right = 439.0 +margin_bottom = 19.0 + +[node name="GeneralSettingsLabel" type="Label" parent="Panel/HBoxContainer/RootVboxGeneralSettings"] +margin_right = 104.0 +margin_bottom = 19.0 +text = "General Settings" + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -77.5 +margin_top = 30.0 +margin_right = 77.5 +margin_bottom = 120.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label" type="Label" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer"] +margin_right = 155.0 +margin_bottom = 19.0 +rect_pivot_offset = Vector2( 62, 14 ) +text = "Volume:" + +[node name="VolumeSlider" type="HSlider" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer"] +margin_top = 23.0 +margin_right = 155.0 +margin_bottom = 39.0 +max_value = 10.0 +rounded = true +tick_count = 10 +ticks_on_borders = true + +[node name="HBoxClosedCaptions" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer"] +margin_top = 43.0 +margin_right = 155.0 +margin_bottom = 70.0 + +[node name="ClosedCaptionsLabel" type="Label" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxClosedCaptions"] +margin_top = 4.0 +margin_right = 108.0 +margin_bottom = 23.0 +text = "Closed Captions:" + +[node name="ClosedCaptionsCheckBox" type="CheckBox" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxClosedCaptions"] +margin_left = 112.0 +margin_right = 136.0 +margin_bottom = 27.0 + +[node name="HBoxDevConsole" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer"] +margin_top = 74.0 +margin_right = 155.0 +margin_bottom = 101.0 + +[node name="DevConsoleLabel" type="Label" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxDevConsole"] +margin_top = 4.0 +margin_right = 126.0 +margin_bottom = 23.0 +text = "Developer Console:" + +[node name="DevConsoleCheckbox" type="CheckBox" parent="Panel/HBoxContainer/RootVboxGeneralSettings/GeneralSettingsLabel/VBoxContainer/HBoxDevConsole"] +margin_left = 130.0 +margin_right = 154.0 +margin_bottom = 27.0 + +[node name="RootVboxVisualControls2" type="VBoxContainer" parent="Panel/HBoxContainer"] +margin_left = 499.0 +margin_right = 597.0 +margin_bottom = 19.0 + +[node name="Label2" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls2"] +margin_right = 98.0 +margin_bottom = 19.0 +text = "Visual Controls" + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -77.5 +margin_top = 30.0 +margin_right = 77.5 +margin_bottom = 52.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxThemes" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer"] +margin_right = 155.0 +margin_bottom = 19.0 + +[node name="ThemesLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/HBoxThemes"] +margin_right = 119.0 +margin_bottom = 19.0 +text = "Theme Preference:" + +[node name="ThemeItemList" type="ItemList" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer"] +margin_top = 23.0 +margin_right = 155.0 +margin_bottom = 32.0 +auto_height = true + +[node name="HBoxVirtualKeyboardEnabled" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer"] +margin_top = 36.0 +margin_right = 155.0 +margin_bottom = 63.0 + +[node name="VisualKeyBoardLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/HBoxVirtualKeyboardEnabled"] +margin_top = 4.0 +margin_right = 110.0 +margin_bottom = 23.0 +text = "Virtual Keyboard" + +[node name="VisualKeyboardCheckBox" type="CheckBox" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/HBoxVirtualKeyboardEnabled"] +margin_left = 114.0 +margin_right = 138.0 +margin_bottom = 27.0 + +[node name="HBoxKeyboardLayout" type="HBoxContainer" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer"] +margin_top = 67.0 +margin_right = 155.0 +margin_bottom = 86.0 + +[node name="LayoutLabel" type="Label" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer/HBoxKeyboardLayout"] +margin_right = 120.0 +margin_bottom = 19.0 +text = "Layout Preference:" + +[node name="LayoutItemList" type="ItemList" parent="Panel/HBoxContainer/RootVboxVisualControls2/Label2/VBoxContainer"] +margin_top = 90.0 +margin_right = 155.0 +margin_bottom = 99.0 +auto_height = true + +[node name="HBoxBottomRow" type="HBoxContainer" parent="Panel"] +anchor_left = 0.500488 +anchor_right = 0.595215 +margin_left = -48.5 +margin_top = 200.0 +margin_right = 48.5 +margin_bottom = 225.0 +alignment = 1 +__meta__ = { +"_edit_use_anchors_": true +} + +[node name="SaveButton" type="Button" parent="Panel/HBoxBottomRow"] +margin_left = 24.0 +margin_right = 121.0 +margin_bottom = 25.0 +text = "Save Settings" + +[node name="But_ChangeScene" parent="Panel/HBoxBottomRow" instance=ExtResource( 3 )] +margin_left = 125.0 +margin_right = 170.0 +margin_bottom = 25.0 +text = "Back" +next_scene_path = "res://screens/MenuScreen.tscn" diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Temp_Button.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Temp_Button.gd new file mode 100644 index 0000000..d5fbca5 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/Temp_Button.gd @@ -0,0 +1,17 @@ +extends Button + + +# Declare member variables here. Examples: +# var a: int = 2 +# var b: String = "text" +var tempToggle = 0 + +func _on_Button_button_up(): + var controlNode = get_node("../../") + print(controlNode.name) + if(tempToggle == 0): + controlNode.theme=load("res://assets/ui_controlNode_dark_theme.tres") + tempToggle = 1 + else: + controlNode.theme=load("res://assets/ui_controlNode_light_theme.tres") + tempToggle = 0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/grabFocus.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/grabFocus.gd new file mode 100644 index 0000000..f3dcd9e --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/screens/grabFocus.gd @@ -0,0 +1,7 @@ +extends Control + +#GRAB FOCUS: simple script for temp files to grab focus + + +func _ready() -> void: + $Title/But_ChangeScene.grab_focus() diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.gd new file mode 100644 index 0000000..bfb86eb --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.gd @@ -0,0 +1,20 @@ +#BUT_CHANGESCENE: +# Generic template script allowing GUI linking of scenes by button press. + +tool +extends Button + +#Creates param usable in the UI; and the params next to export make it string and file browser +export(String, FILE) var next_scene_path: = "" + + + +func _on_But_NewGame_button_up(): + var error_on_change=get_tree().change_scene(next_scene_path) + if error_on_change !=0: + print("ERROR: ",error_on_change) + + +func _get_configuration_warning() -> String: + return "next_scene_path must be set for this button to work" if next_scene_path == "" else "" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.tscn new file mode 100644 index 0000000..80849fc --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ChangeScene.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://UserInterface/But_ChangeScene.gd" type="Script" id=1] + +[node name="But_ChangeScene" type="Button"] +margin_right = 130.0 +margin_bottom = 24.0 +size_flags_vertical = 3 +text = "New Game" +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="button_up" from="." to="." method="_on_But_NewGame_button_up"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History.gd new file mode 100644 index 0000000..6406e14 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History.gd @@ -0,0 +1,39 @@ +#BUT_HISTORY: +# Unique script attached to the But_History to hide/show history versus +# current game page. + +tool +extends Button + +onready var game_history_array = get_node("/root/History").historyScreensSingleton.output_history_array + +var is_history = false + + +func _on_But_History_button_up(): + var history_pager_button = get_node("../../ItemList/But_History_Page") + var history_rows_node = get_node("../../GameInfo/HistoryRows") + var current_text_node = get_node("../../GameInfo/CurrentText") + var option_one = get_node("../../InputArea/VBoxContainer/option1") + var option_two = get_node("../../InputArea/VBoxContainer/option2") + var option_three = get_node("../../InputArea/VBoxContainer/option3") + + if(!is_history): + if(game_history_array != null): + history_rows_node.add_child(game_history_array[0]) + history_pager_button.show() + history_rows_node.show() + current_text_node.hide() + option_one.hide() + option_two.hide() + option_three.hide() + is_history = true + else: + history_pager_button.hide() + history_rows_node.hide() + current_text_node.show() + option_one.show() + option_two.show() + option_three.show() + is_history = false + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History_Page.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History_Page.gd new file mode 100644 index 0000000..f63f1e3 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_History_Page.gd @@ -0,0 +1,21 @@ +#BUT_HISTORY_PAGE: +# Unique paging script for showing next page in the history game's history +# array. + + +tool +extends Button + +var current_page = 0 + +func _on_But_History_Page_button_up(): + var game_history_array = get_node("/root/History").historyScreensSingleton.output_history_array + var history_rows_node = get_node("../../GameInfo/HistoryRows") + if(current_page < game_history_array.size()-1): + current_page += 1 + else: + current_page = 0 + history_rows_node.remove_child(history_rows_node.get_child(0)) + history_rows_node.add_child(game_history_array[current_page]) + + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_PlayButton.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_PlayButton.gd new file mode 100644 index 0000000..3303ae8 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_PlayButton.gd @@ -0,0 +1,28 @@ +#BUT_CHANGESCENE: +# Generic template script allowing GUI linking of scenes by button press. + +tool +extends Button + +#Creates param usable in the UI; and the params next to export make it string and file browser +export(String, FILE) var next_scene_path: = "" + +onready var pSingleton = get_node("/root/PlayerCharacter").pc + +var tempToggle = 0 + +func _on_But_NewGame_button_up(): + if(pSingleton.pcText.length() < 1): + #print("GOT IT! Popup msg: " + $PopupDialog/WarnText.text) + var alertPopup = get_node("../PopupDialog") + var alertPopupText = get_node("../PopupDialog/WarnText") + alertPopupText.text = "No player was loaded! Please load a character to begin game." + alertPopup.popup_centered() + return + else: + get_tree().change_scene(next_scene_path) + + +func _get_configuration_warning() -> String: + return "next_scene_path must be set for this button to work" if next_scene_path == "" else "" + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.gd new file mode 100644 index 0000000..1c6d989 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.gd @@ -0,0 +1,34 @@ +#BUT_QUIT: +# Unique script for ending a game. Will additionally perform or call needed +# shut down and close-out functionality. + +extends Button + +#var history_JSON = "user://history.json" + + +#DKM TEMP: save history is only here temporarily -- needs to move upstream. +func _on_But_Quit_button_up(): + get_tree().quit() + + +#JSON: requires dictionaries: +#func _saveHistory_JSON() -> void: +# var history_screens_arr = get_node("/root/History").historyScreensSingleton.output_history_array +# var file = File.new() +# file.open(history_JSON, File.WRITE) +# file.store_string(to_json(history_screens_arr)) +# +# file.close() +# # #DKM TEMP: +# print("Saved history array size should be: " + str(history_screens_arr.size())) + + +#DKM TEMP: +#tres file: +#func _saveHistory() -> void: +# var history_screens = get_node("/root/History").historyScreensSingleton +# assert(ResourceSaver.save("user://history.tres", history_screens)==OK) +# #DKM TEMP: +# print("Saved history array size: " + str(history_screens.output_history_array.size())) + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.tscn new file mode 100644 index 0000000..e52c053 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_Quit.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://UserInterface/But_Quit.gd" type="Script" id=1] + +[node name="But_Quit" type="Button"] +margin_top = 240.0 +margin_right = 179.0 +margin_bottom = 284.0 +text = "Quit" +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="button_up" from="." to="." method="_on_But_Quit_button_up"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ResumeGame.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ResumeGame.gd new file mode 100644 index 0000000..ee37c4f --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_ResumeGame.gd @@ -0,0 +1,14 @@ +tool +extends Button + + +func _on_But_ResumeGame_button_up(): + var root = get_node("/root") + var thisScene = get_node("/root/MoreOptions") + var gameSingleton = get_node("/root/GameCurrent") + var gameScene = gameSingleton.gameCurrent_scene + root.remove_child(thisScene) + #DKM TEMP: cleanup this scene! + thisScene.queue_free() + root.add_child(gameScene) + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_SaveSettings.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_SaveSettings.gd new file mode 100644 index 0000000..0b09f53 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/But_SaveSettings.gd @@ -0,0 +1,80 @@ +#BUT_SAVESETTINGS: +# Unique script for saving settings on player settings scene. + + +#Tool lets you any code in editor, such as plugins +tool +extends Button + +#Creates param usable in the UI; and the params next to export make it string and file browser +export(String, FILE) var next_scene_path: = "" + +#Button response: save settings and move on. +func _on_But_NewGame_button_up(): + var inputName = get_node("../../VBoxContainer/HBoxContainer/input_name") + var inputRisk = get_node("../../VBoxContainer/HBoxContainer2/input_risk") + _saveSettings(inputName.text, inputRisk.text) + get_tree().change_scene(next_scene_path) + + +#HELPER FUNCTIONS: +func _get_configuration_warning() -> String: + return "next_scene_path must be set for this button to work" if next_scene_path == "" else "" + + +#CONFIG/INI SAVE: +func _saveSettings(inputSettings : String, riskFactor : String) -> void: + var player_settings = get_node("/root/PlayerSettings") + player_settings.playerSettingsSingleton.inputName = inputSettings + player_settings.playerSettingsSingleton.riskFactor = riskFactor + var config = ConfigFile.new() + + config.set_value("Temp player","InputSettings", inputSettings) + config.set_value("Temp player","RiskFactor", riskFactor) + + config.save("user://settings.cfg") + +#JSON SAVE: +#func _saveSettings(inputSettings : String, riskFactor : String) -> void: +# var player_settings = get_node("/root/PlayerSettings") +# player_settings.playerSettingsSingleton.inputName = inputSettings +# player_settings.playerSettingsSingleton.riskFactor = riskFactor +# #Temp: +# var temp_manual_JSON = { +# "playerSettingsTemplate": { +# "inputName": inputSettings, +# "riskFactor": riskFactor +# } +# } +# +# #Save to file (JSON for now) +# var settings_file = "user://testPlayerSettings.sav" +# var file = File.new() +# if file.open(settings_file, File.WRITE) != 0: +# print("Cannot write temporary file to: " + settings_file) +# else: +# file.store_line(to_json(temp_manual_JSON)) +# file.close() + + +#****This save Settings functions as designed; but modified to work with alternate approach of loading +#func _saveSettings(inputSettings : String, riskFactor : String) -> void: + #Debugging: +# print("Input name: " + inputSettings + "; and risk factor set to : " + riskFactor) +# var player_settings = get_node("/root/PlayerSettings") +# player_settings.playerSettingsSingleton.inputName = inputSettings +# player_settings.playerSettingsSingleton.riskFactor = riskFactor + + #Save to file (for now) +# if settings_save_file_name == "": +# settings_save_file_name = "settings.save" +# var settings_file = "user://" + settings_save_file_name +# var file = File.new() +# file.open(settings_file, File.WRITE) +# file.store_var(player_settings.playerSettingsSingleton.inputName) + #DKM TEMP: To save object; removed for testing + #file.store_var(player_settings.playerSettingsSingleton, true) +# file.close() + + + diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.gd new file mode 100644 index 0000000..87f2395 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.gd @@ -0,0 +1,5 @@ +extends VBoxContainer + +func set_text(input: String, response: String): + $InputHistory.text = input + $Response.text = response diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.tscn new file mode 100644 index 0000000..8449256 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/InputResponse.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://UserInterface/Response.tscn" type="PackedScene" id=2] +[ext_resource path="res://UserInterface/InputResponse.gd" type="Script" id=3] + +[node name="InputResponse" type="VBoxContainer"] +margin_right = 984.0 +margin_bottom = 68.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="InputHistory" type="Label" parent="."] +margin_right = 984.0 +margin_bottom = 14.0 +text = " > This is what user selected" +autowrap = true + +[node name="Response" parent="." instance=ExtResource( 2 )] +margin_top = 18.0 +margin_bottom = 32.0 diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.gd new file mode 100644 index 0000000..f034b3a --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.gd @@ -0,0 +1,49 @@ +#LOCALE CLASS: +# Template script for the Locale scene; allows for connecting exits, and also +# maintains a visited bool (currently un-used) and takes additional +# options via the GUI: +# 1. Name +# 2. Description +# 3. The 3 option strings available at the location +# + + +extends PanelContainer +#Allows Godot to handle autocomplete and 'register' class +class_name Locale + +var locale_name = "Location Name" +var locale_description = "This is the description of the location." +var locale_action = "Default action" +var locale_action_params = [] +var options_array = [] +var destinations_array = [] + + +var visited = false; + +var exits: Dictionary = {} + +#DKM TEMP: right now connects both directions, but can make an alt func that c +# connects just one way for example (for one-way-doors) +# currently not in use, but the override defaults false but if passed can let +# you apply custom direction +func connect_exit(direction: String, locale: Locale, override_direction: bool = false): + if(!override_direction): + match direction: + "west": + exits[direction] = locale + locale.exits["east"] = self + "east": + exits[direction] = locale + locale.exits["west"] = self + "north": + exits[direction] = locale + locale.exits["south"] = self + "south": + exits[direction] = locale + locale.exits["north"] = self + _: + printerr("Tried to connect invalid direction: %s", direction) + else: + exits[direction] = locale diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.tscn new file mode 100644 index 0000000..eb96470 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Locale.tscn @@ -0,0 +1,35 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://userInterface/Locale.gd" type="Script" id=3] + +[node name="Locale" type="PanelContainer"] +margin_right = 250.001 +margin_bottom = 200.0 +rect_min_size = Vector2( 250, 200 ) +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarginContainer" type="MarginContainer" parent="."] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 243.001 +margin_bottom = 193.0 + +[node name="Rows" type="VBoxContainer" parent="MarginContainer"] +margin_right = 236.0 +margin_bottom = 186.0 + +[node name="LocaleName" type="Label" parent="MarginContainer/Rows"] +margin_right = 236.0 +margin_bottom = 14.0 +text = "Locale Name" +align = 1 + +[node name="LocaleDescription" type="Label" parent="MarginContainer/Rows"] +margin_top = 18.0 +margin_right = 236.0 +margin_bottom = 49.0 +text = "This is the description text for the locale. " +autowrap = true diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.gd new file mode 100644 index 0000000..1de5518 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.gd @@ -0,0 +1,10 @@ +extends Button + +signal option_pressed(destinationLabel) + +var destinationLabel + +#DKM TEMP: test +func _on_Option_button_up() -> void: + print("Button pushed!") + emit_signal("option_pressed", destinationLabel) diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.tscn new file mode 100644 index 0000000..0da50d0 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Option.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://userInterface/Option.gd" type="Script" id=1] + +[node name="Option" type="Button"] +margin_top = 30.0 +margin_right = 984.0 +margin_bottom = 68.0 +text = "Option # " +align = 0 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="button_up" from="." to="." method="_on_Option_button_up"] diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Response.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Response.tscn new file mode 100644 index 0000000..3891ae3 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Response.tscn @@ -0,0 +1,11 @@ +[gd_scene format=2] + +[node name="Response" type="Label"] +margin_top = 30.0 +margin_right = 984.0 +margin_bottom = 68.0 +text = "Game text continues here... " +autowrap = true +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Title.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Title.tscn new file mode 100644 index 0000000..dc37d75 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/Title.tscn @@ -0,0 +1,14 @@ +[gd_scene format=2] + +[node name="Title" type="Label"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -110.5 +margin_top = 114.422 +margin_right = 110.5 +margin_bottom = 180.422 +text = "Main Menu" +align = 1 +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.gd b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.gd new file mode 100644 index 0000000..d144d48 --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.gd @@ -0,0 +1,16 @@ +extends Node2D + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# pass diff --git a/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.tscn b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.tscn new file mode 100644 index 0000000..5ef58fb --- /dev/null +++ b/Phase2/Databases/Sandbox_Test_Godot_Code/Doug/Database_Testing_2023_1001A/userInterface/testExample.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://userInterface/testExample.gd" type="Script" id=1] + +[node name="testExample" type="Node2D"] +script = ExtResource( 1 )