From 22fdeaf2f011e37064bbd9e168b7fcbcf1734180 Mon Sep 17 00:00:00 2001 From: staphen Date: Sat, 15 Jul 2023 11:24:03 -0400 Subject: [PATCH] Use JNI to check VERSION file in fonts.mpq --- CMake/platforms/android.cmake | 4 ++ Source/diablo.cpp | 2 +- Source/init.cpp | 2 + Source/init.h | 2 + Source/platform/android/CMakeLists.txt | 7 +++ Source/platform/android/android.cpp | 49 +++++++++++++++++++ .../diasurgical/devilutionx/DataActivity.java | 5 +- .../devilutionx/DevilutionXSDLActivity.java | 11 ++--- 8 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 Source/platform/android/CMakeLists.txt create mode 100644 Source/platform/android/android.cpp diff --git a/CMake/platforms/android.cmake b/CMake/platforms/android.cmake index dd329ce71..4000bacac 100644 --- a/CMake/platforms/android.cmake +++ b/CMake/platforms/android.cmake @@ -5,6 +5,10 @@ set(BUILD_TESTING OFF) # All of these will be fetched via FetchContent and linked statically. set(DEVILUTIONX_SYSTEM_SDL2 OFF) +# JNI source directory +list(APPEND DEVILUTIONX_PLATFORM_SUBDIRECTORIES platform/android) +list(APPEND DEVILUTIONX_PLATFORM_LINK_LIBRARIES libdevilutionx_android) + # Static SDL2 on Android requires Position Independent Code. set(SDL_STATIC_PIC ON) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index a0baf228f..1358f0dd5 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1106,7 +1106,7 @@ void CheckArchivesUpToDate() if (handle.ok()) { std::unique_ptr version_contents { new char[size] }; handle.read(version_contents.get(), size); - fontsMpqOutOfDate = string_view { version_contents.get(), size } != "1\n"; + fontsMpqOutOfDate = string_view { version_contents.get(), size } != font_mpq_version; } } else { fontsMpqOutOfDate = false; diff --git a/Source/init.cpp b/Source/init.cpp index f3be4f647..911ecca69 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -74,6 +74,8 @@ std::optional lang_mpq; std::optional font_mpq; #endif +char font_mpq_version[] = "1\n"; + namespace { #ifdef UNPACKED_MPQS diff --git a/Source/init.h b/Source/init.h index b8305c0e8..bce3d2e96 100644 --- a/Source/init.h +++ b/Source/init.h @@ -47,6 +47,8 @@ extern std::optional lang_mpq; extern std::optional devilutionx_mpq; #endif +extern char font_mpq_version[]; + inline bool HaveSpawn() { #ifdef UNPACKED_MPQS diff --git a/Source/platform/android/CMakeLists.txt b/Source/platform/android/CMakeLists.txt new file mode 100644 index 000000000..4f3e10b9d --- /dev/null +++ b/Source/platform/android/CMakeLists.txt @@ -0,0 +1,7 @@ +include(functions/devilutionx_library) +add_devilutionx_object_library(libdevilutionx_android android.cpp) + +target_link_libraries(libdevilutionx_android PUBLIC + DevilutionX::SDL + SDL_audiolib::SDL_audiolib +) diff --git a/Source/platform/android/android.cpp b/Source/platform/android/android.cpp new file mode 100644 index 000000000..5ad2b3956 --- /dev/null +++ b/Source/platform/android/android.cpp @@ -0,0 +1,49 @@ +#include "engine/assets.hpp" +#include "init.h" +#include "mpq/mpq_reader.hpp" + +#include + +namespace devilution { +namespace { + +bool AreFontsOutOfDate(const char *mpqPath) +{ + int32_t error = 0; + std::optional archive = MpqArchive::Open(mpqPath, error); + if (error != 0 || !archive) + return false; + + const char filename[] = "fonts\\VERSION"; + const MpqArchive::FileHash fileHash = MpqArchive::CalculateFileHash(filename); + uint32_t fileNumber; + if (!archive->GetFileNumber(fileHash, fileNumber)) + return true; + + AssetRef ref; + ref.archive = &*archive; + ref.fileNumber = fileNumber; + ref.filename = filename; + + const size_t size = ref.size(); + AssetHandle handle = OpenAsset(std::move(ref), false); + if (!handle.ok()) + return true; + + std::unique_ptr version_contents { new char[size] }; + handle.read(version_contents.get(), size); + return string_view { version_contents.get(), size } != font_mpq_version; +} + +} // namespace +} // namespace devilution + +extern "C" { +JNIEXPORT jboolean JNICALL Java_org_diasurgical_devilutionx_DevilutionXSDLActivity_areFontsOutOfDate(JNIEnv *env, jclass cls, jstring fonts_mpq) +{ + const char *mpqPath = env->GetStringUTFChars(fonts_mpq, nullptr); + bool outOfDate = devilution::AreFontsOutOfDate(mpqPath); + env->ReleaseStringUTFChars(fonts_mpq, mpqPath); + return outOfDate; +} +} diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java index 8c7a35cdb..6b4cbb374 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java @@ -103,10 +103,7 @@ public class DataActivity extends Activity { File fonts_mpq = fileManager.getFile("/fonts.mpq"); if (lang.startsWith("ko") || lang.startsWith("zh") || lang.startsWith("ja") || fonts_mpq.exists()) { - if (!fonts_mpq.exists() || - fonts_mpq.length() == 70471463 /* v1 */ || - fonts_mpq.length() == 53991069 /* v2 */ || - fonts_mpq.length() == 58488019 /* v3 */) { + if (!fonts_mpq.exists() || DevilutionXSDLActivity.areFontsOutOfDate(fonts_mpq.getAbsolutePath())) { if (!isDownloadingFonts) { fonts_mpq.delete(); isDownloadingFonts = true; diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java index 909f546cf..b42da6c6a 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java @@ -78,13 +78,10 @@ public class DevilutionXSDLActivity extends SDLActivity { return true; if (lang.startsWith("ru") && !fileManager.hasFile("ru.mpq")) return true; - if (lang.startsWith("ko") || lang.startsWith("zh") || lang.startsWith("ja")) { - if (!fileManager.hasFile("fonts.mpq") || - fileManager.fileSize("fonts.mpq") == 70471463 /* v1 */ || - fileManager.fileSize("fonts.mpq") == 53991069 /* v2 */ || - fileManager.fileSize("fonts.mpq") == 58488019 /* v3 */) { + File fonts_mpq = fileManager.getFile("/fonts.mpq"); + if (lang.startsWith("ko") || lang.startsWith("zh") || lang.startsWith("ja") || fonts_mpq.exists()) { + if (!fonts_mpq.exists() || areFontsOutOfDate(fonts_mpq.getAbsolutePath())) return true; - } } return !fileManager.hasFile("diabdat.mpq") && @@ -139,4 +136,6 @@ public class DevilutionXSDLActivity extends SDLActivity { "devilutionx" }; } + + public static native boolean areFontsOutOfDate(String fonts_mpq); }