Фикс загрузки карты в вебе: 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()
|
||||
http.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
http.download_file = "user://" + pack_name
|
||||
# Если сервер сжимает пакет gzip, браузер распаковывает его сам; вторая распаковка в движке ломает загрузку
|
||||
http.accept_gzip = false
|
||||
add_child(http)
|
||||
var state := {"done": false, "result": -1, "code": 0}
|
||||
http.request_completed.connect(func(result: int, code: int, _h, _b):
|
||||
# Тело берём в память и пишем в user:// сами: в вебе download_file файл не создаёт
|
||||
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.code = code
|
||||
state.body = body
|
||||
state.done = true)
|
||||
|
||||
var ok := false
|
||||
var detail := "запрос не отправлен"
|
||||
# no-cache: браузер сверяет файл с сервером (после обновления пакета не подсунет старый из кэша)
|
||||
if http.request(_pack_url(pack_name), ["Cache-Control: no-cache"]) == OK:
|
||||
while not state.done:
|
||||
_update_progress(http, title)
|
||||
await get_tree().process_frame
|
||||
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()
|
||||
|
||||
if ok:
|
||||
_loaded[pack_name] = true
|
||||
_hide()
|
||||
else:
|
||||
_label.text = "Не удалось загрузить карту"
|
||||
printerr("MapLoader: не удалось загрузить %s: %s" % [pack_name, detail])
|
||||
_label.text = "Не удалось загрузить карту\n%s" % detail
|
||||
_bar.visible = false
|
||||
await get_tree().create_timer(2.5).timeout
|
||||
_hide()
|
||||
get_tree().paused = false
|
||||
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:
|
||||
for arg in OS.get_cmdline_user_args():
|
||||
if arg.begins_with(PACK_URL_ARG):
|
||||
|
||||
Reference in New Issue
Block a user