├── plugin
├── .gitignore
├── demo
│ ├── .gitignore
│ ├── .gitattributes
│ ├── addons
│ │ └── GodotPrivacyPlugin
│ │ │ ├── plugin.cfg
│ │ │ ├── bin
│ │ │ ├── debug
│ │ │ │ └── GodotPrivacyPlugin-debug.aar
│ │ │ └── release
│ │ │ │ └── GodotPrivacyPlugin-release.aar
│ │ │ ├── config.json
│ │ │ ├── Preivew.gd
│ │ │ ├── export_plugin.gd
│ │ │ └── Preivew.tscn
│ ├── test.txt
│ ├── main.gd
│ ├── main.tscn
│ ├── icon.svg
│ ├── project.godot
│ └── export_presets.cfg
├── export_scripts_template
│ ├── plugin.cfg
│ ├── config.json
│ ├── Preivew.gd
│ ├── export_plugin.gd
│ └── Preivew.tscn
├── src
│ └── main
│ │ ├── java
│ │ └── org
│ │ │ └── godotengine
│ │ │ └── plugin
│ │ │ └── android
│ │ │ └── template
│ │ │ ├── entity
│ │ │ └── ConfigEntity.kt
│ │ │ ├── GodotAndroidPlugin.kt
│ │ │ ├── AlignTagHandler.java
│ │ │ └── MainActivity.kt
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── downloading_expansion.xml
│ │ └── values
│ │ └── strings.xml
└── build.gradle.kts
├── .gitattributes
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle.kts
├── README.md
├── LICENSE
├── gradle.properties
├── gradlew.bat
└── gradlew
/plugin/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/plugin/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 | *.import
4 | /android/
5 |
--------------------------------------------------------------------------------
/plugin/demo/.gitattributes:
--------------------------------------------------------------------------------
1 | # Normalize EOL for all files that Git considers text files.
2 | * text=auto eol=lf
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SakuyaCN/GodotPrivacyPlugin/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/plugin/export_scripts_template/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="GodotPrivacyPlugin"
4 | description="Android 隐私政策启动页插件"
5 | author="Sakuya"
6 | version="1.0.0"
7 | script="export_plugin.gd"
8 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="GodotPrivacyPlugin"
4 | description="Android 隐私政策启动页插件"
5 | author="Sakuya"
6 | version="1.0.0"
7 | script="export_plugin.gd"
8 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/bin/debug/GodotPrivacyPlugin-debug.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SakuyaCN/GodotPrivacyPlugin/HEAD/plugin/demo/addons/GodotPrivacyPlugin/bin/debug/GodotPrivacyPlugin-debug.aar
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/bin/release/GodotPrivacyPlugin-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SakuyaCN/GodotPrivacyPlugin/HEAD/plugin/demo/addons/GodotPrivacyPlugin/bin/release/GodotPrivacyPlugin-release.aar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Aug 25 21:04:51 PDT 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/plugin/export_scripts_template/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "textPath":"res://test.txt",
3 | "backgroundColor":"#F2F2F2",
4 | "contentColor":"#2E5266",
5 | "textColor":"#F2F2F2",
6 | "agreeBtn":{
7 | "color":"#70C1B3",
8 | "textColor":"#0f0f0f"
9 | },
10 | "cancelBtn":{
11 | "color":"#F25F5C",
12 | "textColor":"#F2F2F2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "textPath":"res://test.txt",
3 | "backgroundColor":"#F2F2F2",
4 | "contentColor":"#2E5266",
5 | "textColor":"#F2F2F2",
6 | "agreeBtn":{
7 | "color":"#70C1B3",
8 | "textColor":"#0f0f0f"
9 | },
10 | "cancelBtn":{
11 | "color":"#F25F5C",
12 | "textColor":"#F2F2F2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/plugin/demo/test.txt:
--------------------------------------------------------------------------------
1 | 隐私政策 V999
2 |
3 |
4 | 这是测试界面啊实打实打算
5 |
6 | 这是测试界面啊实打实打算
7 |
8 | 这是测试界面啊实打实打算这是测试界面啊实打实打算这是测试界面啊实打实打算
9 |
10 | 这是测试界面啊实打实打算
11 |
12 | 这是测试界面啊实打实打算
13 |
14 | 这是测试界面啊实打实打算
15 |
16 | 这是测试界面啊实打实打算
17 |
18 | 这是测试界面啊实打实打算
19 | 这是测试界面啊实打实打算
20 |
21 | 这是测试界面啊实打实打算
22 |
23 | 这是测试界面啊实打实打算
24 |
25 | 这是测试界面啊实打实打算
26 | 这是测试界面啊实打实打算
27 | 这是测试界面啊实打实打算
28 |
--------------------------------------------------------------------------------
/plugin/demo/main.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 | # TODO: Update to match your plugin's name
4 | var _plugin_name = "GodotPrivacyPlugin"
5 | var _android_plugin
6 |
7 | func _ready():
8 | if Engine.has_singleton(_plugin_name):
9 | _android_plugin = Engine.get_singleton(_plugin_name)
10 | else:
11 | printerr("Couldn't find plugin " + _plugin_name)
12 |
13 | var config = ConfigFile.new()
14 | # Load data from a file.
15 |
16 | func _on_Button_pressed():
17 | if _android_plugin:
18 | # TODO: Update to match your plugin's API
19 | _android_plugin.helloWorld()
20 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/godotengine/plugin/android/template/entity/ConfigEntity.kt:
--------------------------------------------------------------------------------
1 | package org.godotengine.plugin.android.template.entity
2 |
3 | data class ConfigEntity(
4 | val agreeBtn: AgreeBtn,
5 | val backgroundColor: String,
6 | val cancelBtn: CancelBtn,
7 | val contentColor: String,
8 | val textColor: String,
9 | val textPath: String
10 | )
11 |
12 | data class AgreeBtn(
13 | val color: String,
14 | val textColor: String
15 | )
16 |
17 | data class CancelBtn(
18 | val color: String,
19 | val textColor: String
20 | )
21 |
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle files
2 | .gradle/
3 | build/
4 |
5 | # Local configuration file (sdk path, etc)
6 | local.properties
7 |
8 | # Log/OS Files
9 | *.log
10 |
11 | # Android Studio generated files and folders
12 | captures/
13 | .externalNativeBuild/
14 | .cxx/
15 | *.apk
16 | output.json
17 |
18 | # IntelliJ
19 | *.iml
20 | .idea/
21 | misc.xml
22 | deploymentTargetDropDown.xml
23 | render.experimental.xml
24 |
25 | # Keystore files
26 | *.jks
27 | *.keystore
28 |
29 | # Google Services (e.g. APIs or Firebase)
30 | google-services.json
31 |
32 | # Android Profiling
33 | *.hprof
34 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | maven("https://plugins.gradle.org/m2/")
14 | maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
15 | }
16 | }
17 |
18 | // TODO: Update project's name.
19 | rootProject.name = "GodotPrivacyPlugin"
20 | include(":plugin")
21 |
--------------------------------------------------------------------------------
/plugin/demo/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://cg3hylang5fxn"]
2 |
3 | [ext_resource type="Script" path="res://main.gd" id="1_j0gfq"]
4 |
5 | [node name="Main" type="Node2D"]
6 | script = ExtResource("1_j0gfq")
7 |
8 | [node name="Button" type="Button" parent="."]
9 | anchors_preset = 14
10 | anchor_top = 0.5
11 | anchor_right = 1.0
12 | anchor_bottom = 0.5
13 | offset_left = 178.0
14 | offset_top = 196.0
15 | offset_right = 458.0
16 | offset_bottom = 258.0
17 | grow_horizontal = 2
18 | grow_vertical = 2
19 | text = "Hello World"
20 |
21 | [connection signal="pressed" from="Button" to="." method="_on_Button_pressed"]
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GodotPrivacyPlugin 使用说明
2 |
3 | 此源码包括sdk与godot两部分的完整项目,下载后导入到4.2版本的引擎中便可使用。
4 | * 支持引擎版本:Godot 4.2+
5 |
6 | _________________
7 | ## 安装方法
8 | 1. 复制项目本目录下plugin\demo\addons\GodotPrivacyPlugin文件内全部内容到你的add项目中或者自行编译整个项目。
9 | 2.
10 | 编译命令:./gradlew assemble,编译后的所有东西都在plugin\demo\addons\GodotPrivacyPlugin
11 | 2. 打开项目设置-插件-启用GodotPrivacyPlugin。
12 | 3. 项目导出时在**自定义构建** 中勾选启动。
13 | 4. 导出配置中取消勾选显示在App库中与作为启动器App显示。
14 | _________________
15 | ## 参数说明
16 | ```
17 | {
18 | "textPath":"res://test.txt", //隐私协议文本路径
19 | "backgroundColor":"#F2F2F2", //背景颜色
20 | "contentColor":"#2E5266", //内容背景颜色
21 | "textColor":"#F2F2F2", //内容文本颜色
22 | "agreeBtn":{
23 | "color":"#70C1B3", //同意按钮颜色
24 | "textColor":"#0f0f0f" //同意按钮文本颜色
25 | },
26 | "cancelBtn":{
27 | "color":"#F25F5C", //取消按钮颜色
28 | "textColor":"#F2F2F2" //取消按钮文本颜色
29 | }
30 | }
31 |
32 | ```
--------------------------------------------------------------------------------
/plugin/demo/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/godotengine/plugin/android/template/GodotAndroidPlugin.kt:
--------------------------------------------------------------------------------
1 | // TODO: Update to match your plugin's package name.
2 | package org.godotengine.plugin.android.template
3 |
4 | import android.util.Log
5 | import android.widget.Toast
6 | import androidx.annotation.UiThread
7 | import org.godotengine.godot.Godot
8 | import org.godotengine.godot.plugin.GodotPlugin
9 | import org.godotengine.godot.plugin.UsedByGodot
10 | import org.jetbrains.annotations.Nullable
11 |
12 | class GodotAndroidPlugin(godot: Godot): GodotPlugin(godot) {
13 |
14 | override fun getPluginName() = BuildConfig.GODOT_PLUGIN_NAME
15 |
16 | /**
17 | * Example showing how to declare a method that's used by Godot.
18 | *
19 | * Shows a 'Hello World' toast.
20 | */
21 | @UsedByGodot
22 | @UiThread
23 | private fun helloWorld() {
24 | Toast.makeText(activity, "Hello World", Toast.LENGTH_LONG).show()
25 | Log.v(pluginName, "Hello World")
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/plugin/demo/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Android Plugin Demo"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "GL Compatibility")
16 | config/icon="res://icon.svg"
17 |
18 | [debug]
19 |
20 | settings/stdout/verbose_stdout=true
21 |
22 | [display]
23 |
24 | window/size/viewport_width=648
25 | window/size/viewport_height=1152
26 | window/handheld/orientation=1
27 |
28 | [editor_plugins]
29 |
30 | enabled=PackedStringArray("res://addons/GodotPrivacyPlugin/plugin.cfg")
31 |
32 | [rendering]
33 |
34 | renderer/rendering_method="mobile"
35 | renderer/rendering_method.mobile="gl_compatibility"
36 | textures/vram_compression/import_etc2_astc=true
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Fredia Huya-Kouadio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/plugin/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
24 | android.defaults.buildfeatures.buildconfig=true
25 |
--------------------------------------------------------------------------------
/plugin/export_scripts_template/Preivew.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Window
3 |
4 | const json_file = "res://addons/GodotPrivacyPlugin/config.json"
5 |
6 | @onready var background = $ColorRect
7 | @onready var panel = $ColorRect/Panel
8 | @onready var label = $ColorRect/Panel/ScrollContainer/Label
9 | @onready var agree_btn = $ColorRect/Panel/Button
10 | @onready var cancel_btn = $ColorRect/Panel/Button2
11 |
12 | func loadJson():
13 | var file = FileAccess.open(json_file, FileAccess.READ)
14 | var content = file.get_as_text()
15 | return JSON.parse_string(content)
16 |
17 | func loadText(entity):
18 | var file = FileAccess.open(entity.textPath, FileAccess.READ)
19 | var content = file.get_as_text()
20 | label.text = content
21 |
22 | func loadPanel():
23 | var entity = loadJson()
24 | loadText(entity)
25 | background.color = Color(entity.backgroundColor)
26 | label.label_settings.set_font_color(Color(entity.textColor))
27 | panel.get("theme_override_styles/panel").set("bg_color",Color(entity.contentColor))
28 | agree_btn.get("theme_override_styles/normal").set("bg_color",Color(entity.agreeBtn.color))
29 | agree_btn.set("theme_override_colors/font_color",Color(entity.agreeBtn.textColor))
30 | cancel_btn.get("theme_override_styles/normal").set("bg_color",Color(entity.cancelBtn.color))
31 | cancel_btn.set("theme_override_colors/font_color",Color(entity.cancelBtn.textColor))
32 |
33 | func _on_close_requested() -> void:
34 | hide()
35 |
36 | func _on_about_to_popup() -> void:
37 | loadPanel()
38 |
39 |
40 | func _on_focus_entered() -> void:
41 | loadPanel()
42 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/Preivew.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Window
3 |
4 | const json_file = "res://addons/GodotPrivacyPlugin/config.json"
5 |
6 | @onready var background = $ColorRect
7 | @onready var panel = $ColorRect/Panel
8 | @onready var label = $ColorRect/Panel/ScrollContainer/Label
9 | @onready var agree_btn = $ColorRect/Panel/Button
10 | @onready var cancel_btn = $ColorRect/Panel/Button2
11 |
12 | func loadJson():
13 | var file = FileAccess.open(json_file, FileAccess.READ)
14 | var content = file.get_as_text()
15 | return JSON.parse_string(content)
16 |
17 | func loadText(entity):
18 | var file = FileAccess.open(entity.textPath, FileAccess.READ)
19 | var content = file.get_as_text()
20 | label.text = content
21 |
22 | func loadPanel():
23 | var entity = loadJson()
24 | loadText(entity)
25 | background.color = Color(entity.backgroundColor)
26 | label.label_settings.set_font_color(Color(entity.textColor))
27 | panel.get("theme_override_styles/panel").set("bg_color",Color(entity.contentColor))
28 | agree_btn.get("theme_override_styles/normal").set("bg_color",Color(entity.agreeBtn.color))
29 | agree_btn.set("theme_override_colors/font_color",Color(entity.agreeBtn.textColor))
30 | cancel_btn.get("theme_override_styles/normal").set("bg_color",Color(entity.cancelBtn.color))
31 | cancel_btn.set("theme_override_colors/font_color",Color(entity.cancelBtn.textColor))
32 |
33 | func _on_close_requested() -> void:
34 | hide()
35 |
36 | func _on_about_to_popup() -> void:
37 | loadPanel()
38 |
39 |
40 | func _on_focus_entered() -> void:
41 | loadPanel()
42 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/godotengine/plugin/android/template/AlignTagHandler.java:
--------------------------------------------------------------------------------
1 | package org.godotengine.plugin.android.template;
2 |
3 | import android.text.Layout;
4 | import android.text.style.AlignmentSpan;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.annotation.Nullable;
8 |
9 | import java.util.Collection;
10 | import java.util.Collections;
11 |
12 | import io.noties.markwon.MarkwonConfiguration;
13 | import io.noties.markwon.RenderProps;
14 | import io.noties.markwon.html.HtmlTag;
15 | import io.noties.markwon.html.tag.SimpleTagHandler;
16 |
17 | public class AlignTagHandler extends SimpleTagHandler {
18 |
19 | @Nullable
20 | @Override
21 | public Object getSpans(
22 | @NonNull MarkwonConfiguration configuration,
23 | @NonNull RenderProps renderProps,
24 | @NonNull HtmlTag tag) {
25 |
26 | final Layout.Alignment alignment;
27 |
28 | // html attribute without value,
29 | if (tag.attributes().containsKey("center")) {
30 | alignment = Layout.Alignment.ALIGN_CENTER;
31 | } else if (tag.attributes().containsKey("end")) {
32 | alignment = Layout.Alignment.ALIGN_OPPOSITE;
33 | } else {
34 | // empty value or any other will make regular alignment
35 | alignment = Layout.Alignment.ALIGN_NORMAL;
36 | }
37 |
38 | return new AlignmentSpan.Standard(alignment);
39 | }
40 |
41 | @NonNull
42 | @Override
43 | public Collection supportedTags() {
44 | return Collections.singleton("align");
45 | }
46 | }
--------------------------------------------------------------------------------
/plugin/export_scripts_template/export_plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 |
4 | const preview = preload("res://addons/GodotPrivacyPlugin/Preivew.tscn")
5 |
6 | var export_plugin : AndroidExportPlugin
7 |
8 | var ins
9 |
10 | func _enter_tree():
11 | # Initialization of the plugin goes here.
12 |
13 | export_plugin = AndroidExportPlugin.new()
14 | add_export_plugin(export_plugin)
15 | add_tool_menu_item("隐私页面预览",func onClick():
16 | if ins:
17 | ins.popup_centered()
18 | else:
19 | ins = preview.instantiate()
20 | get_editor_interface().get_base_control().add_child(ins)
21 | ins.popup_centered()
22 | )
23 |
24 |
25 | func _exit_tree():
26 | remove_tool_menu_item("隐私页面预览")
27 | remove_export_plugin(export_plugin)
28 | export_plugin = null
29 | if ins:
30 | ins.queue_free()
31 |
32 | func _make_visible(visible):
33 | if ins:
34 | ins.visible = visible
35 |
36 | func _has_main_screen():
37 | return true
38 |
39 | func _get_plugin_icon():
40 | # Must return some kind of Texture for the icon.
41 | return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
42 |
43 | class AndroidExportPlugin extends EditorExportPlugin:
44 | # TODO: Update to your plugin's name.
45 | var _plugin_name = "GodotPrivacyPlugin"
46 |
47 | func _supports_platform(platform):
48 | if platform is EditorExportPlatformAndroid:
49 | return true
50 | return false
51 |
52 | func _get_android_libraries(platform, debug):
53 | if debug:
54 | return PackedStringArray([_plugin_name + "/bin/debug/" + _plugin_name + "-debug.aar"])
55 | else:
56 | return PackedStringArray([_plugin_name + "/bin/release/" + _plugin_name + "-release.aar"])
57 |
58 | func _get_android_dependencies(platform: EditorExportPlatform, debug: bool) -> PackedStringArray:
59 | return PackedStringArray(["androidx.appcompat:appcompat:1.6.1","androidx.constraintlayout:constraintlayout:2.1.3","com.google.android.material:material:1.5.0","io.noties.markwon:core:4.6.2","io.noties.markwon:html:4.6.2","com.google.code.gson:gson:2.10.1"])
60 |
61 | func _get_name():
62 | return _plugin_name
63 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/export_plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 |
4 | const preview = preload("res://addons/GodotPrivacyPlugin/Preivew.tscn")
5 |
6 | var export_plugin : AndroidExportPlugin
7 |
8 | var ins
9 |
10 | func _enter_tree():
11 | # Initialization of the plugin goes here.
12 |
13 | export_plugin = AndroidExportPlugin.new()
14 | add_export_plugin(export_plugin)
15 | add_tool_menu_item("隐私页面预览",func onClick():
16 | if ins:
17 | ins.popup_centered()
18 | else:
19 | ins = preview.instantiate()
20 | get_editor_interface().get_base_control().add_child(ins)
21 | ins.popup_centered()
22 | )
23 |
24 |
25 | func _exit_tree():
26 | remove_tool_menu_item("隐私页面预览")
27 | remove_export_plugin(export_plugin)
28 | export_plugin = null
29 | if ins:
30 | ins.queue_free()
31 |
32 | func _make_visible(visible):
33 | if ins:
34 | ins.visible = visible
35 |
36 | func _has_main_screen():
37 | return true
38 |
39 | func _get_plugin_icon():
40 | # Must return some kind of Texture for the icon.
41 | return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
42 |
43 | class AndroidExportPlugin extends EditorExportPlugin:
44 | # TODO: Update to your plugin's name.
45 | var _plugin_name = "GodotPrivacyPlugin"
46 |
47 | func _supports_platform(platform):
48 | if platform is EditorExportPlatformAndroid:
49 | return true
50 | return false
51 |
52 | func _get_android_libraries(platform, debug):
53 | if debug:
54 | return PackedStringArray([_plugin_name + "/bin/debug/" + _plugin_name + "-debug.aar"])
55 | else:
56 | return PackedStringArray([_plugin_name + "/bin/release/" + _plugin_name + "-release.aar"])
57 |
58 | func _get_android_dependencies(platform: EditorExportPlatform, debug: bool) -> PackedStringArray:
59 | return PackedStringArray(["androidx.appcompat:appcompat:1.6.1","androidx.constraintlayout:constraintlayout:2.1.3","com.google.android.material:material:1.5.0","io.noties.markwon:core:4.6.2","io.noties.markwon:html:4.6.2","com.google.code.gson:gson:2.10.1"])
60 |
61 | func _get_name():
62 | return _plugin_name
63 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/plugin/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
25 |
29 |
33 |
41 |
42 |
51 |
52 |
60 |
61 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.android.build.gradle.internal.tasks.factory.dependsOn
2 |
3 | plugins {
4 | id("com.android.library")
5 | id("org.jetbrains.kotlin.android")
6 | }
7 |
8 | // TODO: Update value to your plugin's name.
9 | val pluginName = "GodotPrivacyPlugin"
10 |
11 | // TODO: Update value to match your plugin's package name.
12 | val pluginPackageName = "org.godotengine.plugin.android.template"
13 |
14 | val markwonVersion = "4.6.2"
15 |
16 | android {
17 | namespace = pluginPackageName
18 | compileSdk = 33
19 |
20 | buildFeatures {
21 | buildConfig = true
22 | }
23 |
24 | defaultConfig {
25 | minSdk = 21
26 |
27 | manifestPlaceholders["godotPluginName"] = pluginName
28 | manifestPlaceholders["godotPluginPackageName"] = pluginPackageName
29 |
30 | setProperty("archivesBaseName", pluginName)
31 | buildConfigField("String", "GODOT_PLUGIN_NAME", "\"${pluginName}\"")
32 | // buildTypes {
33 | // debug {
34 | // buildConfigField("String", "GODOT_PLUGIN_NAME", "\"${pluginName}\"")
35 | // }
36 | // release {
37 | // buildConfigField("String", "GODOT_PLUGIN_NAME", "\"${pluginName}\"")
38 | // }
39 | // }
40 | }
41 |
42 | compileOptions {
43 | sourceCompatibility = JavaVersion.VERSION_17
44 | targetCompatibility = JavaVersion.VERSION_17
45 | }
46 | kotlinOptions {
47 | jvmTarget = "17"
48 | }
49 | }
50 |
51 | dependencies {
52 | implementation("org.godotengine:godot:4.2.0.stable")
53 | implementation("androidx.appcompat:appcompat:1.6.1")
54 | implementation("com.google.android.material:material:1.5.0")
55 | implementation("androidx.constraintlayout:constraintlayout:2.1.3")
56 | implementation ("io.noties.markwon:core:${markwonVersion}")
57 | implementation ("io.noties.markwon:html:${markwonVersion}")
58 | implementation("com.google.code.gson:gson:2.10.1")
59 |
60 |
61 | }
62 |
63 | // BUILD TASKS DEFINITION
64 | val copyDebugAARToDemoAddons by tasks.registering(Copy::class) {
65 | description = "Copies the generated debug AAR binary to the plugin's addons directory"
66 | from("build/outputs/aar")
67 | include("$pluginName-debug.aar")
68 | into("demo/addons/$pluginName/bin/debug")
69 | }
70 |
71 | val copyReleaseAARToDemoAddons by tasks.registering(Copy::class) {
72 | description = "Copies the generated release AAR binary to the plugin's addons directory"
73 | from("build/outputs/aar")
74 | include("$pluginName-release.aar")
75 | into("demo/addons/$pluginName/bin/release")
76 | }
77 |
78 | val cleanDemoAddons by tasks.registering(Delete::class) {
79 | delete("demo/addons/$pluginName")
80 | }
81 |
82 | val copyAddonsToDemo by tasks.registering(Copy::class) {
83 | description = "Copies the export scripts templates to the plugin's addons directory"
84 |
85 | dependsOn(cleanDemoAddons)
86 | finalizedBy(copyDebugAARToDemoAddons)
87 | finalizedBy(copyReleaseAARToDemoAddons)
88 |
89 | from("export_scripts_template")
90 | into("demo/addons/$pluginName")
91 | }
92 |
93 | tasks.named("assemble").configure {
94 | finalizedBy(copyAddonsToDemo)
95 | }
96 |
97 | tasks.named("clean").apply {
98 | dependsOn(cleanDemoAddons)
99 | }
100 |
--------------------------------------------------------------------------------
/plugin/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | godot-project-name
3 | Would you like to enable downloading over cellular connections? Depending on your data plan, this may cost you money.
4 | If you choose not to enable downloading over cellular connections, the download will automatically resume when wi-fi is available.
5 | Resume download
6 | Wi-Fi settings
7 | Verifying Download
8 | XAPK File Validation Complete. Select OK to exit.
9 | XAPK File Validation Failed.
10 | Pause Download
11 | Resume Download
12 | Cancel
13 | Cancel Verification
14 |
15 |
16 |
17 |
22 | Download complete
23 |
24 |
29 | Download unsuccessful
30 |
31 |
32 | Starting…
33 | Waiting for download to start
34 | Looking for resources to download
35 | Connecting to the download server
36 | Downloading resources
37 | Download finished
38 | Download paused because no network is available
39 | Download paused. Test a website in browser
40 | Download paused
41 | Download paused because wifi is unavailable
42 | Download paused because wifi is disabled
43 | Download paused because you are roaming
44 | Download paused because the external storage is unavailable
45 | Download failed because you may not have purchased this app
46 | Download failed because the resources could not be found
47 | Download failed because the external storage is full
48 | Download cancelled
49 | Download failed
50 |
51 | %1$s KB/s
52 | Time remaining: %1$s
53 | %1$s left
54 |
--------------------------------------------------------------------------------
/plugin/export_scripts_template/Preivew.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=3 uid="uid://drya3riyvlsfn"]
2 |
3 | [ext_resource type="Script" path="res://addons/GodotPrivacyPlugin/Preivew.gd" id="1_xjgiw"]
4 |
5 | [sub_resource type="LabelSettings" id="LabelSettings_a8cc4"]
6 | font_size = 14
7 | font_color = Color(0.376471, 0.376471, 0.376471, 1)
8 |
9 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xc00h"]
10 | bg_color = Color(0.180392, 0.321569, 0.4, 1)
11 | corner_radius_top_left = 8
12 | corner_radius_top_right = 8
13 | corner_radius_bottom_right = 8
14 | corner_radius_bottom_left = 8
15 | shadow_color = Color(0.670588, 0.670588, 0.670588, 0.313726)
16 | shadow_size = 8
17 | shadow_offset = Vector2(0, 4)
18 |
19 | [sub_resource type="LabelSettings" id="LabelSettings_4j0cr"]
20 | font_color = Color(0.94902, 0.94902, 0.94902, 1)
21 |
22 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r35ad"]
23 | bg_color = Color(0.439216, 0.756863, 0.701961, 1)
24 | corner_radius_top_left = 4
25 | corner_radius_top_right = 4
26 | corner_radius_bottom_right = 4
27 | corner_radius_bottom_left = 4
28 | shadow_color = Color(0, 0, 0, 0.0901961)
29 | shadow_size = 4
30 |
31 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nefae"]
32 | bg_color = Color(0.94902, 0.372549, 0.360784, 1)
33 | corner_radius_top_left = 4
34 | corner_radius_top_right = 4
35 | corner_radius_bottom_right = 4
36 | corner_radius_bottom_left = 4
37 | shadow_color = Color(0, 0, 0, 0.0901961)
38 | shadow_size = 4
39 |
40 | [node name="Preivew" type="Window"]
41 | position = Vector2i(0, 36)
42 | size = Vector2i(375, 720)
43 | script = ExtResource("1_xjgiw")
44 |
45 | [node name="ColorRect" type="ColorRect" parent="."]
46 | custom_minimum_size = Vector2(400, 500)
47 | anchors_preset = 15
48 | anchor_right = 1.0
49 | anchor_bottom = 1.0
50 | grow_horizontal = 2
51 | grow_vertical = 2
52 | color = Color(0.94902, 0.94902, 0.94902, 1)
53 |
54 | [node name="Label" type="Label" parent="ColorRect"]
55 | custom_minimum_size = Vector2(0, 40)
56 | layout_mode = 1
57 | anchors_preset = 12
58 | anchor_top = 1.0
59 | anchor_right = 1.0
60 | anchor_bottom = 1.0
61 | offset_top = -23.0
62 | grow_horizontal = 2
63 | grow_vertical = 0
64 | text = "此效果仅供预览,请勿直接修改,
65 | 前往config.json配置参数后自动同步"
66 | label_settings = SubResource("LabelSettings_a8cc4")
67 | horizontal_alignment = 1
68 | vertical_alignment = 1
69 | autowrap_mode = 1
70 |
71 | [node name="Panel" type="Panel" parent="ColorRect"]
72 | layout_mode = 1
73 | anchors_preset = 8
74 | anchor_left = 0.5
75 | anchor_top = 0.5
76 | anchor_right = 0.5
77 | anchor_bottom = 0.5
78 | offset_left = -156.5
79 | offset_top = -249.0
80 | offset_right = 156.5
81 | offset_bottom = 249.0
82 | grow_horizontal = 2
83 | grow_vertical = 2
84 | theme_override_styles/panel = SubResource("StyleBoxFlat_xc00h")
85 |
86 | [node name="ScrollContainer" type="ScrollContainer" parent="ColorRect/Panel"]
87 | layout_mode = 1
88 | anchors_preset = 15
89 | anchor_right = 1.0
90 | anchor_bottom = 1.0
91 | offset_left = 14.0
92 | offset_top = 14.0
93 | offset_right = -11.0
94 | offset_bottom = -79.0
95 | grow_horizontal = 2
96 | grow_vertical = 2
97 | horizontal_scroll_mode = 0
98 |
99 | [node name="Label" type="Label" parent="ColorRect/Panel/ScrollContainer"]
100 | layout_mode = 2
101 | size_flags_horizontal = 3
102 | text = "隐私政策正文"
103 | label_settings = SubResource("LabelSettings_4j0cr")
104 | autowrap_mode = 2
105 |
106 | [node name="Button" type="Button" parent="ColorRect/Panel"]
107 | layout_mode = 0
108 | offset_left = 45.0
109 | offset_top = 434.0
110 | offset_right = 133.0
111 | offset_bottom = 475.0
112 | theme_override_colors/font_color = Color(0.0588235, 0.0588235, 0.0588235, 1)
113 | theme_override_styles/normal = SubResource("StyleBoxFlat_r35ad")
114 | text = "同意"
115 |
116 | [node name="Button2" type="Button" parent="ColorRect/Panel"]
117 | layout_mode = 0
118 | offset_left = 187.0
119 | offset_top = 434.0
120 | offset_right = 275.0
121 | offset_bottom = 475.0
122 | theme_override_colors/font_color = Color(0.94902, 0.94902, 0.94902, 1)
123 | theme_override_styles/normal = SubResource("StyleBoxFlat_nefae")
124 | text = "退出"
125 |
126 | [connection signal="about_to_popup" from="." to="." method="_on_about_to_popup"]
127 | [connection signal="close_requested" from="." to="." method="_on_close_requested"]
128 | [connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
129 |
--------------------------------------------------------------------------------
/plugin/demo/addons/GodotPrivacyPlugin/Preivew.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=3 uid="uid://drya3riyvlsfn"]
2 |
3 | [ext_resource type="Script" path="res://addons/GodotPrivacyPlugin/Preivew.gd" id="1_xjgiw"]
4 |
5 | [sub_resource type="LabelSettings" id="LabelSettings_a8cc4"]
6 | font_size = 14
7 | font_color = Color(0.376471, 0.376471, 0.376471, 1)
8 |
9 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xc00h"]
10 | bg_color = Color(0.180392, 0.321569, 0.4, 1)
11 | corner_radius_top_left = 8
12 | corner_radius_top_right = 8
13 | corner_radius_bottom_right = 8
14 | corner_radius_bottom_left = 8
15 | shadow_color = Color(0.670588, 0.670588, 0.670588, 0.313726)
16 | shadow_size = 8
17 | shadow_offset = Vector2(0, 4)
18 |
19 | [sub_resource type="LabelSettings" id="LabelSettings_4j0cr"]
20 | font_color = Color(0.94902, 0.94902, 0.94902, 1)
21 |
22 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r35ad"]
23 | bg_color = Color(0.439216, 0.756863, 0.701961, 1)
24 | corner_radius_top_left = 4
25 | corner_radius_top_right = 4
26 | corner_radius_bottom_right = 4
27 | corner_radius_bottom_left = 4
28 | shadow_color = Color(0, 0, 0, 0.0901961)
29 | shadow_size = 4
30 |
31 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nefae"]
32 | bg_color = Color(0.94902, 0.372549, 0.360784, 1)
33 | corner_radius_top_left = 4
34 | corner_radius_top_right = 4
35 | corner_radius_bottom_right = 4
36 | corner_radius_bottom_left = 4
37 | shadow_color = Color(0, 0, 0, 0.0901961)
38 | shadow_size = 4
39 |
40 | [node name="Preivew" type="Window"]
41 | position = Vector2i(0, 36)
42 | size = Vector2i(375, 720)
43 | script = ExtResource("1_xjgiw")
44 |
45 | [node name="ColorRect" type="ColorRect" parent="."]
46 | custom_minimum_size = Vector2(400, 500)
47 | anchors_preset = 15
48 | anchor_right = 1.0
49 | anchor_bottom = 1.0
50 | grow_horizontal = 2
51 | grow_vertical = 2
52 | color = Color(0.94902, 0.94902, 0.94902, 1)
53 |
54 | [node name="Label" type="Label" parent="ColorRect"]
55 | custom_minimum_size = Vector2(0, 40)
56 | layout_mode = 1
57 | anchors_preset = 12
58 | anchor_top = 1.0
59 | anchor_right = 1.0
60 | anchor_bottom = 1.0
61 | offset_top = -23.0
62 | grow_horizontal = 2
63 | grow_vertical = 0
64 | text = "此效果仅供预览,请勿直接修改,
65 | 前往config.json配置参数后自动同步"
66 | label_settings = SubResource("LabelSettings_a8cc4")
67 | horizontal_alignment = 1
68 | vertical_alignment = 1
69 | autowrap_mode = 1
70 |
71 | [node name="Panel" type="Panel" parent="ColorRect"]
72 | layout_mode = 1
73 | anchors_preset = 8
74 | anchor_left = 0.5
75 | anchor_top = 0.5
76 | anchor_right = 0.5
77 | anchor_bottom = 0.5
78 | offset_left = -156.5
79 | offset_top = -249.0
80 | offset_right = 156.5
81 | offset_bottom = 249.0
82 | grow_horizontal = 2
83 | grow_vertical = 2
84 | theme_override_styles/panel = SubResource("StyleBoxFlat_xc00h")
85 |
86 | [node name="ScrollContainer" type="ScrollContainer" parent="ColorRect/Panel"]
87 | layout_mode = 1
88 | anchors_preset = 15
89 | anchor_right = 1.0
90 | anchor_bottom = 1.0
91 | offset_left = 14.0
92 | offset_top = 14.0
93 | offset_right = -11.0
94 | offset_bottom = -79.0
95 | grow_horizontal = 2
96 | grow_vertical = 2
97 | horizontal_scroll_mode = 0
98 |
99 | [node name="Label" type="Label" parent="ColorRect/Panel/ScrollContainer"]
100 | layout_mode = 2
101 | size_flags_horizontal = 3
102 | text = "隐私政策正文"
103 | label_settings = SubResource("LabelSettings_4j0cr")
104 | autowrap_mode = 2
105 |
106 | [node name="Button" type="Button" parent="ColorRect/Panel"]
107 | layout_mode = 0
108 | offset_left = 45.0
109 | offset_top = 434.0
110 | offset_right = 133.0
111 | offset_bottom = 475.0
112 | theme_override_colors/font_color = Color(0.0588235, 0.0588235, 0.0588235, 1)
113 | theme_override_styles/normal = SubResource("StyleBoxFlat_r35ad")
114 | text = "同意"
115 |
116 | [node name="Button2" type="Button" parent="ColorRect/Panel"]
117 | layout_mode = 0
118 | offset_left = 187.0
119 | offset_top = 434.0
120 | offset_right = 275.0
121 | offset_bottom = 475.0
122 | theme_override_colors/font_color = Color(0.94902, 0.94902, 0.94902, 1)
123 | theme_override_styles/normal = SubResource("StyleBoxFlat_nefae")
124 | text = "退出"
125 |
126 | [connection signal="about_to_popup" from="." to="." method="_on_about_to_popup"]
127 | [connection signal="close_requested" from="." to="." method="_on_close_requested"]
128 | [connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
129 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/godotengine/plugin/android/template/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.godotengine.plugin.android.template
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import android.graphics.Color
6 | import android.os.Build
7 | import android.os.Bundle
8 | import android.util.Log
9 | import android.view.View
10 | import android.view.WindowInsets
11 | import android.view.WindowInsetsController
12 | import android.view.WindowManager
13 | import android.widget.Button
14 | import android.widget.TextView
15 | import androidx.appcompat.app.AppCompatActivity
16 | import androidx.constraintlayout.widget.ConstraintLayout
17 | import com.google.android.material.card.MaterialCardView
18 | import com.google.gson.Gson
19 | import io.noties.markwon.Markwon
20 | import io.noties.markwon.html.HtmlPlugin
21 | import org.godotengine.plugin.android.template.entity.ConfigEntity
22 | import kotlin.system.exitProcess
23 |
24 | class MainActivity : AppCompatActivity() {
25 |
26 | //声明sp 缓存
27 | private val sp by lazy {
28 | getSharedPreferences("godot_privacy", Activity.MODE_PRIVATE)
29 | }
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 | //判断是否同意
33 | if(sp.getBoolean("argee",false)){
34 | toGodotApp()
35 | return
36 | }
37 | setFullScreen()
38 | setContentView(R.layout.activity_main)
39 | try {
40 | loadJsonFromAsset().let {configEntity ->
41 | findViewById(R.id.textview).apply {
42 | val markwon = Markwon.builder(context)
43 | .usePlugin(HtmlPlugin.create { plugin -> plugin.addHandler(AlignTagHandler()) })
44 | .build()
45 | markwon.setMarkdown(this,loadTextFromAsset(configEntity.textPath))
46 | setTextColor(Color.parseColor(configEntity.textColor))
47 | }
48 |
49 | findViewById