Okay guys, I had an idea to program own communicator in Godot4. The thing is you need to overcome 2 things to bring such program to life. The first thing is to load pictures from devices to your user:// folder in Godot4 Then we need to load such pics into RichTextboxLabel with texts. The second thing is to upload pictures and json to the server file system. Enough of the speaking, lets practice in gd script:
extends Node2D
var fd:FileDialog
var logic=false
func _ready() -> void:
pass # Replace with function body.
func prnt():
print("ok")
func save_to_file(content):
var file = FileAccess.open("user://icon3.png", FileAccess.WRITE)
file.store_buffer(content)
func load_from_file(path):
var file = FileAccess.open(path, FileAccess.READ)
var content = file.get_file_as_bytes(path)
return content
func _process(delta: float) -> void:
if Input.is_action_just_released("a"):
fd = FileDialog.new()
self.add_child(fd)
fd.mode=FileDialog.MODE_WINDOWED
fd.file_mode=FileDialog.FILE_MODE_OPEN_FILE
fd.access=FileDialog.ACCESS_FILESYSTEM
fd.popup(Rect2(0,0, 500, 500))
var image = load("res://icon.svg")
$RichTextLabel.add_image(image,100,100)
$RichTextLabel.append_text("\nyour communicator in godot\n")
if fd:
if logic==false and "icon2" in fd.current_path:
print(fd.current_path)
save_to_file(load_from_file(fd.current_path))
if FileAccess.file_exists("user://icon3.png"):
print("file exists")
var image2 = Image.new()
var err = image2.load("user://icon3.png")
var texture2=ImageTexture.create_from_image(image2)
if err != OK:
print("File not loaded:",err)
else:
$RichTextLabel.add_image(texture2,100,100)
logic=true
extends Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_upload_png("user://icon3.png")
#send_image_binary()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func send_image_binary() -> void:
# Create some random bytes to generate our boundary value
var crypto = Crypto.new()
var random_bytes = crypto.generate_random_bytes(16)
var boundary = '--GODOT%s' % random_bytes.hex_encode()
# Setup the header Content-Type with our bundary
var headers := PackedStringArray()
headers.append("Content-Type: multipart/form-data;boundary=\"WebKitFormBoundaryePkpFF7tjBAqx29L\"")
# Load the image and get the png buffer
var image = load("res://icon3.png").get_image() as Image
var buffer = image.save_png_to_buffer()
# Create our body
var body = PackedByteArray()
append_line(body, "--{{boundary}}".format({"boundary": boundary}, "{{_}}"))
append_line(body, 'Content-Disposition: form-data; name="api_key"')
append_line(body, '')
append_line(body, "MY_API_KEY") # The API key you have
append_line(body, "--{{boundary}}".format({"boundary": boundary}, "{{_}}"))
append_line(body, 'Content-Disposition: form-data; name="image"; filename="my_image.png"')
append_line(body, 'Content-Type: image/png')
append_line(body, 'Content-Transfer-Encoding: binary')
append_line(body, '')
append_bytes(body, buffer)
append_line(body, "--{{boundary}}--".format({"boundary": boundary}, "{{_}}"))
var http = HTTPClient.new()
http.set_blocking_mode(true)
http.connect_to_host( "https://hrubos.tech", 443 )
var err = http.request_raw(HTTPClient.METHOD_POST, "/commie/upload_pic.php" , headers, body)
while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING:
http.poll()
OS.delay_msec(500)
print("connecting...")
if http.get_status() != HTTPClient.STATUS_CONNECTED:
print("not connected ", http.get_status())
return
while http.get_status() == HTTPClient.STATUS_REQUESTING:
print("requesting")
http.poll()
if not OS.has_feature("web"):
OS.delay_msec(500)
else:
await Engine.get_main_loop().idle_frame
# -------------------------------------------------------------------------------------
# IF THERE A RESPONSE -----------------------------------------------------------------
if http.has_response():
#headers = http.get_response_headers_as_dictionary() # Get response headers.
print("code: ", http.get_response_code()) # Show response code.
#print("headers: ", headers) # Show headers.
# Getting the HTTP Body
if http.is_response_chunked():
# Does it use chunks?
print("Response is Chunked!")
else:
# Or just plain Content-Length
var bl = http.get_response_body_length()
print("Response Length: ", bl)
# This method works for both anyway
var resp_body := PackedByteArray()
while http.get_status() == HTTPClient.STATUS_BODY:
# While there is body left to be read
http.poll()
# Get a chunk.
var chunk = http.read_response_body_chunk()
if chunk.size() == 0:
if not OS.has_feature("web"):
OS.delay_usec(1000)
print("OS has no feature web")
else:
await Engine.get_main_loop().idle_frame
else:
resp_body = resp_body + chunk
# Done!
var text := resp_body.get_string_from_utf8().strip_edges()
print(text)
func append_line(buffer:PackedByteArray, line:String) -> void:
buffer.append_array(line.to_utf8_buffer())
buffer.append_array('\r\n'.to_utf8_buffer())
func append_bytes(buffer:PackedByteArray, bytes:PackedByteArray) -> void:
buffer.append_array(bytes)
buffer.append_array('\r\n'.to_utf8_buffer())
func _upload_png( path_to_png : String ):
if !FileAccess.file_exists(path_to_png):
print("file does not exist in path to send, quitting program!")
return
var file_name := path_to_png.get_file()
var file := FileAccess.open(path_to_png, FileAccess.READ)
var file_content = file.get_buffer( file.get_length( ) )
var crypto = Crypto.new()
var random_bytes = crypto.generate_random_bytes(16)
var boundary = '--GODOT%s' % random_bytes.hex_encode()
var body := PackedByteArray()
var image = load("res://icon3.png").get_image() as Image
var buffer = image.save_png_to_buffer()
#body.append_array( "\r\n--WebKitFormBoundaryePkpFF7tjBAqx29L\r\n".to_utf8_buffer() )
#body.append_array( "Content-Disposition: form-data; name=\"pic3\"; filename=\"pic3.png".to_utf8_buffer() )
#body.append_array( file_name.to_utf8_buffer() )
#body.append_array( "\"\r\n".to_utf8_buffer() )
#body.append_array( "Content-Type: image/png\r\n\r\n".to_utf8_buffer() )
#body.append_array( file_content )
#body.append_array( "\r\n--WebKitFormBoundaryePkpFF7tjBAqx29L--\r\n".to_utf8_buffer() )
append_line(body, "--{{boundary}}".format({"boundary": boundary}, "{{_}}"))
append_line(body, 'Content-Disposition: form-data; name="api_key"')
append_line(body, '')
append_line(body, "MY_API_KEY") # The API key you have
append_line(body, "--{{boundary}}".format({"boundary": boundary}, "{{_}}"))
append_line(body, 'Content-Disposition: form-data; name="image"; filename="my_image.png"')
append_line(body, 'Content-Type: image/png')
append_line(body, 'Content-Transfer-Encoding: binary')
append_line(body, '')
append_bytes(body, buffer)
append_line(body, "--{{boundary}}--".format({"boundary": boundary}, "{{_}}"))
#print(file_content)
var headers := PackedStringArray()
#headers.append("Content-Type: multipart/form-data;boundary=\"WebKitFormBoundaryePkpFF7tjBAqx29L\"")
headers.append('Content-Type: multipart/form-data;boundary=%s' % boundary)
var http = HTTPClient.new()
http.set_blocking_mode(true)
http.connect_to_host( "https://hrubos.tech", 443 )
while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING:
http.poll()
OS.delay_msec(500)
print("connecting...")
if http.get_status() != HTTPClient.STATUS_CONNECTED:
print("not connected ", http.get_status())
return
#print(body)
var err = http.request_raw(HTTPClient.METHOD_POST, "/commie/upload_pic.php" , headers, body)
#var err = http.request(HTTPClient.METHOD_POST,"/commie/upload_pic.php",headers,body)
if err != OK:
print("error sending ", err)
return
while http.get_status() == HTTPClient.STATUS_REQUESTING:
print("requesting")
http.poll()
if not OS.has_feature("web"):
OS.delay_msec(500)
else:
await Engine.get_main_loop().idle_frame
# -------------------------------------------------------------------------------------
# IF THERE A RESPONSE -----------------------------------------------------------------
if http.has_response():
#headers = http.get_response_headers_as_dictionary() # Get response headers.
print("code: ", http.get_response_code()) # Show response code.
#print("headers: ", headers) # Show headers.
# Getting the HTTP Body
if http.is_response_chunked():
# Does it use chunks?
print("Response is Chunked!")
else:
# Or just plain Content-Length
var bl = http.get_response_body_length()
print("Response Length: ", bl)
# This method works for both anyway
var resp_body := PackedByteArray()
while http.get_status() == HTTPClient.STATUS_BODY:
# While there is body left to be read
http.poll()
# Get a chunk.
var chunk = http.read_response_body_chunk()
if chunk.size() == 0:
if not OS.has_feature("web"):
OS.delay_usec(1000)
print("OS has no feature web")
else:
await Engine.get_main_loop().idle_frame
else:
resp_body = resp_body + chunk
# Done!
var text := resp_body.get_string_from_utf8().strip_edges()
print(text)
Some pics of running code are:

Comments “So you wanted own communicator in Godot engine 4 like ICQ?”