diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 71315f137716..d46cad68d1f9 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -222,10 +222,33 @@ String EditorExportPreset::get_custom_features() const { return custom_features; } +void EditorExportPreset::set_script_export_mode(int p_mode) { + + script_mode = p_mode; + EditorExport::singleton->save_presets(); +} + +int EditorExportPreset::get_script_export_mode() const { + + return script_mode; +} + +void EditorExportPreset::set_script_encryption_key(const String &p_key) { + + script_key = p_key; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_script_encryption_key() const { + + return script_key; +} + EditorExportPreset::EditorExportPreset() : export_filter(EXPORT_ALL_RESOURCES), export_path(""), - runnable(false) { + runnable(false), + script_mode(MODE_SCRIPT_COMPILED) { } /////////////////////////////////// @@ -474,6 +497,18 @@ void EditorExportPlatform::_edit_filter_list(Set &r_list, const String & memdelete(da); } +void EditorExportPlugin::set_export_preset(const Ref &p_preset) { + + if (p_preset.is_valid()) { + export_preset = p_preset; + } +} + +Ref EditorExportPlugin::get_export_preset() const { + + return export_preset; +} + void EditorExportPlugin::add_file(const String &p_path, const Vector &p_file, bool p_remap) { ExtraFile ef; @@ -658,6 +693,9 @@ Error EditorExportPlatform::export_project_files(const Ref & Vector > export_plugins = EditorExport::get_singleton()->get_export_plugins(); for (int i = 0; i < export_plugins.size(); i++) { + + export_plugins.write[i]->set_export_preset(p_preset); + if (p_so_func) { for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) { p_so_func(p_udata, export_plugins[i]->shared_objects[j]); @@ -1048,6 +1086,7 @@ void EditorExport::_save() { config->set_value(section, "platform", preset->get_platform()->get_name()); config->set_value(section, "runnable", preset->is_runnable()); config->set_value(section, "custom_features", preset->get_custom_features()); + bool save_files = false; switch (preset->get_export_filter()) { case EditorExportPreset::EXPORT_ALL_RESOURCES: { @@ -1071,6 +1110,8 @@ void EditorExport::_save() { config->set_value(section, "exclude_filter", preset->get_exclude_filter()); config->set_value(section, "export_path", preset->get_export_path()); config->set_value(section, "patch_list", preset->get_patches()); + config->set_value(section, "script_export_mode", preset->get_script_export_mode()); + config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); String option_section = "preset." + itos(i) + ".options"; @@ -1233,6 +1274,13 @@ void EditorExport::load_config() { preset->add_patch(patch_list[i]); } + if (config->has_section_key(section, "script_export_mode")) { + preset->set_script_export_mode(config->get_value(section, "script_export_mode")); + } + if (config->has_section_key(section, "script_encryption_key")) { + preset->set_script_encryption_key(config->get_value(section, "script_encryption_key")); + } + String option_section = "preset." + itos(index) + ".options"; List options; diff --git a/editor/editor_export.h b/editor/editor_export.h index 881e86fb12aa..d9cf0b819f7c 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -52,6 +52,12 @@ public: EXPORT_SELECTED_RESOURCES, }; + enum ScriptExportMode { + MODE_SCRIPT_TEXT, + MODE_SCRIPT_COMPILED, + MODE_SCRIPT_ENCRYPTED, + }; + private: Ref platform; ExportFilter export_filter; @@ -75,6 +81,9 @@ private: String custom_features; + int script_mode; + String script_key; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -118,6 +127,12 @@ public: void set_export_path(const String &p_path); String get_export_path() const; + void set_script_export_mode(int p_mode); + int get_script_export_mode() const; + + void set_script_encryption_key(const String &p_key); + String get_script_encryption_key() const; + const List &get_properties() const { return properties; } EditorExportPreset(); @@ -260,6 +275,8 @@ class EditorExportPlugin : public Reference { friend class EditorExportPlatform; + Ref export_preset; + Vector shared_objects; struct ExtraFile { String path; @@ -294,6 +311,9 @@ class EditorExportPlugin : public Reference { void _export_end_script(); protected: + void set_export_preset(const Ref &p_preset); + Ref get_export_preset() const; + void add_file(const String &p_path, const Vector &p_file, bool p_remap); void add_shared_object(const String &p_path, const Vector &tags); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index f82133e0d318..a1f5d7274f69 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -80,7 +80,7 @@ void ProjectExportDialog::popup_export() { _update_presets(); if (presets->get_current() >= 0) { - _edit_preset(presets->get_current()); // triggers rescan for templates if newly installed + _update_current_preset(); // triggers rescan for templates if newly installed } // Restore valid window bounds or pop up at default size. @@ -137,13 +137,18 @@ void ProjectExportDialog::_add_preset(int p_platform) { _edit_preset(EditorExport::get_singleton()->get_export_preset_count() - 1); } +void ProjectExportDialog::_update_current_preset() { + + _edit_preset(presets->get_current()); +} + void ProjectExportDialog::_update_presets() { updating = true; Ref current; if (presets->get_current() >= 0 && presets->get_current() < presets->get_item_count()) - current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + current = get_current_preset(); int current_idx = -1; presets->clear(); @@ -300,12 +305,33 @@ void ProjectExportDialog::_edit_preset(int p_index) { _update_export_all(); minimum_size_changed(); + int script_export_mode = current->get_script_export_mode(); + script_mode->select(script_export_mode); + + String key = current->get_script_encryption_key(); + if (!updating_script_key) { + script_key->set_text(key); + } + if (script_export_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) { + script_key->set_editable(true); + + bool key_valid = _validate_script_encryption_key(key); + if (key_valid) { + script_key_error->hide(); + } else { + script_key_error->show(); + } + } else { + script_key->set_editable(false); + script_key_error->hide(); + } + updating = false; } void ProjectExportDialog::_update_feature_list() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Set fset; @@ -342,7 +368,7 @@ void ProjectExportDialog::_custom_features_changed(const String &p_text) { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); current->set_custom_features(p_text); @@ -359,7 +385,7 @@ void ProjectExportDialog::_patch_button_pressed(Object *p_item, int p_column, in patch_index = ti->get_metadata(0); - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); if (p_id == 0) { @@ -379,7 +405,7 @@ void ProjectExportDialog::_patch_edited() { return; int index = item->get_metadata(0); - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Vector patches = current->get_patches(); @@ -397,7 +423,7 @@ void ProjectExportDialog::_patch_edited() { void ProjectExportDialog::_patch_selected(const String &p_path) { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Vector patches = current->get_patches(); @@ -410,25 +436,25 @@ void ProjectExportDialog::_patch_selected(const String &p_path) { current->set_patch(patch_index, ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + enabled); } - _edit_preset(presets->get_current()); + _update_current_preset(); } void ProjectExportDialog::_patch_deleted() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Vector patches = current->get_patches(); if (patch_index < patches.size()) { current->remove_patch(patch_index); - _edit_preset(presets->get_current()); + _update_current_preset(); } } void ProjectExportDialog::_update_parameters(const String &p_edited_property) { - _edit_preset(presets->get_current()); + _update_current_preset(); } void ProjectExportDialog::_runnable_pressed() { @@ -436,7 +462,7 @@ void ProjectExportDialog::_runnable_pressed() { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); if (runnable->is_pressed()) { @@ -460,7 +486,7 @@ void ProjectExportDialog::_name_changed(const String &p_string) { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); current->set_name(p_string); @@ -468,34 +494,77 @@ void ProjectExportDialog::_name_changed(const String &p_string) { } void ProjectExportDialog::set_export_path(const String &p_value) { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); current->set_export_path(p_value); } String ProjectExportDialog::get_export_path() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND_V(current.is_null(), String("")); return current->get_export_path(); } +Ref ProjectExportDialog::get_current_preset() const { + + return EditorExport::get_singleton()->get_export_preset(presets->get_current()); +} + void ProjectExportDialog::_export_path_changed(const StringName &p_property, const Variant &p_value) { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); current->set_export_path(p_value); _update_presets(); } +void ProjectExportDialog::_script_export_mode_changed(int p_mode) { + + if (updating) + return; + + Ref current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_script_export_mode(p_mode); + + _update_current_preset(); +} + +void ProjectExportDialog::_script_encryption_key_changed(const String &p_key) { + + if (updating) + return; + + Ref current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_script_encryption_key(p_key); + + updating_script_key = true; + _update_current_preset(); + updating_script_key = false; +} + +bool ProjectExportDialog::_validate_script_encryption_key(const String &p_key) { + + bool is_valid = false; + + if (!p_key.empty() && p_key.is_valid_hex_number(false) && p_key.length() == 64) { + is_valid = true; + } + return is_valid; +} + void ProjectExportDialog::_duplicate_preset() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -550,7 +619,7 @@ void ProjectExportDialog::_duplicate_preset() { void ProjectExportDialog::_delete_preset() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -688,12 +757,12 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d to_pos--; } - Ref preset = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref preset = get_current_preset(); String patch = preset->get_patch(from_pos); preset->remove_patch(from_pos); preset->add_patch(patch, to_pos); - _edit_preset(presets->get_current()); + _update_current_preset(); } } @@ -702,7 +771,7 @@ void ProjectExportDialog::_export_type_changed(int p_which) { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -717,7 +786,7 @@ void ProjectExportDialog::_filter_changed(const String &p_filter) { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -731,7 +800,7 @@ void ProjectExportDialog::_fill_resource_tree() { include_label->hide(); include_margin->hide(); - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -793,7 +862,7 @@ void ProjectExportDialog::_tree_changed() { if (updating) return; - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); if (current.is_null()) return; @@ -818,7 +887,7 @@ void ProjectExportDialog::_export_pck_zip() { void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Ref platform = current->get_platform(); ERR_FAIL_COND(platform.is_null()); @@ -857,7 +926,7 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) { void ProjectExportDialog::_export_project() { - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Ref platform = current->get_platform(); ERR_FAIL_COND(platform.is_null()); @@ -895,7 +964,7 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) { default_filename = p_path.get_file().get_basename(); EditorSettings::get_singleton()->set_project_metadata("export_options", "default_filename", default_filename); - Ref current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); + Ref current = get_current_preset(); ERR_FAIL_COND(current.is_null()); Ref platform = current->get_platform(); ERR_FAIL_COND(platform.is_null()); @@ -971,6 +1040,8 @@ void ProjectExportDialog::_bind_methods() { ClassDB::bind_method("_open_export_template_manager", &ProjectExportDialog::_open_export_template_manager); ClassDB::bind_method("_validate_export_path", &ProjectExportDialog::_validate_export_path); ClassDB::bind_method("_export_path_changed", &ProjectExportDialog::_export_path_changed); + ClassDB::bind_method("_script_export_mode_changed", &ProjectExportDialog::_script_export_mode_changed); + ClassDB::bind_method("_script_encryption_key_changed", &ProjectExportDialog::_script_encryption_key_changed); ClassDB::bind_method("_export_project", &ProjectExportDialog::_export_project); ClassDB::bind_method("_export_project_to_path", &ProjectExportDialog::_export_project_to_path); ClassDB::bind_method("_export_all", &ProjectExportDialog::_export_all); @@ -980,6 +1051,7 @@ void ProjectExportDialog::_bind_methods() { ClassDB::bind_method("_tab_changed", &ProjectExportDialog::_tab_changed); ClassDB::bind_method("set_export_path", &ProjectExportDialog::set_export_path); ClassDB::bind_method("get_export_path", &ProjectExportDialog::get_export_path); + ClassDB::bind_method("get_current_preset", &ProjectExportDialog::get_current_preset); ADD_PROPERTY(PropertyInfo(Variant::STRING, "export_path"), "set_export_path", "get_export_path"); } @@ -1127,6 +1199,25 @@ ProjectExportDialog::ProjectExportDialog() { feature_vb->add_margin_child(TTR("Feature List:"), features_panel, true); sections->add_child(feature_vb); + updating_script_key = false; + + VBoxContainer *script_vb = memnew(VBoxContainer); + script_vb->set_name(TTR("Script")); + script_mode = memnew(OptionButton); + script_vb->add_margin_child(TTR("Script Export Mode:"), script_mode); + script_mode->add_item(TTR("Text"), (int)EditorExportPreset::MODE_SCRIPT_TEXT); + script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED); + script_mode->add_item(TTR("Encrypted (Provide Key Below)"), (int)EditorExportPreset::MODE_SCRIPT_ENCRYPTED); + script_mode->connect("item_selected", this, "_script_export_mode_changed"); + script_key = memnew(LineEdit); + script_key->connect("text_changed", this, "_script_encryption_key_changed"); + script_key_error = memnew(Label); + script_key_error->set_text("- " + TTR("Invalid Encryption Key (must be 64 characters long)")); + script_key_error->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor")); + script_vb->add_margin_child(TTR("Script Encryption Key (256-bits as hex):"), script_key); + script_vb->add_child(script_key_error); + sections->add_child(script_vb); + sections->connect("tab_changed", this, "_tab_changed"); //disable by default @@ -1135,6 +1226,7 @@ ProjectExportDialog::ProjectExportDialog() { runnable->set_disabled(true); duplicate_preset->set_disabled(true); delete_preset->set_disabled(true); + script_key_error->hide(); sections->hide(); parameters->edit(NULL); diff --git a/editor/project_export.h b/editor/project_export.h index b43dd9a39270..de0ce83fbc56 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -100,6 +100,10 @@ private: LineEdit *custom_features; RichTextLabel *custom_feature_display; + OptionButton *script_mode; + LineEdit *script_key; + Label *script_key_error; + Label *export_error; HBoxContainer *export_templates_error; @@ -119,6 +123,7 @@ private: void _delete_preset_confirm(); void _update_export_all(); + void _update_current_preset(); void _update_presets(); void _export_type_changed(int p_which); @@ -154,6 +159,11 @@ private: void _update_feature_list(); void _custom_features_changed(const String &p_text); + bool updating_script_key; + void _script_export_mode_changed(int p_mode); + void _script_encryption_key_changed(const String &p_key); + bool _validate_script_encryption_key(const String &p_key); + void _tab_changed(int); protected: @@ -166,6 +176,8 @@ public: void set_export_path(const String &p_value); String get_export_path(); + Ref get_current_preset() const; + ProjectExportDialog(); ~ProjectExportDialog(); }; diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 9c4dc0c92661..3faff4873dd2 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -54,20 +54,74 @@ class EditorExportGDScript : public EditorExportPlugin { public: virtual void _export_file(const String &p_path, const String &p_type, const Set &p_features) { - if (!p_path.ends_with(".gd")) + int script_mode = EditorExportPreset::MODE_SCRIPT_COMPILED; + String script_key; + + const Ref &preset = get_export_preset(); + + if (preset.is_valid()) { + script_mode = preset->get_script_export_mode(); + script_key = preset->get_script_encryption_key().to_lower(); + } + + if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT) return; Vector file = FileAccess::get_file_as_array(p_path); if (file.empty()) return; + String txt; txt.parse_utf8((const char *)file.ptr(), file.size()); file = GDScriptTokenizerBuffer::parse_code_string(txt); - if (file.empty()) - return; + if (!file.empty()) { - add_file(p_path.get_basename() + ".gdc", file, true); + if (script_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) { + + String tmp_path = EditorSettings::get_singleton()->get_settings_dir().plus_file("tmp/script.gde"); + FileAccess *fa = FileAccess::open(tmp_path, FileAccess::WRITE); + + Vector key; + key.resize(32); + for (int i = 0; i < 32; i++) { + int v = 0; + if (i * 2 < script_key.length()) { + CharType ct = script_key[i * 2]; + if (ct >= '0' && ct <= '9') + ct = ct - '0'; + else if (ct >= 'a' && ct <= 'f') + ct = 10 + ct - 'a'; + v |= ct << 4; + } + + if (i * 2 + 1 < script_key.length()) { + CharType ct = script_key[i * 2 + 1]; + if (ct >= '0' && ct <= '9') + ct = ct - '0'; + else if (ct >= 'a' && ct <= 'f') + ct = 10 + ct - 'a'; + v |= ct; + } + key.write[i] = v; + } + FileAccessEncrypted *fae = memnew(FileAccessEncrypted); + Error err = fae->open_and_parse(fa, key, FileAccessEncrypted::MODE_WRITE_AES256); + + if (err == OK) { + fae->store_buffer(file.ptr(), file.size()); + } + + memdelete(fae); + + file = FileAccess::get_file_as_array(tmp_path); + add_file(p_path.get_basename() + ".gde", file, true); + + } else { + + add_file(p_path.get_basename() + ".gdc", file, true); + } + } } };