feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
from misc.utility.scons_hints import *
|
||||
|
||||
Import("env")
|
||||
|
||||
|
|
|
|||
|
|
@ -30,20 +30,17 @@
|
|||
|
||||
#include "codesign.h"
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/plist.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "lipo.h"
|
||||
#include "macho.h"
|
||||
|
||||
#include "core/io/plist.h"
|
||||
#include "core/os/os.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_settings.h"
|
||||
|
||||
#include "modules/modules_enabled.gen.h" // For regex.
|
||||
#include "modules/regex/regex.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
|
||||
/*************************************************************************/
|
||||
/* CodeSignCodeResources */
|
||||
/*************************************************************************/
|
||||
|
|
@ -214,7 +211,7 @@ bool CodeSignCodeResources::add_nested_file(const String &p_root, const String &
|
|||
|
||||
Vector<String> files_to_add;
|
||||
if (LipO::is_lipo(p_exepath)) {
|
||||
String tmp_path_name = EditorPaths::get_singleton()->get_cache_dir().path_join("_lipo");
|
||||
String tmp_path_name = EditorPaths::get_singleton()->get_temp_dir().path_join("_lipo");
|
||||
Error err = da->make_dir_recursive(tmp_path_name);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, false, vformat("CodeSign/CodeResources: Failed to create \"%s\" subfolder.", tmp_path_name));
|
||||
LipO lip;
|
||||
|
|
@ -1248,7 +1245,7 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const
|
|||
Vector<String> files_to_sign;
|
||||
if (LipO::is_lipo(main_exe)) {
|
||||
print_verbose(vformat("CodeSign: Executable is fat, extracting..."));
|
||||
String tmp_path_name = EditorPaths::get_singleton()->get_cache_dir().path_join("_lipo");
|
||||
String tmp_path_name = EditorPaths::get_singleton()->get_temp_dir().path_join("_lipo");
|
||||
Error err = da->make_dir_recursive(tmp_path_name);
|
||||
if (err != OK) {
|
||||
r_error_msg = vformat(TTR("Failed to create \"%s\" subfolder."), tmp_path_name);
|
||||
|
|
@ -1381,14 +1378,14 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const
|
|||
r_error_msg = TTR("Invalid entitlements file.");
|
||||
ERR_FAIL_V_MSG(FAILED, "CodeSign: Invalid entitlements file.");
|
||||
}
|
||||
cet = Ref<CodeSignEntitlementsText>(memnew(CodeSignEntitlementsText(entitlements)));
|
||||
ceb = Ref<CodeSignEntitlementsBinary>(memnew(CodeSignEntitlementsBinary(entitlements)));
|
||||
cet.instantiate(entitlements);
|
||||
ceb.instantiate(entitlements);
|
||||
}
|
||||
|
||||
print_verbose("CodeSign: Generating requirements...");
|
||||
Ref<CodeSignRequirements> rq;
|
||||
String team_id = "";
|
||||
rq = Ref<CodeSignRequirements>(memnew(CodeSignRequirements()));
|
||||
rq.instantiate();
|
||||
|
||||
// Sign executables.
|
||||
for (int i = 0; i < files_to_sign.size(); i++) {
|
||||
|
|
@ -1487,7 +1484,7 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const
|
|||
|
||||
print_verbose("CodeSign: Generating signature...");
|
||||
Ref<CodeSignSignature> cs;
|
||||
cs = Ref<CodeSignSignature>(memnew(CodeSignSignature()));
|
||||
cs.instantiate();
|
||||
|
||||
print_verbose("CodeSign: Writing signature superblob...");
|
||||
// Write signature data to the executable.
|
||||
|
|
@ -1569,5 +1566,3 @@ Error CodeSign::codesign(bool p_use_hardened_runtime, bool p_force, const String
|
|||
ERR_FAIL_V_MSG(FAILED, "CodeSign: Unknown object type.");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MODULE_REGEX_ENABLED
|
||||
|
|
|
|||
|
|
@ -41,19 +41,9 @@
|
|||
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
|
||||
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/plist.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
#include "modules/modules_enabled.gen.h" // For regex.
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
#include "modules/regex/regex.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
|
||||
/*************************************************************************/
|
||||
/* CodeSignCodeResources */
|
||||
/*************************************************************************/
|
||||
|
|
@ -166,7 +156,7 @@ public:
|
|||
|
||||
virtual int get_size() const override;
|
||||
|
||||
virtual uint32_t get_index_type() const override { return 0x00000002; };
|
||||
virtual uint32_t get_index_type() const override { return 0x00000002; }
|
||||
virtual void write_to_file(Ref<FileAccess> p_file) const override;
|
||||
};
|
||||
|
||||
|
|
@ -188,7 +178,7 @@ public:
|
|||
|
||||
virtual int get_size() const override;
|
||||
|
||||
virtual uint32_t get_index_type() const override { return 0x00000005; };
|
||||
virtual uint32_t get_index_type() const override { return 0x00000005; }
|
||||
virtual void write_to_file(Ref<FileAccess> p_file) const override;
|
||||
};
|
||||
|
||||
|
|
@ -210,7 +200,7 @@ public:
|
|||
|
||||
virtual int get_size() const override;
|
||||
|
||||
virtual uint32_t get_index_type() const override { return 0x00000007; };
|
||||
virtual uint32_t get_index_type() const override { return 0x00000007; }
|
||||
virtual void write_to_file(Ref<FileAccess> p_file) const override;
|
||||
};
|
||||
|
||||
|
|
@ -285,7 +275,7 @@ private:
|
|||
uint32_t spare3; // Not used.
|
||||
uint64_t code_limit_64; // Set to 0 and ignore.
|
||||
// Version 0x20400
|
||||
uint64_t exec_seg_base; // Start of the signed code segmet.
|
||||
uint64_t exec_seg_base; // Start of the signed code segment.
|
||||
uint64_t exec_seg_limit; // Code segment (__TEXT) vmsize.
|
||||
uint64_t exec_seg_flags; // Executable segment flags.
|
||||
// Version 0x20500
|
||||
|
|
@ -311,7 +301,7 @@ public:
|
|||
virtual PackedByteArray get_hash_sha256() const override;
|
||||
|
||||
virtual int get_size() const override;
|
||||
virtual uint32_t get_index_type() const override { return 0x00000000; };
|
||||
virtual uint32_t get_index_type() const override { return 0x00000000; }
|
||||
|
||||
virtual void write_to_file(Ref<FileAccess> p_file) const override;
|
||||
};
|
||||
|
|
@ -330,7 +320,7 @@ public:
|
|||
virtual PackedByteArray get_hash_sha256() const override;
|
||||
|
||||
virtual int get_size() const override;
|
||||
virtual uint32_t get_index_type() const override { return 0x00010000; };
|
||||
virtual uint32_t get_index_type() const override { return 0x00010000; }
|
||||
|
||||
virtual void write_to_file(Ref<FileAccess> p_file) const override;
|
||||
};
|
||||
|
|
@ -362,6 +352,4 @@ public:
|
|||
static Error codesign(bool p_use_hardened_runtime, bool p_force, const String &p_path, const String &p_ent_path, String &r_error_msg);
|
||||
};
|
||||
|
||||
#endif // MODULE_REGEX_ENABLED
|
||||
|
||||
#endif // CODESIGN_H
|
||||
|
|
|
|||
|
|
@ -83,8 +83,12 @@ void EditorExport::_save() {
|
|||
config->set_value(section, "include_filter", preset->get_include_filter());
|
||||
config->set_value(section, "exclude_filter", preset->get_exclude_filter());
|
||||
config->set_value(section, "export_path", preset->get_export_path());
|
||||
config->set_value(section, "patches", preset->get_patches());
|
||||
|
||||
config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter());
|
||||
config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter());
|
||||
config->set_value(section, "seed", preset->get_seed());
|
||||
|
||||
config->set_value(section, "encrypt_pck", preset->get_enc_pck());
|
||||
config->set_value(section, "encrypt_directory", preset->get_enc_directory());
|
||||
config->set_value(section, "script_export_mode", preset->get_script_export_mode());
|
||||
|
|
@ -124,7 +128,17 @@ void EditorExport::_bind_methods() {
|
|||
|
||||
void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) {
|
||||
export_platforms.push_back(p_platform);
|
||||
|
||||
should_update_presets = true;
|
||||
should_reload_presets = true;
|
||||
}
|
||||
|
||||
void EditorExport::remove_export_platform(const Ref<EditorExportPlatform> &p_platform) {
|
||||
export_platforms.erase(p_platform);
|
||||
p_platform->cleanup();
|
||||
|
||||
should_update_presets = true;
|
||||
should_reload_presets = true;
|
||||
}
|
||||
|
||||
int EditorExport::get_export_platform_count() {
|
||||
|
|
@ -242,9 +256,9 @@ void EditorExport::load_config() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!preset.is_valid()) {
|
||||
if (preset.is_null()) {
|
||||
index++;
|
||||
ERR_CONTINUE(!preset.is_valid());
|
||||
continue; // Unknown platform, skip without error (platform might be loaded later).
|
||||
}
|
||||
|
||||
preset->set_name(config->get_value(section, "name"));
|
||||
|
|
@ -293,7 +307,11 @@ void EditorExport::load_config() {
|
|||
preset->set_exclude_filter(config->get_value(section, "exclude_filter"));
|
||||
preset->set_export_path(config->get_value(section, "export_path", ""));
|
||||
preset->set_script_export_mode(config->get_value(section, "script_export_mode", EditorExportPreset::MODE_SCRIPT_BINARY_TOKENS_COMPRESSED));
|
||||
preset->set_patches(config->get_value(section, "patches", Vector<String>()));
|
||||
|
||||
if (config->has_section_key(section, "seed")) {
|
||||
preset->set_seed(config->get_value(section, "seed"));
|
||||
}
|
||||
if (config->has_section_key(section, "encrypt_pck")) {
|
||||
preset->set_enc_pck(config->get_value(section, "encrypt_pck"));
|
||||
}
|
||||
|
|
@ -343,6 +361,12 @@ void EditorExport::load_config() {
|
|||
void EditorExport::update_export_presets() {
|
||||
HashMap<StringName, List<EditorExportPlatform::ExportOption>> platform_options;
|
||||
|
||||
if (should_reload_presets) {
|
||||
should_reload_presets = false;
|
||||
export_presets.clear();
|
||||
load_config();
|
||||
}
|
||||
|
||||
for (int i = 0; i < export_platforms.size(); i++) {
|
||||
Ref<EditorExportPlatform> platform = export_platforms[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class EditorExport : public Node {
|
|||
Timer *save_timer = nullptr;
|
||||
bool block_save = false;
|
||||
bool should_update_presets = false;
|
||||
bool should_reload_presets = false;
|
||||
|
||||
static EditorExport *singleton;
|
||||
|
||||
|
|
@ -66,6 +67,7 @@ public:
|
|||
void add_export_platform(const Ref<EditorExportPlatform> &p_platform);
|
||||
int get_export_platform_count();
|
||||
Ref<EditorExportPlatform> get_export_platform(int p_idx);
|
||||
void remove_export_platform(const Ref<EditorExportPlatform> &p_platform);
|
||||
|
||||
void add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos = -1);
|
||||
int get_export_preset_count() const;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -53,9 +53,18 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
|
||||
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
typedef Error (*EditorExportRemoveFunction)(void *p_userdata, const String &p_path);
|
||||
typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so);
|
||||
|
||||
enum DebugFlags {
|
||||
DEBUG_FLAG_DUMB_CLIENT = 1,
|
||||
DEBUG_FLAG_REMOTE_DEBUG = 2,
|
||||
DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4,
|
||||
DEBUG_FLAG_VIEW_COLLISIONS = 8,
|
||||
DEBUG_FLAG_VIEW_NAVIGATION = 16,
|
||||
};
|
||||
|
||||
enum ExportMessageType {
|
||||
EXPORT_MESSAGE_NONE,
|
||||
EXPORT_MESSAGE_INFO,
|
||||
|
|
@ -74,6 +83,7 @@ private:
|
|||
uint64_t ofs = 0;
|
||||
uint64_t size = 0;
|
||||
bool encrypted = false;
|
||||
bool removal = false;
|
||||
Vector<uint8_t> md5;
|
||||
CharString path_utf8;
|
||||
|
||||
|
|
@ -92,6 +102,8 @@ private:
|
|||
struct ZipData {
|
||||
void *zip = nullptr;
|
||||
EditorProgress *ep = nullptr;
|
||||
Vector<SharedObject> *so_files = nullptr;
|
||||
int file_count = 0;
|
||||
};
|
||||
|
||||
Vector<ExportMessage> messages;
|
||||
|
|
@ -100,13 +112,30 @@ private:
|
|||
void _export_find_customized_resources(const Ref<EditorExportPreset> &p_preset, EditorFileSystemDirectory *p_dir, EditorExportPreset::FileExportMode p_mode, HashSet<String> &p_paths);
|
||||
void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths);
|
||||
|
||||
static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
|
||||
static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
|
||||
static bool _check_hash(const uint8_t *p_hash, const Vector<uint8_t> &p_data);
|
||||
|
||||
static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
static Error _save_pack_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
static Error _pack_add_shared_object(void *p_userdata, const SharedObject &p_so);
|
||||
|
||||
static Error _remove_pack_file(void *p_userdata, const String &p_path);
|
||||
|
||||
static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
static Error _save_zip_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
static Error _zip_add_shared_object(void *p_userdata, const SharedObject &p_so);
|
||||
|
||||
struct ScriptCallbackData {
|
||||
Callable file_cb;
|
||||
Callable so_cb;
|
||||
};
|
||||
|
||||
static Error _script_save_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed);
|
||||
static Error _script_add_shared_object(void *p_userdata, const SharedObject &p_so);
|
||||
|
||||
void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude);
|
||||
void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude);
|
||||
|
||||
static Error _add_shared_object(void *p_userdata, const SharedObject &p_so);
|
||||
static Vector<uint8_t> _filter_extension_list_config_file(const String &p_config_path, const HashSet<String> &p_paths);
|
||||
|
||||
struct FileExportCache {
|
||||
uint64_t source_modified_time = 0;
|
||||
|
|
@ -126,23 +155,55 @@ private:
|
|||
|
||||
protected:
|
||||
struct ExportNotifier {
|
||||
ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags);
|
||||
ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags);
|
||||
~ExportNotifier();
|
||||
};
|
||||
|
||||
HashSet<String> get_features(const Ref<EditorExportPreset> &p_preset, bool p_debug) const;
|
||||
|
||||
bool exists_export_template(const String &template_file_name, String *err) const;
|
||||
String find_export_template(const String &template_file_name, String *err = nullptr) const;
|
||||
void gen_export_flags(Vector<String> &r_flags, int p_flags);
|
||||
void gen_debug_flags(Vector<String> &r_flags, int p_flags);
|
||||
Dictionary _find_export_template(const String &p_template_file_name) const {
|
||||
Dictionary ret;
|
||||
String err;
|
||||
|
||||
String path = find_export_template(p_template_file_name, &err);
|
||||
ret["result"] = (err.is_empty() && !path.is_empty()) ? OK : FAILED;
|
||||
ret["path"] = path;
|
||||
ret["error_string"] = err;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool exists_export_template(const String &p_template_file_name, String *r_err) const;
|
||||
String find_export_template(const String &p_template_file_name, String *r_err = nullptr) const;
|
||||
Vector<String> gen_export_flags(BitField<EditorExportPlatform::DebugFlags> p_flags);
|
||||
|
||||
virtual void zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name);
|
||||
|
||||
Error _ssh_run_on_remote(const String &p_host, const String &p_port, const Vector<String> &p_ssh_args, const String &p_cmd_args, Array r_output = Array(), int p_port_fwd = -1) const {
|
||||
String pipe;
|
||||
Error err = ssh_run_on_remote(p_host, p_port, p_ssh_args, p_cmd_args, &pipe, p_port_fwd);
|
||||
r_output.push_back(pipe);
|
||||
return err;
|
||||
}
|
||||
OS::ProcessID _ssh_run_on_remote_no_wait(const String &p_host, const String &p_port, const Vector<String> &p_ssh_args, const String &p_cmd_args, int p_port_fwd = -1) const {
|
||||
OS::ProcessID pid = 0;
|
||||
Error err = ssh_run_on_remote_no_wait(p_host, p_port, p_ssh_args, p_cmd_args, &pid, p_port_fwd);
|
||||
if (err != OK) {
|
||||
return -1;
|
||||
} else {
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
Error ssh_run_on_remote(const String &p_host, const String &p_port, const Vector<String> &p_ssh_args, const String &p_cmd_args, String *r_out = nullptr, int p_port_fwd = -1) const;
|
||||
Error ssh_run_on_remote_no_wait(const String &p_host, const String &p_port, const Vector<String> &p_ssh_args, const String &p_cmd_args, OS::ProcessID *r_pid = nullptr, int p_port_fwd = -1) const;
|
||||
Error ssh_push_to_remote(const String &p_host, const String &p_port, const Vector<String> &p_scp_args, const String &p_src_file, const String &p_dst_file) const;
|
||||
|
||||
Error _load_patches(const Vector<String> &p_patches);
|
||||
void _unload_patches();
|
||||
|
||||
Ref<Image> _load_icon_or_splash_image(const String &p_path, Error *r_error) const;
|
||||
|
||||
public:
|
||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const = 0;
|
||||
|
||||
|
|
@ -195,6 +256,21 @@ public:
|
|||
return messages[p_index];
|
||||
}
|
||||
|
||||
virtual ExportMessageType _get_message_type(int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, messages.size(), EXPORT_MESSAGE_NONE);
|
||||
return messages[p_index].msg_type;
|
||||
}
|
||||
|
||||
virtual String _get_message_category(int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, messages.size(), String());
|
||||
return messages[p_index].category;
|
||||
}
|
||||
|
||||
virtual String _get_message_text(int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, messages.size(), String());
|
||||
return messages[p_index].text;
|
||||
}
|
||||
|
||||
virtual ExportMessageType get_worst_message_type() const {
|
||||
ExportMessageType worst_type = EXPORT_MESSAGE_NONE;
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
|
|
@ -203,6 +279,8 @@ public:
|
|||
return worst_type;
|
||||
}
|
||||
|
||||
Dictionary get_internal_export_files(const Ref<EditorExportPreset> &p_preset, bool p_debug);
|
||||
|
||||
static Vector<String> get_forced_export_files();
|
||||
|
||||
virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err);
|
||||
|
|
@ -216,10 +294,22 @@ public:
|
|||
virtual String get_name() const = 0;
|
||||
virtual Ref<Texture2D> get_logo() const = 0;
|
||||
|
||||
Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
|
||||
Array get_current_presets() const;
|
||||
|
||||
Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
|
||||
Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
|
||||
Error _export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, const Callable &p_save_func, const Callable &p_so_func);
|
||||
Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_save_func, EditorExportRemoveFunction p_remove_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
|
||||
|
||||
Dictionary _save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, bool p_embed = false);
|
||||
Dictionary _save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
|
||||
|
||||
Dictionary _save_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
|
||||
Dictionary _save_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
|
||||
|
||||
Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, EditorExportSaveFunction p_save_func = nullptr, EditorExportRemoveFunction p_remove_func = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
|
||||
Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, EditorExportSaveFunction p_save_func = nullptr);
|
||||
|
||||
Error save_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
|
||||
Error save_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr);
|
||||
|
||||
virtual bool poll_export() { return false; }
|
||||
virtual int get_options_count() const { return 0; }
|
||||
|
|
@ -229,31 +319,29 @@ public:
|
|||
virtual String get_option_tooltip(int p_device) const { return ""; }
|
||||
virtual String get_device_architecture(int p_device) const { return ""; }
|
||||
|
||||
enum DebugFlags {
|
||||
DEBUG_FLAG_DUMB_CLIENT = 1,
|
||||
DEBUG_FLAG_REMOTE_DEBUG = 2,
|
||||
DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4,
|
||||
DEBUG_FLAG_VIEW_COLLISIONS = 8,
|
||||
DEBUG_FLAG_VIEW_NAVIGATION = 16,
|
||||
};
|
||||
|
||||
virtual void cleanup() {}
|
||||
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; }
|
||||
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) { return OK; }
|
||||
virtual Ref<Texture2D> get_run_icon() const { return get_logo(); }
|
||||
|
||||
bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const;
|
||||
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const;
|
||||
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const = 0;
|
||||
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const = 0;
|
||||
|
||||
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0;
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0;
|
||||
virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
|
||||
virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) = 0;
|
||||
virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
|
||||
virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
|
||||
virtual Error export_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches = Vector<String>(), BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
|
||||
virtual Error export_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches = Vector<String>(), BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
|
||||
virtual void get_platform_features(List<String> *r_features) const = 0;
|
||||
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0;
|
||||
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) {}
|
||||
virtual String get_debug_protocol() const { return "tcp://"; }
|
||||
virtual HashMap<String, Variant> get_custom_project_settings(const Ref<EditorExportPreset> &p_preset) const { return HashMap<String, Variant>(); }
|
||||
|
||||
EditorExportPlatform();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(EditorExportPlatform::ExportMessageType)
|
||||
VARIANT_BITFIELD_CAST(EditorExportPlatform::DebugFlags);
|
||||
|
||||
#endif // EDITOR_EXPORT_PLATFORM_H
|
||||
|
|
|
|||
357
engine/editor/export/editor_export_platform_extension.cpp
Normal file
357
engine/editor/export/editor_export_platform_extension.cpp
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
/**************************************************************************/
|
||||
/* editor_export_platform_extension.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "editor_export_platform_extension.h"
|
||||
|
||||
void EditorExportPlatformExtension::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_config_error", "error_text"), &EditorExportPlatformExtension::set_config_error);
|
||||
ClassDB::bind_method(D_METHOD("get_config_error"), &EditorExportPlatformExtension::get_config_error);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_config_missing_templates", "missing_templates"), &EditorExportPlatformExtension::set_config_missing_templates);
|
||||
ClassDB::bind_method(D_METHOD("get_config_missing_templates"), &EditorExportPlatformExtension::get_config_missing_templates);
|
||||
|
||||
GDVIRTUAL_BIND(_get_preset_features, "preset");
|
||||
GDVIRTUAL_BIND(_is_executable, "path");
|
||||
GDVIRTUAL_BIND(_get_export_options);
|
||||
GDVIRTUAL_BIND(_should_update_export_options);
|
||||
GDVIRTUAL_BIND(_get_export_option_visibility, "preset", "option");
|
||||
GDVIRTUAL_BIND(_get_export_option_warning, "preset", "option");
|
||||
|
||||
GDVIRTUAL_BIND(_get_os_name);
|
||||
GDVIRTUAL_BIND(_get_name);
|
||||
GDVIRTUAL_BIND(_get_logo);
|
||||
|
||||
GDVIRTUAL_BIND(_poll_export);
|
||||
GDVIRTUAL_BIND(_get_options_count);
|
||||
GDVIRTUAL_BIND(_get_options_tooltip);
|
||||
|
||||
GDVIRTUAL_BIND(_get_option_icon, "device");
|
||||
GDVIRTUAL_BIND(_get_option_label, "device");
|
||||
GDVIRTUAL_BIND(_get_option_tooltip, "device");
|
||||
GDVIRTUAL_BIND(_get_device_architecture, "device");
|
||||
|
||||
GDVIRTUAL_BIND(_cleanup);
|
||||
|
||||
GDVIRTUAL_BIND(_run, "preset", "device", "debug_flags");
|
||||
GDVIRTUAL_BIND(_get_run_icon);
|
||||
|
||||
GDVIRTUAL_BIND(_can_export, "preset", "debug");
|
||||
GDVIRTUAL_BIND(_has_valid_export_configuration, "preset", "debug");
|
||||
GDVIRTUAL_BIND(_has_valid_project_configuration, "preset");
|
||||
|
||||
GDVIRTUAL_BIND(_get_binary_extensions, "preset");
|
||||
|
||||
GDVIRTUAL_BIND(_export_project, "preset", "debug", "path", "flags");
|
||||
GDVIRTUAL_BIND(_export_pack, "preset", "debug", "path", "flags");
|
||||
GDVIRTUAL_BIND(_export_zip, "preset", "debug", "path", "flags");
|
||||
GDVIRTUAL_BIND(_export_pack_patch, "preset", "debug", "path", "patches", "flags");
|
||||
GDVIRTUAL_BIND(_export_zip_patch, "preset", "debug", "path", "patches", "flags");
|
||||
|
||||
GDVIRTUAL_BIND(_get_platform_features);
|
||||
|
||||
GDVIRTUAL_BIND(_get_debug_protocol);
|
||||
}
|
||||
|
||||
void EditorExportPlatformExtension::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
|
||||
Vector<String> ret;
|
||||
if (GDVIRTUAL_CALL(_get_preset_features, p_preset, ret) && r_features) {
|
||||
for (const String &E : ret) {
|
||||
r_features->push_back(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::is_executable(const String &p_path) const {
|
||||
bool ret = false;
|
||||
GDVIRTUAL_CALL(_is_executable, p_path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EditorExportPlatformExtension::get_export_options(List<ExportOption> *r_options) const {
|
||||
TypedArray<Dictionary> ret;
|
||||
if (GDVIRTUAL_CALL(_get_export_options, ret) && r_options) {
|
||||
for (const Variant &var : ret) {
|
||||
const Dictionary &d = var;
|
||||
ERR_CONTINUE(!d.has("name"));
|
||||
ERR_CONTINUE(!d.has("type"));
|
||||
|
||||
PropertyInfo pinfo = PropertyInfo::from_dict(d);
|
||||
ERR_CONTINUE(pinfo.name.is_empty() && (pinfo.usage & PROPERTY_USAGE_STORAGE));
|
||||
ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX);
|
||||
|
||||
Variant default_value;
|
||||
if (d.has("default_value")) {
|
||||
default_value = d["default_value"];
|
||||
}
|
||||
bool update_visibility = false;
|
||||
if (d.has("update_visibility")) {
|
||||
update_visibility = d["update_visibility"];
|
||||
}
|
||||
bool required = false;
|
||||
if (d.has("required")) {
|
||||
required = d["required"];
|
||||
}
|
||||
|
||||
r_options->push_back(ExportOption(pinfo, default_value, update_visibility, required));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::should_update_export_options() {
|
||||
bool ret = false;
|
||||
GDVIRTUAL_CALL(_should_update_export_options, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const {
|
||||
bool ret = true;
|
||||
GDVIRTUAL_CALL(_get_export_option_visibility, Ref<EditorExportPreset>(p_preset), p_option, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_export_option_warning, Ref<EditorExportPreset>(p_preset), p_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_os_name() const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_os_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_name() const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ref<Texture2D> EditorExportPlatformExtension::get_logo() const {
|
||||
Ref<Texture2D> ret;
|
||||
GDVIRTUAL_CALL(_get_logo, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::poll_export() {
|
||||
bool ret = false;
|
||||
GDVIRTUAL_CALL(_poll_export, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EditorExportPlatformExtension::get_options_count() const {
|
||||
int ret = 0;
|
||||
GDVIRTUAL_CALL(_get_options_count, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_options_tooltip() const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_options_tooltip, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ref<ImageTexture> EditorExportPlatformExtension::get_option_icon(int p_index) const {
|
||||
Ref<ImageTexture> ret;
|
||||
if (GDVIRTUAL_CALL(_get_option_icon, p_index, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return EditorExportPlatform::get_option_icon(p_index);
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_option_label(int p_device) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_option_label, p_device, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_option_tooltip(int p_device) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_option_tooltip, p_device, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_device_architecture(int p_device) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_device_architecture, p_device, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EditorExportPlatformExtension::cleanup() {
|
||||
GDVIRTUAL_CALL(_cleanup);
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::run(const Ref<EditorExportPreset> &p_preset, int p_device, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) {
|
||||
Error ret = OK;
|
||||
GDVIRTUAL_CALL(_run, p_preset, p_device, p_debug_flags, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ref<Texture2D> EditorExportPlatformExtension::get_run_icon() const {
|
||||
Ref<Texture2D> ret;
|
||||
if (GDVIRTUAL_CALL(_get_run_icon, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return EditorExportPlatform::get_run_icon();
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
|
||||
bool ret = false;
|
||||
config_error = r_error;
|
||||
config_missing_templates = r_missing_templates;
|
||||
if (GDVIRTUAL_CALL(_can_export, p_preset, p_debug, ret)) {
|
||||
r_error = config_error;
|
||||
r_missing_templates = config_missing_templates;
|
||||
return ret;
|
||||
}
|
||||
return EditorExportPlatform::can_export(p_preset, r_error, r_missing_templates, p_debug);
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
|
||||
bool ret = false;
|
||||
config_error = r_error;
|
||||
config_missing_templates = r_missing_templates;
|
||||
if (GDVIRTUAL_CALL(_has_valid_export_configuration, p_preset, p_debug, ret)) {
|
||||
r_error = config_error;
|
||||
r_missing_templates = config_missing_templates;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool EditorExportPlatformExtension::has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const {
|
||||
bool ret = false;
|
||||
config_error = r_error;
|
||||
if (GDVIRTUAL_CALL(_has_valid_project_configuration, p_preset, ret)) {
|
||||
r_error = config_error;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
List<String> EditorExportPlatformExtension::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
|
||||
List<String> ret_list;
|
||||
Vector<String> ret;
|
||||
if (GDVIRTUAL_CALL(_get_binary_extensions, p_preset, ret)) {
|
||||
for (const String &E : ret) {
|
||||
ret_list.push_back(E);
|
||||
}
|
||||
}
|
||||
return ret_list;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error ret = FAILED;
|
||||
GDVIRTUAL_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error ret = FAILED;
|
||||
if (GDVIRTUAL_CALL(_export_pack, p_preset, p_debug, p_path, p_flags, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return save_pack(p_preset, p_debug, p_path);
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error ret = FAILED;
|
||||
if (GDVIRTUAL_CALL(_export_zip, p_preset, p_debug, p_path, p_flags, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return save_zip(p_preset, p_debug, p_path);
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::export_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error err = _load_patches(p_patches.is_empty() ? p_preset->get_patches() : p_patches);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
Error ret = FAILED;
|
||||
if (GDVIRTUAL_CALL(_export_pack_patch, p_preset, p_debug, p_path, p_patches, p_flags, ret)) {
|
||||
_unload_patches();
|
||||
return ret;
|
||||
}
|
||||
|
||||
err = save_pack_patch(p_preset, p_debug, p_path);
|
||||
_unload_patches();
|
||||
return err;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformExtension::export_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error err = _load_patches(p_patches.is_empty() ? p_preset->get_patches() : p_patches);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
Error ret = FAILED;
|
||||
if (GDVIRTUAL_CALL(_export_zip_patch, p_preset, p_debug, p_path, p_patches, p_flags, ret)) {
|
||||
_unload_patches();
|
||||
return ret;
|
||||
}
|
||||
|
||||
err = save_zip_patch(p_preset, p_debug, p_path);
|
||||
_unload_patches();
|
||||
return err;
|
||||
}
|
||||
|
||||
void EditorExportPlatformExtension::get_platform_features(List<String> *r_features) const {
|
||||
Vector<String> ret;
|
||||
if (GDVIRTUAL_CALL(_get_platform_features, ret) && r_features) {
|
||||
for (const String &E : ret) {
|
||||
r_features->push_back(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String EditorExportPlatformExtension::get_debug_protocol() const {
|
||||
String ret;
|
||||
if (GDVIRTUAL_CALL(_get_debug_protocol, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return EditorExportPlatform::get_debug_protocol();
|
||||
}
|
||||
|
||||
EditorExportPlatformExtension::EditorExportPlatformExtension() {
|
||||
//NOP
|
||||
}
|
||||
|
||||
EditorExportPlatformExtension::~EditorExportPlatformExtension() {
|
||||
//NOP
|
||||
}
|
||||
155
engine/editor/export/editor_export_platform_extension.h
Normal file
155
engine/editor/export/editor_export_platform_extension.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/**************************************************************************/
|
||||
/* editor_export_platform_extension.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_EXPORT_PLATFORM_EXTENSION_H
|
||||
#define EDITOR_EXPORT_PLATFORM_EXTENSION_H
|
||||
|
||||
#include "editor_export_platform.h"
|
||||
#include "editor_export_preset.h"
|
||||
|
||||
class EditorExportPlatformExtension : public EditorExportPlatform {
|
||||
GDCLASS(EditorExportPlatformExtension, EditorExportPlatform);
|
||||
|
||||
mutable String config_error;
|
||||
mutable bool config_missing_templates = false;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
||||
GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_preset_features, Ref<EditorExportPreset>);
|
||||
|
||||
virtual bool is_executable(const String &p_path) const override;
|
||||
GDVIRTUAL1RC(bool, _is_executable, const String &);
|
||||
|
||||
virtual void get_export_options(List<ExportOption> *r_options) const override;
|
||||
GDVIRTUAL0RC(TypedArray<Dictionary>, _get_export_options);
|
||||
|
||||
virtual bool should_update_export_options() override;
|
||||
GDVIRTUAL0R(bool, _should_update_export_options);
|
||||
|
||||
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override;
|
||||
GDVIRTUAL2RC(bool, _get_export_option_visibility, Ref<EditorExportPreset>, const String &);
|
||||
|
||||
virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override;
|
||||
GDVIRTUAL2RC(String, _get_export_option_warning, Ref<EditorExportPreset>, const StringName &);
|
||||
|
||||
virtual String get_os_name() const override;
|
||||
GDVIRTUAL0RC_REQUIRED(String, _get_os_name);
|
||||
|
||||
virtual String get_name() const override;
|
||||
GDVIRTUAL0RC_REQUIRED(String, _get_name);
|
||||
|
||||
virtual Ref<Texture2D> get_logo() const override;
|
||||
GDVIRTUAL0RC_REQUIRED(Ref<Texture2D>, _get_logo);
|
||||
|
||||
virtual bool poll_export() override;
|
||||
GDVIRTUAL0R(bool, _poll_export);
|
||||
|
||||
virtual int get_options_count() const override;
|
||||
GDVIRTUAL0RC(int, _get_options_count);
|
||||
|
||||
virtual String get_options_tooltip() const override;
|
||||
GDVIRTUAL0RC(String, _get_options_tooltip);
|
||||
|
||||
virtual Ref<ImageTexture> get_option_icon(int p_index) const override;
|
||||
GDVIRTUAL1RC(Ref<ImageTexture>, _get_option_icon, int);
|
||||
|
||||
virtual String get_option_label(int p_device) const override;
|
||||
GDVIRTUAL1RC(String, _get_option_label, int);
|
||||
|
||||
virtual String get_option_tooltip(int p_device) const override;
|
||||
GDVIRTUAL1RC(String, _get_option_tooltip, int);
|
||||
|
||||
virtual String get_device_architecture(int p_device) const override;
|
||||
GDVIRTUAL1RC(String, _get_device_architecture, int);
|
||||
|
||||
virtual void cleanup() override;
|
||||
GDVIRTUAL0(_cleanup);
|
||||
|
||||
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) override;
|
||||
GDVIRTUAL3R(Error, _run, Ref<EditorExportPreset>, int, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual Ref<Texture2D> get_run_icon() const override;
|
||||
GDVIRTUAL0RC(Ref<Texture2D>, _get_run_icon);
|
||||
|
||||
void set_config_error(const String &p_error) const {
|
||||
config_error = p_error;
|
||||
}
|
||||
String get_config_error() const {
|
||||
return config_error;
|
||||
}
|
||||
|
||||
void set_config_missing_templates(bool p_missing_templates) const {
|
||||
config_missing_templates = p_missing_templates;
|
||||
}
|
||||
bool get_config_missing_templates() const {
|
||||
return config_missing_templates;
|
||||
}
|
||||
|
||||
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
|
||||
GDVIRTUAL2RC(bool, _can_export, Ref<EditorExportPreset>, bool);
|
||||
|
||||
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
|
||||
GDVIRTUAL2RC_REQUIRED(bool, _has_valid_export_configuration, Ref<EditorExportPreset>, bool);
|
||||
|
||||
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
|
||||
GDVIRTUAL1RC_REQUIRED(bool, _has_valid_project_configuration, Ref<EditorExportPreset>);
|
||||
|
||||
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override;
|
||||
GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_binary_extensions, Ref<EditorExportPreset>);
|
||||
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
GDVIRTUAL4R_REQUIRED(Error, _export_project, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
GDVIRTUAL4R(Error, _export_pack, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
GDVIRTUAL4R(Error, _export_zip, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual Error export_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches = Vector<String>(), BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
GDVIRTUAL5R(Error, _export_pack_patch, Ref<EditorExportPreset>, bool, const String &, const Vector<String> &, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual Error export_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, const Vector<String> &p_patches = Vector<String>(), BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
GDVIRTUAL5R(Error, _export_zip_patch, Ref<EditorExportPreset>, bool, const String &, const Vector<String> &, BitField<EditorExportPlatform::DebugFlags>);
|
||||
|
||||
virtual void get_platform_features(List<String> *r_features) const override;
|
||||
GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_platform_features);
|
||||
|
||||
virtual String get_debug_protocol() const override;
|
||||
GDVIRTUAL0RC(String, _get_debug_protocol);
|
||||
|
||||
EditorExportPlatformExtension();
|
||||
~EditorExportPlatformExtension();
|
||||
};
|
||||
|
||||
#endif // EDITOR_EXPORT_PLATFORM_EXTENSION_H
|
||||
|
|
@ -115,7 +115,7 @@ bool EditorExportPlatformPC::has_valid_project_configuration(const Ref<EditorExp
|
|||
return true;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
||||
Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
|
||||
Error err = prepare_template(p_preset, p_debug, p_path, p_flags);
|
||||
|
|
@ -129,7 +129,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
|
|||
return err;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
||||
Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
if (!DirAccess::exists(p_path.get_base_dir())) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist."));
|
||||
return ERR_FILE_BAD_PATH;
|
||||
|
|
@ -182,7 +182,7 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_
|
|||
return err;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
|
||||
Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
|
||||
String pck_path;
|
||||
if (p_preset->get("binary_format/embed_pck")) {
|
||||
pck_path = p_path;
|
||||
|
|
@ -194,7 +194,7 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset>
|
|||
|
||||
int64_t embedded_pos;
|
||||
int64_t embedded_size;
|
||||
Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
|
||||
Error err = save_pack(p_preset, p_debug, pck_path, &so_files, nullptr, nullptr, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
|
||||
if (err == OK && p_preset->get("binary_format/embed_pck")) {
|
||||
if (embedded_size >= 0x100000000 && String(p_preset->get("binary_format/architecture")).contains("32")) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
|
||||
|
|
@ -222,9 +222,15 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset>
|
|||
err = da->make_dir_recursive(target_path);
|
||||
if (err == OK) {
|
||||
err = da->copy_dir(src_path, target_path, -1, true);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), vformat(TTR("Failed to copy shared object \"%s\"."), src_path));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = da->copy(src_path, target_path);
|
||||
if (err != OK) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), vformat(TTR("Failed to copy shared object \"%s\"."), src_path));
|
||||
}
|
||||
if (err == OK) {
|
||||
err = sign_shared_object(p_preset, p_debug, target_path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ public:
|
|||
|
||||
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
|
||||
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
|
||||
virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
|
||||
virtual String get_template_file_name(const String &p_target, const String &p_arch) const = 0;
|
||||
|
||||
virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags);
|
||||
virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; };
|
||||
virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags);
|
||||
virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags);
|
||||
virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) { return OK; }
|
||||
virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags);
|
||||
|
||||
void set_name(const String &p_name);
|
||||
void set_os_name(const String &p_name);
|
||||
|
|
|
|||
|
|
@ -31,12 +31,7 @@
|
|||
#include "editor_export_plugin.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/export/editor_export_platform.h"
|
||||
#include "scene/resources/resource_format_text.h"
|
||||
|
||||
void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) {
|
||||
if (p_preset.is_valid()) {
|
||||
|
|
@ -48,6 +43,14 @@ Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const {
|
|||
return export_preset;
|
||||
}
|
||||
|
||||
Ref<EditorExportPlatform> EditorExportPlugin::get_export_platform() const {
|
||||
if (export_preset.is_valid()) {
|
||||
return export_preset->get_platform();
|
||||
} else {
|
||||
return Ref<EditorExportPlatform>();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) {
|
||||
ExtraFile ef;
|
||||
ef.data = p_file;
|
||||
|
|
@ -132,7 +135,7 @@ Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
|
|||
}
|
||||
|
||||
Variant EditorExportPlugin::get_option(const StringName &p_name) const {
|
||||
ERR_FAIL_NULL_V(export_preset, Variant());
|
||||
ERR_FAIL_COND_V(export_preset.is_null(), Variant());
|
||||
return export_preset->get(p_name);
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +182,7 @@ bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatfo
|
|||
|
||||
Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) {
|
||||
Ref<Resource> ret;
|
||||
GDVIRTUAL_REQUIRED_CALL(_customize_resource, p_resource, p_path, ret);
|
||||
GDVIRTUAL_CALL(_customize_resource, p_resource, p_path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -191,13 +194,13 @@ bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform>
|
|||
|
||||
Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) {
|
||||
Node *ret = nullptr;
|
||||
GDVIRTUAL_REQUIRED_CALL(_customize_scene, p_root, p_path, ret);
|
||||
GDVIRTUAL_CALL(_customize_scene, p_root, p_path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t EditorExportPlugin::_get_customization_configuration_hash() const {
|
||||
uint64_t ret = 0;
|
||||
GDVIRTUAL_REQUIRED_CALL(_get_customization_configuration_hash, ret);
|
||||
GDVIRTUAL_CALL(_get_customization_configuration_hash, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +214,7 @@ void EditorExportPlugin::_end_customize_resources() {
|
|||
|
||||
String EditorExportPlugin::get_name() const {
|
||||
String ret;
|
||||
GDVIRTUAL_REQUIRED_CALL(_get_name, ret);
|
||||
GDVIRTUAL_CALL(_get_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +224,10 @@ bool EditorExportPlugin::supports_platform(const Ref<EditorExportPlatform> &p_ex
|
|||
return ret;
|
||||
}
|
||||
|
||||
PackedStringArray EditorExportPlugin::get_export_features(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||
return _get_export_features(p_export_platform, p_debug);
|
||||
}
|
||||
|
||||
PackedStringArray EditorExportPlugin::get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||
PackedStringArray ret;
|
||||
GDVIRTUAL_CALL(_get_android_dependencies, p_export_platform, p_debug, ret);
|
||||
|
|
@ -283,6 +290,12 @@ bool EditorExportPlugin::_should_update_export_options(const Ref<EditorExportPla
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool EditorExportPlugin::_get_export_option_visibility(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const {
|
||||
bool ret = true;
|
||||
GDVIRTUAL_CALL(_get_export_option_visibility, p_export_platform, p_option_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String EditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_export_option_warning, p_export_platform, p_option_name, ret);
|
||||
|
|
@ -321,6 +334,9 @@ void EditorExportPlugin::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
|
||||
ClassDB::bind_method(D_METHOD("get_option", "name"), &EditorExportPlugin::get_option);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_export_preset"), &EditorExportPlugin::get_export_preset);
|
||||
ClassDB::bind_method(D_METHOD("get_export_platform"), &EditorExportPlugin::get_export_platform);
|
||||
|
||||
GDVIRTUAL_BIND(_export_file, "path", "type", "features");
|
||||
GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags");
|
||||
GDVIRTUAL_BIND(_export_end);
|
||||
|
|
@ -339,6 +355,7 @@ void EditorExportPlugin::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_get_export_options, "platform");
|
||||
GDVIRTUAL_BIND(_get_export_options_overrides, "platform");
|
||||
GDVIRTUAL_BIND(_should_update_export_options, "platform");
|
||||
GDVIRTUAL_BIND(_get_export_option_visibility, "platform", "option");
|
||||
GDVIRTUAL_BIND(_get_export_option_warning, "platform", "option");
|
||||
|
||||
GDVIRTUAL_BIND(_get_export_features, "platform", "debug");
|
||||
|
|
@ -353,8 +370,3 @@ void EditorExportPlugin::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_get_android_manifest_application_element_contents, "platform", "debug");
|
||||
GDVIRTUAL_BIND(_get_android_manifest_element_contents, "platform", "debug");
|
||||
}
|
||||
|
||||
EditorExportPlugin::EditorExportPlugin() {
|
||||
EDITOR_DEF("export/ssh/ssh", "");
|
||||
EDITOR_DEF("export/ssh/scp", "");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#ifndef EDITOR_EXPORT_PLUGIN_H
|
||||
#define EDITOR_EXPORT_PLUGIN_H
|
||||
|
||||
#include "core/extension/gdextension.h"
|
||||
#include "core/os/shared_object.h"
|
||||
#include "editor_export_platform.h"
|
||||
#include "editor_export_preset.h"
|
||||
|
|
@ -91,6 +90,7 @@ class EditorExportPlugin : public RefCounted {
|
|||
protected:
|
||||
void set_export_preset(const Ref<EditorExportPreset> &p_preset);
|
||||
Ref<EditorExportPreset> get_export_preset() const;
|
||||
Ref<EditorExportPlatform> get_export_platform() const;
|
||||
|
||||
void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap);
|
||||
void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String());
|
||||
|
|
@ -118,11 +118,11 @@ protected:
|
|||
GDVIRTUAL0(_export_end)
|
||||
|
||||
GDVIRTUAL2RC(bool, _begin_customize_resources, const Ref<EditorExportPlatform> &, const Vector<String> &)
|
||||
GDVIRTUAL2R(Ref<Resource>, _customize_resource, const Ref<Resource> &, String)
|
||||
GDVIRTUAL2R_REQUIRED(Ref<Resource>, _customize_resource, const Ref<Resource> &, String)
|
||||
|
||||
GDVIRTUAL2RC(bool, _begin_customize_scenes, const Ref<EditorExportPlatform> &, const Vector<String> &)
|
||||
GDVIRTUAL2R(Node *, _customize_scene, Node *, String)
|
||||
GDVIRTUAL0RC(uint64_t, _get_customization_configuration_hash)
|
||||
GDVIRTUAL2R_REQUIRED(Node *, _customize_scene, Node *, String)
|
||||
GDVIRTUAL0RC_REQUIRED(uint64_t, _get_customization_configuration_hash)
|
||||
|
||||
GDVIRTUAL0(_end_customize_scenes)
|
||||
GDVIRTUAL0(_end_customize_resources)
|
||||
|
|
@ -131,9 +131,10 @@ protected:
|
|||
GDVIRTUAL1RC(TypedArray<Dictionary>, _get_export_options, const Ref<EditorExportPlatform> &);
|
||||
GDVIRTUAL1RC(Dictionary, _get_export_options_overrides, const Ref<EditorExportPlatform> &);
|
||||
GDVIRTUAL1RC(bool, _should_update_export_options, const Ref<EditorExportPlatform> &);
|
||||
GDVIRTUAL2RC(bool, _get_export_option_visibility, const Ref<EditorExportPlatform> &, String);
|
||||
GDVIRTUAL2RC(String, _get_export_option_warning, const Ref<EditorExportPlatform> &, String);
|
||||
|
||||
GDVIRTUAL0RC(String, _get_name)
|
||||
GDVIRTUAL0RC_REQUIRED(String, _get_name)
|
||||
|
||||
GDVIRTUAL1RC(bool, _supports_platform, const Ref<EditorExportPlatform> &);
|
||||
|
||||
|
|
@ -159,12 +160,14 @@ protected:
|
|||
virtual void _get_export_options(const Ref<EditorExportPlatform> &p_export_platform, List<EditorExportPlatform::ExportOption> *r_options) const;
|
||||
virtual Dictionary _get_export_options_overrides(const Ref<EditorExportPlatform> &p_export_platform) const;
|
||||
virtual bool _should_update_export_options(const Ref<EditorExportPlatform> &p_export_platform) const;
|
||||
virtual bool _get_export_option_visibility(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const;
|
||||
virtual String _get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const;
|
||||
|
||||
public:
|
||||
virtual String get_name() const;
|
||||
|
||||
virtual bool supports_platform(const Ref<EditorExportPlatform> &p_export_platform) const;
|
||||
PackedStringArray get_export_features(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
|
||||
|
||||
virtual PackedStringArray get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
|
||||
virtual PackedStringArray get_android_dependencies_maven_repos(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
|
||||
|
|
@ -182,8 +185,6 @@ public:
|
|||
String get_ios_cpp_code() const;
|
||||
const Vector<String> &get_macos_plugin_files() const;
|
||||
Variant get_option(const StringName &p_name) const;
|
||||
|
||||
EditorExportPlugin();
|
||||
};
|
||||
|
||||
#endif // EDITOR_EXPORT_PLUGIN_H
|
||||
|
|
|
|||
|
|
@ -62,6 +62,49 @@ bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const {
|
|||
|
||||
void EditorExportPreset::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_get_property_warning", "name"), &EditorExportPreset::_get_property_warning);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has", "property"), &EditorExportPreset::has);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_files_to_export"), &EditorExportPreset::get_files_to_export);
|
||||
ClassDB::bind_method(D_METHOD("get_customized_files"), &EditorExportPreset::get_customized_files);
|
||||
ClassDB::bind_method(D_METHOD("get_customized_files_count"), &EditorExportPreset::get_customized_files_count);
|
||||
ClassDB::bind_method(D_METHOD("has_export_file", "path"), &EditorExportPreset::has_export_file);
|
||||
ClassDB::bind_method(D_METHOD("get_file_export_mode", "path", "default"), &EditorExportPreset::get_file_export_mode, DEFVAL(MODE_FILE_NOT_CUSTOMIZED));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_preset_name"), &EditorExportPreset::get_name);
|
||||
ClassDB::bind_method(D_METHOD("is_runnable"), &EditorExportPreset::is_runnable);
|
||||
ClassDB::bind_method(D_METHOD("are_advanced_options_enabled"), &EditorExportPreset::are_advanced_options_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_dedicated_server"), &EditorExportPreset::is_dedicated_server);
|
||||
ClassDB::bind_method(D_METHOD("get_export_filter"), &EditorExportPreset::get_export_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_include_filter"), &EditorExportPreset::get_include_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_exclude_filter"), &EditorExportPreset::get_exclude_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_features"), &EditorExportPreset::get_custom_features);
|
||||
ClassDB::bind_method(D_METHOD("get_patches"), &EditorExportPreset::get_patches);
|
||||
ClassDB::bind_method(D_METHOD("get_export_path"), &EditorExportPreset::get_export_path);
|
||||
ClassDB::bind_method(D_METHOD("get_encryption_in_filter"), &EditorExportPreset::get_enc_in_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_encryption_ex_filter"), &EditorExportPreset::get_enc_ex_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_encrypt_pck"), &EditorExportPreset::get_enc_pck);
|
||||
ClassDB::bind_method(D_METHOD("get_encrypt_directory"), &EditorExportPreset::get_enc_directory);
|
||||
ClassDB::bind_method(D_METHOD("get_encryption_key"), &EditorExportPreset::get_script_encryption_key);
|
||||
ClassDB::bind_method(D_METHOD("get_script_export_mode"), &EditorExportPreset::get_script_export_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_or_env", "name", "env_var"), &EditorExportPreset::_get_or_env);
|
||||
ClassDB::bind_method(D_METHOD("get_version", "name", "windows_version"), &EditorExportPreset::get_version);
|
||||
|
||||
BIND_ENUM_CONSTANT(EXPORT_ALL_RESOURCES);
|
||||
BIND_ENUM_CONSTANT(EXPORT_SELECTED_SCENES);
|
||||
BIND_ENUM_CONSTANT(EXPORT_SELECTED_RESOURCES);
|
||||
BIND_ENUM_CONSTANT(EXCLUDE_SELECTED_RESOURCES);
|
||||
BIND_ENUM_CONSTANT(EXPORT_CUSTOMIZED);
|
||||
|
||||
BIND_ENUM_CONSTANT(MODE_FILE_NOT_CUSTOMIZED);
|
||||
BIND_ENUM_CONSTANT(MODE_FILE_STRIP);
|
||||
BIND_ENUM_CONSTANT(MODE_FILE_KEEP);
|
||||
BIND_ENUM_CONSTANT(MODE_FILE_REMOVE);
|
||||
|
||||
BIND_ENUM_CONSTANT(MODE_SCRIPT_TEXT);
|
||||
BIND_ENUM_CONSTANT(MODE_SCRIPT_BINARY_TOKENS);
|
||||
BIND_ENUM_CONSTANT(MODE_SCRIPT_BINARY_TOKENS_COMPRESSED);
|
||||
}
|
||||
|
||||
String EditorExportPreset::_get_property_warning(const StringName &p_name) const {
|
||||
|
|
@ -93,8 +136,29 @@ String EditorExportPreset::_get_property_warning(const StringName &p_name) const
|
|||
|
||||
void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const KeyValue<StringName, PropertyInfo> &E : properties) {
|
||||
if (!value_overrides.has(E.key) && platform->get_export_option_visibility(this, E.key)) {
|
||||
p_list->push_back(E.value);
|
||||
if (!value_overrides.has(E.key)) {
|
||||
bool property_visible = platform->get_export_option_visibility(this, E.key);
|
||||
if (!property_visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get option visibility from editor export plugins.
|
||||
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
|
||||
for (int i = 0; i < export_plugins.size(); i++) {
|
||||
if (!export_plugins[i]->supports_platform(platform)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
export_plugins.write[i]->set_export_preset(Ref<EditorExportPreset>(this));
|
||||
property_visible = export_plugins[i]->_get_export_option_visibility(platform, E.key);
|
||||
if (!property_visible) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (property_visible) {
|
||||
p_list->push_back(E.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +388,42 @@ EditorExportPreset::FileExportMode EditorExportPreset::get_file_export_mode(cons
|
|||
return p_default;
|
||||
}
|
||||
|
||||
void EditorExportPreset::add_patch(const String &p_path, int p_at_pos) {
|
||||
ERR_FAIL_COND_EDMSG(patches.has(p_path), vformat("Failed to add patch \"%s\". Patches must be unique.", p_path));
|
||||
|
||||
if (p_at_pos < 0) {
|
||||
patches.push_back(p_path);
|
||||
} else {
|
||||
patches.insert(p_at_pos, p_path);
|
||||
}
|
||||
|
||||
EditorExport::singleton->save_presets();
|
||||
}
|
||||
|
||||
void EditorExportPreset::set_patch(int p_index, const String &p_path) {
|
||||
remove_patch(p_index);
|
||||
add_patch(p_path, p_index);
|
||||
}
|
||||
|
||||
String EditorExportPreset::get_patch(int p_index) {
|
||||
ERR_FAIL_INDEX_V(p_index, patches.size(), String());
|
||||
return patches[p_index];
|
||||
}
|
||||
|
||||
void EditorExportPreset::remove_patch(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, patches.size());
|
||||
patches.remove_at(p_index);
|
||||
EditorExport::singleton->save_presets();
|
||||
}
|
||||
|
||||
void EditorExportPreset::set_patches(const Vector<String> &p_patches) {
|
||||
patches = p_patches;
|
||||
}
|
||||
|
||||
Vector<String> EditorExportPreset::get_patches() const {
|
||||
return patches;
|
||||
}
|
||||
|
||||
void EditorExportPreset::set_custom_features(const String &p_custom_features) {
|
||||
custom_features = p_custom_features;
|
||||
EditorExport::singleton->save_presets();
|
||||
|
|
@ -351,6 +451,15 @@ String EditorExportPreset::get_enc_ex_filter() const {
|
|||
return enc_ex_filters;
|
||||
}
|
||||
|
||||
void EditorExportPreset::set_seed(uint64_t p_seed) {
|
||||
seed = p_seed;
|
||||
EditorExport::singleton->save_presets();
|
||||
}
|
||||
|
||||
uint64_t EditorExportPreset::get_seed() const {
|
||||
return seed;
|
||||
}
|
||||
|
||||
void EditorExportPreset::set_enc_pck(bool p_enabled) {
|
||||
enc_pck = p_enabled;
|
||||
EditorExport::singleton->save_presets();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ private:
|
|||
bool advanced_options_enabled = false;
|
||||
bool dedicated_server = false;
|
||||
|
||||
Vector<String> patches;
|
||||
|
||||
friend class EditorExport;
|
||||
friend class EditorExportPlatform;
|
||||
|
||||
|
|
@ -90,6 +92,7 @@ private:
|
|||
String enc_ex_filters;
|
||||
bool enc_pck = false;
|
||||
bool enc_directory = false;
|
||||
uint64_t seed = 0;
|
||||
|
||||
String script_key;
|
||||
int script_mode = MODE_SCRIPT_BINARY_TOKENS_COMPRESSED;
|
||||
|
|
@ -144,6 +147,13 @@ public:
|
|||
void set_exclude_filter(const String &p_exclude);
|
||||
String get_exclude_filter() const;
|
||||
|
||||
void add_patch(const String &p_path, int p_at_pos = -1);
|
||||
void set_patch(int p_index, const String &p_path);
|
||||
String get_patch(int p_index);
|
||||
void remove_patch(int p_index);
|
||||
void set_patches(const Vector<String> &p_patches);
|
||||
Vector<String> get_patches() const;
|
||||
|
||||
void set_custom_features(const String &p_custom_features);
|
||||
String get_custom_features() const;
|
||||
|
||||
|
|
@ -156,6 +166,9 @@ public:
|
|||
void set_enc_ex_filter(const String &p_filter);
|
||||
String get_enc_ex_filter() const;
|
||||
|
||||
void set_seed(uint64_t p_seed);
|
||||
uint64_t get_seed() const;
|
||||
|
||||
void set_enc_pck(bool p_enabled);
|
||||
bool get_enc_pck() const;
|
||||
|
||||
|
|
@ -168,6 +181,9 @@ public:
|
|||
void set_script_export_mode(int p_mode);
|
||||
int get_script_export_mode() const;
|
||||
|
||||
Variant _get_or_env(const StringName &p_name, const String &p_env_var) const {
|
||||
return get_or_env(p_name, p_env_var);
|
||||
}
|
||||
Variant get_or_env(const StringName &p_name, const String &p_env_var, bool *r_valid = nullptr) const;
|
||||
|
||||
// Return the preset's version number, or fall back to the
|
||||
|
|
@ -183,4 +199,8 @@ public:
|
|||
EditorExportPreset();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(EditorExportPreset::ExportFilter);
|
||||
VARIANT_ENUM_CAST(EditorExportPreset::FileExportMode);
|
||||
VARIANT_ENUM_CAST(EditorExportPreset::ScriptExportMode);
|
||||
|
||||
#endif // EDITOR_EXPORT_PRESET_H
|
||||
|
|
|
|||
|
|
@ -34,11 +34,12 @@
|
|||
#include "core/io/json.h"
|
||||
#include "core/io/zip_io.h"
|
||||
#include "core/version.h"
|
||||
#include "editor/editor_file_system.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "editor/export/editor_export.h"
|
||||
#include "editor/export/editor_export_preset.h"
|
||||
#include "editor/progress_dialog.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/file_dialog.h"
|
||||
|
|
@ -47,6 +48,32 @@
|
|||
#include "scene/gui/tree.h"
|
||||
#include "scene/main/http_request.h"
|
||||
|
||||
enum DownloadsAvailability {
|
||||
DOWNLOADS_AVAILABLE,
|
||||
DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE,
|
||||
DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS,
|
||||
};
|
||||
|
||||
static DownloadsAvailability _get_downloads_availability() {
|
||||
const int network_mode = EDITOR_GET("network/connection/network_mode");
|
||||
if (network_mode == EditorSettings::NETWORK_OFFLINE) {
|
||||
return DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE;
|
||||
}
|
||||
|
||||
// Downloadable export templates are only available for stable and official alpha/beta/RC builds
|
||||
// (which always have a number following their status, e.g. "alpha1").
|
||||
// Therefore, don't display download-related features when using a development version
|
||||
// (whose builds aren't numbered).
|
||||
if (String(VERSION_STATUS) == String("dev") ||
|
||||
String(VERSION_STATUS) == String("alpha") ||
|
||||
String(VERSION_STATUS) == String("beta") ||
|
||||
String(VERSION_STATUS) == String("rc")) {
|
||||
return DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS;
|
||||
}
|
||||
|
||||
return DOWNLOADS_AVAILABLE;
|
||||
}
|
||||
|
||||
void ExportTemplateManager::_update_template_status() {
|
||||
// Fetch installed templates from the file system.
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
|
|
@ -111,7 +138,9 @@ void ExportTemplateManager::_update_template_status() {
|
|||
TreeItem *ti = installed_table->create_item(installed_root);
|
||||
ti->set_text(0, version_string);
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
ti->add_button(0, get_editor_theme_icon(SNAME("Folder")), OPEN_TEMPLATE_FOLDER, false, TTR("Open the folder containing these templates."));
|
||||
#endif
|
||||
ti->add_button(0, get_editor_theme_icon(SNAME("Remove")), UNINSTALL_TEMPLATE, false, TTR("Uninstall these templates."));
|
||||
}
|
||||
}
|
||||
|
|
@ -408,6 +437,13 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
|
|||
}
|
||||
|
||||
String file = String::utf8(fname);
|
||||
|
||||
// Skip the __MACOSX directory created by macOS's built-in file zipper.
|
||||
if (file.begins_with("__MACOSX")) {
|
||||
ret = unzGoToNextFile(pkg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.ends_with("version.txt")) {
|
||||
Vector<uint8_t> uncomp_data;
|
||||
uncomp_data.resize(info.uncompressed_size);
|
||||
|
|
@ -483,7 +519,8 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
|
|||
|
||||
String file = file_path.get_file();
|
||||
|
||||
if (file.size() == 0) {
|
||||
// Skip the __MACOSX directory created by macOS's built-in file zipper.
|
||||
if (file.is_empty() || file.begins_with("__MACOSX")) {
|
||||
ret = unzGoToNextFile(pkg);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -543,7 +580,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
|
|||
unzClose(pkg);
|
||||
|
||||
_update_template_status();
|
||||
EditorSettings::get_singleton()->set_meta("export_template_download_directory", p_file.get_base_dir());
|
||||
EditorSettings::get_singleton()->set("_export_template_download_directory", p_file.get_base_dir());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -639,9 +676,55 @@ void ExportTemplateManager::_open_template_folder(const String &p_version) {
|
|||
|
||||
void ExportTemplateManager::popup_manager() {
|
||||
_update_template_status();
|
||||
if (downloads_available && !is_downloading_templates) {
|
||||
_refresh_mirrors();
|
||||
|
||||
switch (_get_downloads_availability()) {
|
||||
case DOWNLOADS_AVAILABLE: {
|
||||
current_missing_label->set_text(TTR("Export templates are missing. Download them or install from a file."));
|
||||
|
||||
mirrors_list->clear();
|
||||
mirrors_list->add_item(TTR("Best available mirror"), 0);
|
||||
mirrors_list->set_disabled(false);
|
||||
mirrors_list->set_tooltip_text("");
|
||||
|
||||
mirror_options_button->set_disabled(false);
|
||||
|
||||
download_current_button->set_disabled(false);
|
||||
download_current_button->set_tooltip_text("");
|
||||
|
||||
if (!is_downloading_templates) {
|
||||
_refresh_mirrors();
|
||||
}
|
||||
} break;
|
||||
|
||||
case DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE: {
|
||||
current_missing_label->set_text(TTR("Export templates are missing. Install them from a file."));
|
||||
|
||||
mirrors_list->clear();
|
||||
mirrors_list->add_item(TTR("Not available in offline mode"), 0);
|
||||
mirrors_list->set_disabled(true);
|
||||
mirrors_list->set_tooltip_text(TTR("Template downloading is disabled in offline mode."));
|
||||
|
||||
mirror_options_button->set_disabled(true);
|
||||
|
||||
download_current_button->set_disabled(true);
|
||||
download_current_button->set_tooltip_text(TTR("Template downloading is disabled in offline mode."));
|
||||
} break;
|
||||
|
||||
case DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS: {
|
||||
current_missing_label->set_text(TTR("Export templates are missing. Install them from a file."));
|
||||
|
||||
mirrors_list->clear();
|
||||
mirrors_list->add_item(TTR("No templates for development builds"), 0);
|
||||
mirrors_list->set_disabled(true);
|
||||
mirrors_list->set_tooltip_text(TTR("Official export templates aren't available for development builds."));
|
||||
|
||||
mirror_options_button->set_disabled(true);
|
||||
|
||||
download_current_button->set_disabled(true);
|
||||
download_current_button->set_tooltip_text(TTR("Official export templates aren't available for development builds."));
|
||||
} break;
|
||||
}
|
||||
|
||||
popup_centered(Size2(720, 280) * EDSCALE);
|
||||
}
|
||||
|
||||
|
|
@ -802,7 +885,7 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_
|
|||
|
||||
ProgressDialog::get_singleton()->end_task("uncompress_src");
|
||||
unzClose(pkg);
|
||||
|
||||
EditorFileSystem::get_singleton()->scan_changes();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -814,7 +897,7 @@ void ExportTemplateManager::_notification(int p_what) {
|
|||
current_missing_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
|
||||
current_installed_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)));
|
||||
|
||||
mirror_options_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
|
||||
mirror_options_button->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||
|
|
@ -859,24 +942,11 @@ void ExportTemplateManager::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
void ExportTemplateManager::_bind_methods() {
|
||||
}
|
||||
|
||||
ExportTemplateManager::ExportTemplateManager() {
|
||||
set_title(TTR("Export Template Manager"));
|
||||
set_hide_on_ok(false);
|
||||
set_ok_button_text(TTR("Close"));
|
||||
|
||||
// Downloadable export templates are only available for stable and official alpha/beta/RC builds
|
||||
// (which always have a number following their status, e.g. "alpha1").
|
||||
// Therefore, don't display download-related features when using a development version
|
||||
// (whose builds aren't numbered).
|
||||
downloads_available =
|
||||
String(VERSION_STATUS) != String("dev") &&
|
||||
String(VERSION_STATUS) != String("alpha") &&
|
||||
String(VERSION_STATUS) != String("beta") &&
|
||||
String(VERSION_STATUS) != String("rc");
|
||||
|
||||
VBoxContainer *main_vb = memnew(VBoxContainer);
|
||||
add_child(main_vb);
|
||||
|
||||
|
|
@ -899,11 +969,6 @@ ExportTemplateManager::ExportTemplateManager() {
|
|||
|
||||
current_missing_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
current_missing_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
|
||||
if (downloads_available) {
|
||||
current_missing_label->set_text(TTR("Export templates are missing. Download them or install from a file."));
|
||||
} else {
|
||||
current_missing_label->set_text(TTR("Export templates are missing. Install them from a file."));
|
||||
}
|
||||
current_hb->add_child(current_missing_label);
|
||||
|
||||
// Status: Current version is installed.
|
||||
|
|
@ -924,11 +989,13 @@ ExportTemplateManager::ExportTemplateManager() {
|
|||
current_installed_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
current_installed_hb->add_child(current_installed_path);
|
||||
|
||||
current_open_button = memnew(Button);
|
||||
#ifndef ANDROID_ENABLED
|
||||
Button *current_open_button = memnew(Button);
|
||||
current_open_button->set_text(TTR("Open Folder"));
|
||||
current_open_button->set_tooltip_text(TTR("Open the folder containing installed templates for the current version."));
|
||||
current_installed_hb->add_child(current_open_button);
|
||||
current_open_button->connect(SceneStringName(pressed), callable_mp(this, &ExportTemplateManager::_open_template_folder).bind(VERSION_FULL_CONFIG));
|
||||
#endif
|
||||
|
||||
current_uninstall_button = memnew(Button);
|
||||
current_uninstall_button->set_text(TTR("Uninstall"));
|
||||
|
|
@ -956,12 +1023,6 @@ ExportTemplateManager::ExportTemplateManager() {
|
|||
|
||||
mirrors_list = memnew(OptionButton);
|
||||
mirrors_list->set_custom_minimum_size(Size2(280, 0) * EDSCALE);
|
||||
if (downloads_available) {
|
||||
mirrors_list->add_item(TTR("Best available mirror"), 0);
|
||||
} else {
|
||||
mirrors_list->add_item(TTR("(no templates for development builds)"), 0);
|
||||
mirrors_list->set_disabled(true);
|
||||
}
|
||||
download_install_hb->add_child(mirrors_list);
|
||||
|
||||
request_mirrors = memnew(HTTPRequest);
|
||||
|
|
@ -971,24 +1032,17 @@ ExportTemplateManager::ExportTemplateManager() {
|
|||
mirror_options_button = memnew(MenuButton);
|
||||
mirror_options_button->get_popup()->add_item(TTR("Open in Web Browser"), VISIT_WEB_MIRROR);
|
||||
mirror_options_button->get_popup()->add_item(TTR("Copy Mirror URL"), COPY_MIRROR_URL);
|
||||
mirror_options_button->set_disabled(!downloads_available);
|
||||
download_install_hb->add_child(mirror_options_button);
|
||||
mirror_options_button->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &ExportTemplateManager::_mirror_options_button_cbk));
|
||||
|
||||
download_install_hb->add_spacer();
|
||||
|
||||
Button *download_current_button = memnew(Button);
|
||||
download_current_button = memnew(Button);
|
||||
download_current_button->set_text(TTR("Download and Install"));
|
||||
download_current_button->set_tooltip_text(TTR("Download and install templates for the current version from the best possible mirror."));
|
||||
download_install_hb->add_child(download_current_button);
|
||||
download_current_button->connect(SceneStringName(pressed), callable_mp(this, &ExportTemplateManager::_download_current));
|
||||
|
||||
// Update downloads buttons to prevent unsupported downloads.
|
||||
if (!downloads_available) {
|
||||
download_current_button->set_disabled(true);
|
||||
download_current_button->set_tooltip_text(TTR("Official export templates aren't available for development builds."));
|
||||
}
|
||||
|
||||
HBoxContainer *install_file_hb = memnew(HBoxContainer);
|
||||
install_file_hb->set_alignment(BoxContainer::ALIGNMENT_END);
|
||||
install_options_vb->add_child(install_file_hb);
|
||||
|
|
@ -1057,7 +1111,7 @@ ExportTemplateManager::ExportTemplateManager() {
|
|||
install_file_dialog->set_title(TTR("Select Template File"));
|
||||
install_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
|
||||
install_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
|
||||
install_file_dialog->set_current_dir(EditorSettings::get_singleton()->get_meta("export_template_download_directory", ""));
|
||||
install_file_dialog->set_current_dir(EDITOR_DEF("_export_template_download_directory", ""));
|
||||
install_file_dialog->add_filter("*.tpz", TTR("Godot Export Templates"));
|
||||
install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected).bind(false));
|
||||
add_child(install_file_dialog);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class ExportTemplateManager : public AcceptDialog {
|
|||
GDCLASS(ExportTemplateManager, AcceptDialog);
|
||||
|
||||
bool current_version_exists = false;
|
||||
bool downloads_available = true;
|
||||
bool mirrors_available = false;
|
||||
bool is_refreshing_mirrors = false;
|
||||
bool is_downloading_templates = false;
|
||||
|
|
@ -58,7 +57,6 @@ class ExportTemplateManager : public AcceptDialog {
|
|||
|
||||
HBoxContainer *current_installed_hb = nullptr;
|
||||
LineEdit *current_installed_path = nullptr;
|
||||
Button *current_open_button = nullptr;
|
||||
Button *current_uninstall_button = nullptr;
|
||||
|
||||
VBoxContainer *install_options_vb = nullptr;
|
||||
|
|
@ -75,6 +73,7 @@ class ExportTemplateManager : public AcceptDialog {
|
|||
Label *download_progress_label = nullptr;
|
||||
HTTPRequest *download_templates = nullptr;
|
||||
Button *install_file_button = nullptr;
|
||||
Button *download_current_button = nullptr;
|
||||
HTTPRequest *request_mirrors = nullptr;
|
||||
|
||||
enum TemplatesAction {
|
||||
|
|
@ -119,7 +118,6 @@ class ExportTemplateManager : public AcceptDialog {
|
|||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static String get_android_build_directory(const Ref<EditorExportPreset> &p_preset);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "lipo.h"
|
||||
|
||||
#include "macho.h"
|
||||
|
||||
bool LipO::is_lipo(const String &p_path) {
|
||||
Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ);
|
||||
ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("LipO: Can't open file: \"%s\".", p_path));
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
// Universal / Universal 2 fat binary file creator and extractor.
|
||||
|
||||
#include "macho.h"
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "macho.h"
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
|
||||
uint32_t MachO::seg_align(uint64_t p_vmaddr, uint32_t p_min, uint32_t p_max) {
|
||||
uint32_t salign = p_max;
|
||||
if (p_vmaddr != 0) {
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
// Mach-O binary object file format parser and editor.
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include "editor/gui/editor_file_dialog.h"
|
||||
#include "editor/import/resource_importer_texture_settings.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/check_button.h"
|
||||
#include "scene/gui/item_list.h"
|
||||
#include "scene/gui/link_button.h"
|
||||
|
|
@ -100,13 +99,15 @@ void ProjectExportDialog::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
|
||||
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
|
||||
duplicate_preset->set_button_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
|
||||
delete_preset->set_button_icon(presets->get_editor_theme_icon(SNAME("Remove")));
|
||||
patch_add_btn->set_button_icon(get_editor_theme_icon(SNAME("Add")));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
|
||||
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
|
||||
duplicate_preset->set_button_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
|
||||
delete_preset->set_button_icon(presets->get_editor_theme_icon(SNAME("Remove")));
|
||||
patch_add_btn->set_button_icon(get_editor_theme_icon(SNAME("Add")));
|
||||
connect(SceneStringName(confirmed), callable_mp(this, &ProjectExportDialog::_export_pck_zip));
|
||||
_update_export_all();
|
||||
} break;
|
||||
|
|
@ -137,7 +138,7 @@ void ProjectExportDialog::popup_export() {
|
|||
|
||||
void ProjectExportDialog::_add_preset(int p_platform) {
|
||||
Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_platform(p_platform)->create_preset();
|
||||
ERR_FAIL_COND(!preset.is_valid());
|
||||
ERR_FAIL_COND(preset.is_null());
|
||||
|
||||
String preset_name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name();
|
||||
bool make_runnable = true;
|
||||
|
|
@ -248,6 +249,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
|
|||
duplicate_preset->set_disabled(true);
|
||||
delete_preset->set_disabled(true);
|
||||
sections->hide();
|
||||
patches->clear();
|
||||
export_error->hide();
|
||||
export_templates_error->hide();
|
||||
return;
|
||||
|
|
@ -292,6 +294,21 @@ void ProjectExportDialog::_edit_preset(int p_index) {
|
|||
exclude_filters->set_text(current->get_exclude_filter());
|
||||
server_strip_message->set_visible(current->get_export_filter() == EditorExportPreset::EXPORT_CUSTOMIZED);
|
||||
|
||||
patches->clear();
|
||||
TreeItem *patch_root = patches->create_item();
|
||||
Vector<String> patch_list = current->get_patches();
|
||||
for (int i = 0; i < patch_list.size(); i++) {
|
||||
TreeItem *patch = patches->create_item(patch_root);
|
||||
const String &patch_path = patch_list[i];
|
||||
patch->set_cell_mode(0, TreeItem::CELL_MODE_STRING);
|
||||
patch->set_editable(0, true);
|
||||
patch->set_text(0, patch_path.get_file());
|
||||
patch->set_tooltip_text(0, patch_path);
|
||||
patch->set_metadata(0, i);
|
||||
patch->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0);
|
||||
patch->add_button(0, get_editor_theme_icon(SNAME("FileBrowse")), 1);
|
||||
}
|
||||
|
||||
_fill_resource_tree();
|
||||
|
||||
bool needs_templates;
|
||||
|
|
@ -364,10 +381,16 @@ void ProjectExportDialog::_edit_preset(int p_index) {
|
|||
bool enc_pck_mode = current->get_enc_pck();
|
||||
enc_pck->set_pressed(enc_pck_mode);
|
||||
|
||||
uint64_t seed = current->get_seed();
|
||||
if (!updating_seed) {
|
||||
seed_input->set_text(itos(seed));
|
||||
}
|
||||
|
||||
enc_directory->set_disabled(!enc_pck_mode);
|
||||
enc_in_filters->set_editable(enc_pck_mode);
|
||||
enc_ex_filters->set_editable(enc_pck_mode);
|
||||
script_key->set_editable(enc_pck_mode);
|
||||
seed_input->set_editable(enc_pck_mode);
|
||||
|
||||
bool enc_directory_mode = current->get_enc_directory();
|
||||
enc_directory->set_pressed(enc_directory_mode);
|
||||
|
|
@ -573,6 +596,21 @@ void ProjectExportDialog::_enc_pck_changed(bool p_pressed) {
|
|||
_update_current_preset();
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_seed_input_changed(const String &p_text) {
|
||||
if (updating) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
current->set_seed(seed_input->get_text().to_int());
|
||||
|
||||
updating_seed = true;
|
||||
_update_current_preset();
|
||||
updating_seed = false;
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_enc_directory_changed(bool p_pressed) {
|
||||
if (updating) {
|
||||
return;
|
||||
|
|
@ -630,7 +668,7 @@ void ProjectExportDialog::_duplicate_preset() {
|
|||
}
|
||||
|
||||
Ref<EditorExportPreset> preset = current->get_platform()->create_preset();
|
||||
ERR_FAIL_COND(!preset.is_valid());
|
||||
ERR_FAIL_COND(preset.is_null());
|
||||
|
||||
String preset_name = current->get_name() + " (copy)";
|
||||
bool make_runnable = true;
|
||||
|
|
@ -664,7 +702,14 @@ void ProjectExportDialog::_duplicate_preset() {
|
|||
preset->set_export_filter(current->get_export_filter());
|
||||
preset->set_include_filter(current->get_include_filter());
|
||||
preset->set_exclude_filter(current->get_exclude_filter());
|
||||
preset->set_patches(current->get_patches());
|
||||
preset->set_custom_features(current->get_custom_features());
|
||||
preset->set_enc_in_filter(current->get_enc_in_filter());
|
||||
preset->set_enc_ex_filter(current->get_enc_ex_filter());
|
||||
preset->set_enc_pck(current->get_enc_pck());
|
||||
preset->set_enc_directory(current->get_enc_directory());
|
||||
preset->set_script_encryption_key(current->get_script_encryption_key());
|
||||
preset->set_script_export_mode(current->get_script_export_mode());
|
||||
|
||||
for (const KeyValue<StringName, Variant> &E : current->get_values()) {
|
||||
preset->set(E.key, E.value);
|
||||
|
|
@ -713,14 +758,29 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_
|
|||
drag->add_child(tr);
|
||||
Label *label = memnew(Label);
|
||||
label->set_text(presets->get_item_text(pos));
|
||||
label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate user input.
|
||||
drag->add_child(label);
|
||||
|
||||
presets->set_drag_preview(drag);
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
||||
} else if (p_from == patches) {
|
||||
TreeItem *item = patches->get_item_at_position(p_point);
|
||||
|
||||
if (item) {
|
||||
int item_metadata = item->get_metadata(0);
|
||||
Dictionary d;
|
||||
d["type"] = "export_patch";
|
||||
d["patch"] = item_metadata;
|
||||
|
||||
Label *label = memnew(Label);
|
||||
label->set_text(item->get_text(0));
|
||||
patches->set_drag_preview(label);
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +794,18 @@ bool ProjectExportDialog::can_drop_data_fw(const Point2 &p_point, const Variant
|
|||
if (presets->get_item_at_position(p_point, true) < 0 && !presets->is_pos_at_end_of_items(p_point)) {
|
||||
return false;
|
||||
}
|
||||
} else if (p_from == patches) {
|
||||
Dictionary d = p_data;
|
||||
if (d.get("type", "") != "export_patch") {
|
||||
return false;
|
||||
}
|
||||
|
||||
TreeItem *item = patches->get_item_at_position(p_point);
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
patches->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -770,6 +842,31 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d
|
|||
} else {
|
||||
_edit_preset(presets->get_item_count() - 1);
|
||||
}
|
||||
} else if (p_from == patches) {
|
||||
Dictionary d = p_data;
|
||||
int from_pos = d["patch"];
|
||||
|
||||
TreeItem *item = patches->get_item_at_position(p_point);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
int to_pos = item->get_metadata(0);
|
||||
|
||||
if (patches->get_drop_section_at_position(p_point) > 0) {
|
||||
to_pos++;
|
||||
}
|
||||
|
||||
if (to_pos > from_pos) {
|
||||
to_pos--;
|
||||
}
|
||||
|
||||
Ref<EditorExportPreset> preset = get_current_preset();
|
||||
String patch = preset->get_patch(from_pos);
|
||||
preset->remove_patch(from_pos);
|
||||
preset->add_patch(patch, to_pos);
|
||||
|
||||
_update_current_preset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -903,7 +1000,7 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem
|
|||
if (p_export_filter == EditorExportPreset::EXPORT_SELECTED_SCENES && type != "PackedScene") {
|
||||
continue;
|
||||
}
|
||||
if (type == "TextFile") {
|
||||
if (type == "TextFile" || type == "OtherFile") {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1025,6 +1122,75 @@ void ProjectExportDialog::_set_file_export_mode(int p_id) {
|
|||
_propagate_file_export_mode(include_files->get_root(), EditorExportPreset::MODE_FILE_NOT_CUSTOMIZED);
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_patch_tree_button_clicked(Object *p_item, int p_column, int p_id, int p_mouse_button_index) {
|
||||
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
|
||||
|
||||
patch_index = ti->get_metadata(0);
|
||||
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
if (p_id == 0) {
|
||||
Vector<String> preset_patches = current->get_patches();
|
||||
ERR_FAIL_INDEX(patch_index, preset_patches.size());
|
||||
patch_erase->set_text(vformat(TTR("Delete patch '%s' from list?"), preset_patches[patch_index].get_file()));
|
||||
patch_erase->popup_centered();
|
||||
} else {
|
||||
patch_dialog->popup_file_dialog();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_patch_tree_item_edited() {
|
||||
TreeItem *item = patches->get_edited();
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
int index = item->get_metadata(0);
|
||||
String patch_path = item->get_text(0);
|
||||
|
||||
current->set_patch(index, patch_path);
|
||||
item->set_tooltip_text(0, patch_path);
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_patch_file_selected(const String &p_path) {
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
String relative_path = ProjectSettings::get_singleton()->get_resource_path().path_to_file(p_path);
|
||||
|
||||
Vector<String> preset_patches = current->get_patches();
|
||||
if (patch_index >= preset_patches.size()) {
|
||||
current->add_patch(relative_path);
|
||||
} else {
|
||||
current->set_patch(patch_index, relative_path);
|
||||
}
|
||||
|
||||
_update_current_preset();
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_patch_delete_confirmed() {
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
Vector<String> preset_patches = current->get_patches();
|
||||
if (patch_index < preset_patches.size()) {
|
||||
current->remove_patch(patch_index);
|
||||
_update_current_preset();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_patch_add_pack_pressed() {
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
||||
patch_index = current->get_patches().size();
|
||||
patch_dialog->popup_file_dialog();
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_export_pck_zip() {
|
||||
Ref<EditorExportPreset> current = get_current_preset();
|
||||
ERR_FAIL_COND(current.is_null());
|
||||
|
|
@ -1043,11 +1209,23 @@ void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) {
|
|||
|
||||
const Dictionary &fd_option = export_pck_zip->get_selected_options();
|
||||
bool export_debug = fd_option.get(TTR("Export With Debug"), true);
|
||||
bool export_as_patch = fd_option.get(TTR("Export As Patch"), true);
|
||||
|
||||
EditorSettings::get_singleton()->set_project_metadata("export_options", "export_debug", export_debug);
|
||||
EditorSettings::get_singleton()->set_project_metadata("export_options", "export_as_patch", export_as_patch);
|
||||
|
||||
if (p_path.ends_with(".zip")) {
|
||||
platform->export_zip(current, export_debug, p_path);
|
||||
if (export_as_patch) {
|
||||
platform->export_zip_patch(current, export_debug, p_path);
|
||||
} else {
|
||||
platform->export_zip(current, export_debug, p_path);
|
||||
}
|
||||
} else if (p_path.ends_with(".pck")) {
|
||||
platform->export_pack(current, export_debug, p_path);
|
||||
if (export_as_patch) {
|
||||
platform->export_pack_patch(current, export_debug, p_path);
|
||||
} else {
|
||||
platform->export_pack(current, export_debug, p_path);
|
||||
}
|
||||
} else {
|
||||
ERR_FAIL_MSG("Path must end with .pck or .zip");
|
||||
}
|
||||
|
|
@ -1072,10 +1250,10 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) {
|
|||
|
||||
if (invalid_path) {
|
||||
export_project->get_ok_button()->set_disabled(true);
|
||||
export_project->get_line_edit()->disconnect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
export_project->get_line_edit()->disconnect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
} else {
|
||||
export_project->get_ok_button()->set_disabled(false);
|
||||
export_project->get_line_edit()->connect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
export_project->get_line_edit()->connect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1108,9 +1286,9 @@ void ProjectExportDialog::_export_project() {
|
|||
// with _validate_export_path.
|
||||
// FIXME: This is a hack, we should instead change EditorFileDialog to allow
|
||||
// disabling validation by the "text_submitted" signal.
|
||||
if (!export_project->get_line_edit()->is_connected("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted))) {
|
||||
if (!export_project->get_line_edit()->is_connected(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted))) {
|
||||
export_project->get_ok_button()->set_disabled(false);
|
||||
export_project->get_line_edit()->connect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
export_project->get_line_edit()->connect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
|
||||
}
|
||||
|
||||
export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
|
||||
|
|
@ -1135,6 +1313,8 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
|
|||
Dictionary fd_option = export_project->get_selected_options();
|
||||
bool export_debug = fd_option.get(TTR("Export With Debug"), true);
|
||||
|
||||
EditorSettings::get_singleton()->set_project_metadata("export_options", "export_debug", export_debug);
|
||||
|
||||
Error err = platform->export_project(current, export_debug, current->get_export_path(), 0);
|
||||
result_dialog_log->clear();
|
||||
if (err != ERR_SKIP) {
|
||||
|
|
@ -1147,10 +1327,8 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
|
|||
}
|
||||
|
||||
void ProjectExportDialog::_export_all_dialog() {
|
||||
#ifndef ANDROID_ENABLED
|
||||
export_all_dialog->show();
|
||||
export_all_dialog->popup_centered(Size2(300, 80));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ProjectExportDialog::_export_all_dialog_action(const String &p_str) {
|
||||
|
|
@ -1243,6 +1421,7 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
preset_vb->add_child(mc);
|
||||
mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
presets = memnew(ItemList);
|
||||
presets->set_theme_type_variation("ItemListSecondary");
|
||||
presets->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
SET_DRAG_FORWARDING_GCD(presets, ProjectExportDialog);
|
||||
mc->add_child(presets);
|
||||
|
|
@ -1387,6 +1566,40 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
exclude_filters);
|
||||
exclude_filters->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_filter_changed));
|
||||
|
||||
// Patch packages.
|
||||
|
||||
VBoxContainer *patch_vb = memnew(VBoxContainer);
|
||||
sections->add_child(patch_vb);
|
||||
patch_vb->set_name(TTR("Patches"));
|
||||
|
||||
patches = memnew(Tree);
|
||||
patches->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
patches->set_hide_root(true);
|
||||
patches->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
patches->connect("button_clicked", callable_mp(this, &ProjectExportDialog::_patch_tree_button_clicked));
|
||||
patches->connect("item_edited", callable_mp(this, &ProjectExportDialog::_patch_tree_item_edited));
|
||||
SET_DRAG_FORWARDING_GCD(patches, ProjectExportDialog);
|
||||
patches->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
|
||||
patch_vb->add_margin_child(TTR("Base Packs:"), patches, true);
|
||||
|
||||
patch_dialog = memnew(EditorFileDialog);
|
||||
patch_dialog->add_filter("*.pck", TTR("Godot Project Pack"));
|
||||
patch_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
|
||||
patch_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
|
||||
patch_dialog->connect("file_selected", callable_mp(this, &ProjectExportDialog::_patch_file_selected));
|
||||
add_child(patch_dialog);
|
||||
|
||||
patch_erase = memnew(ConfirmationDialog);
|
||||
patch_erase->set_ok_button_text(TTR("Delete"));
|
||||
patch_erase->connect(SceneStringName(confirmed), callable_mp(this, &ProjectExportDialog::_patch_delete_confirmed));
|
||||
add_child(patch_erase);
|
||||
|
||||
patch_add_btn = memnew(Button);
|
||||
patch_add_btn->set_text(TTR("Add Pack"));
|
||||
patch_add_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
patch_add_btn->connect(SceneStringName(pressed), callable_mp(this, &ProjectExportDialog::_patch_add_pack_pressed));
|
||||
patch_vb->add_child(patch_add_btn);
|
||||
|
||||
// Feature tags.
|
||||
|
||||
VBoxContainer *feature_vb = memnew(VBoxContainer);
|
||||
|
|
@ -1412,12 +1625,12 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
sec_scroll_container->add_child(sec_vb);
|
||||
|
||||
enc_pck = memnew(CheckButton);
|
||||
enc_pck->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_pck_changed));
|
||||
enc_pck->connect(SceneStringName(toggled), callable_mp(this, &ProjectExportDialog::_enc_pck_changed));
|
||||
enc_pck->set_text(TTR("Encrypt Exported PCK"));
|
||||
sec_vb->add_child(enc_pck);
|
||||
|
||||
enc_directory = memnew(CheckButton);
|
||||
enc_directory->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_directory_changed));
|
||||
enc_directory->connect(SceneStringName(toggled), callable_mp(this, &ProjectExportDialog::_enc_directory_changed));
|
||||
enc_directory->set_text(TTR("Encrypt Index (File Names and Info)"));
|
||||
sec_vb->add_child(enc_directory);
|
||||
|
||||
|
|
@ -1442,6 +1655,10 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
sec_vb->add_child(script_key_error);
|
||||
sections->add_child(sec_scroll_container);
|
||||
|
||||
seed_input = memnew(LineEdit);
|
||||
seed_input->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_seed_input_changed));
|
||||
sec_vb->add_margin_child(TTR("Initialization vector seed"), seed_input);
|
||||
|
||||
Label *sec_info = memnew(Label);
|
||||
sec_info->set_text(TTR("Note: Encryption key needs to be stored in the binary,\nyou need to build the export templates from source."));
|
||||
sec_vb->add_child(sec_info);
|
||||
|
|
@ -1491,13 +1708,9 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
set_ok_button_text(TTR("Export PCK/ZIP..."));
|
||||
get_ok_button()->set_tooltip_text(TTR("Export the project resources as a PCK or ZIP package. This is not a playable build, only the project data without a Godot executable."));
|
||||
get_ok_button()->set_disabled(true);
|
||||
#ifdef ANDROID_ENABLED
|
||||
export_button = memnew(Button);
|
||||
export_button->hide();
|
||||
#else
|
||||
|
||||
export_button = add_button(TTR("Export Project..."), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
|
||||
export_button->set_tooltip_text(TTR("Export the project as a playable build (Godot executable and project data) for the selected preset."));
|
||||
#endif
|
||||
export_button->connect(SceneStringName(pressed), callable_mp(this, &ProjectExportDialog::_export_project));
|
||||
// Disable initially before we select a valid preset
|
||||
export_button->set_disabled(true);
|
||||
|
|
@ -1510,14 +1723,8 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
export_all_dialog->add_button(TTR("Debug"), true, "debug");
|
||||
export_all_dialog->add_button(TTR("Release"), true, "release");
|
||||
export_all_dialog->connect("custom_action", callable_mp(this, &ProjectExportDialog::_export_all_dialog_action));
|
||||
#ifdef ANDROID_ENABLED
|
||||
export_all_dialog->hide();
|
||||
|
||||
export_all_button = memnew(Button);
|
||||
export_all_button->hide();
|
||||
#else
|
||||
export_all_button = add_button(TTR("Export All..."), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
|
||||
#endif
|
||||
export_all_button->connect(SceneStringName(pressed), callable_mp(this, &ProjectExportDialog::_export_all_dialog));
|
||||
export_all_button->set_disabled(true);
|
||||
|
||||
|
|
@ -1578,8 +1785,9 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
export_project->connect("file_selected", callable_mp(this, &ProjectExportDialog::_export_project_to_path));
|
||||
export_project->get_line_edit()->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_validate_export_path));
|
||||
|
||||
export_project->add_option(TTR("Export With Debug"), Vector<String>(), true);
|
||||
export_pck_zip->add_option(TTR("Export With Debug"), Vector<String>(), true);
|
||||
export_project->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true));
|
||||
export_pck_zip->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true));
|
||||
export_pck_zip->add_option(TTR("Export As Patch"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_as_patch", true));
|
||||
|
||||
set_hide_on_ok(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ class ProjectExportDialog : public ConfirmationDialog {
|
|||
AcceptDialog *export_all_dialog = nullptr;
|
||||
|
||||
RBSet<String> feature_set;
|
||||
|
||||
Tree *patches = nullptr;
|
||||
int patch_index = -1;
|
||||
EditorFileDialog *patch_dialog = nullptr;
|
||||
ConfirmationDialog *patch_erase = nullptr;
|
||||
Button *patch_add_btn = nullptr;
|
||||
|
||||
LineEdit *custom_features = nullptr;
|
||||
RichTextLabel *custom_feature_display = nullptr;
|
||||
|
||||
|
|
@ -148,6 +155,12 @@ class ProjectExportDialog : public ConfirmationDialog {
|
|||
void _tree_popup_edited(bool p_arrow_clicked);
|
||||
void _set_file_export_mode(int p_id);
|
||||
|
||||
void _patch_tree_button_clicked(Object *p_item, int p_column, int p_id, int p_mouse_button_index);
|
||||
void _patch_tree_item_edited();
|
||||
void _patch_file_selected(const String &p_path);
|
||||
void _patch_delete_confirmed();
|
||||
void _patch_add_pack_pressed();
|
||||
|
||||
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
|
||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
|
|
@ -159,6 +172,7 @@ class ProjectExportDialog : public ConfirmationDialog {
|
|||
CheckButton *enc_directory = nullptr;
|
||||
LineEdit *enc_in_filters = nullptr;
|
||||
LineEdit *enc_ex_filters = nullptr;
|
||||
LineEdit *seed_input = nullptr;
|
||||
|
||||
OptionButton *script_mode = nullptr;
|
||||
|
||||
|
|
@ -179,9 +193,11 @@ class ProjectExportDialog : public ConfirmationDialog {
|
|||
|
||||
bool updating_script_key = false;
|
||||
bool updating_enc_filters = false;
|
||||
bool updating_seed = false;
|
||||
void _enc_pck_changed(bool p_pressed);
|
||||
void _enc_directory_changed(bool p_pressed);
|
||||
void _enc_filters_changed(const String &p_text);
|
||||
void _seed_input_changed(const String &p_text);
|
||||
void _script_encryption_key_changed(const String &p_key);
|
||||
bool _validate_script_encryption_key(const String &p_key);
|
||||
|
||||
|
|
@ -203,7 +219,7 @@ public:
|
|||
|
||||
Ref<EditorExportPreset> get_current_preset() const;
|
||||
|
||||
bool is_exporting() const { return exporting; };
|
||||
bool is_exporting() const { return exporting; }
|
||||
|
||||
ProjectExportDialog();
|
||||
~ProjectExportDialog();
|
||||
|
|
|
|||
122
engine/editor/export/project_zip_packer.cpp
Normal file
122
engine/editor/export/project_zip_packer.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/**************************************************************************/
|
||||
/* project_zip_packer.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "project_zip_packer.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/os/time.h"
|
||||
|
||||
String ProjectZIPPacker::get_project_zip_safe_name() {
|
||||
// Name the downloaded ZIP file to contain the project name and download date for easier organization.
|
||||
// Replace characters not allowed (or risky) in Windows file names with safe characters.
|
||||
// In the project name, all invalid characters become an empty string so that a name
|
||||
// like "Platformer 2: Godette's Revenge" becomes "platformer_2-_godette-s_revenge".
|
||||
const String project_name = GLOBAL_GET("application/config/name");
|
||||
const String project_name_safe = project_name.to_lower().replace(" ", "_");
|
||||
const String datetime_safe =
|
||||
Time::get_singleton()->get_datetime_string_from_system(false, true).replace(" ", "_");
|
||||
const String output_name = OS::get_singleton()->get_safe_dir_name(vformat("%s_%s.zip", project_name_safe, datetime_safe));
|
||||
return output_name;
|
||||
}
|
||||
|
||||
void ProjectZIPPacker::pack_project_zip(const String &p_path) {
|
||||
Ref<FileAccess> io_fa;
|
||||
zlib_filefunc_def io = zipio_create_io(&io_fa);
|
||||
|
||||
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
const String base_path = resource_path.substr(0, resource_path.rfind_char('/')) + "/";
|
||||
|
||||
zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io);
|
||||
_zip_recursive(resource_path, base_path, zip);
|
||||
zipClose(zip, nullptr);
|
||||
}
|
||||
|
||||
void ProjectZIPPacker::_zip_file(const String &p_path, const String &p_base_path, zipFile p_zip) {
|
||||
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (f.is_null()) {
|
||||
WARN_PRINT("Unable to open file for zipping: " + p_path);
|
||||
return;
|
||||
}
|
||||
Vector<uint8_t> data;
|
||||
uint64_t len = f->get_length();
|
||||
data.resize(len);
|
||||
f->get_buffer(data.ptrw(), len);
|
||||
|
||||
String path = p_path.replace_first(p_base_path, "");
|
||||
zipOpenNewFileInZip(p_zip,
|
||||
path.utf8().get_data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
Z_DEFLATED,
|
||||
Z_DEFAULT_COMPRESSION);
|
||||
zipWriteInFileInZip(p_zip, data.ptr(), data.size());
|
||||
zipCloseFileInZip(p_zip);
|
||||
}
|
||||
|
||||
void ProjectZIPPacker::_zip_recursive(const String &p_path, const String &p_base_path, zipFile p_zip) {
|
||||
Ref<DirAccess> dir = DirAccess::open(p_path);
|
||||
if (dir.is_null()) {
|
||||
WARN_PRINT("Unable to open directory for zipping: " + p_path);
|
||||
return;
|
||||
}
|
||||
dir->list_dir_begin();
|
||||
String cur = dir->get_next();
|
||||
String project_data_dir_name = ProjectSettings::get_singleton()->get_project_data_dir_name();
|
||||
while (!cur.is_empty()) {
|
||||
String cs = p_path.path_join(cur);
|
||||
if (cur == "." || cur == ".." || cur == project_data_dir_name) {
|
||||
// Skip
|
||||
} else if (dir->current_is_dir()) {
|
||||
String path = cs.replace_first(p_base_path, "") + "/";
|
||||
zipOpenNewFileInZip(p_zip,
|
||||
path.utf8().get_data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
Z_DEFLATED,
|
||||
Z_DEFAULT_COMPRESSION);
|
||||
zipCloseFileInZip(p_zip);
|
||||
_zip_recursive(cs, p_base_path, p_zip);
|
||||
} else {
|
||||
_zip_file(cs, p_base_path, p_zip);
|
||||
}
|
||||
cur = dir->get_next();
|
||||
}
|
||||
}
|
||||
46
engine/editor/export/project_zip_packer.h
Normal file
46
engine/editor/export/project_zip_packer.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**************************************************************************/
|
||||
/* project_zip_packer.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PROJECT_ZIP_PACKER_H
|
||||
#define PROJECT_ZIP_PACKER_H
|
||||
|
||||
#include "core/io/zip_io.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
class ProjectZIPPacker {
|
||||
static void _zip_file(const String &p_path, const String &p_base_path, zipFile p_zip);
|
||||
static void _zip_recursive(const String &p_path, const String &p_base_path, zipFile p_zip);
|
||||
|
||||
public:
|
||||
static String get_project_zip_safe_name();
|
||||
static void pack_project_zip(const String &p_path);
|
||||
};
|
||||
|
||||
#endif // PROJECT_ZIP_PACKER_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue