Фикс загрузки карты в вебе: gzip и запись пакета
HTTPRequest в браузере пытался второй раз распаковать уже распакованный gzip (код 8), а download_file в вебе не создаёт файл. Теперь accept_gzip=false, тело берём в память и пишем в user:// сами; в сообщении об ошибке показываем причину. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
+29
-5
@@ -34,35 +34,59 @@ func _download_and_mount(pack_name: String, title: String) -> bool:
|
|||||||
|
|
||||||
var http := HTTPRequest.new()
|
var http := HTTPRequest.new()
|
||||||
http.process_mode = Node.PROCESS_MODE_ALWAYS
|
http.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
http.download_file = "user://" + pack_name
|
# Если сервер сжимает пакет gzip, браузер распаковывает его сам; вторая распаковка в движке ломает загрузку
|
||||||
|
http.accept_gzip = false
|
||||||
add_child(http)
|
add_child(http)
|
||||||
var state := {"done": false, "result": -1, "code": 0}
|
# Тело берём в память и пишем в user:// сами: в вебе download_file файл не создаёт
|
||||||
http.request_completed.connect(func(result: int, code: int, _h, _b):
|
var state := {"done": false, "result": -1, "code": 0, "body": PackedByteArray()}
|
||||||
|
http.request_completed.connect(func(result: int, code: int, _h, body: PackedByteArray):
|
||||||
state.result = result
|
state.result = result
|
||||||
state.code = code
|
state.code = code
|
||||||
|
state.body = body
|
||||||
state.done = true)
|
state.done = true)
|
||||||
|
|
||||||
var ok := false
|
var ok := false
|
||||||
|
var detail := "запрос не отправлен"
|
||||||
# no-cache: браузер сверяет файл с сервером (после обновления пакета не подсунет старый из кэша)
|
# no-cache: браузер сверяет файл с сервером (после обновления пакета не подсунет старый из кэша)
|
||||||
if http.request(_pack_url(pack_name), ["Cache-Control: no-cache"]) == OK:
|
if http.request(_pack_url(pack_name), ["Cache-Control: no-cache"]) == OK:
|
||||||
while not state.done:
|
while not state.done:
|
||||||
_update_progress(http, title)
|
_update_progress(http, title)
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
if state.result == HTTPRequest.RESULT_SUCCESS and state.code == 200:
|
if state.result == HTTPRequest.RESULT_SUCCESS and state.code == 200:
|
||||||
ok = ProjectSettings.load_resource_pack("user://" + pack_name, false) # false: файлы основной игры в приоритете
|
var path := "user://" + pack_name
|
||||||
|
var file := FileAccess.open(path, FileAccess.WRITE)
|
||||||
|
if file == null:
|
||||||
|
detail = "не удалось сохранить пакет, код %d" % FileAccess.get_open_error()
|
||||||
|
else:
|
||||||
|
file.store_buffer(state.body)
|
||||||
|
file.close()
|
||||||
|
state.body = PackedByteArray() # Освобождаем память: пакет уже на диске
|
||||||
|
ok = ProjectSettings.load_resource_pack(path, false) # false: файлы основной игры в приоритете
|
||||||
|
detail = "пакет скачан, но не подключился (%s)" % _describe_file(path)
|
||||||
|
else:
|
||||||
|
detail = "HTTP %d, код загрузки %d" % [state.code, state.result]
|
||||||
http.queue_free()
|
http.queue_free()
|
||||||
|
|
||||||
if ok:
|
if ok:
|
||||||
_loaded[pack_name] = true
|
_loaded[pack_name] = true
|
||||||
_hide()
|
_hide()
|
||||||
else:
|
else:
|
||||||
_label.text = "Не удалось загрузить карту"
|
printerr("MapLoader: не удалось загрузить %s: %s" % [pack_name, detail])
|
||||||
|
_label.text = "Не удалось загрузить карту\n%s" % detail
|
||||||
_bar.visible = false
|
_bar.visible = false
|
||||||
await get_tree().create_timer(2.5).timeout
|
await get_tree().create_timer(2.5).timeout
|
||||||
_hide()
|
_hide()
|
||||||
get_tree().paused = false
|
get_tree().paused = false
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
|
# Для сообщения об ошибке: размер и первые байты скачанного файла
|
||||||
|
func _describe_file(path: String) -> String:
|
||||||
|
var f := FileAccess.open(path, FileAccess.READ)
|
||||||
|
if f == null:
|
||||||
|
return "файл не открывается, код %d" % FileAccess.get_open_error()
|
||||||
|
var head := f.get_buffer(4)
|
||||||
|
return "%d байт, начало %s" % [f.get_length(), head.hex_encode()]
|
||||||
|
|
||||||
func _pack_url(pack_name: String) -> String:
|
func _pack_url(pack_name: String) -> String:
|
||||||
for arg in OS.get_cmdline_user_args():
|
for arg in OS.get_cmdline_user_args():
|
||||||
if arg.begins_with(PACK_URL_ARG):
|
if arg.begins_with(PACK_URL_ARG):
|
||||||
|
|||||||
Reference in New Issue
Block a user