added firebase and rudimentary leaderboard support
This commit is contained in:
362
addons/godot-firebase/storage/storage.gd
Normal file
362
addons/godot-firebase/storage/storage.gd
Normal file
@@ -0,0 +1,362 @@
|
||||
## @meta-authors SIsilicon
|
||||
## @meta-version 2.2
|
||||
## The Storage API for Firebase.
|
||||
## This object handles all firebase storage tasks, variables and references. To use this API, you must first create a [StorageReference] with [method ref]. With the reference, you can then query and manipulate the file or folder in the cloud storage.
|
||||
##
|
||||
## [i]Note: In HTML builds, you must configure [url=https://firebase.google.com/docs/storage/web/download-files#cors_configuration]CORS[/url] in your storage bucket.[i]
|
||||
@tool
|
||||
class_name FirebaseStorage
|
||||
extends Node
|
||||
|
||||
const _API_VERSION : String = "v0"
|
||||
|
||||
## @arg-types int, int, PackedStringArray
|
||||
## @arg-enums HTTPRequest.Result, HTTPClient.ResponseCode
|
||||
## Emitted when a [StorageTask] has finished with an error.
|
||||
signal task_failed(result, response_code, data)
|
||||
|
||||
## The current storage bucket the Storage API is referencing.
|
||||
var bucket : String
|
||||
|
||||
## @default false
|
||||
## Whether a task is currently being processed.
|
||||
var requesting : bool = false
|
||||
|
||||
var _auth : Dictionary
|
||||
var _config : Dictionary
|
||||
|
||||
var _references : Dictionary = {}
|
||||
|
||||
var _base_url : String = ""
|
||||
var _extended_url : String = "/[API_VERSION]/b/[APP_ID]/o/[FILE_PATH]"
|
||||
var _root_ref : StorageReference
|
||||
|
||||
var _http_client : HTTPClient = HTTPClient.new()
|
||||
var _pending_tasks : Array = []
|
||||
|
||||
var _current_task : StorageTask
|
||||
var _response_code : int
|
||||
var _response_headers : PackedStringArray
|
||||
var _response_data : PackedByteArray
|
||||
var _content_length : int
|
||||
var _reading_body : bool
|
||||
|
||||
func _notification(what : int) -> void:
|
||||
if what == NOTIFICATION_INTERNAL_PROCESS:
|
||||
_internal_process(get_process_delta_time())
|
||||
|
||||
func _internal_process(_delta : float) -> void:
|
||||
if not requesting:
|
||||
set_process_internal(false)
|
||||
return
|
||||
|
||||
var task = _current_task
|
||||
|
||||
match _http_client.get_status():
|
||||
HTTPClient.STATUS_DISCONNECTED:
|
||||
_http_client.connect_to_host(_base_url, 443, TLSOptions.client()) # Uhh, check if this is going to work. I assume not.
|
||||
|
||||
HTTPClient.STATUS_RESOLVING, \
|
||||
HTTPClient.STATUS_REQUESTING, \
|
||||
HTTPClient.STATUS_CONNECTING:
|
||||
_http_client.poll()
|
||||
|
||||
HTTPClient.STATUS_CONNECTED:
|
||||
var err := _http_client.request_raw(task._method, task._url, task._headers, task.data)
|
||||
if err:
|
||||
_finish_request(HTTPRequest.RESULT_CONNECTION_ERROR)
|
||||
|
||||
HTTPClient.STATUS_BODY:
|
||||
if _http_client.has_response() or _reading_body:
|
||||
_reading_body = true
|
||||
|
||||
# If there is a response...
|
||||
if _response_headers.is_empty():
|
||||
_response_headers = _http_client.get_response_headers() # Get response headers.
|
||||
_response_code = _http_client.get_response_code()
|
||||
|
||||
for header in _response_headers:
|
||||
if "Content-Length" in header:
|
||||
_content_length = header.trim_prefix("Content-Length: ").to_int()
|
||||
break
|
||||
|
||||
_http_client.poll()
|
||||
var chunk = _http_client.read_response_body_chunk() # Get a chunk.
|
||||
if chunk.size() == 0:
|
||||
# Got nothing, wait for buffers to fill a bit.
|
||||
pass
|
||||
else:
|
||||
_response_data += chunk # Append to read buffer.
|
||||
if _content_length != 0:
|
||||
task.progress = float(_response_data.size()) / _content_length
|
||||
|
||||
if _http_client.get_status() != HTTPClient.STATUS_BODY:
|
||||
task.progress = 1.0
|
||||
_finish_request(HTTPRequest.RESULT_SUCCESS)
|
||||
else:
|
||||
task.progress = 1.0
|
||||
_finish_request(HTTPRequest.RESULT_SUCCESS)
|
||||
|
||||
HTTPClient.STATUS_CANT_CONNECT:
|
||||
_finish_request(HTTPRequest.RESULT_CANT_CONNECT)
|
||||
HTTPClient.STATUS_CANT_RESOLVE:
|
||||
_finish_request(HTTPRequest.RESULT_CANT_RESOLVE)
|
||||
HTTPClient.STATUS_CONNECTION_ERROR:
|
||||
_finish_request(HTTPRequest.RESULT_CONNECTION_ERROR)
|
||||
HTTPClient.STATUS_TLS_HANDSHAKE_ERROR:
|
||||
_finish_request(HTTPRequest.RESULT_TLS_HANDSHAKE_ERROR)
|
||||
|
||||
## @args path
|
||||
## @arg-defaults ""
|
||||
## @return StorageReference
|
||||
## Returns a reference to a file or folder in the storage bucket. It's this reference that should be used to control the file/folder checked the server end.
|
||||
func ref(path := "") -> StorageReference:
|
||||
if _config == null or _config.is_empty():
|
||||
return null
|
||||
|
||||
# Create a root storage reference if there's none
|
||||
# and we're not making one.
|
||||
if path != "" and not _root_ref:
|
||||
_root_ref = ref()
|
||||
|
||||
path = _simplify_path(path)
|
||||
if not _references.has(path):
|
||||
var ref := StorageReference.new()
|
||||
_references[path] = ref
|
||||
ref.bucket = bucket
|
||||
ref.full_path = path
|
||||
ref.file_name = path.get_file()
|
||||
ref.parent = ref(path.path_join(".."))
|
||||
ref.root = _root_ref
|
||||
ref.storage = self
|
||||
add_child(ref)
|
||||
return ref
|
||||
else:
|
||||
return _references[path]
|
||||
|
||||
func _set_config(config_json : Dictionary) -> void:
|
||||
_config = config_json
|
||||
if bucket != _config.storageBucket:
|
||||
bucket = _config.storageBucket
|
||||
_http_client.close()
|
||||
_check_emulating()
|
||||
|
||||
|
||||
func _check_emulating() -> void :
|
||||
## Check emulating
|
||||
if not Firebase.emulating:
|
||||
_base_url = "https://firebasestorage.googleapis.com"
|
||||
else:
|
||||
var port : String = _config.emulators.ports.storage
|
||||
if port == "":
|
||||
Firebase._printerr("You are in 'emulated' mode, but the port for Storage has not been configured.")
|
||||
else:
|
||||
_base_url = "http://localhost:{port}/{version}/".format({ version = _API_VERSION, port = port })
|
||||
|
||||
|
||||
func _upload(data : PackedByteArray, headers : PackedStringArray, ref : StorageReference, meta_only : bool) -> Variant:
|
||||
if _is_invalid_authentication():
|
||||
Firebase._printerr("Error uploading to storage: Invalid authentication")
|
||||
return 0
|
||||
|
||||
var task := StorageTask.new()
|
||||
task.ref = ref
|
||||
task._url = _get_file_url(ref)
|
||||
task.action = StorageTask.Task.TASK_UPLOAD_META if meta_only else StorageTask.Task.TASK_UPLOAD
|
||||
task._headers = headers
|
||||
task.data = data
|
||||
_process_request(task)
|
||||
return await task.task_finished
|
||||
|
||||
func _download(ref : StorageReference, meta_only : bool, url_only : bool) -> Variant:
|
||||
if _is_invalid_authentication():
|
||||
Firebase._printerr("Error downloading from storage: Invalid authentication")
|
||||
return 0
|
||||
|
||||
var info_task := StorageTask.new()
|
||||
info_task.ref = ref
|
||||
info_task._url = _get_file_url(ref)
|
||||
info_task.action = StorageTask.Task.TASK_DOWNLOAD_URL if url_only else StorageTask.Task.TASK_DOWNLOAD_META
|
||||
_process_request(info_task)
|
||||
|
||||
if url_only or meta_only:
|
||||
return await info_task.task_finished
|
||||
|
||||
var task := StorageTask.new()
|
||||
task.ref = ref
|
||||
task._url = _get_file_url(ref) + "?alt=media&token="
|
||||
task.action = StorageTask.Task.TASK_DOWNLOAD
|
||||
_pending_tasks.append(task)
|
||||
|
||||
var data = await info_task.task_finished
|
||||
if info_task.result == OK:
|
||||
task._url += info_task.data.downloadTokens
|
||||
else:
|
||||
task.data = info_task.data
|
||||
task.response_headers = info_task.response_headers
|
||||
task.response_code = info_task.response_code
|
||||
task.result = info_task.result
|
||||
task.finished = true
|
||||
task.task_finished.emit(null)
|
||||
task_failed.emit(task.result, task.response_code, task.data)
|
||||
_pending_tasks.erase(task)
|
||||
return null
|
||||
|
||||
return await task.task_finished
|
||||
|
||||
func _list(ref : StorageReference, list_all : bool) -> Array:
|
||||
if _is_invalid_authentication():
|
||||
Firebase._printerr("Error getting object list from storage: Invalid authentication")
|
||||
return []
|
||||
|
||||
var task := StorageTask.new()
|
||||
task.ref = ref
|
||||
task._url = _get_file_url(_root_ref).trim_suffix("/")
|
||||
task.action = StorageTask.Task.TASK_LIST_ALL if list_all else StorageTask.Task.TASK_LIST
|
||||
_process_request(task)
|
||||
return await task.task_finished
|
||||
|
||||
func _delete(ref : StorageReference) -> bool:
|
||||
if _is_invalid_authentication():
|
||||
Firebase._printerr("Error deleting object from storage: Invalid authentication")
|
||||
return false
|
||||
|
||||
var task := StorageTask.new()
|
||||
task.ref = ref
|
||||
task._url = _get_file_url(ref)
|
||||
task.action = StorageTask.Task.TASK_DELETE
|
||||
_process_request(task)
|
||||
var data = await task.task_finished
|
||||
|
||||
return data == null
|
||||
|
||||
func _process_request(task : StorageTask) -> void:
|
||||
if requesting:
|
||||
_pending_tasks.append(task)
|
||||
return
|
||||
requesting = true
|
||||
|
||||
var headers = Array(task._headers)
|
||||
headers.append("Authorization: Bearer " + _auth.idtoken)
|
||||
task._headers = PackedStringArray(headers)
|
||||
|
||||
_current_task = task
|
||||
_response_code = 0
|
||||
_response_headers = PackedStringArray()
|
||||
_response_data = PackedByteArray()
|
||||
_content_length = 0
|
||||
_reading_body = false
|
||||
|
||||
if not _http_client.get_status() in [HTTPClient.STATUS_CONNECTED, HTTPClient.STATUS_DISCONNECTED]:
|
||||
_http_client.close()
|
||||
set_process_internal(true)
|
||||
|
||||
func _finish_request(result : int) -> void:
|
||||
var task := _current_task
|
||||
requesting = false
|
||||
|
||||
task.result = result
|
||||
task.response_code = _response_code
|
||||
task.response_headers = _response_headers
|
||||
|
||||
match task.action:
|
||||
StorageTask.Task.TASK_DOWNLOAD:
|
||||
task.data = _response_data
|
||||
|
||||
StorageTask.Task.TASK_DELETE:
|
||||
_references.erase(task.ref.full_path)
|
||||
for child in get_children():
|
||||
if child.full_path == task.ref.full_path:
|
||||
child.queue_free()
|
||||
break
|
||||
if typeof(task.data) == TYPE_PACKED_BYTE_ARRAY:
|
||||
task.data = null
|
||||
|
||||
StorageTask.Task.TASK_DOWNLOAD_URL:
|
||||
var json = Utilities.get_json_data(_response_data)
|
||||
if json != null and json.has("error"):
|
||||
Firebase._printerr("Error getting object download url: "+json["error"].message)
|
||||
if json != null and json.has("downloadTokens"):
|
||||
task.data = _base_url + _get_file_url(task.ref) + "?alt=media&token=" + json.downloadTokens
|
||||
else:
|
||||
task.data = ""
|
||||
|
||||
StorageTask.Task.TASK_LIST, StorageTask.Task.TASK_LIST_ALL:
|
||||
var json = Utilities.get_json_data(_response_data)
|
||||
var items := []
|
||||
if json != null and json.has("error"):
|
||||
Firebase._printerr("Error getting data from storage: "+json["error"].message)
|
||||
if json != null and json.has("items"):
|
||||
for item in json.items:
|
||||
var item_name : String = item.name
|
||||
if item.bucket != bucket:
|
||||
continue
|
||||
if not item_name.begins_with(task.ref.full_path):
|
||||
continue
|
||||
if task.action == StorageTask.Task.TASK_LIST:
|
||||
var dir_path : Array = item_name.split("/")
|
||||
var slash_count : int = task.ref.full_path.count("/")
|
||||
item_name = ""
|
||||
for i in slash_count + 1:
|
||||
item_name += dir_path[i]
|
||||
if i != slash_count and slash_count != 0:
|
||||
item_name += "/"
|
||||
if item_name in items:
|
||||
continue
|
||||
|
||||
items.append(item_name)
|
||||
task.data = items
|
||||
|
||||
_:
|
||||
var json = Utilities.get_json_data(_response_data)
|
||||
task.data = json
|
||||
|
||||
var next_task = _get_next_pending_task()
|
||||
|
||||
task.finished = true
|
||||
task.task_finished.emit(task.data) # I believe this parameter has been missing all along, but not sure. Caused weird results at times with a yield/await returning null, but the task containing data.
|
||||
if typeof(task.data) == TYPE_DICTIONARY and task.data.has("error"):
|
||||
task_failed.emit(task.result, task.response_code, task.data)
|
||||
|
||||
if next_task and not next_task.finished:
|
||||
_process_request(next_task)
|
||||
|
||||
func _get_next_pending_task() -> StorageTask:
|
||||
if _pending_tasks.is_empty():
|
||||
return null
|
||||
|
||||
return _pending_tasks.pop_front()
|
||||
|
||||
func _get_file_url(ref : StorageReference) -> String:
|
||||
var url := _extended_url.replace("[APP_ID]", ref.bucket)
|
||||
url = url.replace("[API_VERSION]", _API_VERSION)
|
||||
return url.replace("[FILE_PATH]", ref.full_path.uri_encode())
|
||||
|
||||
# Removes any "../" or "./" in the file path.
|
||||
func _simplify_path(path : String) -> String:
|
||||
var dirs := path.split("/")
|
||||
var new_dirs := []
|
||||
for dir in dirs:
|
||||
if dir == "..":
|
||||
new_dirs.pop_back()
|
||||
elif dir == ".":
|
||||
pass
|
||||
else:
|
||||
new_dirs.push_back(dir)
|
||||
|
||||
var new_path := "/".join(PackedStringArray(new_dirs))
|
||||
new_path = new_path.replace("//", "/")
|
||||
new_path = new_path.replace("\\", "/")
|
||||
return new_path
|
||||
|
||||
func _on_FirebaseAuth_login_succeeded(auth_token : Dictionary) -> void:
|
||||
_auth = auth_token
|
||||
|
||||
func _on_FirebaseAuth_token_refresh_succeeded(auth_result : Dictionary) -> void:
|
||||
_auth = auth_result
|
||||
|
||||
func _on_FirebaseAuth_logout() -> void:
|
||||
_auth = {}
|
||||
|
||||
func _is_invalid_authentication() -> bool:
|
||||
return (_config == null or _config.is_empty()) or (_auth == null or _auth.is_empty())
|
||||
1
addons/godot-firebase/storage/storage.gd.uid
Normal file
1
addons/godot-firebase/storage/storage.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://vxab4cp6e8hx
|
||||
159
addons/godot-firebase/storage/storage_reference.gd
Normal file
159
addons/godot-firebase/storage/storage_reference.gd
Normal file
@@ -0,0 +1,159 @@
|
||||
## @meta-authors SIsilicon
|
||||
## @meta-version 2.2
|
||||
## A reference to a file or folder in the Firebase cloud storage.
|
||||
## This object is used to interact with the cloud storage. You may get data from the server, as well as upload your own back to it.
|
||||
@tool
|
||||
class_name StorageReference
|
||||
extends Node
|
||||
|
||||
## The default MIME type to use when uploading a file.
|
||||
## Data sent with this type are interpreted as plain binary data. Note that firebase will generate an MIME type based checked the file extenstion if none is provided.
|
||||
const DEFAULT_MIME_TYPE = "application/octet-stream"
|
||||
|
||||
## A dictionary of common MIME types based checked a file extension.
|
||||
## Example: [code]MIME_TYPES.png[/code] will return [code]image/png[/code].
|
||||
const MIME_TYPES = {
|
||||
"bmp": "image/bmp",
|
||||
"css": "text/css",
|
||||
"csv": "text/csv",
|
||||
"gd": "text/plain",
|
||||
"htm": "text/html",
|
||||
"html": "text/html",
|
||||
"jpeg": "image/jpeg",
|
||||
"jpg": "image/jpeg",
|
||||
"json": "application/json",
|
||||
"mp3": "audio/mpeg",
|
||||
"mpeg": "video/mpeg",
|
||||
"ogg": "audio/ogg",
|
||||
"ogv": "video/ogg",
|
||||
"png": "image/png",
|
||||
"shader": "text/plain",
|
||||
"svg": "image/svg+xml",
|
||||
"tif": "image/tiff",
|
||||
"tiff": "image/tiff",
|
||||
"tres": "text/plain",
|
||||
"tscn": "text/plain",
|
||||
"txt": "text/plain",
|
||||
"wav": "audio/wav",
|
||||
"webm": "video/webm",
|
||||
"webp": "image/webp",
|
||||
"xml": "text/xml",
|
||||
}
|
||||
|
||||
## @default ""
|
||||
## The stroage bucket this referenced file/folder is located in.
|
||||
var bucket : String = ""
|
||||
|
||||
## @default ""
|
||||
## The path to the file/folder relative to [member bucket].
|
||||
var full_path : String = ""
|
||||
|
||||
## @default ""
|
||||
## The name of the file/folder, including any file extension.
|
||||
## Example: If the [member full_path] is [code]images/user/image.png[/code], then the [member name] would be [code]image.png[/code].
|
||||
var file_name : String = ""
|
||||
|
||||
## The parent [StorageReference] one level up the file hierarchy.
|
||||
## If the current [StorageReference] is the root (i.e. the [member full_path] is [code]""[/code]) then the [member parent] will be [code]null[/code].
|
||||
var parent : StorageReference
|
||||
|
||||
## The root [StorageReference].
|
||||
var root : StorageReference
|
||||
|
||||
## @type FirebaseStorage
|
||||
## The Storage API that created this [StorageReference] to begin with.
|
||||
var storage # FirebaseStorage (Can't static type due to cyclic reference)
|
||||
|
||||
## @args path
|
||||
## @return StorageReference
|
||||
## Returns a reference to another [StorageReference] relative to this one.
|
||||
func child(path : String) -> StorageReference:
|
||||
return storage.ref(full_path.path_join(path))
|
||||
|
||||
## @args data, metadata
|
||||
## @return int
|
||||
## Makes an attempt to upload data to the referenced file location. Returns Variant
|
||||
func put_data(data : PackedByteArray, metadata := {}) -> Variant:
|
||||
if not "Content-Length" in metadata and not Utilities.is_web():
|
||||
metadata["Content-Length"] = data.size()
|
||||
|
||||
var headers := []
|
||||
for key in metadata:
|
||||
headers.append("%s: %s" % [key, metadata[key]])
|
||||
|
||||
return await storage._upload(data, headers, self, false)
|
||||
|
||||
|
||||
## @args data, metadata
|
||||
## @return int
|
||||
## Like [method put_data], but [code]data[/code] is a [String].
|
||||
func put_string(data : String, metadata := {}) -> Variant:
|
||||
return await put_data(data.to_utf8_buffer(), metadata)
|
||||
|
||||
## @args file_path, metadata
|
||||
## @return int
|
||||
## Like [method put_data], but the data comes from a file at [code]file_path[/code].
|
||||
func put_file(file_path : String, metadata := {}) -> Variant:
|
||||
var file := FileAccess.open(file_path, FileAccess.READ)
|
||||
var data := file.get_buffer(file.get_length())
|
||||
|
||||
if "Content-Type" in metadata:
|
||||
metadata["Content-Type"] = MIME_TYPES.get(file_path.get_extension(), DEFAULT_MIME_TYPE)
|
||||
|
||||
return await put_data(data, metadata)
|
||||
|
||||
## @return Variant
|
||||
## Makes an attempt to download the files from the referenced file location. Status checked this task is found in the returned [StorageTask].
|
||||
func get_data() -> Variant:
|
||||
var result = await storage._download(self, false, false)
|
||||
return result
|
||||
|
||||
## @return StorageTask
|
||||
## Like [method get_data], but the data in the returned [StorageTask] comes in the form of a [String].
|
||||
func get_string() -> String:
|
||||
var task := await get_data()
|
||||
_on_task_finished(task, "stringify")
|
||||
return task.data
|
||||
|
||||
## @return StorageTask
|
||||
## Attempts to get the download url that points to the referenced file's data. Using the url directly may require an authentication header. Status checked this task is found in the returned [StorageTask].
|
||||
func get_download_url() -> Variant:
|
||||
return await storage._download(self, false, true)
|
||||
|
||||
## @return StorageTask
|
||||
## Attempts to get the metadata of the referenced file. Status checked this task is found in the returned [StorageTask].
|
||||
func get_metadata() -> Variant:
|
||||
return await storage._download(self, true, false)
|
||||
|
||||
## @args metadata
|
||||
## @return StorageTask
|
||||
## Attempts to update the metadata of the referenced file. Any field with a value of [code]null[/code] will be deleted checked the server end. Status checked this task is found in the returned [StorageTask].
|
||||
func update_metadata(metadata : Dictionary) -> Variant:
|
||||
var data := JSON.stringify(metadata).to_utf8_buffer()
|
||||
var headers := PackedStringArray(["Accept: application/json"])
|
||||
return await storage._upload(data, headers, self, true)
|
||||
|
||||
## @return StorageTask
|
||||
## Attempts to get the list of files and/or folders under the referenced folder This function is not nested unlike [method list_all]. Status checked this task is found in the returned [StorageTask].
|
||||
func list() -> Array:
|
||||
return await storage._list(self, false)
|
||||
|
||||
## @return StorageTask
|
||||
## Attempts to get the list of files and/or folders under the referenced folder This function is nested unlike [method list]. Status checked this task is found in the returned [StorageTask].
|
||||
func list_all() -> Array:
|
||||
return await storage._list(self, true)
|
||||
|
||||
## @return StorageTask
|
||||
## Attempts to delete the referenced file/folder. If successful, the reference will become invalid And can no longer be used. If you need to reference this location again, make a new reference with [method StorageTask.ref]. Status checked this task is found in the returned [StorageTask].
|
||||
func delete() -> bool:
|
||||
return await storage._delete(self)
|
||||
|
||||
func _to_string() -> String:
|
||||
var string := "gs://%s/%s" % [bucket, full_path]
|
||||
return string
|
||||
|
||||
func _on_task_finished(task : StorageTask, action : String) -> void:
|
||||
match action:
|
||||
"stringify":
|
||||
if typeof(task.data) == TYPE_PACKED_BYTE_ARRAY:
|
||||
task.data = task.data.get_string_from_utf8()
|
||||
1
addons/godot-firebase/storage/storage_reference.gd.uid
Normal file
1
addons/godot-firebase/storage/storage_reference.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bpvs4eelnej5i
|
||||
74
addons/godot-firebase/storage/storage_task.gd
Normal file
74
addons/godot-firebase/storage/storage_task.gd
Normal file
@@ -0,0 +1,74 @@
|
||||
## @meta-authors SIsilicon, Kyle 'backat50ft' Szklenski
|
||||
## @meta-version 2.2
|
||||
## An object that keeps track of an operation performed by [StorageReference].
|
||||
@tool
|
||||
class_name StorageTask
|
||||
extends RefCounted
|
||||
|
||||
enum Task {
|
||||
TASK_UPLOAD,
|
||||
TASK_UPLOAD_META,
|
||||
TASK_DOWNLOAD,
|
||||
TASK_DOWNLOAD_META,
|
||||
TASK_DOWNLOAD_URL,
|
||||
TASK_LIST,
|
||||
TASK_LIST_ALL,
|
||||
TASK_DELETE,
|
||||
TASK_MAX ## The number of [enum Task] constants.
|
||||
}
|
||||
|
||||
## Emitted when the task is finished. Returns data depending checked the success and action of the task.
|
||||
signal task_finished(data)
|
||||
|
||||
## Boolean to determine if this request involves metadata only
|
||||
var is_meta : bool
|
||||
|
||||
## @enum Task
|
||||
## @default -1
|
||||
## @setter set_action
|
||||
## The kind of operation this [StorageTask] is keeping track of.
|
||||
var action : int = -1 : set = set_action
|
||||
|
||||
var ref # Should not be needed, damnit
|
||||
|
||||
## @default PackedByteArray()
|
||||
## Data that the tracked task will/has returned.
|
||||
var data = PackedByteArray() # data can be of any type.
|
||||
|
||||
## @default 0.0
|
||||
## The percentage of data that has been received.
|
||||
var progress : float = 0.0
|
||||
|
||||
## @default -1
|
||||
## @enum HTTPRequest.Result
|
||||
## The resulting status of the task. Anyting other than [constant HTTPRequest.RESULT_SUCCESS] means an error has occured.
|
||||
var result : int = -1
|
||||
|
||||
## @default false
|
||||
## Whether the task is finished processing.
|
||||
var finished : bool = false
|
||||
|
||||
## @default PackedStringArray()
|
||||
## The returned HTTP response headers.
|
||||
var response_headers := PackedStringArray()
|
||||
|
||||
## @default 0
|
||||
## @enum HTTPClient.ResponseCode
|
||||
## The returned HTTP response code.
|
||||
var response_code : int = 0
|
||||
|
||||
var _method : int = -1
|
||||
var _url : String = ""
|
||||
var _headers : PackedStringArray = PackedStringArray()
|
||||
|
||||
func set_action(value : int) -> void:
|
||||
action = value
|
||||
match action:
|
||||
Task.TASK_UPLOAD:
|
||||
_method = HTTPClient.METHOD_POST
|
||||
Task.TASK_UPLOAD_META:
|
||||
_method = HTTPClient.METHOD_PATCH
|
||||
Task.TASK_DELETE:
|
||||
_method = HTTPClient.METHOD_DELETE
|
||||
_:
|
||||
_method = HTTPClient.METHOD_GET
|
||||
1
addons/godot-firebase/storage/storage_task.gd.uid
Normal file
1
addons/godot-firebase/storage/storage_task.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bfw61qsheaqjr
|
||||
Reference in New Issue
Block a user