diff options
Diffstat (limited to 'platform/javascript/export/export.cpp')
-rw-r--r-- | platform/javascript/export/export.cpp | 101 |
1 files changed, 70 insertions, 31 deletions
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index f3e8d6911a..c1cb8bcb58 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -86,17 +86,28 @@ public: ERR_FAIL_COND_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", "Invalid method or HTTP version."); String filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); - String basereq = "/tmp_js_export"; + const String basereq = "/tmp_js_export"; + String ctype = ""; if (req[1] == basereq + ".html") { filepath += ".html"; + ctype = "text/html"; } else if (req[1] == basereq + ".js") { filepath += ".js"; + ctype = "application/javascript"; } else if (req[1] == basereq + ".pck") { filepath += ".pck"; - } else if (req[1] == basereq + ".png") { - filepath += ".png"; + ctype = "application/octet-stream"; + } else if (req[1] == basereq + ".png" || req[1] == "/favicon.png") { + // Also allow serving the generated favicon for a smoother loading experience. + if (req[1] == "/favicon.png") { + filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png"); + } else { + filepath += ".png"; + } + ctype = "image/png"; } else if (req[1] == basereq + ".wasm") { filepath += ".wasm"; + ctype = "application/wasm"; } else { String s = "HTTP/1.1 404 Not Found\r\n"; s += "Connection: Close\r\n"; @@ -109,10 +120,14 @@ public: ERR_FAIL_COND(!f); String s = "HTTP/1.1 200 OK\r\n"; s += "Connection: Close\r\n"; + s += "Content-Type: " + ctype + "\r\n"; s += "\r\n"; CharString cs = s.utf8(); Error err = connection->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); - ERR_FAIL_COND(err != OK); + if (err != OK) { + memdelete(f); + ERR_FAIL(); + } while (true) { uint8_t bytes[4096]; @@ -121,8 +136,12 @@ public: break; } err = connection->put_data(bytes, read); - ERR_FAIL_COND(err != OK); + if (err != OK) { + memdelete(f); + ERR_FAIL(); + } } + memdelete(f); } void poll() { @@ -288,32 +307,32 @@ Ref<Texture> EditorExportPlatformJavaScript::get_logo() const { bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - bool valid = false; String err; + bool valid = false; + + // Look for export templates (first official, and if defined custom templates). - if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) != "") - valid = true; - else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) != "") - valid = true; + bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err); + bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err); if (p_preset->get("custom_template/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_template/debug"))) { - valid = true; - } else { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - if (p_preset->get("custom_template/release") != "") { - if (FileAccess::exists(p_preset->get("custom_template/release"))) { - valid = true; - } else { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } + valid = dvalid || rvalid; r_missing_templates = !valid; + // Validate the rest of the configuration. + if (p_preset->get("vram_texture_compression/for_mobile")) { String etc_error = test_etc2(); if (etc_error != String()) { @@ -456,11 +475,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } Ref<Image> splash; - String splash_path = GLOBAL_GET("application/boot_splash/image"); - splash_path = splash_path.strip_edges(); + const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges(); if (!splash_path.empty()) { splash.instance(); - Error err = splash->load(splash_path); + const Error err = splash->load(splash_path); if (err) { EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:") + "\n" + splash_path + "\n" + TTR("Using default boot splash image.")); splash.unref(); @@ -469,11 +487,32 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese if (splash.is_null()) { splash = Ref<Image>(memnew(Image(boot_splash_png))); } - String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); - if (splash->save_png(png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + png_path); + const String splash_png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); + if (splash->save_png(splash_png_path) != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + splash_png_path); return ERR_FILE_CANT_WRITE; } + + // Save a favicon that can be accessed without waiting for the project to finish loading. + // This way, the favicon can be displayed immediately when loading the page. + Ref<Image> favicon; + const String favicon_path = String(GLOBAL_GET("application/config/icon")).strip_edges(); + if (!favicon_path.empty()) { + favicon.instance(); + const Error err = favicon->load(favicon_path); + if (err) { + favicon.unref(); + } + } + + if (favicon.is_valid()) { + const String favicon_png_path = p_path.get_base_dir().plus_file("favicon.png"); + if (favicon->save_png(favicon_png_path) != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + favicon_png_path); + return ERR_FILE_CANT_WRITE; + } + } + return OK; } @@ -522,9 +561,8 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese return OK; } - String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); - String path = basepath + ".html"; - Error err = export_project(p_preset, true, path, p_debug_flags); + const String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); + Error err = export_project(p_preset, true, basepath + ".html", p_debug_flags); if (err != OK) { // Export generates several files, clean them up on failure. DirAccess::remove_file_or_error(basepath + ".html"); @@ -532,13 +570,14 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese DirAccess::remove_file_or_error(basepath + ".pck"); DirAccess::remove_file_or_error(basepath + ".png"); DirAccess::remove_file_or_error(basepath + ".wasm"); + DirAccess::remove_file_or_error(EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png")); return err; } - IP_Address bind_ip; - uint16_t bind_port = EDITOR_GET("export/web/http_port"); + const uint16_t bind_port = EDITOR_GET("export/web/http_port"); // Resolve host if needed. - String bind_host = EDITOR_GET("export/web/http_host"); + const String bind_host = EDITOR_GET("export/web/http_host"); + IP_Address bind_ip; if (bind_host.is_valid_ip_address()) { bind_ip = bind_host; } else { |