|
|
|
@ -85,36 +85,44 @@ public:
|
|
|
|
|
// Wrong protocol
|
|
|
|
|
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");
|
|
|
|
|
const String cache_path = EditorSettings::get_singleton()->get_cache_dir();
|
|
|
|
|
const String basereq = "/tmp_js_export";
|
|
|
|
|
String ctype = "";
|
|
|
|
|
String filepath;
|
|
|
|
|
String ctype;
|
|
|
|
|
if (req[1] == basereq + ".html") {
|
|
|
|
|
filepath += ".html";
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "text/html";
|
|
|
|
|
} else if (req[1] == basereq + ".js") {
|
|
|
|
|
filepath += ".js";
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "application/javascript";
|
|
|
|
|
} else if (req[1] == basereq + ".audio.worklet.js") {
|
|
|
|
|
filepath += ".audio.worklet.js";
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "application/javascript";
|
|
|
|
|
} else if (req[1] == basereq + ".worker.js") {
|
|
|
|
|
filepath += ".worker.js";
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "application/javascript";
|
|
|
|
|
} else if (req[1] == basereq + ".pck") {
|
|
|
|
|
filepath += ".pck";
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
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";
|
|
|
|
|
filepath = basereq + ".png";
|
|
|
|
|
}
|
|
|
|
|
ctype = "image/png";
|
|
|
|
|
} else if (req[1] == basereq + ".wasm") {
|
|
|
|
|
filepath += ".wasm";
|
|
|
|
|
} else if (req[1] == basereq + ".side.wasm") {
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "application/wasm";
|
|
|
|
|
} else {
|
|
|
|
|
} else if (req[1] == basereq + ".wasm") {
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file());
|
|
|
|
|
ctype = "application/wasm";
|
|
|
|
|
} else if (req[1].ends_with(".wasm")) {
|
|
|
|
|
filepath = cache_path.plus_file(req[1].get_file()); // TODO dangerous?
|
|
|
|
|
ctype = "application/wasm";
|
|
|
|
|
}
|
|
|
|
|
if (filepath.empty() || !FileAccess::exists(filepath)) {
|
|
|
|
|
String s = "HTTP/1.1 404 Not Found\r\n";
|
|
|
|
|
s += "Connection: Close\r\n";
|
|
|
|
|
s += "\r\n";
|
|
|
|
@ -204,7 +212,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
|
|
|
|
|
Ref<ImageTexture> stop_icon;
|
|
|
|
|
int menu_options;
|
|
|
|
|
|
|
|
|
|
void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug);
|
|
|
|
|
void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, const Vector<SharedObject> p_shared_objects);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Ref<EditorHTTPServer> server;
|
|
|
|
@ -248,11 +256,15 @@ public:
|
|
|
|
|
~EditorExportPlatformJavaScript();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug) {
|
|
|
|
|
void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, const Vector<SharedObject> p_shared_objects) {
|
|
|
|
|
|
|
|
|
|
String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
|
|
|
|
|
String str_export;
|
|
|
|
|
Vector<String> lines = str_template.split("\n");
|
|
|
|
|
String libs;
|
|
|
|
|
for (int i = 0; i < p_shared_objects.size(); i++) {
|
|
|
|
|
libs += "\"" + p_shared_objects[i].path.get_file() + "\",";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < lines.size(); i++) {
|
|
|
|
|
|
|
|
|
@ -261,6 +273,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
|
|
|
|
|
current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
|
|
|
|
|
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
|
|
|
|
|
current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false");
|
|
|
|
|
current_line = current_line.replace("$GODOT_GDNATIVE_LIBS", libs);
|
|
|
|
|
current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
|
|
|
|
|
str_export += current_line + "\n";
|
|
|
|
|
}
|
|
|
|
@ -297,7 +310,6 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
|
|
|
|
|
|
|
|
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC
|
|
|
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
|
|
|
|
|
|
|
|
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
|
|
|
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
|
|
|
|
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true));
|
|
|
|
@ -395,12 +407,24 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
|
|
|
|
|
return ERR_FILE_NOT_FOUND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Vector<SharedObject> shared_objects;
|
|
|
|
|
String pck_path = p_path.get_basename() + ".pck";
|
|
|
|
|
Error error = save_pack(p_preset, pck_path);
|
|
|
|
|
Error error = save_pack(p_preset, pck_path, &shared_objects);
|
|
|
|
|
if (error != OK) {
|
|
|
|
|
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
|
|
|
|
for (int i = 0; i < shared_objects.size(); i++) {
|
|
|
|
|
String dst = p_path.get_base_dir().plus_file(shared_objects[i].path.get_file());
|
|
|
|
|
error = da->copy(shared_objects[i].path, dst);
|
|
|
|
|
if (error != OK) {
|
|
|
|
|
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + shared_objects[i].path.get_file());
|
|
|
|
|
memdelete(da);
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
memdelete(da);
|
|
|
|
|
|
|
|
|
|
FileAccess *src_f = NULL;
|
|
|
|
|
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
|
|
|
|
@ -441,7 +465,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
|
|
|
|
|
if (!custom_html.empty()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
_fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug);
|
|
|
|
|
_fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, shared_objects);
|
|
|
|
|
file = p_path.get_file();
|
|
|
|
|
|
|
|
|
|
} else if (file == "godot.js") {
|
|
|
|
@ -451,6 +475,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
|
|
|
|
|
|
|
|
|
|
file = p_path.get_file().get_basename() + ".worker.js";
|
|
|
|
|
|
|
|
|
|
} else if (file == "godot.side.wasm") {
|
|
|
|
|
|
|
|
|
|
file = p_path.get_file().get_basename() + ".side.wasm";
|
|
|
|
|
|
|
|
|
|
} else if (file == "godot.audio.worklet.js") {
|
|
|
|
|
|
|
|
|
|
file = p_path.get_file().get_basename() + ".audio.worklet.js";
|
|
|
|
@ -484,7 +512,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
|
|
|
|
|
buf.resize(f->get_len());
|
|
|
|
|
f->get_buffer(buf.ptrw(), buf.size());
|
|
|
|
|
memdelete(f);
|
|
|
|
|
_fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug);
|
|
|
|
|
_fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, shared_objects);
|
|
|
|
|
|
|
|
|
|
f = FileAccess::open(p_path, FileAccess::WRITE);
|
|
|
|
|
if (!f) {
|
|
|
|
@ -592,6 +620,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
|
|
|
|
|
DirAccess::remove_file_or_error(basepath + ".audio.worklet.js");
|
|
|
|
|
DirAccess::remove_file_or_error(basepath + ".pck");
|
|
|
|
|
DirAccess::remove_file_or_error(basepath + ".png");
|
|
|
|
|
DirAccess::remove_file_or_error(basepath + ".side.wasm");
|
|
|
|
|
DirAccess::remove_file_or_error(basepath + ".wasm");
|
|
|
|
|
DirAccess::remove_file_or_error(EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png"));
|
|
|
|
|
return err;
|
|
|
|
|