Initial Commit

This commit is contained in:
Mario Steele 2025-04-29 22:06:23 -05:00
commit 0321a1b77e
10 changed files with 774 additions and 0 deletions

510
.gitignore vendored Normal file
View file

@ -0,0 +1,510 @@
# ---> Godot
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

7
default_env.tres Normal file
View file

@ -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)

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

34
icon.png.import Normal file
View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dyo0krcrceiio"
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

16
project.godot Normal file
View file

@ -0,0 +1,16 @@
; 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=5
[application]
config/name="HttpClientDebugger"
config/description="Enter an interesting project description here!"
config/features=PackedStringArray("4.4")
config/icon="res://icon.png"

7
test_get_version_info.gd Normal file
View file

@ -0,0 +1,7 @@
@tool
extends EditorScript
# Called when the script is executed (using File -> Run in Script Editor).
func _run() -> void:
print(Engine.get_version_info()["string"])

View file

@ -0,0 +1 @@
uid://b8qdsr36mlp3h

189
test_node.gd Normal file
View file

@ -0,0 +1,189 @@
extends Node2D
class_name DebuggableHttpRequest
signal request_completed(response: HTTPResponse)
@export_category("HTTP Server")
@export var host: String = "192.168.1.29"
@export var port: int = 80
@export var query: String = "/"
@export var ssl: bool = false
@export_category("HTTP Headers")
@export var user_agent: String = "Godot/4.4.1 (Windows)"
@export var accept: String = "*/*"
var client: StreamPeerTCP
var sclient: StreamPeerTLS
var state: State = State.CLOSED
var buffer: PackedByteArray
var headers: PackedStringArray
enum State {
CONNECTING,
REQUESTING,
RESPONSE,
ERROR,
CLOSED
}
func _ready() -> void:
request()
request_completed.connect(func(resp: HTTPResponse) -> void:
print_rich("[color=green][b]Request Completed:[/b] Status ", resp.code, "[/color]\n")
print_rich("[color=cyan]Headers:\n[/color]")
print_rich("[color=cyan]", JSON.stringify(resp.headers, "\t"), "[/color]\n")
print("Body:")
print(resp.body.get_string_from_utf8())
)
func request(path: String = "") -> void:
assert(state == State.CLOSED, "A request is already being made.")
if path != "":
query = path
if port == 443:
ssl = true
print_rich("[color=yellow]Starting connection to %s:%d[/color]\n" % [host, port])
client = StreamPeerTCP.new()
client.connect_to_host(host, port)
state = State.CONNECTING
func _process(_delta: float) -> void:
if not client:
return
if state == State.CLOSED:
if ssl and sclient:
sclient.disconnect_from_stream()
sclient = null
client.disconnect_from_host()
client = null
return
client.poll()
if client.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED and state == State.CONNECTING:
if ssl:
_handle_ssl()
return
print_rich("[color=green]Connected to %s:%d[/color]\n" % [host, port])
state = State.REQUESTING
print_rich("[color=green]Sending Request for %s from server %s:%d[/color]\n" % [query, host, port])
_send_request(client)
elif client.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED and state == State.REQUESTING:
print_rich("[color=green]Reading response from %s:%d[/color]\n" % [host, port])
state = State.RESPONSE
_handle_response(sclient if ssl else client)
elif client.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED and state == State.RESPONSE:
_handle_response(sclient if ssl else client)
elif client.get_status() == StreamPeerTCP.Status.STATUS_ERROR:
state = State.ERROR
_handle_error(client.get_status())
func _send_request(peer: StreamPeer) -> void:
var request_str := "GET %s://%s:%d/%s HTTP/1.1\r\n" % [
"https" if ssl else "http",
host, port, query
]
if (ssl and port == 443) or (not ssl and port == 80):
request_str += "Host: %s\r\n" % host
else:
request_str += "Host: %s:%d\r\n" % [host,port]
# TODO: Handle Body Length here
#"3.1.4.stable.mono.official"
var ver := Engine.get_version_info()
var version := "%d.%d.%d.%s.%s" % [
ver["major"], ver["minor"], ver["patch"],
ver["status"], ver["build"]
]
request_str += "User-Agent: GodotEngine/%s (%s)" % [
version,
OS.get_name()
]
request_str += "Accept: %s\r\n\r\n" % accept
peer.put_data(request_str.to_utf8_buffer())
func _handle_response(peer: StreamPeer) -> void:
peer.poll()
if headers.size() == 0:
while true:
var byte := peer.get_partial_data(1)
if byte[0] == OK and byte[1].size() == 0:
peer.poll()
continue
elif byte[0] == OK:
buffer.push_back(byte[1][0])
else:
state = State.ERROR
_handle_error(byte[0])
return
if buffer.size() < 4:
peer.poll()
continue
if (buffer[-2] == 10 and buffer[-1] == 10) or \
(buffer[-4] == 13 and buffer[-3] == 10 and buffer[-2] == 13 and buffer[-1] == 10):
var data := buffer.get_string_from_utf8()
buffer = []
headers = data.replace("\r","").rstrip("\n\n").split("\n")
break
peer.poll()
if headers.size() == 0:
return
var chunk := peer.get_partial_data(1024)
if chunk[0] == OK and chunk[1].size() > 0:
buffer.append_array(chunk[1])
else:
var resp = HTTPResponse.new(headers, buffer)
request_completed.emit(resp)
state = State.CLOSED
func _handle_error(error: Variant) -> void:
print_rich("[color=brickred]Error: %s[/color]" % error)
func _handle_ssl() -> void:
if sclient == null:
print_rich("[color=yellow]SSL Connection requested, negotiating SSL Connection with %s:%d[/color]\n" % [host,port])
sclient = StreamPeerTLS.new()
sclient.connect_to_stream(client, host)
sclient.poll()
if sclient.get_status() == StreamPeerTLS.Status.STATUS_CONNECTED:
print_rich("[color=yellow]SSL Connection established, Sending Request for %s from server %s:%d[/color]" % [query, host, port])
state = State.REQUESTING
_send_request(sclient)
elif sclient.get_status() == StreamPeerTLS.Status.STATUS_ERROR or \
sclient.get_status() == StreamPeerTLS.Status.STATUS_ERROR_HOSTNAME_MISMATCH:
_handle_error(sclient.get_status())
class HTTPResponse:
var headers: Dictionary[String, String] = {}
var body: PackedByteArray = []
var code: String
var message: String
func _init(p_headers: PackedStringArray, p_buffer: PackedByteArray) -> void:
body = p_buffer
for line in p_headers:
if line.contains(": "):
var parts := line.split(": ")
headers[parts[0]] = parts[1]
else:
# HTTP Intro Line: HTTP/1.1 200 OK
var parts := Array(line.split(" "))
if parts.pop_front() == "HTTP/1.1":
code = parts.pop_front()
message = " ".join(parts)
else:
code = "INVALID_PROTOCOL"

1
test_node.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://dkb5dxuccrpnp

9
test_node.tscn Normal file
View file

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://dj1kvk06ycncu"]
[ext_resource type="Script" uid="uid://dkb5dxuccrpnp" path="res://test_node.gd" id="1_6uery"]
[node name="TestNode" type="Node2D"]
script = ExtResource("1_6uery")
host = "api.github.com"
port = 443
query = "/repos/godotengine/godot/releases/latest"