Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protecting game resources in exported apk #39115

Closed
dariuspranskus opened this issue May 28, 2020 · 31 comments
Closed

Protecting game resources in exported apk #39115

dariuspranskus opened this issue May 28, 2020 · 31 comments
Labels

Comments

@dariuspranskus
Copy link

Hello

This is not a bug as such, this was raised and discussed some time ago #19790 but I would like to raise this question again.

I completely understand, that there is no way to securely export encrypted/compressed assets and script files to apk which couldn't be hacked or broken in.

But I still believe that the files should not be exported to apk in plain text or the whole folder structure is visible. For me this is one of the biggest issues at the moment.

I started my game with unity, and was overwhelmed how it is heavy not for development but how it is running, every task takes ages. Then I played with the Game Maker, and it was OK, except that it demanded so much resources. And then I came across Godot, and it was almost perfect, light, fast and full of features. Until I discovered this issue

I do not want to port my game third time to some other platform.

So I would like to ask, please, how would it be possible to pack and encrypt my assets/code/scenes in apk into single/few files, so it is not visible just by unzipping.

I have recently became patreon and would also be willing to contribute to the codebase. I am a developer with many years of experience in various languages, unfortunately not in C++, but I understand the syntax, and would figure it out somehow, if someone can lead me into right direction. I would really want to develop such feature in Godot.

Thanks
Regards,
Darius

@dariuspranskus dariuspranskus changed the title Some files are being exported in plain text in the apk export and project files structure is visible Protecting game resources in exported apk May 28, 2020
@Calinou
Copy link
Member

Calinou commented May 28, 2020

Please don't ask support questions here, as this issue tracker is meant to be used for bug reports only. Use one of the other community channels instead.

You could also open a proposal on the Godot proposals repository, although writing a good proposal will be easier if you have prior experience with obfuscation/encryption systems.

Also, I would consider this to be mostly a duplicate of #24716 (since all game data is located in the PCK file which is in the APK).

Edit: The part about PCK is not actually correct, see #39115 (comment).

@akien-mga
Copy link
Member

Also see #38308 (which aims at solving #24716).

@dariuspranskus
Copy link
Author

dariuspranskus commented May 28, 2020

This solves the issue only partially. All the file directory structure is visible in APK. Some of the files are still in plain text

@Calinou
Copy link
Member

Calinou commented May 28, 2020

@dariuspranskus There should only be a handful of manifest files outside the PCK file. All your game scripts and artwork are inside the PCK.

Edit: This is not actually correct, see #39115 (comment).

@dariuspranskus
Copy link
Author

Please don't ask support questions here, as this issue tracker is meant to be used for bug reports only. Use one of the other community channels instead.

You could also open a proposal on the Godot proposals repository, although writing a good proposal will be easier if you have prior experience with obfuscation/encryption systems.

Also, I would consider this to be mostly a duplicate of #24716 (since all game data is located in the PCK file which is in the APK).

I asked 3 or 4 questions on discord, did not receive the answer for most of them. Also I was recommended to ask on github.

@Calinou
Copy link
Member

Calinou commented May 28, 2020

Also I was recommended to ask on github.

Well, I guess they were wrong 🙂

In general, large GitHub issue trackers don't make for good support platforms, as bug reports will become intertwined with support requests (and sometimes feature requests) over time.

@dariuspranskus
Copy link
Author

dariuspranskus commented May 28, 2020

@dariuspranskus There should only be a handful of manifest files outside the PCK file. All your game scripts and artwork are inside the PCK.

When I export my game into Android APK I am getting all asset files (be it with script encryption or not) put individually into the assets folder. Folders are visible and some files are in plain text. Scripts are either encrypted or compiled.

image

What I am not getting here. Thanks

@Calinou
Copy link
Member

Calinou commented May 28, 2020

@dariuspranskus Did you export the project using the "old" method or the "new" method? Maybe the final structure differs depending on the method used. Still, I was pretty sure only a PCK file was included in the APK.

cc @m4gr3d

@dariuspranskus
Copy link
Author

dariuspranskus commented May 28, 2020

@danielkulas Did you export the project using the "old" method or the "new" method? Maybe the final structure differs depending on the method used. Still, I was pretty sure only a PCK file was included in the APK.

cc @m4gr3d

I used the old method. Will try the new one. Thanks

@dariuspranskus
Copy link
Author

dariuspranskus commented May 28, 2020

@Calinou Same with the "new-way" - individual folders and files in assets folder in APK.

I also found the following discussion about the legal liability to protect loyalty-free assets
https://godotforums.org/discussion/22122/there-should-be-options-for-protecting-game-resources-even-if-they-are-third-party#latest.

@Zireael07
Copy link
Contributor

@dariuspranskus There were issues with the export changes not 'sticking' - did you clear the export folder on PC/uninstall the app completely before retesting? Just making sure you're not seeing the old export...

@dariuspranskus
Copy link
Author

@dariuspranskus There were issues with the export changes not 'sticking' - did you clear the export folder on PC/uninstall the app completely before retesting? Just making sure you're not seeing the old export...

@Zireael07 : Using v.3.2.2beta2, emptied the export folder, used the custom build, still no PCK file in the APK, individual folders and indicidual assets and compiled/encrypted scripts in the asset folder inside the APK

@dariuspranskus
Copy link
Author

I searched for a PCK string in the Godot source platform sub-folder. As you can see there is no android platform there. It seems that the feature is not available. But it is essential in my opinion

image

@akien-mga
Copy link
Member

You can unzip the .apk to see what the contents are.

@akien-mga
Copy link
Member

Example from https://gitlab.com/QbieShay/bring-out-your-dead:

        ./AndroidManifest.xml
        ./resources.arsc
        ./kotlin
        ./kotlin/math
        ./kotlin/math/UMathKt.kotlin_metadata
        ./kotlin/math/MathHKt.kotlin_metadata
        ./kotlin/time
        ./kotlin/time/DurationUnit.kotlin_metadata
        ./kotlin/time/ClockKt.kotlin_metadata
        ./kotlin/time/MeasureTimeKt.kotlin_metadata
        ./kotlin/time/Duration.kotlin_metadata
        ./kotlin/time/MonoClock.kotlin_metadata
        ./kotlin/time/Clock.kotlin_metadata
        ./kotlin/time/TestClock.kotlin_metadata
        ./kotlin/time/AdjustedClockMark.kotlin_metadata
        ./kotlin/time/TimedValue.kotlin_metadata
        ./kotlin/time/AbstractDoubleClock.kotlin_metadata
        ./kotlin/time/DurationUnitKt.kotlin_metadata
        ./kotlin/time/AbstractLongClock.kotlin_metadata
        ./kotlin/time/ClockMark.kotlin_metadata
        ./kotlin/time/ExperimentalTime.kotlin_metadata
        ./kotlin/time/DurationKt.kotlin_metadata
        ./kotlin/annotation
        ./kotlin/annotation/annotation.kotlin_builtins
        ./kotlin/ranges
        ./kotlin/ranges/RangesKt.kotlin_metadata
        ./kotlin/ranges/ClosedDoubleRange.kotlin_metadata
        ./kotlin/ranges/ClosedFloatingPointRange.kotlin_metadata
        ./kotlin/ranges/ULongProgression.kotlin_metadata
        ./kotlin/ranges/ULongRange.kotlin_metadata
        ./kotlin/ranges/UIntProgression.kotlin_metadata
        ./kotlin/ranges/ranges.kotlin_builtins
        ./kotlin/ranges/UIntProgressionIterator.kotlin_metadata
        ./kotlin/ranges/UIntRange.kotlin_metadata
        ./kotlin/ranges/ComparableRange.kotlin_metadata
        ./kotlin/ranges/ULongProgressionIterator.kotlin_metadata
        ./kotlin/SuccessOrFailureKt.kotlin_metadata
        ./kotlin/ResultKt.kotlin_metadata
        ./kotlin/StandardKt.kotlin_metadata
        ./kotlin/NoSuchElementException.kotlin_metadata
        ./kotlin/SuspendKt.kotlin_metadata
        ./kotlin/native
        ./kotlin/native/concurrent
        ./kotlin/native/concurrent/ThreadLocal.kotlin_metadata
        ./kotlin/native/concurrent/SharedImmutable.kotlin_metadata
        ./kotlin/UShort.kotlin_metadata
        ./kotlin/OptionalExpectation.kotlin_metadata
        ./kotlin/IllegalStateException.kotlin_metadata
        ./kotlin/InitializedLazyImpl.kotlin_metadata
        ./kotlin/UseExperimental.kotlin_metadata
        ./kotlin/UByteArrayKt.kotlin_metadata
        ./kotlin/UIntArrayKt.kotlin_metadata
        ./kotlin/IllegalArgumentException.kotlin_metadata
        ./kotlin/ConcurrentModificationException.kotlin_metadata
        ./kotlin/LazyKt.kotlin_metadata
        ./kotlin/io
        ./kotlin/io/IoHKt.kotlin_metadata
        ./kotlin/io/Serializable.kotlin_metadata
        ./kotlin/TuplesKt.kotlin_metadata
        ./kotlin/properties
        ./kotlin/properties/ReadOnlyProperty.kotlin_metadata
        ./kotlin/properties/ReadWriteProperty.kotlin_metadata
        ./kotlin/properties/Delegates.kotlin_metadata
        ./kotlin/properties/ObservableProperty.kotlin_metadata
        ./kotlin/properties/NotNullVar.kotlin_metadata
        ./kotlin/UIntKt.kotlin_metadata
        ./kotlin/UninitializedPropertyAccessException.kotlin_metadata
        ./kotlin/experimental
        ./kotlin/experimental/ExperimentalTypeInference.kotlin_metadata
        ./kotlin/experimental/BitwiseOperationsKt.kotlin_metadata
        ./kotlin/ClassCastException.kotlin_metadata
        ./kotlin/NumbersKt.kotlin_metadata
        ./kotlin/ExperimentalUnsignedTypes.kotlin_metadata
        ./kotlin/Result.kotlin_metadata
        ./kotlin/KotlinVersion.kotlin_metadata
        ./kotlin/Pair.kotlin_metadata
        ./kotlin/UIntArray.kotlin_metadata
        ./kotlin/UNumbersKt.kotlin_metadata
        ./kotlin/Triple.kotlin_metadata
        ./kotlin/UByteKt.kotlin_metadata
        ./kotlin/Experimental.kotlin_metadata
        ./kotlin/ULongKt.kotlin_metadata
        ./kotlin/Comparator.kotlin_metadata
        ./kotlin/ULongArray.kotlin_metadata
        ./kotlin/KotlinHKt.kotlin_metadata
        ./kotlin/Error.kotlin_metadata
        ./kotlin/UnsafeLazyImpl.kotlin_metadata
        ./kotlin/UInt.kotlin_metadata
        ./kotlin/collections
        ./kotlin/collections/IndexingIterator.kotlin_metadata
        ./kotlin/collections/HashMap.kotlin_metadata
        ./kotlin/collections/ReversedViewsKt.kotlin_metadata
        ./kotlin/collections/MapAccessorsKt.kotlin_metadata
        ./kotlin/collections/ArrayList.kotlin_metadata
        ./kotlin/collections/UIntIterator.kotlin_metadata
        ./kotlin/collections/SlidingWindowKt.kotlin_metadata
        ./kotlin/collections/RingBuffer.kotlin_metadata
        ./kotlin/collections/ArrayAsCollection.kotlin_metadata
        ./kotlin/collections/ULongIterator.kotlin_metadata
        ./kotlin/collections/SetsKt.kotlin_metadata
        ./kotlin/collections/MutableMapWithDefault.kotlin_metadata
        ./kotlin/collections/AbstractMap.kotlin_metadata
        ./kotlin/collections/LinkedHashSet.kotlin_metadata
        ./kotlin/collections/AbstractSet.kotlin_metadata
        ./kotlin/collections/UArraySortingKt.kotlin_metadata
        ./kotlin/collections/IndexedValue.kotlin_metadata
        ./kotlin/collections/CollectionsHKt.kotlin_metadata
        ./kotlin/collections/AbstractMutableMap.kotlin_metadata
        ./kotlin/collections/MapWithDefaultKt.kotlin_metadata
        ./kotlin/collections/AbstractMutableList.kotlin_metadata
        ./kotlin/collections/UByteIterator.kotlin_metadata
        ./kotlin/collections/MovingSubList.kotlin_metadata
        ./kotlin/collections/IteratorsKt.kotlin_metadata
        ./kotlin/collections/collections.kotlin_builtins
        ./kotlin/collections/AbstractMutableCollection.kotlin_metadata
        ./kotlin/collections/ReversedList.kotlin_metadata
        ./kotlin/collections/AbstractList.kotlin_metadata
        ./kotlin/collections/EmptySet.kotlin_metadata
        ./kotlin/collections/MapWithDefaultImpl.kotlin_metadata
        ./kotlin/collections/AbstractMutableSet.kotlin_metadata
        ./kotlin/collections/State.kotlin_metadata
        ./kotlin/collections/AbstractIterator.kotlin_metadata
        ./kotlin/collections/CollectionsKt.kotlin_metadata
        ./kotlin/collections/Grouping.kotlin_metadata
        ./kotlin/collections/GroupingKt.kotlin_metadata
        ./kotlin/collections/ArraysKt.kotlin_metadata
        ./kotlin/collections/UShortIterator.kotlin_metadata
        ./kotlin/collections/MutableCollectionsKt.kotlin_metadata
        ./kotlin/collections/AbstractCollection.kotlin_metadata
        ./kotlin/collections/EmptyIterator.kotlin_metadata
        ./kotlin/collections/ReversedListReadOnly.kotlin_metadata
        ./kotlin/collections/HashSet.kotlin_metadata
        ./kotlin/collections/MutableMapWithDefaultImpl.kotlin_metadata
        ./kotlin/collections/RandomAccess.kotlin_metadata
        ./kotlin/collections/MapWithDefault.kotlin_metadata
        ./kotlin/collections/EmptyMap.kotlin_metadata
        ./kotlin/collections/IterablesKt.kotlin_metadata
        ./kotlin/collections/MapsKt.kotlin_metadata
        ./kotlin/collections/LinkedHashMap.kotlin_metadata
        ./kotlin/collections/IndexingIterable.kotlin_metadata
        ./kotlin/collections/EmptyList.kotlin_metadata
        ./kotlin/jvm
        ./kotlin/jvm/Strictfp.kotlin_metadata
        ./kotlin/jvm/Transient.kotlin_metadata
        ./kotlin/jvm/Synchronized.kotlin_metadata
        ./kotlin/jvm/JvmName.kotlin_metadata
        ./kotlin/jvm/JvmStatic.kotlin_metadata
        ./kotlin/jvm/JvmOverloads.kotlin_metadata
        ./kotlin/jvm/JvmWildcard.kotlin_metadata
        ./kotlin/jvm/JvmSynthetic.kotlin_metadata
        ./kotlin/jvm/JvmPackageName.kotlin_metadata
        ./kotlin/jvm/JvmField.kotlin_metadata
        ./kotlin/jvm/JvmSuppressWildcards.kotlin_metadata
        ./kotlin/jvm/JvmMultifileClass.kotlin_metadata
        ./kotlin/jvm/Volatile.kotlin_metadata
        ./kotlin/UnsignedUtilsKt.kotlin_metadata
        ./kotlin/UShortKt.kotlin_metadata
        ./kotlin/text
        ./kotlin/text/Regex.kotlin_metadata
        ./kotlin/text/StringBuilderKt.kotlin_metadata
        ./kotlin/text/StringsKt.kotlin_metadata
        ./kotlin/text/DelimitedRangesSequence.kotlin_metadata
        ./kotlin/text/Appendable.kotlin_metadata
        ./kotlin/text/MatchGroupCollection.kotlin_metadata
        ./kotlin/text/MatchGroup.kotlin_metadata
        ./kotlin/text/UStringsKt.kotlin_metadata
        ./kotlin/text/RegexOption.kotlin_metadata
        ./kotlin/text/StringBuilder.kotlin_metadata
        ./kotlin/text/TextHKt.kotlin_metadata
        ./kotlin/text/IndentKt.kotlin_metadata
        ./kotlin/text/CharKt.kotlin_metadata
        ./kotlin/text/MatchResult.kotlin_metadata
        ./kotlin/text/RegexExtensionsKt.kotlin_metadata
        ./kotlin/text/CharacterCodingException.kotlin_metadata
        ./kotlin/text/Typography.kotlin_metadata
        ./kotlin/text/StringNumberConversionsKt.kotlin_metadata
        ./kotlin/text/MatchNamedGroupCollection.kotlin_metadata
        ./kotlin/random
        ./kotlin/random/RandomKt.kotlin_metadata
        ./kotlin/random/XorWowRandom.kotlin_metadata
        ./kotlin/random/URandomKt.kotlin_metadata
        ./kotlin/random/Random.kotlin_metadata
        ./kotlin/ULongArrayKt.kotlin_metadata
        ./kotlin/comparisons
        ./kotlin/comparisons/ReversedComparator.kotlin_metadata
        ./kotlin/comparisons/ReverseOrderComparator.kotlin_metadata
        ./kotlin/comparisons/ComparisonsKt.kotlin_metadata
        ./kotlin/comparisons/NaturalOrderComparator.kotlin_metadata
        ./kotlin/internal
        ./kotlin/internal/UProgressionUtilKt.kotlin_metadata
        ./kotlin/internal/DynamicExtension.kotlin_metadata
        ./kotlin/internal/LowPriorityInOverloadResolution.kotlin_metadata
        ./kotlin/internal/NoInfer.kotlin_metadata
        ./kotlin/internal/AccessibleLateinitPropertyLiteral.kotlin_metadata
        ./kotlin/internal/ContractsDsl.kotlin_metadata
        ./kotlin/internal/RequireKotlinVersionKind.kotlin_metadata
        ./kotlin/internal/InlineOnly.kotlin_metadata
        ./kotlin/internal/internal.kotlin_builtins
        ./kotlin/internal/HidesMembers.kotlin_metadata
        ./kotlin/internal/RequireKotlin.kotlin_metadata
        ./kotlin/internal/Exact.kotlin_metadata
        ./kotlin/internal/OnlyInputTypes.kotlin_metadata
        ./kotlin/IndexOutOfBoundsException.kotlin_metadata
        ./kotlin/ArithmeticException.kotlin_metadata
        ./kotlin/PreconditionsKt.kotlin_metadata
        ./kotlin/NoWhenBranchMatchedException.kotlin_metadata
        ./kotlin/NotImplementedError.kotlin_metadata
        ./kotlin/UByteArray.kotlin_metadata
        ./kotlin/BuilderInference.kotlin_metadata
        ./kotlin/UShortArrayKt.kotlin_metadata
        ./kotlin/Exception.kotlin_metadata
        ./kotlin/Lazy.kotlin_metadata
        ./kotlin/NullPointerException.kotlin_metadata
        ./kotlin/AssertionError.kotlin_metadata
        ./kotlin/UNINITIALIZED_VALUE.kotlin_metadata
        ./kotlin/reflect
        ./kotlin/reflect/KMutableProperty.kotlin_metadata
        ./kotlin/reflect/KProperty1.kotlin_metadata
        ./kotlin/reflect/KMutableProperty0.kotlin_metadata
        ./kotlin/reflect/KProperty.kotlin_metadata
        ./kotlin/reflect/reflect.kotlin_builtins
        ./kotlin/reflect/TypeOfKt.kotlin_metadata
        ./kotlin/reflect/KProperty0.kotlin_metadata
        ./kotlin/reflect/KMutableProperty2.kotlin_metadata
        ./kotlin/reflect/KCallable.kotlin_metadata
        ./kotlin/reflect/KClass.kotlin_metadata
        ./kotlin/reflect/KMutableProperty1.kotlin_metadata
        ./kotlin/reflect/KProperty2.kotlin_metadata
        ./kotlin/coroutines
        ./kotlin/coroutines/RestrictsSuspension.kotlin_metadata
        ./kotlin/coroutines/AbstractCoroutineContextElement.kotlin_metadata
        ./kotlin/coroutines/Continuation.kotlin_metadata
        ./kotlin/coroutines/experimental
        ./kotlin/coroutines/experimental/SequenceBuilderKt.kotlin_metadata
        ./kotlin/coroutines/experimental/RestrictsSuspension.kotlin_metadata
        ./kotlin/coroutines/experimental/AbstractCoroutineContextElement.kotlin_metadata
        ./kotlin/coroutines/experimental/Continuation.kotlin_metadata
        ./kotlin/coroutines/experimental/EmptyCoroutineContext.kotlin_metadata
        ./kotlin/coroutines/experimental/CombinedContext.kotlin_metadata
        ./kotlin/coroutines/experimental/CoroutineContext.kotlin_metadata
        ./kotlin/coroutines/experimental/intrinsics
        ./kotlin/coroutines/experimental/intrinsics/IntrinsicsKt.kotlin_metadata
        ./kotlin/coroutines/experimental/intrinsics/CoroutinesIntrinsicsExperimentalHKt.kotlin_metadata
        ./kotlin/coroutines/experimental/CoroutinesLibraryKt.kotlin_metadata
        ./kotlin/coroutines/experimental/SequenceBuilder.kotlin_metadata
        ./kotlin/coroutines/experimental/SequenceBuilderIterator.kotlin_metadata
        ./kotlin/coroutines/experimental/ContinuationInterceptor.kotlin_metadata
        ./kotlin/coroutines/experimental/SafeContinuation.kotlin_metadata
        ./kotlin/coroutines/EmptyCoroutineContext.kotlin_metadata
        ./kotlin/coroutines/CombinedContext.kotlin_metadata
        ./kotlin/coroutines/ContinuationKt.kotlin_metadata
        ./kotlin/coroutines/CoroutineContext.kotlin_metadata
        ./kotlin/coroutines/intrinsics
        ./kotlin/coroutines/intrinsics/CoroutineSingletons.kotlin_metadata
        ./kotlin/coroutines/intrinsics/IntrinsicsKt.kotlin_metadata
        ./kotlin/coroutines/intrinsics/CoroutinesIntrinsicsHKt.kotlin_metadata
        ./kotlin/coroutines/ContinuationInterceptor.kotlin_metadata
        ./kotlin/coroutines/SafeContinuation.kotlin_metadata
        ./kotlin/coroutines/coroutines.kotlin_builtins
        ./kotlin/ExperimentalMultiplatform.kotlin_metadata
        ./kotlin/ULong.kotlin_metadata
        ./kotlin/contracts
        ./kotlin/contracts/Returns.kotlin_metadata
        ./kotlin/contracts/ExperimentalContracts.kotlin_metadata
        ./kotlin/contracts/InvocationKind.kotlin_metadata
        ./kotlin/contracts/CallsInPlace.kotlin_metadata
        ./kotlin/contracts/ReturnsNotNull.kotlin_metadata
        ./kotlin/contracts/ContractBuilderKt.kotlin_metadata
        ./kotlin/contracts/SimpleEffect.kotlin_metadata
        ./kotlin/contracts/ConditionalEffect.kotlin_metadata
        ./kotlin/contracts/ContractBuilder.kotlin_metadata
        ./kotlin/contracts/Effect.kotlin_metadata
        ./kotlin/js
        ./kotlin/js/JsName.kotlin_metadata
        ./kotlin/LazyThreadSafetyMode.kotlin_metadata
        ./kotlin/RuntimeException.kotlin_metadata
        ./kotlin/kotlin.kotlin_builtins
        ./kotlin/LateinitKt.kotlin_metadata
        ./kotlin/UShortArray.kotlin_metadata
        ./kotlin/sequences
        ./kotlin/sequences/SubSequence.kotlin_metadata
        ./kotlin/sequences/TakeSequence.kotlin_metadata
        ./kotlin/sequences/SequenceBuilderKt.kotlin_metadata
        ./kotlin/sequences/MergingSequence.kotlin_metadata
        ./kotlin/sequences/TakeWhileSequence.kotlin_metadata
        ./kotlin/sequences/DistinctIterator.kotlin_metadata
        ./kotlin/sequences/TransformingSequence.kotlin_metadata
        ./kotlin/sequences/EmptySequence.kotlin_metadata
        ./kotlin/sequences/GeneratorSequence.kotlin_metadata
        ./kotlin/sequences/TransformingIndexedSequence.kotlin_metadata
        ./kotlin/sequences/DropWhileSequence.kotlin_metadata
        ./kotlin/sequences/IndexingSequence.kotlin_metadata
        ./kotlin/sequences/DistinctSequence.kotlin_metadata
        ./kotlin/sequences/FlatteningSequence.kotlin_metadata
        ./kotlin/sequences/SequenceBuilderIterator.kotlin_metadata
        ./kotlin/sequences/SequenceScope.kotlin_metadata
        ./kotlin/sequences/FilteringSequence.kotlin_metadata
        ./kotlin/sequences/Sequence.kotlin_metadata
        ./kotlin/sequences/DropSequence.kotlin_metadata
        ./kotlin/sequences/SequencesKt.kotlin_metadata
        ./kotlin/sequences/ConstrainedOnceSequence.kotlin_metadata
        ./kotlin/sequences/DropTakeSequence.kotlin_metadata
        ./kotlin/ExperimentalStdlibApi.kotlin_metadata
        ./kotlin/NumberFormatException.kotlin_metadata
        ./kotlin/UnsupportedOperationException.kotlin_metadata
        ./kotlin/HashCodeKt.kotlin_metadata
        ./kotlin/WasExperimental.kotlin_metadata
        ./kotlin/UByte.kotlin_metadata
        ./res
        ./res/mipmap-xhdpi-v4
        ./res/mipmap-xhdpi-v4/icon_foreground.png
        ./res/mipmap-xhdpi-v4/icon.png
        ./res/mipmap-xhdpi-v4/icon_background.png
        ./res/mipmap-anydpi-v26
        ./res/mipmap-anydpi-v26/icon.xml
        ./res/layout
        ./res/layout/notification_template_part_chronometer.xml
        ./res/layout/notification_template_media_custom.xml
        ./res/layout/notification_action.xml
        ./res/layout/notification_template_media.xml
        ./res/layout/notification_template_lines_media.xml
        ./res/layout/status_bar_ongoing_event_progress_bar.xml
        ./res/layout/notification_template_icon_group.xml
        ./res/layout/notification_template_big_media_narrow.xml
        ./res/layout/downloading_expansion.xml
        ./res/layout/notification_template_big_media.xml
        ./res/layout/notification_action_tombstone.xml
        ./res/layout/notification_template_big_media_narrow_custom.xml
        ./res/layout/notification_template_big_media_custom.xml
        ./res/layout/notification_template_part_time.xml
        ./res/layout/notification_media_action.xml
        ./res/layout/notification_media_cancel_action.xml
        ./res/drawable
        ./res/drawable/notification_tile_bg.xml
        ./res/drawable/notification_icon_background.xml
        ./res/drawable/notification_bg_low.xml
        ./res/drawable/notification_bg.xml
        ./res/drawable-mdpi-v4
        ./res/drawable-mdpi-v4/notification_bg_low_normal.9.png
        ./res/drawable-mdpi-v4/notification_bg_normal.9.png
        ./res/drawable-mdpi-v4/notification_bg_normal_pressed.9.png
        ./res/drawable-mdpi-v4/notify_panel_notification_icon_bg.png
        ./res/drawable-mdpi-v4/notification_bg_low_pressed.9.png
        ./res/layout-v16
        ./res/layout-v16/notification_template_custom_big.xml
        ./res/mipmap-xxhdpi-v4
        ./res/mipmap-xxhdpi-v4/icon_foreground.png
        ./res/mipmap-xxhdpi-v4/icon.png
        ./res/mipmap-xxhdpi-v4/icon_background.png
        ./res/mipmap-xxxhdpi-v4
        ./res/mipmap-xxxhdpi-v4/icon_foreground.png
        ./res/mipmap-xxxhdpi-v4/icon.png
        ./res/mipmap-xxxhdpi-v4/icon_background.png
        ./res/layout-v21
        ./res/layout-v21/notification_action.xml
        ./res/layout-v21/notification_template_custom_big.xml
        ./res/layout-v21/notification_template_icon_group.xml
        ./res/layout-v21/notification_action_tombstone.xml
        ./res/mipmap-hdpi-v4
        ./res/mipmap-hdpi-v4/icon_foreground.png
        ./res/mipmap-hdpi-v4/icon.png
        ./res/mipmap-hdpi-v4/icon_background.png
        ./res/drawable-v21
        ./res/drawable-v21/notification_action_background.xml
        ./res/mipmap
        ./res/mipmap/icon_foreground.png
        ./res/mipmap/icon.png
        ./res/mipmap/icon_background.png
        ./res/drawable-hdpi-v4
        ./res/drawable-hdpi-v4/notification_bg_low_normal.9.png
        ./res/drawable-hdpi-v4/notification_bg_normal.9.png
        ./res/drawable-hdpi-v4/notification_bg_normal_pressed.9.png
        ./res/drawable-hdpi-v4/notify_panel_notification_icon_bg.png
        ./res/drawable-hdpi-v4/notification_bg_low_pressed.9.png
        ./res/mipmap-mdpi-v4
        ./res/mipmap-mdpi-v4/icon_foreground.png
        ./res/mipmap-mdpi-v4/icon.png
        ./res/mipmap-mdpi-v4/icon_background.png
        ./res/drawable-xhdpi-v4
        ./res/drawable-xhdpi-v4/notification_bg_low_normal.9.png
        ./res/drawable-xhdpi-v4/notification_bg_normal.9.png
        ./res/drawable-xhdpi-v4/notification_bg_normal_pressed.9.png
        ./res/drawable-xhdpi-v4/notify_panel_notification_icon_bg.png
        ./res/drawable-xhdpi-v4/notification_bg_low_pressed.9.png
        ./classes.dex
        ./META-INF
        ./META-INF/MANIFEST.MF
        ./META-INF/ANDROIDD.RSA
        ./META-INF/ANDROIDD.SF
        ./lib
        ./lib/arm64-v8a
        ./lib/arm64-v8a/libgodot_android.so
        ./lib/arm64-v8a/libc++_shared.so
        ./lib/armeabi-v7a
        ./lib/armeabi-v7a/libgodot_android.so
        ./lib/armeabi-v7a/libc++_shared.so
        ./assets
        ./assets/project.binary
        ./assets/_cl_
        ./assets/icon.png.import
        ./assets/scripts
        ./assets/scripts/Dead.gdc
        ./assets/scripts/collector.gdc
        ./assets/scripts/Level.gd.remap
        ./assets/scripts/dump.gdc
        ./assets/scripts/collector.gd.remap
        ./assets/scripts/Window.gd.remap
        ./assets/scripts/global.gdc
        ./assets/scripts/global.gd.remap
        ./assets/scripts/cart.gdc
        ./assets/scripts/Window.gdc
        ./assets/scripts/cart.gd.remap
        ./assets/scripts/Dead.gd.remap
        ./assets/scripts/Level.gdc
        ./assets/scripts/dump.gd.remap
        ./assets/.import
        ./assets/.import/house-window-bg.png-74fc7d4cc4b6ea74b2b4b4abbc256f2c.stex
        ./assets/.import/house-window-top.png-b447a08db369aee34be8995e2bb5344b.stex
        ./assets/.import/churchbell.wav-e54174026516443fd546530a48df5b3d.sample
        ./assets/.import/dump.png-565eb851d6833be7ecfcdc2d21b21386.stex
        ./assets/.import/house-ground-floor.png-29527bade4e73106d2548a7ee71d8030.stex
        ./assets/.import/bringout.wav-f4c8f08ce60ffb308bf8f12213c87e0d.sample
        ./assets/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex
        ./assets/.import/star.png-db40ec76fb3fd808480ce0481255e27b.stex
        ./assets/.import/triangle-dude-spritesheet.png-a7a33e15689a0a26a594c760755b4db4.stex
        ./assets/.import/bg.png-23a59c2e9cba2223a50fa3fe41b70b25.stex
        ./assets/.import/bringout2.wav-fb663ac2e386cdf4bb8119ee45f0a145.sample
        ./assets/.import/gaslamp_funworks.ogg-ef6ece76ae0b6538a5d2eab31c14866d.oggstr
        ./assets/.import/house-roof.png-59cde44fe40ce7a395f5b89fb2cf1115.stex
        ./assets/.import/wheel.png-842e45fbc3d7e57d167cfb4b1fa152b4.stex
        ./assets/.import/alpha-2x2.png-fd2c8b3a568534be2c0beaf4c88f6b84.stex
        ./assets/.import/road.png-72005ad96a94b3869b023c4f4a0b0b7d.stex
        ./assets/.import/filling.png-d01074696edf202528a79348df6e0010.stex
        ./assets/.import/cart.png-5acbb80ef3e75e7c02b4d1a258771f47.stex
        ./assets/.import/house-middle-floors.png-e9e41c2761e192668d99b5f795e6f59f.stex
        ./assets/.import/ded.png-9b16a5eaac971d13ca7e3ee24a9928fb.stex
        ./assets/scenes
        ./assets/scenes/Level.tscn
        ./assets/scenes/Window.tscn
        ./assets/scenes/Background.tscn
        ./assets/scenes/collector.tscn
        ./assets/scenes/Dead.tscn
        ./assets/scenes/House.tscn
        ./assets/scenes/cart.tscn
        ./assets/scenes/House.gdc
        ./assets/scenes/dump.tscn
        ./assets/scenes/Ground.tscn
        ./assets/scenes/HouseTall.tscn
        ./assets/scenes/House.gd.remap
        ./assets/assets
        ./assets/assets/bg.png.import
        ./assets/assets/gaslamp_funworks.ogg.import
        ./assets/assets/house-roof.png.import
        ./assets/assets/bringout.wav.import
        ./assets/assets/cart
        ./assets/assets/cart/filling.png.import
        ./assets/assets/cart/cart.png.import
        ./assets/assets/cart/wheel.png.import
        ./assets/assets/house-window-top.png.import
        ./assets/assets/bringout2.wav.import
        ./assets/assets/house-middle-floors.png.import
        ./assets/assets/triangle-dude
        ./assets/assets/triangle-dude/triangle-dude-spritesheet.png.import
        ./assets/assets/triangle-dude/stick.tres
        ./assets/assets/triangle-dude/bot-arm.tres
        ./assets/assets/triangle-dude/effect.tres
        ./assets/assets/triangle-dude/triangle.tres
        ./assets/assets/triangle-dude/cape-up.tres
        ./assets/assets/triangle-dude/face.tres
        ./assets/assets/triangle-dude/cape.tres
        ./assets/assets/triangle-dude/up-arm.tres
        ./assets/assets/churchbell.wav.import
        ./assets/assets/alpha-2x2.png.import
        ./assets/assets/road.png.import
        ./assets/assets/star.png.import
        ./assets/assets/dump.png
        ./assets/assets/ded
        ./assets/assets/ded/head.tres
        ./assets/assets/ded/shirt.tres
        ./assets/assets/ded/arm-bot.tres
        ./assets/assets/ded/ded.png.import
        ./assets/assets/ded/arm-up.tres
        ./assets/assets/ded/leg.tres
        ./assets/assets/house-window-bg.png.import
        ./assets/assets/FiraSans-Regular.ttf
        ./assets/assets/dump.png.import
        ./assets/assets/house-ground-floor.png.import

So yeah it doesn't use a PCK, the project files are exported to the assets folder.

Scripts are compiled by default (.gdc) and could likely be encrypted if configured.
Scenes are in plain text.

@m4gr3d
Copy link
Contributor

m4gr3d commented May 28, 2020

As @akien-mga mentioned, the project files are exported directly to the assets folder on Android.

However the engine supports reading project data from an exported .pck or .zip file in the assets folder (validated through testing), so we could get to the desired outcome through a few steps:

  1. Change the default Android export behavior so that a .pck or .zip file of the project is pushed to the assets folder instead of the project files.
    • This should be fairly simple as the plumbing is already there and just need to be hooked up properly.
    • @akien-mga @Calinou Is there a breakdown for the use-cases between exporting to .zip vs exporting to .pck file? Is pck a custom Godot format?
  2. Update the default loading behavior so that the engine also looks for the exported .pck or .zip file in the assets folder.
  3. Add the option (and logic) to encrypt the exported .pck or .zip file and decrypt it at runtime to access the data. I believe Adds PCK encryption support (using script encryption key for export). #38308 may be providing that capability.

@dariuspranskus Could you open a godot-proposals for the described process. Once the proposal is opened, could you take a stab at the first step.

One thing to make clear though is that this would make it harder for the game resources to be accessed, not impossible.
Given the need to decrypt the data at runtime, the encryption key would need to be available to the apk and thus accessible to anyone with the ability to introspect an apk.
In addition, since this project is open-source, anyone can see the logic used for encryption/decryption, and the location of the data (and/or keys) by looking at the engine source code.
As long as this is clear and understood, then we should proceed!

@akien-mga slightly unrelated, do we know if the apk expansion feature is being used at all and/or works? I noticed it writes a pack file with .obb extension, but the file is not packaged with the generated apk so it's not clear how the apk would ever access it.

@Calinou
Copy link
Member

Calinou commented May 28, 2020

@m4gr3d PCK is a custom, Godot-specific format. Unlike ZIP, it's not compressed but it supports fast random seeking. You can use the PCKPacker class to create them programmatically.

@m4gr3d
Copy link
Contributor

m4gr3d commented May 28, 2020

@m4gr3d PCK is a custom, Godot-specific format. Unlike ZIP, it's not compressed but it supports fast random seeking. You can use the PCKPacker class to create them programmatically.

Thanks! So we should probably use that as the default for export to the apk assets folder.
Do you know if there are available tools to inspect the contents of .pck file outside of the Godot codebase?
If not, then just implementing #1 and #2 may resolve @dariuspranskus's concern.

@Calinou
Copy link
Member

Calinou commented May 28, 2020

@m4gr3d There are a few tools for that, such as https://github.com/hhyyrylainen/GodotPckTool. I don't consider this to be much of a problem, as you'll never find a way to have unencrypted data that's not easily extractible. (There are tools that can recognize data structures even in custom, undocumented formats.)

Also, the APK expansion feature appears to be broken: #28214

@bruvzg
Copy link
Member

bruvzg commented May 28, 2020

I noticed it writes a pack file with .obb extension, but the file is not packaged with the generated apk so it's not clear how the apk would ever access it.

This is correct behavior, APK size is limited to 100MB, AAB to 150MB (and it's not supported yet), OBBs are additional files if you need bigger size (2GB each), Play Store should download and place it to the correct location automatically.

@bruvzg
Copy link
Member

bruvzg commented May 28, 2020

Also, the APK expansion feature appears to be broken: #28214

As mentioned in this issue, OBBs do require "READ_EXTERNAL_STORAGE" permission (on some implementations of Android 6+ and all older versions), so it's probably not broken.

@m4gr3d
Copy link
Contributor

m4gr3d commented May 28, 2020

@Calinou reading #28214, seems the issue may be user error. Also probably worth closing that bug since the user resolved the issue albeit through a different path.

@bruvzg Thanks for the clarification.

@dariuspranskus
Copy link
Author

dariuspranskus commented May 28, 2020

@m4gr3d Created godot proposals #946 #947 and #948. I am happy to take a stab on #946. Do you have any materials for me to read to get up and running with that faster? My background is not in C++ development, but I know C# and Javascript pretty well. Thanks

@m4gr3d
Copy link
Contributor

m4gr3d commented May 29, 2020

@dariuspranskus Most of the logic you need to tie together for proposal #946 should be in the export.cpp source file.

I'd recommend taking a look at the Engine development section, and particularly the Introduction to Godot development and the IDE configuration section to get started.

Once you're set, I'd take a look at the Compiling section.

You'll probably have to validate your changes by compiling the editor, exporting an Android apk, and validate the apk's assets directory contains the generated .pck or .zip file.

Feel free to ask here or on irc if you have any questions.

@dariuspranskus
Copy link
Author

@m4gr3d Thanks. will take a look.

@rieniter

This comment has been minimized.

@dariuspranskus
Copy link
Author

@m4gr3d, @Calinou, @akien-mga Hello. Could someone please help me with the following:

I have the following development environment set up:

  • MAC OS Catalina
  • Visual Studio Code
  • C/C++ and CodeLLDB Extensions

I am able to debug the core editor app - set breakpoints, stop at them, see variables, etc.

But I am struggling to debug the code in platform/android, can't set the breakpoints there, it looks like it is a separate module or something. How do I debug the export code?

Thanks

@m4gr3d
Copy link
Contributor

m4gr3d commented Jun 2, 2020

@dariuspranskus Most of the code in platform/android is compiled and linked to the generated Android apk and not used by the editor, so you shouldn't need to modify it for #946.
The platform/android/export/export.cpp which I've referenced above should be accessible via the debugger as it's part of the editor code.

@dariuspranskus
Copy link
Author

@m4gr3 Thanks for the response.
Not sure what might be a reason, but I am actually trying to set the breakpoint in platform/android/export/export.cpp, but when I run the code, the breakpoint becomes disabled:
image
if I set the breakpoint in editor/editor_export.cpp, then it works:
image
I also tried with the Qt Creator and got the same result.
Please advice. Thank you

@m4gr3d
Copy link
Contributor

m4gr3d commented Jun 2, 2020

@dariuspranskus just to confirm, you're generating the build using target=debug scons parameter instead of release or release_debug?

@phil-hudson
Copy link
Contributor

@m4gr3d or anyone else - if you have any pointers about implementation, please let me know.

Looking to get this done as I need to encrypt the contents of my app for shipping the .aab to Play Console.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants