Initial commit
|
@ -0,0 +1,424 @@
|
|||
build/
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
.idea/
|
||||
apk/*.apk
|
||||
apk/*.old
|
||||
*.keystore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Libs
|
||||
#lib/cocos
|
||||
#lib/Dobby
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
.vscode/
|
||||
|
||||
abiproxy/build/
|
||||
lib/cocos_old/
|
||||
lib/Dobby_old/
|
||||
sign.bat
|
|
@ -0,0 +1,20 @@
|
|||
[submodule "lib/Dobby"]
|
||||
path = lib/Dobby
|
||||
url = https://github.com/jmpews/Dobby
|
||||
branch = master
|
||||
[submodule "lib/cocos"]
|
||||
path = lib/cocos
|
||||
url = https://github.com/neobenedict/cocos2d-src-only/
|
||||
branch = master
|
||||
[submodule "smali/okhttp-smali"]
|
||||
path = smali/okhttp-smali
|
||||
url = https://github.com/neobenedict/okhttp-smali
|
||||
branch = master
|
||||
[submodule "lib/untp"]
|
||||
path = lib/untp
|
||||
url = https://github.com/neobenedict/untp
|
||||
branch = develop
|
||||
[submodule "patches/images"]
|
||||
path = patches/images
|
||||
url = https://git.rayshift.io/kamihama/magia-client-image-patches
|
||||
branch = master
|
|
@ -0,0 +1,89 @@
|
|||
# CMakeList.txt : CMake project for MagiaClient, include source and define
|
||||
# project specific logic here.
|
||||
#
|
||||
#set(CMAKE_CXX_STANDARD 11)
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
project ("MagiaClient")
|
||||
set(TARGET_NAME uwasa)
|
||||
#if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++ -fsanitize=address -fno-omit-frame-pointer")
|
||||
#else
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||
#endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fvisibility=hidden -fvisibility-inlines-hidden -g0 -O3 -ffunction-sections -fdata-sections")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden -fvisibility-inlines-hidden -g0 -O3 -ffunction-sections -fdata-sections")
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
set(DobbyHome ${CMAKE_CURRENT_SOURCE_DIR}/lib/Dobby)
|
||||
include_directories(
|
||||
${DobbyHome}/include
|
||||
${DobbyHome}/builtin-plugin
|
||||
${DobbyHome}/builtin-plugin/SymbolResolver
|
||||
${DobbyHome}/external/logging
|
||||
${DobbyHome}/source
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib/cocos
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/abiproxy/src
|
||||
)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(json
|
||||
GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
|
||||
GIT_TAG v3.9.1)
|
||||
|
||||
FetchContent_GetProperties(json)
|
||||
if(NOT json_POPULATED)
|
||||
FetchContent_Populate(json)
|
||||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
link_libraries("-Wl,--strip-all")
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
add_library( # Sets the name of the library.
|
||||
${TARGET_NAME}
|
||||
# Sets the library as a shared library.
|
||||
SHARED
|
||||
|
||||
# Provides a relative path to your source file(s).
|
||||
"lib/cocos/math/CCGeometry.cpp"
|
||||
"lib/cocos/math/Vec2.cpp"
|
||||
"src/MagiaClient.cpp"
|
||||
"src/Utils.cpp"
|
||||
"src/rest/MagiaRest.cpp"
|
||||
)
|
||||
|
||||
find_library(ANDROID_LOG_LIB log)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE ${ANDROID_LOG_LIB})
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE dobby)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
|
||||
if (CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/abiproxy/build/armeabi-v7a/libabiproxy.so)
|
||||
message(STATUS "Linking for armeabi-v7a")
|
||||
endif (CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
|
||||
|
||||
if (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/abiproxy/build/arm64-v8a/libabiproxy.so)
|
||||
message(STATUS "Linking for arm64-v8a")
|
||||
endif (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
|
||||
|
||||
macro(SET_OPTION option value)
|
||||
set(${option} ${value} CACHE INTERNAL "" FORCE)
|
||||
endmacro()
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET_OPTION(DOBBY_DEBUG ON)
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET_OPTION(DOBBY_GENERATE_SHARED OFF)
|
||||
SET_OPTION(DynamicBinaryInstrument ON)
|
||||
SET_OPTION(NearBranch ON)
|
||||
SET_OPTION(Plugin.SymbolResolver ON)
|
||||
|
||||
add_subdirectory(${DobbyHome} dobby)
|
|
@ -0,0 +1,39 @@
|
|||
# CMakeList.txt : CMake project for AbiProxy, include source and define
|
||||
# project specific logic here.
|
||||
#
|
||||
#set(CMAKE_CXX_STANDARD 11)
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
project ("AbiProxy")
|
||||
set(TARGET_NAME abiproxy)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fvisibility=hidden -fvisibility-inlines-hidden -g0 -O3 -ffunction-sections -fdata-sections")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden -fvisibility-inlines-hidden -g0 -O3 -ffunction-sections -fdata-sections")
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../lib/cocos
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
link_libraries("-Wl,--strip-all")
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
add_library( # Sets the name of the library.
|
||||
${TARGET_NAME}
|
||||
# Sets the library as a shared library.
|
||||
SHARED
|
||||
|
||||
# Provides a relative path to your source file(s).
|
||||
"src/magia/StringsProxy.cc"
|
||||
"src/magia/DialogueBox.cc")
|
||||
|
||||
find_library(ANDROID_LOG_LIB log)
|
||||
target_link_libraries(${TARGET_NAME} ${ANDROID_LOG_LIB})
|
||||
|
||||
macro(SET_OPTION option value)
|
||||
set(${option} ${value} CACHE INTERNAL "" FORCE)
|
||||
endmacro()
|
|
@ -0,0 +1,40 @@
|
|||
@echo off
|
||||
|
||||
:start
|
||||
set ndk="C:/Android/android-ndk-r16b-windows-x86_64/android-ndk-r16b/"
|
||||
set /p ndk="Enter ndk Location [C:/Android/android-ndk-r16b-windows-x86_64/android-ndk-r16b/]: "
|
||||
|
||||
if not exist %~dp0\build mkdir %~dp0\build
|
||||
|
||||
:build
|
||||
echo Building libraries.
|
||||
|
||||
rmdir /S /Q %~dp0\build\armeabi-v7a\
|
||||
rmdir /S /Q %~dp0\build\arm64-v8a\
|
||||
mkdir %~dp0\build\armeabi-v7a
|
||||
mkdir %~dp0\build\arm64-v8a
|
||||
|
||||
echo Running cmake armeabi-v7a...
|
||||
|
||||
cd %~dp0\build\armeabi-v7a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="armeabi-v7a" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\armeabi-v7a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=android-19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DCMAKE_ANDROID_STL_TYPE=gnustl_static" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Running cmake arm64-v8a...
|
||||
cd %~dp0\build\arm64-v8a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="arm64-v8a" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\arm64-v8a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=android-19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DCMAKE_ANDROID_STL_TYPE=gnustl_static" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Successful.
|
||||
goto :exit
|
||||
|
||||
:errorexit
|
||||
echo An error has occurred, exiting.
|
||||
goto exit
|
||||
|
||||
:exit
|
||||
pause
|
|
@ -0,0 +1,40 @@
|
|||
@echo off
|
||||
|
||||
:start
|
||||
set ndk="C:/Android/android-ndk-r16b-windows-x86_64/android-ndk-r16b/"
|
||||
set /p ndk="Enter ndk Location [C:/Android/android-ndk-r16b-windows-x86_64/android-ndk-r16b/]: "
|
||||
|
||||
if not exist %~dp0\build mkdir %~dp0\build
|
||||
|
||||
:build
|
||||
echo Building libraries.
|
||||
|
||||
rmdir /S /Q %~dp0\build\armeabi-v7a\
|
||||
rmdir /S /Q %~dp0\build\arm64-v8a\
|
||||
mkdir %~dp0\build\armeabi-v7a
|
||||
mkdir %~dp0\build\arm64-v8a
|
||||
|
||||
echo Running cmake armeabi-v7a...
|
||||
|
||||
cd %~dp0\build\armeabi-v7a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="armeabi-v7a" -DCMAKE_BUILD_TYPE:STRING="Release" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\armeabi-v7a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=android-19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DCMAKE_ANDROID_STL_TYPE=gnustl_static" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Running cmake arm64-v8a...
|
||||
cd %~dp0\build\arm64-v8a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="arm64-v8a" -DCMAKE_BUILD_TYPE:STRING="Release" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\arm64-v8a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=android-19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DCMAKE_ANDROID_STL_TYPE=gnustl_static" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Successful.
|
||||
goto :exit
|
||||
|
||||
:errorexit
|
||||
echo An error has occurred, exiting.
|
||||
goto exit
|
||||
|
||||
:exit
|
||||
pause
|
|
@ -0,0 +1,39 @@
|
|||
#include <cstdint>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include "cocos/base/CCRef.h"
|
||||
#include "cocos2d.h"
|
||||
#include <android/log.h>
|
||||
#include "DialogueBox.h"
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MagiaHook", __VA_ARGS__)
|
||||
|
||||
typedef std::function<void(cocos2d::Ref*)> ccMenuCallback;
|
||||
typedef int *(*openMessageBoxType)(char const* title, char const* body, char const* button, const ccMenuCallback& callback, bool xButton);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
void DialogueBoxProxy::DialogueBox(void* dialogueBoxPointer) {
|
||||
LOGI("Called extern dialogue box");
|
||||
auto openMessageBoxFunc = reinterpret_cast<openMessageBoxType>(dialogueBoxPointer);
|
||||
|
||||
auto dontDisappear = std::bind(&DialogueBoxProxy::testCallback, this, std::placeholders::_1);
|
||||
|
||||
openMessageBoxFunc("Update required", "An update for Magia Translate is strongly recommended! 2", "OK",
|
||||
dontDisappear, false);
|
||||
//sleep(100);
|
||||
}
|
||||
|
||||
//void DialogueBoxProxy::motdBox(void * dialogueboxPointer, void * loadContinuePointer);
|
||||
|
||||
void DialogueBoxProxy::testCallback(cocos2d::Ref* sender) {
|
||||
LOGI("Recalled VALUE");
|
||||
}
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
DialogueBoxProxy::DialogueBoxProxy() {
|
||||
|
||||
}
|
||||
__attribute__((visibility("default")))
|
||||
DialogueBoxProxy::~DialogueBoxProxy() {
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __DIALOGUEBOX_H__
|
||||
#define __DIALOGUEBOX_H__
|
||||
#include <cstdint>
|
||||
#include "cocos/base/CCRef.h"
|
||||
|
||||
class DialogueBoxProxy {
|
||||
public:
|
||||
DialogueBoxProxy();
|
||||
virtual ~DialogueBoxProxy();
|
||||
virtual void DialogueBox(void* dialogueBoxPointer);
|
||||
virtual void testCallback(cocos2d::Ref* sender);
|
||||
private:
|
||||
std::function<void(cocos2d::Ref*)> dialogueCallback;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#include "StringsProxy.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*extern "C" StringsProxy* create_object(uintptr_t str)
|
||||
{
|
||||
return new StringsProxy(str);
|
||||
}
|
||||
extern "C" StringsProxy* create_object(const char* str)
|
||||
{
|
||||
return new StringsProxy(str);
|
||||
}
|
||||
|
||||
extern "C" void destroy_object( StringsProxy* object )
|
||||
{
|
||||
delete object;
|
||||
}*/
|
||||
__attribute__((visibility("default")))
|
||||
extern "C" StringsProxy::StringsProxy(const char* contents)
|
||||
{
|
||||
set_string = std::string(contents);
|
||||
}
|
||||
__attribute__((visibility("default")))
|
||||
extern "C" StringsProxy::StringsProxy(uintptr_t str) {
|
||||
set_string = *reinterpret_cast<proxy_string*>(str);
|
||||
}
|
||||
__attribute__((visibility("default")))
|
||||
extern "C" const char* StringsProxy::c_str() {
|
||||
return set_string.c_str();
|
||||
}
|
||||
__attribute__((visibility("default")))
|
||||
extern "C" const uintptr_t* StringsProxy::ptr() {
|
||||
return reinterpret_cast<uintptr_t *>(&set_string);
|
||||
}
|
||||
__attribute__((visibility("default")))
|
||||
extern "C" StringsProxy::~StringsProxy() {
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __STRINGSPROXY_H__
|
||||
#define __STRINGSPROXY_H__
|
||||
#include <string>
|
||||
|
||||
typedef std::basic_string<char> proxy_string;
|
||||
|
||||
class StringsProxy
|
||||
{
|
||||
public:
|
||||
/* Initialize StringsProxy with a pointer to an existing string */
|
||||
|
||||
StringsProxy(uintptr_t str);
|
||||
/* Initialize StringsProxy with a new string */
|
||||
|
||||
StringsProxy(const char* str);
|
||||
/* Get C string */
|
||||
|
||||
virtual const char* c_str();
|
||||
/* Get pointer to string for injection */
|
||||
|
||||
const virtual uintptr_t* ptr();
|
||||
|
||||
virtual ~StringsProxy();
|
||||
private:
|
||||
proxy_string set_string;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,106 @@
|
|||
@echo off
|
||||
for /r "%~dp0\apk" %%a in (*.apk) do set apk=%%~dpnxa
|
||||
if "%apk%" neq "" (
|
||||
echo Found apk %apk%.
|
||||
goto :start
|
||||
)
|
||||
echo Did not find any MagiReco APK! Add it to the apk/ directory.
|
||||
goto errorexit
|
||||
pause
|
||||
|
||||
:start
|
||||
set ndk="C:/Android/android-ndk-r21d/"
|
||||
set /p ndk="Enter ndk Location [C:/Android/android-ndk-r21d/]: "
|
||||
|
||||
if not exist %~dp0\build mkdir %~dp0\build
|
||||
if exist %~dp0\build\apktool_2.4.1.jar goto apktoolexists
|
||||
echo Downloading apktool...
|
||||
CALL curl -A "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64)" -o "%~dp0\build\apktool_2.4.1.jar" -L "https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.4.1.jar"
|
||||
|
||||
:apktoolexists
|
||||
if not exist %~dp0\build\app\ goto create
|
||||
|
||||
set deleteold=N
|
||||
set /p deleteold="Remake existing APK work directory (Y/[N])? "
|
||||
if %deleteold% NEQ Y goto build
|
||||
|
||||
:create
|
||||
echo Removing existing build files...
|
||||
rmdir /S /Q %~dp0\build\app\
|
||||
echo Running apktool...
|
||||
CALL java -jar %~dp0\build\apktool_2.4.1.jar d %apk% -o %~dp0\build\app\
|
||||
mkdir %~dp0\build\app\smali\com\loadLib\
|
||||
if not exist %~dp0\build\app\lib\armeabi-v7a mkdir %~dp0\build\app\lib\armeabi-v7a
|
||||
if not exist %~dp0\build\app\lib\arm64-v8a mkdir %~dp0\build\app\lib\arm64-v8a
|
||||
|
||||
echo Applying smali patches...
|
||||
cd %~dp0
|
||||
call git apply --stat "%~dp0\patches\NativeBridge.patch"
|
||||
call git apply --stat "%~dp0\patches\Hook.patch"
|
||||
call git apply "%~dp0\patches\NativeBridge.patch"
|
||||
call git apply "%~dp0\patches\Hook.patch"
|
||||
echo Applying misc patches...
|
||||
REM call copy /Y "%~dp0\patches\images\story_ui_sprites00_patch.plist" "%~dp0\build\app\assets\package\story\story_ui_sprites00.plist"
|
||||
REM call copy /Y "%~dp0\patches\images\story_ui_sprites00_patch.png" "%~dp0\build\app\assets\package\story\story_ui_sprites00.png"
|
||||
|
||||
call copy /Y "%~dp0\patches\koruri-semibold.ttf" "%~dp0\build\app\assets\fonts\koruri-semibold.ttf"
|
||||
|
||||
echo Updating sprites and AndroidManifest.xml...
|
||||
call python buildassets.py
|
||||
|
||||
:build
|
||||
echo Copying new smali files...
|
||||
call copy /Y "%~dp0\smali\loader\*.smali" "%~dp0\build\app\smali\com\loadLib\"
|
||||
mkdir %~dp0\build\app\smali_classes2\io\kamihama\magianative\
|
||||
echo Copying magianative...
|
||||
call copy /Y "%~dp0\smali\MagiaNative\app\src\main\java\io\kamihama\magianative\*.smali" "%~dp0\build\app\smali_classes2\io\kamihama\magianative\"
|
||||
echo Copying libraries...
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\smali\okhttp-smali\okhttp3\ %~dp0\build\app\smali_classes2\okhttp3\
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\smali\okhttp-smali\okio\ %~dp0\build\app\smali_classes2\okio\
|
||||
echo Copying unknown...
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\patches\unknown\ %~dp0\build\app\unknown\
|
||||
call copy /Y "%~dp0\patches\strings.xml" "%~dp0\build\app\res\values\strings.xml"
|
||||
|
||||
echo Building libraries.
|
||||
|
||||
rmdir /S /Q %~dp0\build\armeabi-v7a\
|
||||
rmdir /S /Q %~dp0\build\arm64-v8a\
|
||||
mkdir %~dp0\build\armeabi-v7a
|
||||
mkdir %~dp0\build\arm64-v8a
|
||||
|
||||
echo Running cmake armeabi-v7a...
|
||||
|
||||
cd %~dp0\build\armeabi-v7a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="armeabi-v7a" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\armeabi-v7a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DDOBBY_DEBUG=ON" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Running cmake arm64-v8a...
|
||||
cd %~dp0\build\arm64-v8a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="arm64-v8a" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\arm64-v8a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=21" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DDOBBY_DEBUG=ON" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Copying libraries...
|
||||
call copy /Y %~dp0\build\armeabi-v7a\libuwasa.so %~dp0\build\app\lib\armeabi-v7a\libuwasa.so
|
||||
call copy /Y %~dp0\abiproxy\build\armeabi-v7a\libabiproxy.so %~dp0\build\app\lib\armeabi-v7a\libabiproxy.so
|
||||
call copy /Y %~dp0\build\arm64-v8a\libuwasa.so %~dp0\build\app\lib\arm64-v8a\libuwasa.so
|
||||
call copy /Y %~dp0\abiproxy\build\arm64-v8a\libabiproxy.so %~dp0\build\app\lib\arm64-v8a\libabiproxy.so
|
||||
|
||||
echo Rebuilding APK...
|
||||
call java -jar %~dp0\build\apktool_2.4.1.jar b %~dp0\build\app\ -o %~dp0\build\magia_patched.apk
|
||||
|
||||
:signandupload
|
||||
echo Signing apk...
|
||||
call %~dp0\sign.bat
|
||||
echo Finished!
|
||||
goto exit
|
||||
|
||||
:errorexit
|
||||
echo An error has occurred, exiting.
|
||||
goto exit
|
||||
|
||||
:exit
|
||||
pause
|
|
@ -0,0 +1,106 @@
|
|||
@echo off
|
||||
for /r "%~dp0\apk" %%a in (*.apk) do set apk=%%~dpnxa
|
||||
if "%apk%" neq "" (
|
||||
echo Found apk %apk%.
|
||||
goto :start
|
||||
)
|
||||
echo Did not find any MagiReco APK! Add it to the apk/ directory.
|
||||
goto errorexit
|
||||
pause
|
||||
|
||||
:start
|
||||
set ndk="C:/Android/android-ndk-r21d/"
|
||||
set /p ndk="Enter ndk Location [C:/Android/android-ndk-r21d/]: "
|
||||
|
||||
if not exist %~dp0\build mkdir %~dp0\build
|
||||
if exist %~dp0\build\apktool_2.4.1.jar goto apktoolexists
|
||||
echo Downloading apktool...
|
||||
CALL curl -A "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64)" -o "%~dp0\build\apktool_2.4.1.jar" -L "https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.4.1.jar"
|
||||
|
||||
:apktoolexists
|
||||
if not exist %~dp0\build\app\ goto create
|
||||
|
||||
set deleteold=N
|
||||
set /p deleteold="Remake existing APK work directory (Y/[N])? "
|
||||
if %deleteold% NEQ Y goto build
|
||||
|
||||
:create
|
||||
echo Removing existing build files...
|
||||
rmdir /S /Q %~dp0\build\app\
|
||||
echo Running apktool...
|
||||
CALL java -jar %~dp0\build\apktool_2.4.1.jar d %apk% -o %~dp0\build\app\
|
||||
mkdir %~dp0\build\app\smali\com\loadLib\
|
||||
if not exist %~dp0\build\app\lib\armeabi-v7a mkdir %~dp0\build\app\lib\armeabi-v7a
|
||||
if not exist %~dp0\build\app\lib\arm64-v8a mkdir %~dp0\build\app\lib\arm64-v8a
|
||||
|
||||
echo Applying smali patches...
|
||||
cd %~dp0
|
||||
call git apply --stat "%~dp0\patches\NativeBridge.patch"
|
||||
call git apply --stat "%~dp0\patches\Hook.patch"
|
||||
call git apply "%~dp0\patches\NativeBridge.patch"
|
||||
call git apply "%~dp0\patches\Hook.patch"
|
||||
echo Applying misc patches...
|
||||
REM call copy /Y "%~dp0\patches\images\story_ui_sprites00_patch.plist" "%~dp0\build\app\assets\package\story\story_ui_sprites00.plist"
|
||||
REM call copy /Y "%~dp0\patches\images\story_ui_sprites00_patch.png" "%~dp0\build\app\assets\package\story\story_ui_sprites00.png"
|
||||
|
||||
call copy /Y "%~dp0\patches\koruri-semibold.ttf" "%~dp0\build\app\assets\fonts\koruri-semibold.ttf"
|
||||
|
||||
echo Updating sprites and AndroidManifest.xml...
|
||||
call python buildassets.py
|
||||
|
||||
:build
|
||||
echo Copying new smali files...
|
||||
call copy /Y "%~dp0\smali\loader\*.smali" "%~dp0\build\app\smali\com\loadLib\"
|
||||
mkdir %~dp0\build\app\smali_classes2\io\kamihama\magianative\
|
||||
echo Copying magianative...
|
||||
call copy /Y "%~dp0\smali\MagiaNative\app\src\main\java\io\kamihama\magianative\*.smali" "%~dp0\build\app\smali_classes2\io\kamihama\magianative\"
|
||||
echo Copying libraries...
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\smali\okhttp-smali\okhttp3\ %~dp0\build\app\smali_classes2\okhttp3\
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\smali\okhttp-smali\okio\ %~dp0\build\app\smali_classes2\okio\
|
||||
echo Copying unknown...
|
||||
call robocopy /NFL /NDL /NJH /NJS /nc /ns /e %~dp0\patches\unknown\ %~dp0\build\app\unknown\
|
||||
call copy /Y "%~dp0\patches\strings.xml" "%~dp0\build\app\res\values\strings.xml"
|
||||
|
||||
echo Building libraries.
|
||||
|
||||
rmdir /S /Q %~dp0\build\armeabi-v7a\
|
||||
rmdir /S /Q %~dp0\build\arm64-v8a\
|
||||
mkdir %~dp0\build\armeabi-v7a
|
||||
mkdir %~dp0\build\arm64-v8a
|
||||
|
||||
echo Running cmake armeabi-v7a...
|
||||
|
||||
cd %~dp0\build\armeabi-v7a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="armeabi-v7a" -DCMAKE_BUILD_TYPE:STRING="Release" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\armeabi-v7a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=19" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DDOBBY_DEBUG=OFF" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Running cmake arm64-v8a...
|
||||
cd %~dp0\build\arm64-v8a
|
||||
call "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G Ninja -DANDROID_ABI="arm64-v8a" -DCMAKE_BUILD_TYPE:STRING="Release" -DCMAKE_INSTALL_PREFIX:PATH="%~dp0\build\arm64-v8a" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="%ndk%/build/cmake/android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM:FILEPATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe" "-DANDROID_PLATFORM=21" "-DCMAKE_SYSTEM_NAME=Android" "-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a" "-DCMAKE_ANDROID_NDK=%ndk%" "-DCMAKE_SYSTEM_VERSION=16" "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" "-DDOBBY_DEBUG=OFF" "%~dp0\"
|
||||
if errorlevel 1 goto errorexit
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe"
|
||||
if errorlevel 1 goto errorexit
|
||||
|
||||
echo Copying libraries...
|
||||
call copy /Y %~dp0\build\armeabi-v7a\libuwasa.so %~dp0\build\app\lib\armeabi-v7a\libuwasa.so
|
||||
call copy /Y %~dp0\abiproxy\build\armeabi-v7a\libabiproxy.so %~dp0\build\app\lib\armeabi-v7a\libabiproxy.so
|
||||
call copy /Y %~dp0\build\arm64-v8a\libuwasa.so %~dp0\build\app\lib\arm64-v8a\libuwasa.so
|
||||
call copy /Y %~dp0\abiproxy\build\arm64-v8a\libabiproxy.so %~dp0\build\app\lib\arm64-v8a\libabiproxy.so
|
||||
|
||||
echo Rebuilding APK...
|
||||
call java -jar %~dp0\build\apktool_2.4.1.jar b %~dp0\build\app\ -o %~dp0\build\magia_patched.apk
|
||||
|
||||
:signandupload
|
||||
echo Signing apk...
|
||||
call %~dp0\sign.bat
|
||||
echo Finished!
|
||||
goto exit
|
||||
|
||||
:errorexit
|
||||
echo An error has occurred, exiting.
|
||||
goto exit
|
||||
|
||||
:exit
|
||||
pause
|
|
@ -0,0 +1,130 @@
|
|||
import sys, os
|
||||
from PIL import Image
|
||||
import plistlib
|
||||
import ast
|
||||
from pathlib import Path
|
||||
sys.path.append('lib/untp/src/untp')
|
||||
import untp
|
||||
from PyTexturePacker import Packer
|
||||
from shutil import copyfile
|
||||
import shutil
|
||||
|
||||
def rmdir(directory):
|
||||
if os.path.exists(directory):
|
||||
directory = Path(directory)
|
||||
|
||||
for item in directory.iterdir():
|
||||
if item.is_dir():
|
||||
rmdir(item)
|
||||
else:
|
||||
item.unlink()
|
||||
directory.rmdir()
|
||||
|
||||
en_path = "L:/MagiaReco/com.aniplex.magireco.en_1.2.0_checkonly-debugSigned/assets/package/"
|
||||
jp_path = os.path.dirname(os.path.realpath(__file__)) + "/build/app/assets/package/"
|
||||
print("EN Path: " + en_path)
|
||||
print("JP Path: " + jp_path)
|
||||
|
||||
en_assets = {}
|
||||
jp_assets = {}
|
||||
for path in Path(en_path).rglob('*.png'):
|
||||
en_assets[path.name] = path
|
||||
for path in Path(jp_path).rglob('*.png'):
|
||||
jp_assets[path.name] = path
|
||||
|
||||
|
||||
|
||||
required_assets = [["quest_image0","quest_image1"],
|
||||
["data_download0"],
|
||||
["ef_battle000","ef_battle001"],
|
||||
["qb_auto_settings0"],
|
||||
["qb_continue"],
|
||||
["qb_ef_sp_combo0"],
|
||||
["qb_help"],
|
||||
["story_ui_sprites00"],
|
||||
["toppage_bg_020", "toppage_bg_021"],
|
||||
["web_ef_magia_lvup0"],
|
||||
["web_ef_memoria0", "web_ef_memoria1"],
|
||||
["web_ef_reality_up0"],
|
||||
["web_ef_strengthening0"],
|
||||
["qb_menu_top0"]]
|
||||
ignored_images = ["dl_loading_bar01.png", "qb_menu_top_14.png"]
|
||||
|
||||
copyfile(en_path + "/top/toppage_bg_02.ExportJson", jp_path + "/top/toppage_bg_02.ExportJson")
|
||||
copyfile(en_path + "/memoria/web_ef_memoria.ExportJson", jp_path + "/memoria/web_ef_memoria.ExportJson")
|
||||
|
||||
print("Updating AndroidManifest.xml")
|
||||
path = Path("build/app/AndroidManifest.xml")
|
||||
text = path.read_text()
|
||||
text = text.replace("com.aniplex.magireco", "io.kamihama.magiatranslate")
|
||||
path.write_text(text)
|
||||
|
||||
basePath = os.path.dirname(os.path.realpath(__file__))
|
||||
rmdir("build/assets")
|
||||
Path("build/assets").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for assets in required_assets:
|
||||
rmdir("build/assets/work_jp")
|
||||
Path("build/assets/work_jp").mkdir(parents=True, exist_ok=True)
|
||||
rmdir("build/assets/work_jp_old")
|
||||
Path("build/assets/work_jp_old").mkdir(parents=True, exist_ok=True)
|
||||
rmdir("build/assets/work_en")
|
||||
Path("build/assets/work_en").mkdir(parents=True, exist_ok=True)
|
||||
rmdir("build/assets/work_out")
|
||||
Path("build/assets/work_out").mkdir(parents=True, exist_ok=True)
|
||||
for asset in assets:
|
||||
asset_png = asset + ".png"
|
||||
jp_asset_plist = str(jp_assets[asset_png])[:-4] + ".plist"
|
||||
jp_asset_png = jp_assets[asset_png]
|
||||
#print("Working on JP " + jp_asset_plist)
|
||||
|
||||
untp.unpacker(str(jp_asset_plist), image_file = str(jp_asset_png), output_dir = "build/assets/work_jp")
|
||||
untp.unpacker(str(jp_asset_plist), image_file = str(jp_asset_png), output_dir = "build/assets/work_jp_old")
|
||||
|
||||
for asset in assets:
|
||||
asset_png = asset + ".png"
|
||||
|
||||
if asset_png in en_assets:
|
||||
na_asset_plist = str(en_assets[asset_png])[:-4] + ".plist"
|
||||
na_asset_png = en_assets[asset_png]
|
||||
#print("Working on NA " + na_asset_plist)
|
||||
untp.unpacker(str(na_asset_plist), image_file = str(na_asset_png), output_dir = "build/assets/work_en")
|
||||
#print("Skipping NA %s" % asset_png)
|
||||
|
||||
for toCopy in Path("build/assets/work_en").rglob("*.*"):
|
||||
filename = os.path.basename(str(toCopy))
|
||||
#print("Copying %s" % str(toCopy)[8:])
|
||||
if (filename not in ignored_images):
|
||||
copyfile("build/assets/work_en/" + filename, "build/assets/work_jp/" + filename)
|
||||
|
||||
manualPath = basePath + "patches/images/" + assets[0] + "/"
|
||||
if os.path.exists(manualPath):
|
||||
print("Adding manual replacements for " + assets[0] + ".")
|
||||
for toCopy in Path(manualPath).rglob("*.*"):
|
||||
filename = os.path.basename(str(toCopy))
|
||||
print("Copying " + filename + "...")
|
||||
copyfile(toCopy, "build/assets/work_jp/" + filename)
|
||||
|
||||
if assets[0] == "toppage_bg_020":
|
||||
print("Manual override for toppage")
|
||||
packer = Packer.create(max_width=2048, max_height=1920, bg_color=0x00ffffff, enable_rotated=False)
|
||||
else:
|
||||
packer = Packer.create(max_width=2048, max_height=2048, bg_color=0x00ffffff, enable_rotated=False)
|
||||
|
||||
if str(assets[0][-1]) == '0':
|
||||
packer.pack("build/assets/work_jp/", str(assets[0][:-1]) + "%d", output_path="build/assets/work_out/")
|
||||
else:
|
||||
packer.pack("build/assets/work_jp/", str(assets[0]), output_path="build/assets/work_out/")
|
||||
|
||||
for asset in assets:
|
||||
asset_png = asset + ".png"
|
||||
jp_asset_plist = str(jp_assets[asset_png])[:-4] + ".plist"
|
||||
jp_asset_png = jp_assets[asset_png]
|
||||
os.remove(jp_asset_png)
|
||||
os.remove(jp_asset_plist)
|
||||
savedir = os.path.dirname(jp_asset_png)
|
||||
print("Saving to %s" % savedir)
|
||||
file_names = os.listdir("build/assets/work_out/")
|
||||
|
||||
for file_name in file_names:
|
||||
shutil.move(os.path.join("build/assets/work_out/", file_name), savedir)
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 0aec6c146a3140b917d42850f3c48d19e6c64746
|
|
@ -0,0 +1 @@
|
|||
Subproject commit b06eab6779fa27b6b4518a877ded7131cf9b90c6
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 9d305b40ba0d1bd3f845e0102fa6815b7f2b718c
|
|
@ -0,0 +1,26 @@
|
|||
diff --git a/build/app/smali/jp/f4samurai/MyApplication.smali b/build/app/smali/jp/f4samurai/MyApplication.smali
|
||||
index 2a83c1d..c18fa78 100644
|
||||
--- "a/build/app/smali/jp/f4samurai/MyApplication.smali"
|
||||
+++ "b/build/app/smali/jp/f4samurai/MyApplication.smali"
|
||||
@@ -6,6 +6,7 @@
|
||||
# direct methods
|
||||
.method public constructor <init>()V
|
||||
.locals 0
|
||||
+ invoke-static {}, Lcom/loadLib/libLoader;->loadLib()V
|
||||
|
||||
.line 12
|
||||
invoke-direct {p0}, Landroid/app/Application;-><init>()V
|
||||
@@ -36,12 +37,7 @@
|
||||
.end method
|
||||
|
||||
.method public onCreate()V
|
||||
- .locals 1
|
||||
-
|
||||
- const-string v0, "19418f5e-aacd-437e-af3e-2c9967abcb2f"
|
||||
-
|
||||
- .line 16
|
||||
- invoke-static {p0, v0}, Lcom/smrtbeat/SmartBeat;->initAndStartSession(Landroid/app/Application;Ljava/lang/String;)V
|
||||
+ .locals 0
|
||||
|
||||
.line 17
|
||||
invoke-super {p0}, Landroid/app/Application;->onCreate()V
|
|
@ -0,0 +1,40 @@
|
|||
diff --git a/build/app/smali_classes2/jp/f4samurai/bridge/NativeBridge.smali b/build/app/smali_classes2/jp/f4samurai/bridge/NativeBridge.smali
|
||||
index 0c7b0b1..c283cbc 100644
|
||||
--- a/build/app/smali_classes2/jp/f4samurai/bridge/NativeBridge.smali
|
||||
+++ b/build/app/smali_classes2/jp/f4samurai/bridge/NativeBridge.smali
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
.field private static sAppActivity:Ljp/f4samurai/AppActivity;
|
||||
|
||||
-.field private static sCheatHandler:Ljp/f4samurai/bridge/CheatHandler;
|
||||
-
|
||||
.field private static sClipboardManager:Landroid/content/ClipboardManager;
|
||||
|
||||
|
||||
@@ -36,13 +34,6 @@
|
||||
sput-object v0, Ljp/f4samurai/bridge/NativeBridge;->sAppActivity:Ljp/f4samurai/AppActivity;
|
||||
|
||||
.line 34
|
||||
- new-instance v0, Ljp/f4samurai/bridge/CheatHandler;
|
||||
-
|
||||
- sget-object v1, Ljp/f4samurai/bridge/NativeBridge;->sAppActivity:Ljp/f4samurai/AppActivity;
|
||||
-
|
||||
- invoke-direct {v0, v1}, Ljp/f4samurai/bridge/CheatHandler;-><init>(Landroid/content/Context;)V
|
||||
-
|
||||
- sput-object v0, Ljp/f4samurai/bridge/NativeBridge;->sCheatHandler:Ljp/f4samurai/bridge/CheatHandler;
|
||||
|
||||
.line 35
|
||||
sget-object v0, Ljp/f4samurai/bridge/NativeBridge;->sAppActivity:Ljp/f4samurai/AppActivity;
|
||||
@@ -354,11 +345,7 @@
|
||||
.locals 1
|
||||
|
||||
.line 180
|
||||
- sget-object v0, Ljp/f4samurai/bridge/NativeBridge;->sCheatHandler:Ljp/f4samurai/bridge/CheatHandler;
|
||||
-
|
||||
- invoke-virtual {v0}, Ljp/f4samurai/bridge/CheatHandler;->isUnauthorizedUser()Z
|
||||
-
|
||||
- move-result v0
|
||||
+ const v0, 0
|
||||
|
||||
return v0
|
||||
.end method
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 8ea15ac03dec652206844acf950f7b124d08e166
|
|
@ -0,0 +1,142 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="abc_action_bar_home_description">Navigate home</string>
|
||||
<string name="abc_action_bar_up_description">Navigate up</string>
|
||||
<string name="abc_action_menu_overflow_description">More options</string>
|
||||
<string name="abc_action_mode_done">Done</string>
|
||||
<string name="abc_activity_chooser_view_see_all">See all</string>
|
||||
<string name="abc_activitychooserview_choose_application">Choose an app</string>
|
||||
<string name="abc_capital_off">OFF</string>
|
||||
<string name="abc_capital_on">ON</string>
|
||||
<string name="abc_font_family_body_1_material">sans-serif</string>
|
||||
<string name="abc_font_family_body_2_material">sans-serif-medium</string>
|
||||
<string name="abc_font_family_button_material">sans-serif-medium</string>
|
||||
<string name="abc_font_family_caption_material">sans-serif</string>
|
||||
<string name="abc_font_family_display_1_material">sans-serif</string>
|
||||
<string name="abc_font_family_display_2_material">sans-serif</string>
|
||||
<string name="abc_font_family_display_3_material">sans-serif</string>
|
||||
<string name="abc_font_family_display_4_material">sans-serif-light</string>
|
||||
<string name="abc_font_family_headline_material">sans-serif</string>
|
||||
<string name="abc_font_family_menu_material">sans-serif</string>
|
||||
<string name="abc_font_family_subhead_material">sans-serif</string>
|
||||
<string name="abc_font_family_title_material">sans-serif-medium</string>
|
||||
<string name="abc_search_hint">Search…</string>
|
||||
<string name="abc_searchview_description_clear">Clear query</string>
|
||||
<string name="abc_searchview_description_query">Search query</string>
|
||||
<string name="abc_searchview_description_search">Search</string>
|
||||
<string name="abc_searchview_description_submit">Submit query</string>
|
||||
<string name="abc_searchview_description_voice">Voice search</string>
|
||||
<string name="abc_shareactionprovider_share_with">Share with</string>
|
||||
<string name="abc_shareactionprovider_share_with_application">Share with %s</string>
|
||||
<string name="abc_toolbar_collapse_description">Collapse</string>
|
||||
<string name="app_name">Magia Record JP</string>
|
||||
<string name="app_type">APP</string>
|
||||
<string name="build_type">RELEASE</string>
|
||||
<string name="cast_ad_label">Ad</string>
|
||||
<string name="cast_casting_to_device">Casting to %1$s</string>
|
||||
<string name="cast_closed_captions">Closed captions</string>
|
||||
<string name="cast_closed_captions_unavailable">Closed captions unavailable</string>
|
||||
<string name="cast_connecting_to_device">Connecting to %1$s</string>
|
||||
<string name="cast_disconnect">Disconnect</string>
|
||||
<string name="cast_expanded_controller_ad_image_description">Image displayed while the cast receiver is playing an ad</string>
|
||||
<string name="cast_expanded_controller_ad_in_progress">Ad in progress…</string>
|
||||
<string name="cast_expanded_controller_background_image">Album art</string>
|
||||
<string name="cast_expanded_controller_live_stream_indicator">Live stream</string>
|
||||
<string name="cast_expanded_controller_loading">Loading…</string>
|
||||
<string name="cast_expanded_controller_skip_ad_label">Skip</string>
|
||||
<string name="cast_forward">Forward</string>
|
||||
<string name="cast_forward_10">Forward ten seconds</string>
|
||||
<string name="cast_forward_30">Forward thirty seconds</string>
|
||||
<string name="cast_intro_overlay_button_text">@android:string/ok</string>
|
||||
<string name="cast_invalid_stream_duration_text">--:--</string>
|
||||
<string name="cast_invalid_stream_position_text">--:--</string>
|
||||
<string name="cast_mute">Mute</string>
|
||||
<string name="cast_notification_connected_message">Connected to %1$s</string>
|
||||
<string name="cast_notification_connecting_message">Connecting to %1$s</string>
|
||||
<string name="cast_notification_default_channel_name">Cast</string>
|
||||
<string name="cast_notification_disconnect">Disconnect</string>
|
||||
<string name="cast_pause">Pause</string>
|
||||
<string name="cast_play">Play</string>
|
||||
<string name="cast_rewind">Rewind</string>
|
||||
<string name="cast_rewind_10">Rewind ten seconds</string>
|
||||
<string name="cast_rewind_30">Rewind thirty seconds</string>
|
||||
<string name="cast_seek_bar">Playback seek control</string>
|
||||
<string name="cast_skip_next">Skip to next item</string>
|
||||
<string name="cast_skip_prev">Skip to previous item</string>
|
||||
<string name="cast_stop">Stop</string>
|
||||
<string name="cast_stop_live_stream">Stop live stream</string>
|
||||
<string name="cast_tracks_chooser_dialog_audio">Audio</string>
|
||||
<string name="cast_tracks_chooser_dialog_cancel">Cancel</string>
|
||||
<string name="cast_tracks_chooser_dialog_closed_captions">Closed Captions</string>
|
||||
<string name="cast_tracks_chooser_dialog_default_track_name">Track %1$d</string>
|
||||
<string name="cast_tracks_chooser_dialog_none">None</string>
|
||||
<string name="cast_tracks_chooser_dialog_ok">OK</string>
|
||||
<string name="cast_tracks_chooser_dialog_subtitles">Subtitles</string>
|
||||
<string name="cast_unmute">Unmute</string>
|
||||
<string name="common_google_play_services_enable_button">Enable</string>
|
||||
<string name="common_google_play_services_enable_text">"%1$s won't work unless you enable Google Play services."</string>
|
||||
<string name="common_google_play_services_enable_title">Enable Google Play services</string>
|
||||
<string name="common_google_play_services_install_button">Install</string>
|
||||
<string name="common_google_play_services_install_text">"%1$s won't run without Google Play services, which are missing from your device."</string>
|
||||
<string name="common_google_play_services_install_title">Get Google Play services</string>
|
||||
<string name="common_google_play_services_notification_channel_name">Google Play services availability</string>
|
||||
<string name="common_google_play_services_notification_ticker">Google Play services error</string>
|
||||
<string name="common_google_play_services_unknown_issue">%1$s is having trouble with Google Play services. Please try again.</string>
|
||||
<string name="common_google_play_services_unsupported_text">"%1$s won't run without Google Play services, which are not supported by your device."</string>
|
||||
<string name="common_google_play_services_update_button">Update</string>
|
||||
<string name="common_google_play_services_update_text">"%1$s won't run unless you update Google Play services."</string>
|
||||
<string name="common_google_play_services_update_title">Update Google Play services</string>
|
||||
<string name="common_google_play_services_updating_text">"%1$s won't run without Google Play services, which are currently updating."</string>
|
||||
<string name="common_google_play_services_wear_update_text">New version of Google Play services needed. It will update itself shortly.</string>
|
||||
<string name="common_open_on_phone">Open on phone</string>
|
||||
<string name="common_signin_button_text">Sign in</string>
|
||||
<string name="common_signin_button_text_long">Sign in with Google</string>
|
||||
<string name="default_web_client_id">48695978581-l3g2vae3su7td5tilbunf8fpb1875np4.apps.googleusercontent.com</string>
|
||||
<string name="fcm_channel_id">android_channel_id</string>
|
||||
<string name="fcm_fallback_notification_channel_label">Miscellaneous</string>
|
||||
<string name="firebase_database_url">https://kamihama-io.firebaseio.com</string>
|
||||
<string name="gcm_defaultSenderId">48695978581</string>
|
||||
<string name="gcm_fallback_notification_channel_label">Miscellaneous</string>
|
||||
<string name="google_api_key">AIzaSyBlHoCTAsEa1zsIhKfE8nvMVewd0ULYmkw</string>
|
||||
<string name="google_app_id">1:48695978581:android:bc7cc007c2de2d0e79c2dc</string>
|
||||
<string name="google_crash_reporting_api_key">AIzaSyBlHoCTAsEa1zsIhKfE8nvMVewd0ULYmkw</string>
|
||||
<string name="google_storage_bucket">kamihama-io.appspot.com</string>
|
||||
<string name="mr_button_content_description">Cast button</string>
|
||||
<string name="mr_cast_button_connected">Cast button. Connected</string>
|
||||
<string name="mr_cast_button_connecting">Cast button. Connecting</string>
|
||||
<string name="mr_cast_button_disconnected">Cast button. Disconnected</string>
|
||||
<string name="mr_chooser_searching">Finding devices</string>
|
||||
<string name="mr_chooser_title">Cast to</string>
|
||||
<string name="mr_controller_album_art">Album art</string>
|
||||
<string name="mr_controller_casting_screen">Casting screen</string>
|
||||
<string name="mr_controller_close_description">Close</string>
|
||||
<string name="mr_controller_collapse_group">Collapse</string>
|
||||
<string name="mr_controller_disconnect">Disconnect</string>
|
||||
<string name="mr_controller_expand_group">Expand</string>
|
||||
<string name="mr_controller_no_info_available">No info available</string>
|
||||
<string name="mr_controller_no_media_selected">No media selected</string>
|
||||
<string name="mr_controller_pause">Pause</string>
|
||||
<string name="mr_controller_play">Play</string>
|
||||
<string name="mr_controller_stop">Stop</string>
|
||||
<string name="mr_controller_stop_casting">Stop casting</string>
|
||||
<string name="mr_controller_volume_slider">Volume slider</string>
|
||||
<string name="mr_system_route_name">System</string>
|
||||
<string name="mr_user_route_category_name">Devices</string>
|
||||
<string name="place_autocomplete_clear_button">Clear search</string>
|
||||
<string name="place_autocomplete_search_hint">Search</string>
|
||||
<string name="project_id">magireco-754ac</string>
|
||||
<string name="s1">Save image</string>
|
||||
<string name="s2">Allow Ad to store image in Picture gallery?</string>
|
||||
<string name="s3">Accept</string>
|
||||
<string name="s4">Decline</string>
|
||||
<string name="s5">Create calendar event</string>
|
||||
<string name="s6">Allow Ad to create a calendar event?</string>
|
||||
<string name="s7">Test Ad</string>
|
||||
<string name="search_menu_title">Search</string>
|
||||
<string name="server_type">PRODUCT</string>
|
||||
<string name="status_bar_notification_info_overflow">999+</string>
|
||||
<string name="tagmanager_preview_dialog_button">Continue</string>
|
||||
<string name="tagmanager_preview_dialog_message">Preview mode updated.</string>
|
||||
<string name="tagmanager_preview_dialog_title">Preview</string>
|
||||
<string name="wallet_buy_button_place_holder">Buy with Google</string>
|
||||
</resources>
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"project_info": {
|
||||
"project_number": "48695978581",
|
||||
"firebase_url": "https://kamihama-io.firebaseio.com",
|
||||
"project_id": "kamihama-io",
|
||||
"storage_bucket": "kamihama-io.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:48695978581:android:bc7cc007c2de2d0e79c2dc",
|
||||
"android_client_info": {
|
||||
"package_name": "io.kamihama.magiatranslate"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "48695978581-l3g2vae3su7td5tilbunf8fpb1875np4.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBlHoCTAsEa1zsIhKfE8nvMVewd0ULYmkw"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "48695978581-l3g2vae3su7td5tilbunf8fpb1875np4.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
parse==1.18.0
|
||||
Pillow==8.0.1
|
||||
pkg-resources==0.0.0
|
||||
PyTexturePacker==1.1.0
|
|
@ -0,0 +1,101 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
# Built application files
|
||||
*.apk
|
||||
*.aar
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
# Uncomment the following line in case you need and you don't have the release build type files in your app
|
||||
# release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
# Android Studio 3 in .gitignore file.
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||
.idea/navEditor.xml
|
||||
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
.cxx/
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/readme.md
|
||||
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
# lint/reports/
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,29 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.2"
|
||||
defaultConfig {
|
||||
applicationId "io.kamihama.magianative"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation("com.squareup.okhttp3:okhttp:3.12.9")
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
|
@ -0,0 +1,27 @@
|
|||
package io.kamihama.magianative;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("io.kamihama.magianative", appContext.getPackageName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.kamihama.magianative">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme" />
|
||||
</manifest>
|
|
@ -0,0 +1,73 @@
|
|||
.class final Lio/kamihama/magianative/RestClient$1;
|
||||
.super Ljava/lang/Object;
|
||||
.source "RestClient.java"
|
||||
|
||||
# interfaces
|
||||
.implements Ljavax/net/ssl/X509TrustManager;
|
||||
|
||||
|
||||
# annotations
|
||||
.annotation system Ldalvik/annotation/EnclosingMethod;
|
||||
value = Lio/kamihama/magianative/RestClient;->getUnsafeOkHttpClient()Lokhttp3/OkHttpClient;
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/InnerClass;
|
||||
accessFlags = 0x8
|
||||
name = null
|
||||
.end annotation
|
||||
|
||||
|
||||
# direct methods
|
||||
.method constructor <init>()V
|
||||
.registers 1
|
||||
|
||||
.prologue
|
||||
.line 86
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public checkClientTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V
|
||||
.registers 3
|
||||
.param p1, "chain" # [Ljava/security/cert/X509Certificate;
|
||||
.param p2, "authType" # Ljava/lang/String;
|
||||
.annotation system Ldalvik/annotation/Throws;
|
||||
value = {
|
||||
Ljava/security/cert/CertificateException;
|
||||
}
|
||||
.end annotation
|
||||
|
||||
.prologue
|
||||
.line 89
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V
|
||||
.registers 3
|
||||
.param p1, "chain" # [Ljava/security/cert/X509Certificate;
|
||||
.param p2, "authType" # Ljava/lang/String;
|
||||
.annotation system Ldalvik/annotation/Throws;
|
||||
value = {
|
||||
Ljava/security/cert/CertificateException;
|
||||
}
|
||||
.end annotation
|
||||
|
||||
.prologue
|
||||
.line 93
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public getAcceptedIssuers()[Ljava/security/cert/X509Certificate;
|
||||
.registers 2
|
||||
|
||||
.prologue
|
||||
.line 97
|
||||
const/4 v0, 0x0
|
||||
|
||||
new-array v0, v0, [Ljava/security/cert/X509Certificate;
|
||||
|
||||
return-object v0
|
||||
.end method
|
|
@ -0,0 +1,43 @@
|
|||
.class final Lio/kamihama/magianative/RestClient$2;
|
||||
.super Ljava/lang/Object;
|
||||
.source "RestClient.java"
|
||||
|
||||
# interfaces
|
||||
.implements Ljavax/net/ssl/HostnameVerifier;
|
||||
|
||||
|
||||
# annotations
|
||||
.annotation system Ldalvik/annotation/EnclosingMethod;
|
||||
value = Lio/kamihama/magianative/RestClient;->getUnsafeOkHttpClient()Lokhttp3/OkHttpClient;
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/InnerClass;
|
||||
accessFlags = 0x8
|
||||
name = null
|
||||
.end annotation
|
||||
|
||||
|
||||
# direct methods
|
||||
.method constructor <init>()V
|
||||
.registers 1
|
||||
|
||||
.prologue
|
||||
.line 110
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public verify(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z
|
||||
.registers 4
|
||||
.param p1, "hostname" # Ljava/lang/String;
|
||||
.param p2, "session" # Ljavax/net/ssl/SSLSession;
|
||||
|
||||
.prologue
|
||||
.line 113
|
||||
const/4 v0, 0x1
|
||||
|
||||
return v0
|
||||
.end method
|
|
@ -0,0 +1,34 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#008577"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#008577</color>
|
||||
<color name="colorPrimaryDark">#00574B</color>
|
||||
<color name="colorAccent">#D81B60</color>
|
||||
</resources>
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">MagiaNative</string>
|
||||
</resources>
|
|
@ -0,0 +1,11 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,17 @@
|
|||
package io.kamihama.magianative;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#Mon Sep 21 21:15:19 BST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,84 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
|
@ -0,0 +1 @@
|
|||
include ':app', ':magianativelib'
|
|
@ -0,0 +1,44 @@
|
|||
.class final Lcom/loadLib/libLoader$1;
|
||||
.super Ljava/lang/Object;
|
||||
.source "libLoader.java"
|
||||
|
||||
# interfaces
|
||||
.implements Ljava/lang/Runnable;
|
||||
|
||||
|
||||
# annotations
|
||||
.annotation system Ldalvik/annotation/EnclosingMethod;
|
||||
value = Lcom/JvRuit/Ldr;->loadLib()V
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/InnerClass;
|
||||
accessFlags = 0x8
|
||||
name = null
|
||||
.end annotation
|
||||
|
||||
|
||||
# direct methods
|
||||
.method constructor <init>()V
|
||||
.locals 0
|
||||
|
||||
.prologue
|
||||
.line 14
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public run()V
|
||||
.locals 1
|
||||
|
||||
.prologue
|
||||
.line 17
|
||||
const-string/jumbo v0, "uwasa"
|
||||
|
||||
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
|
||||
|
||||
.line 18
|
||||
return-void
|
||||
.end method
|
|
@ -0,0 +1,36 @@
|
|||
.class public Lcom/loadLib/libLoader;
|
||||
.super Landroid/app/Activity;
|
||||
.source "libLoader.java"
|
||||
|
||||
|
||||
# direct methods
|
||||
.method public constructor <init>()V
|
||||
.locals 0
|
||||
|
||||
.prologue
|
||||
.line 12
|
||||
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public static loadLib()V
|
||||
.locals 4
|
||||
|
||||
.prologue
|
||||
.line 14
|
||||
new-instance v0, Landroid/os/Handler;
|
||||
|
||||
invoke-direct {v0}, Landroid/os/Handler;-><init>()V
|
||||
|
||||
new-instance v1, Lcom/loadLib/libLoader$1;
|
||||
|
||||
invoke-direct {v1}, Lcom/loadLib/libLoader$1;-><init>()V
|
||||
|
||||
const-wide/16 v2, 0x1
|
||||
|
||||
invoke-virtual {v0, v1, v2, v3}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
|
||||
|
||||
.line 20
|
||||
return-void
|
||||
.end method
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 0c50e8e3935b66710255d73588735fde19a28683
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
/**************************
|
||||
* Magia Translate Ver *
|
||||
**************************/
|
||||
#define MT_VERSION 110
|
||||
|
||||
#endif
|
|
@ -0,0 +1,747 @@
|
|||
#include <jni.h>
|
||||
#include <cstdint>
|
||||
#include <android/log.h>
|
||||
#include <dobby.h>
|
||||
#include <memory.h>
|
||||
#include <dlfcn.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "Utils.h"
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include "Config.h"
|
||||
#include <cocos2d.h>
|
||||
#include "libmadomagi.h"
|
||||
#include "magia/StringsProxy.h"
|
||||
#include "magia/DialogueBox.h"
|
||||
#include "rest/MagiaRest.h"
|
||||
|
||||
const char* libName = "libmadomagi_native.so";
|
||||
const char* hookName = "libuwasa.so";
|
||||
|
||||
JavaVM* gJvm = nullptr;
|
||||
static jobject gClassLoader;
|
||||
static jmethodID gFindClassMethod;
|
||||
uintptr_t libBase = 0;
|
||||
|
||||
//namespace fs = std::filesystem; ndk 22+ required
|
||||
|
||||
struct hook_loop_args {
|
||||
std::string libso;
|
||||
};
|
||||
|
||||
uintptr_t storyMessageUnitStartOffset = 0;
|
||||
uintptr_t storyMessageUnitCreateMessageAreaOffset = 0;
|
||||
uintptr_t storyLogUnitAddMessageOffset = 0;
|
||||
uintptr_t storyLogUnitAddNarrationOffset = 0;
|
||||
uintptr_t storyCharaUnitonTextHomeOffset = 0;
|
||||
uintptr_t storyNarrationUnitCreateLabelOffset = 0;
|
||||
uintptr_t initCenterWidthOutline = 0;
|
||||
|
||||
int max_threads = 10;
|
||||
|
||||
void* openMessageBoxPtr = nullptr;
|
||||
uintptr_t* resourceUrlPtr = nullptr;
|
||||
|
||||
bool initialized = false;
|
||||
|
||||
const std::string assetBase = "/magica/resource";
|
||||
const std::string assetTrunk = "/download/asset/master";
|
||||
const std::string assetScenario = "/resource/scenario";
|
||||
void* urlEndpoints[] = {nullptr, nullptr, nullptr};
|
||||
|
||||
StringsProxy* koruriFont = new StringsProxy("fonts/koruri-semibold.ttf");
|
||||
|
||||
typedef int *(*setUrlType)(int *);
|
||||
typedef int *(*setResourceType)(int *, unsigned int *);
|
||||
typedef uintptr_t *(*UrlConfigImplResourceType)(uintptr_t &a1, int a2, unsigned int a3, int a4);
|
||||
|
||||
// Hooked functions
|
||||
void *(*setPositionHooked)(uintptr_t label, cocos2d::Vec2 const& position);
|
||||
void *(*setMaxLineWidthHooked)(uintptr_t label, float length);
|
||||
void *(*setDimensionsHooked)(uintptr_t label, float width, float a3);
|
||||
|
||||
void *(*urlConfigResourceHooked)(void* a1, UrlConfigResourceType type); // There is also api, chat, web, etc for other endpoints
|
||||
|
||||
//void* urlConfig_ImplObj = nullptr;
|
||||
|
||||
// Cocos functions
|
||||
typedef cocos2d::Director* (*director_type)(void* dummy);
|
||||
typedef const cocos2d::Size& (*get_win_size_type)(cocos2d::Director* director);
|
||||
typedef cocos2d::Vec2 (*get_visible_origin_type)(cocos2d::Director* director);
|
||||
|
||||
director_type getDirector;
|
||||
get_win_size_type getWinSize;
|
||||
get_visible_origin_type getVisibleOrigin;
|
||||
|
||||
/* BROKEN
|
||||
void testDialogue() {
|
||||
if (openMessageBoxPtr != nullptr) {
|
||||
auto x = DialogueBoxProxy();
|
||||
x.DialogueBox(openMessageBoxPtr);
|
||||
}
|
||||
}*/
|
||||
jclass findClass(JNIEnv* env, const char* name) {
|
||||
return static_cast<jclass>(env->CallObjectMethod(gClassLoader, gFindClassMethod, env->NewStringUTF(name)));
|
||||
}
|
||||
|
||||
void displayMessage(const std::string& title, const std::string& description) {
|
||||
auto env = getEnv(gJvm);
|
||||
const char* cocosHelper = "org/cocos2dx/lib/Cocos2dxHelper";
|
||||
const char* showDialogueBox = "showDialog";
|
||||
std::string signature = "(" + std::string(getJNISignature(title, description)) + ")V";
|
||||
|
||||
jclass klass = findClass(env, cocosHelper);
|
||||
if (klass == nullptr) {
|
||||
LOGE("No Cocos2dxHelper found.");
|
||||
return;
|
||||
}
|
||||
|
||||
jmethodID mid = env->GetStaticMethodID(klass, showDialogueBox, signature.c_str());
|
||||
if (mid == nullptr) {
|
||||
LOGE("No showDialog found.");
|
||||
return;
|
||||
}
|
||||
jstring str1 = env->NewStringUTF(title.c_str());
|
||||
jstring str2 = env->NewStringUTF(description.c_str());
|
||||
env->CallStaticObjectMethod(klass, mid, str1, str2);
|
||||
}
|
||||
|
||||
int *(*sceneLayerManagerCreateSceneLayerOld)(uintptr_t *sceneLayerManager, BaseSceneLayerInfo* sceneLayerInfo);
|
||||
|
||||
int *sceneLayerManagerCreateSceneLayer(uintptr_t *sceneLayerManager, BaseSceneLayerInfo* sceneLayerInfo) {
|
||||
auto sceneType = sceneLayerInfo->layerType;
|
||||
if (sceneType >= BaseSceneLayerType::BaseSceneLayerTypeMaxValue || sceneType < 0) {
|
||||
LOGW("Unknown scene triggered. %d", sceneType);
|
||||
}
|
||||
else {
|
||||
LOGD("Scene layer changed to: %s", BaseSceneLayerTypeStrings[sceneType]);
|
||||
}
|
||||
|
||||
if (!initialized && sceneType == BaseSceneLayerType::WebSceneLayer) { // Set up everything here
|
||||
auto rest = MagiaRest(gJvm);
|
||||
switch(rest.Endpoint()) {
|
||||
case MAGIAREST_EMPTY:
|
||||
{
|
||||
auto emptyMessage = string_format("Unable to connect to the translation server. Restart the app to retry, or continue to play in Japanese. (Response length: %zu)",
|
||||
rest.EndpointStringLength());
|
||||
|
||||
displayMessage("MagiaTranslate Error", emptyMessage.c_str());
|
||||
break;
|
||||
}
|
||||
case MAGIAREST_ERROR:
|
||||
{
|
||||
auto errorMessage = string_format("An error has occurred. Restart the app to retry, or continue to play in Japanese.\nError: %s", rest.GetEndpointError().c_str());
|
||||
displayMessage("MagiaTranslate Error", errorMessage.c_str());
|
||||
break;
|
||||
}
|
||||
case MAGIAREST_SUCCESS:
|
||||
{
|
||||
auto ver = rest.GetEndpointVersion();
|
||||
if (MT_VERSION < ver) {
|
||||
LOGI("Version update required.");
|
||||
auto updateMessage = string_format("A new version of MagiaTranslate is available, please update your app at kamihama.io. Continuing may result in crashes.\nApp version installed: %d\nApp version available: %d",
|
||||
MT_VERSION, ver);
|
||||
displayMessage("MagiaTranslate Update", updateMessage.c_str());
|
||||
}
|
||||
auto endpointUrl = rest.GetEndpointUrl();
|
||||
if (endpointUrl.empty()) {
|
||||
LOGW("Empty endpoint URL.");
|
||||
displayMessage("MagiaTranslate Error", "Error 115 has occurred, the returned translate endpoint URL is empty, please try again later.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Set max download threads
|
||||
auto mt = rest.GetMaxThreads();
|
||||
if (mt > 0) {
|
||||
LOGD("Set maximum threads from API, value %d.", mt);
|
||||
max_threads = mt;
|
||||
}
|
||||
|
||||
const std::string assetNameBase = endpointUrl + assetBase;
|
||||
const std::string assetNameFull = endpointUrl + assetBase + assetTrunk;
|
||||
const std::string assetNameScript = endpointUrl + assetBase + assetTrunk + assetScenario;
|
||||
|
||||
// new keyword to stop freeing
|
||||
StringsProxy* assetNameBaseProxy = new StringsProxy(assetNameBase.c_str());
|
||||
StringsProxy* assetNameFullProxy = new StringsProxy(assetNameFull.c_str());
|
||||
StringsProxy* assetNameScriptProxy = new StringsProxy(assetNameScript.c_str());
|
||||
|
||||
LOGD("Setting endpoint URLs.");
|
||||
|
||||
urlEndpoints[UrlConfigResourceType::BaseUrl] = (void*)assetNameBaseProxy->ptr();
|
||||
urlEndpoints[UrlConfigResourceType::TrunkUrl] = (void*)assetNameFullProxy->ptr();
|
||||
urlEndpoints[UrlConfigResourceType::ScenarioUrl] = (void*)assetNameScriptProxy->ptr();
|
||||
LOGD("Finished setting endpoint URLs.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
auto y = sceneLayerManagerCreateSceneLayerOld(sceneLayerManager, sceneLayerInfo);
|
||||
return y;
|
||||
}
|
||||
|
||||
return sceneLayerManagerCreateSceneLayerOld(sceneLayerManager, sceneLayerInfo);
|
||||
|
||||
}
|
||||
|
||||
// Change function to fetch resource URLs
|
||||
void* urlConfigResource(void* a1, UrlConfigResourceType type) {
|
||||
LOGD("Fetching URL config resource %d", (int)type);
|
||||
if (type < UrlConfigResourceType::UrlConfigResourceTypeMaxValue) {
|
||||
if (urlEndpoints[type] != nullptr) {
|
||||
return (void *)urlEndpoints[type];
|
||||
}
|
||||
else {
|
||||
LOGW("Nullptr endpoint found for endpoint type %d!", (int)type);
|
||||
}
|
||||
}
|
||||
return urlConfigResourceHooked(a1, type);
|
||||
}
|
||||
|
||||
|
||||
void* (*cocosCreateLabelHooked)(const uintptr_t* textPtr, const uintptr_t* fontPtr, float textSize, cocos2d::Size const& cocosSize, cocos2d::TextHAlignment hAlign, cocos2d::TextVAlignment vAlign);
|
||||
void* cocosCreateLabel(const uintptr_t* textPtr, const uintptr_t* fontPtr, float textSize, cocos2d::Size const& cocosSize, cocos2d::TextHAlignment hAlign, cocos2d::TextVAlignment vAlign) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(__builtin_extract_return_addr(__builtin_return_address(0)));
|
||||
LOGD("Label created at %p (%p), size %.1f.", (void*) addr, (void*)(addr - libBase), textSize);
|
||||
if (storyMessageUnitCreateMessageAreaOffset != 0 && addr >= storyMessageUnitCreateMessageAreaOffset) {
|
||||
uintptr_t difference = addr - storyMessageUnitCreateMessageAreaOffset;
|
||||
if (difference <= 0x200) {
|
||||
LOGD("Setting new text font for main story text.");
|
||||
if (textSize == 27.0) {
|
||||
textSize = 30.0;
|
||||
}
|
||||
return cocosCreateLabelHooked(textPtr, koruriFont->ptr(), textSize, cocosSize, hAlign, vAlign);
|
||||
}
|
||||
}
|
||||
if (storyNarrationUnitCreateLabelOffset != 0 && addr >= storyNarrationUnitCreateLabelOffset) {
|
||||
uintptr_t difference = addr - storyNarrationUnitCreateLabelOffset;
|
||||
|
||||
if (difference <= 0x200) { // 0x8e
|
||||
LOGD("Setting new narration text font. Difference: %p", (void*)difference);
|
||||
return cocosCreateLabelHooked(textPtr, koruriFont->ptr(), textSize, cocosSize, hAlign, vAlign);
|
||||
}
|
||||
}
|
||||
if (initCenterWidthOutline != 0 && addr >= initCenterWidthOutline) {
|
||||
uintptr_t difference = addr - initCenterWidthOutline;
|
||||
|
||||
if (difference <= 0x200) {
|
||||
LOGD("Setting new home text font and size.");
|
||||
textSize = textSize * 0.85;
|
||||
return cocosCreateLabelHooked(textPtr, koruriFont->ptr(), textSize, cocosSize, hAlign, vAlign);
|
||||
}
|
||||
}
|
||||
if (storyLogUnitAddMessageOffset != 0 && addr >= storyLogUnitAddMessageOffset) {
|
||||
uintptr_t difference = addr - storyLogUnitAddMessageOffset;
|
||||
|
||||
if (difference <= 0x640) { // 0xec, 0x54e
|
||||
LOGD("Setting new log text font. Difference: %p", (void*)difference);
|
||||
return cocosCreateLabelHooked(textPtr, koruriFont->ptr(), textSize, cocosSize, hAlign, vAlign);
|
||||
}
|
||||
}
|
||||
if (storyLogUnitAddNarrationOffset != 0 && addr >= storyLogUnitAddNarrationOffset) {
|
||||
uintptr_t difference = addr - storyLogUnitAddNarrationOffset;
|
||||
if (difference <= 0x640) { // 0x43e, 0x5b0
|
||||
LOGD("Setting new log text font (narration). Difference: %p", (void*)difference);
|
||||
return cocosCreateLabelHooked(textPtr, koruriFont->ptr(), textSize, cocosSize, hAlign, vAlign);
|
||||
}
|
||||
}
|
||||
return cocosCreateLabelHooked(textPtr, fontPtr, textSize, cocosSize, hAlign, vAlign);
|
||||
|
||||
}
|
||||
|
||||
// New functions
|
||||
void *setPositionNew(uintptr_t label, cocos2d::Vec2 const& position) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(__builtin_extract_return_addr(__builtin_return_address(0)));
|
||||
//LOGI("Move at %p to x: %.2f, y: %.2f", (addr - libBase), position.x, position.y);
|
||||
|
||||
// Story message boxes
|
||||
if (storyMessageUnitStartOffset != 0 && addr >= storyMessageUnitStartOffset) {
|
||||
uintptr_t difference = addr - storyMessageUnitStartOffset;
|
||||
|
||||
// Alignment of main text in box
|
||||
if (difference <= 0x200) { // Offset = 0x76 as of 2.15
|
||||
LOGD("Moving story text.");
|
||||
//LOGI("Difference: %p", difference);
|
||||
//LOGD("old [message] x: %.2f, y: %.2f", position.x, position.y);
|
||||
|
||||
// Move text to the left and up a bit
|
||||
if (position.x == -222.0 && position.y == 20.0) {
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(-368.0, 25.0);
|
||||
//LOGD("new 1 x: %.2f, y: %.2f", newPosition.x, newPosition.y);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (position.x == -207.0 && position.y == 30.0) {
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(-360.0, 40.0);
|
||||
//LOGD("new 2 x: %.2f, y: %.2f", newPosition.x, newPosition.y);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Names alignment
|
||||
if (storyMessageUnitCreateMessageAreaOffset != 0 && addr >= storyMessageUnitCreateMessageAreaOffset) {
|
||||
|
||||
uintptr_t difference = addr - storyMessageUnitCreateMessageAreaOffset;
|
||||
//LOGI("Difference: %p", difference);
|
||||
|
||||
// Move names into the right place
|
||||
if (difference <= 0x600) { // Offset = 0x35e as of 2.15
|
||||
//LOGD("old [name] x: %.2f, y: %.2f", position.x, position.y);
|
||||
LOGD("Moving story name.");
|
||||
if (position.x == -215.0 && position.y == 57.0) { // Left names
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(-320.0, 55.0);
|
||||
//LOGD("new l-1 x: %.2f, y: %.2f", newPosition.x, newPosition.y);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (position.x == -55.0 && position.y == 57.0) { // Center names
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(30.0, 55.0);
|
||||
//LOGD("new m-1 x: %.2f, y: %.2f", newPosition.x, newPosition.y);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (position.x == 215.0 && position.y == 57.0) { // Right names
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(320.0, 55.0);
|
||||
//LOGD("new r-1 x: %.2f, y: %.2f", newPosition.x, newPosition.y);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// History
|
||||
if (storyLogUnitAddMessageOffset != 0 && addr >= storyLogUnitAddMessageOffset) {
|
||||
uintptr_t difference = addr - storyLogUnitAddMessageOffset;
|
||||
//LOGI("LOG MESSAGE: %.2f %.2f", position.x, position.y);
|
||||
//LOGI("Difference: %p", (void *)difference);
|
||||
if (position.y >= 55.50 && position.y <= 56.50 && difference <= 0x800) {
|
||||
float newPosX = position.x + 125.0;
|
||||
//LOGD("Moved log text from %.2f to %.2f", position.x, newPosX);
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(newPosX, 66.50);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (difference <= 0x200 && position.x == 70.00) {
|
||||
LOGD("Moving left-aligned name down in the log.");
|
||||
auto newY = position.y - 15.0;
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(position.x, newY);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (difference <= 0x200 && position.x == 500.00) { // Names on the right
|
||||
LOGD("Moving name further to the right in log.");
|
||||
auto newX = position.x + 200;
|
||||
auto newY = position.y - 15.0;
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(newX, newY);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
else if (difference <= 0x200 && position.x == 280.00) { // Names in the center, 280.00?
|
||||
LOGD("Moving center name to the left in the log.");
|
||||
auto newX = 71.50;
|
||||
auto newY = position.y;
|
||||
cocos2d::Vec2 newPosition = cocos2d::Vec2(newX, newY);
|
||||
return setPositionHooked(label, newPosition);
|
||||
}
|
||||
}
|
||||
return setPositionHooked(label, position);
|
||||
}
|
||||
|
||||
void *setMaxLineWidthNew(uintptr_t label, float length) {
|
||||
//LOGI("Hook triggered - line length");
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(__builtin_extract_return_addr(__builtin_return_address(0)));
|
||||
//LOGI("%p", (addr - libBase));
|
||||
|
||||
if (storyMessageUnitCreateMessageAreaOffset != 0 && addr >= storyMessageUnitCreateMessageAreaOffset) {
|
||||
uintptr_t difference = addr - storyMessageUnitCreateMessageAreaOffset;
|
||||
//LOGI("Difference: %p", difference);
|
||||
|
||||
// Make lines longer
|
||||
if (difference <= 0x244 && length == 410.0) { // Offset = 0x144 as of 2.15
|
||||
LOGD("Set line length from 410.0 to 810.0");
|
||||
length = 810.0;
|
||||
}
|
||||
}
|
||||
return setMaxLineWidthHooked(label, length);
|
||||
}
|
||||
|
||||
void *setDimensionsNew(uintptr_t label, float width, float height) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(__builtin_extract_return_addr(__builtin_return_address(0)));
|
||||
uintptr_t difference = addr - storyLogUnitAddMessageOffset;
|
||||
//LOGI("Difference [dimensions]: %p, addr: %p", difference, addr);
|
||||
|
||||
if (storyLogUnitAddMessageOffset != 0 && addr >= storyLogUnitAddMessageOffset) {
|
||||
//LOGI("%p, %.2f, %.2f", label, width, a3);
|
||||
if (difference <= 0x900 && width == 410.0) { // Offset = 0x5ac as of 2.15
|
||||
LOGD("Set dimensions for log from 410.0 to 710.0.");
|
||||
return setDimensionsHooked(label, 710.0, height);
|
||||
}
|
||||
}
|
||||
//LOGD("Dimensions: %f, %f", width, height);
|
||||
return setDimensionsHooked(label, width, height);
|
||||
}
|
||||
|
||||
// Fix the position of homeText under live2d girls
|
||||
cocos2d::Size (*lbGetViewPositionHooked)(float x, float y);
|
||||
cocos2d::Size lbGetViewPositionNew(float x, float y) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(__builtin_extract_return_addr(__builtin_return_address(0)));
|
||||
uintptr_t difference = addr - storyCharaUnitonTextHomeOffset;
|
||||
//LOGI("Difference (viewPos): %p, addr: %p", (void*)difference, (void*)addr);
|
||||
|
||||
if (storyCharaUnitonTextHomeOffset != 0 && addr >= storyCharaUnitonTextHomeOffset) {
|
||||
if (difference <= 0x1000) {
|
||||
auto oldx = x;
|
||||
auto oldy = y;
|
||||
x = x - 30.0;
|
||||
y = y - 30.0;
|
||||
LOGD("Set live2d subtitle dimensions from (%f, %f) to (%f, %f).", oldx, oldy, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__aarch64__)
|
||||
return lbGetViewPositionHooked(x, y);
|
||||
#endif
|
||||
//LOGI("Size 1: %f, size 2: %f", sizes.width, sizes.height);
|
||||
|
||||
// Reimplement from scratch because arm is bugged (also this segfaults on arm64)
|
||||
auto director = getDirector((void *)0x00);
|
||||
//LOGI("Obtained director at %p.", (void*) director);
|
||||
|
||||
auto dirSize = getWinSize(director);
|
||||
//LOGI("Obtained winsize, %f %f.", dirSize.width, dirSize.height);
|
||||
auto origin = getVisibleOrigin(director);
|
||||
//LOGI("Obtained visible origin, %f %f.", origin.x, origin.y);
|
||||
auto sizes = cocos2d::Size();
|
||||
sizes.width = origin.x + x + (float)dirSize.width * 0.5;
|
||||
sizes.height = origin.y + y + (float)dirSize.height * 0.5;
|
||||
//sizes.width = origin.x + x + (float)dirSize.width * 0.5;
|
||||
//sizes.height = origin.y + y + (float)dirSize.height * 0.5;
|
||||
|
||||
//LOGI("NEW size 1: %f, size 2: %f", sizes.width, sizes.height);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
|
||||
pthread_mutex_t *(*setUriDebugOld)(uintptr_t a1, uintptr_t st);
|
||||
pthread_mutex_t *setUriDebug(uintptr_t a1, uintptr_t stri) {
|
||||
auto mut = setUriDebugOld(a1, stri);
|
||||
|
||||
auto y = StringsProxy(stri);
|
||||
auto outstr = y.c_str();
|
||||
LOGI("Uri base set: %s", outstr);
|
||||
return mut;
|
||||
}
|
||||
|
||||
pthread_mutex_t *(*http2SessionSetMaxConnectionNumOld)(uintptr_t *session, int max);
|
||||
|
||||
pthread_mutex_t *http2SessionSetMaxConnectionNum(uintptr_t *session, int max) {
|
||||
if (max == 4) {
|
||||
max = max_threads;
|
||||
}
|
||||
LOGD("Set max number of connections to %d.", max);
|
||||
return http2SessionSetMaxConnectionNumOld(session, max);
|
||||
}
|
||||
|
||||
void initialization_error(const char* error) {
|
||||
LOGE("%s", error);
|
||||
auto errorMsg = string_format("A critical error has occurred, MagiaTranslate will not work properly and may crash. Please report this error on GitHub or Discord.\n%s", error);
|
||||
displayMessage("MagiaTranslate Error", errorMsg);
|
||||
}
|
||||
|
||||
// Hook loop function. We run this in a separate thread so it doesn't block the main thread.
|
||||
void *hook_loop(void *arguments) {
|
||||
std::unique_ptr<hook_loop_args> args((struct hook_loop_args *)arguments);
|
||||
auto libLocation = (args->libso).c_str();
|
||||
|
||||
LOGI("Library location: %s", libLocation);
|
||||
|
||||
while(libBase == 0) {
|
||||
libBase = get_libBase(libName);
|
||||
}
|
||||
LOGI("Base address: %p", (void*)libBase);
|
||||
|
||||
// Hook resource endpoint
|
||||
void *resourceHook = lookup_symbol(libLocation, "_ZNK9UrlConfig8resourceENS_8Resource4TypeE"); // UrlConfig::resource(UrlConfig::Resource::Type)const
|
||||
if (DobbyHook(resourceHook, (void *)urlConfigResource, (void **)&urlConfigResourceHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked UrlConfig::resource.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Failed to hook UrlConfig::resource.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
// Hook scene creator
|
||||
void *sceneHook = lookup_symbol(libLocation, "_ZN17SceneLayerManager16createSceneLayerEP18BaseSceneLayerInfo"); //_DWORD __fastcall SceneLayerManager::createSceneLayer(SceneLayerManager *__hidden this, BaseSceneLayerInfo *)
|
||||
if (DobbyHook(sceneHook, (void *)sceneLayerManagerCreateSceneLayer, (void **)&sceneLayerManagerCreateSceneLayerOld) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked SceneLayerManager::createSceneLayer.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Failed to hook SceneLayerManager::createSceneLayer.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
// Speed up downloads
|
||||
void *maxDlHook = lookup_symbol(libLocation, "_ZN5http212Http2Session19setMaxConnectionNumEi"); //_DWORD __fastcall http2::Http2Session::setMaxConnectionNum(http2::Http2Session *__hidden this, int)
|
||||
if (DobbyHook(maxDlHook, (void *)http2SessionSetMaxConnectionNum, (void **)&http2SessionSetMaxConnectionNumOld) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked http2::Http2Session::setMaxConnectionNum.");
|
||||
}
|
||||
else {
|
||||
LOGW("Failed to hook http2::Http2Session::setMaxConnectionNum.");
|
||||
}
|
||||
|
||||
|
||||
//openMessageBoxPtr = lookup_symbol(libLocation, "_ZN10MessageBox4openEPKcS1_S1_RKSt8functionIFvPN7cocos2d3RefEEEb");
|
||||
//LOGI("Set openMessageBox ptr to %p", openMessageBoxPtr);
|
||||
|
||||
// For debugging
|
||||
//DobbyHook(lookup_symbol(libLocation, "_ZN5http212Http2Session6setURIERKSs"), (void *)setUriDebug, (void **)&setUriDebugOld); - crashes arm32 now.
|
||||
|
||||
|
||||
// Hooks
|
||||
void *cocos2dnodeSetPosition = lookup_symbol(libLocation, "_ZN7cocos2d4Node11setPositionERKNS_4Vec2E");
|
||||
// cocos2d::Node::setPosition(cocos2d::Vec2 const&)
|
||||
if (cocos2dnodeSetPosition != nullptr) {
|
||||
LOGD("Found cocos2d::Node::setPosition at %p.", (void *)cocos2dnodeSetPosition);
|
||||
if (DobbyHook(cocos2dnodeSetPosition, (void *)setPositionNew, (void **)&setPositionHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked cocos2d::Node::setPosition.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Node::setPosition.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Node::setPosition.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void *cocos2dlineLength = lookup_symbol(libLocation, "_ZN7cocos2d5Label15setMaxLineWidthEf");
|
||||
// cocos2d::Label::setMaxLineWidth(float)
|
||||
if (cocos2dlineLength != nullptr) {
|
||||
LOGD("Found cocos2d::Label::setMaxLineWidth at %p.", (void *)cocos2dlineLength);
|
||||
if (DobbyHook(cocos2dlineLength, (void *)setMaxLineWidthNew, (void **)&setMaxLineWidthHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked cocos2d::Label::setMaxLineWidth.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::setMaxLineWidth.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::setMaxLineWidth.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void *cocos2dsetDimensions = lookup_symbol(libLocation, "_ZN7cocos2d5Label13setDimensionsEff");
|
||||
//_DWORD __fastcall cocos2d::Label::setDimensions(cocos2d::Label *__hidden this, float, float)
|
||||
if (cocos2dsetDimensions != nullptr) {
|
||||
LOGD("Found cocos2d::Label::setDimensions at %p.", (void *)cocos2dsetDimensions);
|
||||
if (DobbyHook(cocos2dsetDimensions, (void *)setDimensionsNew, (void **)&setDimensionsHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked cocos2d::Label::setDimensions.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::setDimensions.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::setDimensions.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
// For moving live2d subtitles
|
||||
void *lbGetViewPosition = lookup_symbol(libLocation, "_ZN9LbUtility15getViewPositionEff");
|
||||
//_DWORD __fastcall LbUtility::getViewPosition(LbUtility *__hidden this, float, float)
|
||||
if (lbGetViewPosition != nullptr) {
|
||||
LOGD("Found LbUtility::getViewPosition at %p.", (void *)lbGetViewPosition);
|
||||
if (DobbyHook(lbGetViewPosition, (void *)lbGetViewPositionNew, (void **)&lbGetViewPositionHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked LbUtility::getViewPosition.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook LbUtility::getViewPosition.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook LbUtility::getViewPosition.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
// Change font
|
||||
void *cocosCreateLabelPtr = lookup_symbol(libLocation, "_ZN7cocos2d5Label13createWithTTFERKSsS2_fRKNS_4SizeENS_14TextHAlignmentENS_14TextVAlignmentE");
|
||||
|
||||
if (cocosCreateLabelPtr != nullptr) {
|
||||
LOGD("Found cocos2d::Label::createWithTTF at %p.", (void *)cocosCreateLabel);
|
||||
if (DobbyHook(cocosCreateLabelPtr, (void*) cocosCreateLabel, (void **)& cocosCreateLabelHooked) == RS_SUCCESS) {
|
||||
LOGI("Successfully hooked cocos2d::Label::createWithTTF.");
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::createWithTTF.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
initialization_error("Unable to hook cocos2d::Label::createWithTTF.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
// Find key functions, TODO: Tidy up into 1 nice loop
|
||||
|
||||
void *storyMessageUnitTextStart = lookup_symbol(libLocation, "_ZN16StoryMessageUnit9textStartENS_11TextPosType13TextPosType__E");
|
||||
// StoryMessageUnit::textStart(StoryMessageUnit::TextPosType::TextPosType__)
|
||||
if (storyMessageUnitTextStart == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryMessageUnit::textStart.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
storyMessageUnitStartOffset = reinterpret_cast<uintptr_t>(storyMessageUnitTextStart);
|
||||
|
||||
void *storyMessageUnitCreateMessageArea = lookup_symbol(libLocation, "_ZN16StoryMessageUnit17createMessageAreaENS_11TextPosType13TextPosType__E");
|
||||
// StoryMessageUnit::createMessageArea(StoryMessageUnit::TextPosType::TextPosType__)
|
||||
if (storyMessageUnitCreateMessageArea == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryMessageUnit::createMessageArea.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
storyMessageUnitCreateMessageAreaOffset = reinterpret_cast<uintptr_t>(storyMessageUnitCreateMessageArea);
|
||||
|
||||
void *storyLogUnitAddMessage = lookup_symbol(libLocation, "_ZN12StoryLogUnit10addMessageENS_11MessageType13MessageType__ERKSs");
|
||||
|
||||
if (storyLogUnitAddMessage == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryLogUnit::addMessage.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
storyLogUnitAddMessageOffset = reinterpret_cast<uintptr_t>(storyLogUnitAddMessage);
|
||||
|
||||
void *storyLogUnitAddNarrationOffsetPtr = lookup_symbol(libLocation, "_ZN12StoryLogUnit19addNarrationMessageERKSs");
|
||||
|
||||
if (storyLogUnitAddNarrationOffsetPtr == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryLogUnit::addNarrationMessage.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
storyLogUnitAddNarrationOffset = reinterpret_cast<uintptr_t>(storyLogUnitAddNarrationOffsetPtr);
|
||||
|
||||
void *storyCharaUnitonTextHome = lookup_symbol(libLocation, "_ZN14StoryCharaUnit10onTextHomeESt10shared_ptrI16StoryTurnCommandEb");
|
||||
// StoryCharaUnit::onTextHome(std::shared_ptr<StoryTurnCommand>, bool)
|
||||
|
||||
if (storyCharaUnitonTextHome == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryCharaUnit::onTextHome.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
storyCharaUnitonTextHomeOffset = reinterpret_cast<uintptr_t>(storyCharaUnitonTextHome);
|
||||
|
||||
void *initLabelCWO = lookup_symbol(libLocation, "_ZN9LbUtility27initLabelCenterWidthOutlineEPN7cocos2d4NodeERPNS0_5LabelEPKcfNS0_4Vec2EiNS0_4SizeEiNS0_7Color4BEiSA_");
|
||||
// LbUtility::initLabelCenterWidthOutline(cocos2d::Node *, cocos2d::Label *&, char const*, float, cocos2d::Vec2, int, cocos2d::Size, int, cocos2d::Color4B, int, cocos2d::Color4B)
|
||||
|
||||
if (initLabelCWO == nullptr) {
|
||||
initialization_error("Unable to find a pointer for LbUtility::initLabelCenterWidthOutline.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
initCenterWidthOutline = reinterpret_cast<uintptr_t>(initLabelCWO);
|
||||
|
||||
void* storyNarrationUnitCreateLabelPtr = lookup_symbol(libLocation, "_ZN18StoryNarrationUnit11createLabelEv");
|
||||
|
||||
if (storyNarrationUnitCreateLabelPtr == nullptr) {
|
||||
initialization_error("Unable to find a pointer for StoryNarrationUnit::createLabel.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
storyNarrationUnitCreateLabelOffset = reinterpret_cast<uintptr_t>(storyNarrationUnitCreateLabelPtr);
|
||||
|
||||
// Cocos functions
|
||||
void *directorPtr = lookup_symbol(libLocation, "_ZN7cocos2d8Director11getInstanceEv");
|
||||
if (directorPtr == nullptr) {
|
||||
initialization_error("Unable to find a pointer for cocos2d::Director::getInstance()");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
getDirector = (director_type) directorPtr;
|
||||
|
||||
void* getWinSizePtr = lookup_symbol(libLocation, "_ZNK7cocos2d8Director10getWinSizeEv");
|
||||
if (getWinSizePtr == nullptr) {
|
||||
initialization_error("Unable to find a pointer for cocos2d::Director::getWinSize()");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
getWinSize = (get_win_size_type) getWinSizePtr;
|
||||
|
||||
void* getVisibleOriginPtr = lookup_symbol(libLocation, "_ZNK7cocos2d8Director16getVisibleOriginEv");
|
||||
if (getVisibleOriginPtr == nullptr) {
|
||||
initialization_error("Unable to find a pointer for cocos2d::Director::getVisibleOrigin()");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
getVisibleOrigin = (get_visible_origin_type) getVisibleOriginPtr;
|
||||
|
||||
|
||||
|
||||
LOGI("Exiting hook thread.");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
void hook_main() {
|
||||
|
||||
}
|
||||
|
||||
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
LOGI("Starting MagiaHook.");
|
||||
|
||||
gJvm = vm; // cache the JavaVM pointer
|
||||
Dl_info dlInfo;
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/16302771/9665729
|
||||
// Cache ClassLoader object due to threading bug
|
||||
auto randomClass = env->FindClass("org/cocos2dx/lib/Cocos2dxHelper");
|
||||
jclass classClass = env->GetObjectClass(randomClass);
|
||||
auto classLoaderClass = env->FindClass("java/lang/ClassLoader");
|
||||
auto getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader",
|
||||
"()Ljava/lang/ClassLoader;");
|
||||
gClassLoader = env->NewGlobalRef(env->CallObjectMethod(randomClass, getClassLoaderMethod));
|
||||
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass",
|
||||
"(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
|
||||
|
||||
if (dladdr((const void*) hook_main, &dlInfo))
|
||||
{
|
||||
//fs::path ilso = fs::path(dlInfo.dli_fname).remove_filename(); ndk 22+ required
|
||||
//ilso /= "il2cpp.so"; ndk 22+ required
|
||||
hook_loop_args* args = new hook_loop_args;
|
||||
auto ilso = (std::string) dirname((char *)dlInfo.dli_fname);
|
||||
|
||||
ilso += "/";
|
||||
ilso += libName;
|
||||
|
||||
//if (fs::exists(ilso)) { ndk 22+ required
|
||||
if (!file_exists(ilso)) {
|
||||
// Fix for some devices
|
||||
auto this_ilso = get_libFoldername(hookName);
|
||||
if (this_ilso.empty()) {
|
||||
LOGE("Failed to locate shared library %s. Checked: %s", libName, ilso.c_str());
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
auto ilso2 = this_ilso.substr(0, this_ilso.length() - strlen(hookName) - 1);
|
||||
ilso2 += libName;
|
||||
if (!file_exists(ilso2)) {
|
||||
LOGE("Failed to load shared library %s. Checked: %s", libName, ilso2.c_str());
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
args->libso = ilso2;
|
||||
}
|
||||
else {
|
||||
args->libso = ilso;
|
||||
}
|
||||
pthread_t ptid;
|
||||
if (pthread_create(&ptid, NULL, &hook_loop, args) != 0) {
|
||||
LOGE("Hooking thread failed to start.");
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
}
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
#include "Utils.h"
|
||||
#include <jni.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdint>
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
uintptr_t get_libBase(const char* libName) {
|
||||
FILE *fp;
|
||||
uintptr_t addr = 0;
|
||||
char filename[32], buffer[1024];
|
||||
snprintf(filename, sizeof(filename), "/proc/%d/maps", getpid());
|
||||
fp = fopen(filename, "rt");
|
||||
if (fp != NULL) {
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (strstr(buffer, libName)) {
|
||||
addr = (uintptr_t) strtoul(buffer, NULL, 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
std::string get_libFoldername(const char* libName) {
|
||||
FILE *fp;
|
||||
uintptr_t addr = 0;
|
||||
char filename[32], buffer[1024];
|
||||
snprintf(filename, sizeof(filename), "/proc/%d/maps", getpid());
|
||||
fp = fopen(filename, "rt");
|
||||
if (fp != NULL) {
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (strstr(buffer, libName)) {
|
||||
std::string delimiter = "/";
|
||||
std::string strBuffer = buffer;
|
||||
std::string token = strBuffer.substr(strBuffer.find(delimiter), std::string::npos);
|
||||
return token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//uintptr_t getRealOffset(const char* libName, uintptr_t address) {
|
||||
//if (libBase == 0) {
|
||||
//libBase = get_libBase(libName);
|
||||
//}
|
||||
//return (libBase + address);
|
||||
//}
|
||||
|
||||
void* lookup_symbol(const char* path, const char* symbolname)
|
||||
{
|
||||
void *imagehandle = dlopen(path, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (imagehandle != NULL){
|
||||
void * sym = dlsym(imagehandle, symbolname);
|
||||
if (sym != NULL){
|
||||
return sym;
|
||||
}
|
||||
else{
|
||||
LOGI("(lookup_symbol) dlsym didn't work\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
LOGI("(lookup_symbol) dlerror: %s\n",dlerror());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool file_exists (const std::string& name) {
|
||||
struct stat buffer;
|
||||
return (stat (name.c_str(), &buffer) == 0);
|
||||
}
|
||||
|
||||
std::string getJNISignature() {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getJNISignature(bool) {
|
||||
return "Z";
|
||||
}
|
||||
|
||||
std::string getJNISignature(char) {
|
||||
return "C";
|
||||
}
|
||||
|
||||
std::string getJNISignature(short) {
|
||||
return "S";
|
||||
}
|
||||
|
||||
std::string getJNISignature(int) {
|
||||
return "I";
|
||||
}
|
||||
|
||||
std::string getJNISignature(long) {
|
||||
return "J";
|
||||
}
|
||||
|
||||
std::string getJNISignature(float) {
|
||||
return "F";
|
||||
}
|
||||
|
||||
std::string getJNISignature(double) {
|
||||
return "D";
|
||||
}
|
||||
|
||||
std::string getJNISignature(const char*) {
|
||||
return "Ljava/lang/String;";
|
||||
}
|
||||
|
||||
std::string getJNISignature(const std::string&) {
|
||||
return "Ljava/lang/String;";
|
||||
}
|
||||
|
||||
JNIEnv* getEnv(JavaVM* gJvm) {
|
||||
JNIEnv *env;
|
||||
int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
if(status < 0) {
|
||||
status = gJvm->AttachCurrentThread(&env, NULL);
|
||||
if(status < 0) {
|
||||
LOGW("Null JNIEnv obtained!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
jclass findClass(JNIEnv* env, jobject gClassLoader, jmethodID gFindClassMethod, const char* name) {
|
||||
return static_cast<jclass>(env->CallObjectMethod(gClassLoader, gFindClassMethod, env->NewStringUTF(name)));
|
||||
}
|
||||
|
||||
std::string longlong_to_string( unsigned long long value ){
|
||||
std::ostringstream os;
|
||||
os << value;
|
||||
return os.str();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <jni.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdint>
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
#if DEBUG
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "MagiaHook", __VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...) do {} while(false)
|
||||
#endif
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MagiaHook", __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "MagiaHook", __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "MagiaHook", __VA_ARGS__)
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
uintptr_t get_libBase(const char* libName);
|
||||
|
||||
std::string get_libFoldername(const char* libName);
|
||||
|
||||
void* lookup_symbol(const char* path, const char* symbolname);
|
||||
|
||||
bool file_exists (const std::string& name);
|
||||
|
||||
std::string getJNISignature();
|
||||
std::string getJNISignature(bool);
|
||||
std::string getJNISignature(char);
|
||||
std::string getJNISignature(short);
|
||||
std::string getJNISignature(int);
|
||||
std::string getJNISignature(long);
|
||||
std::string getJNISignature(float);
|
||||
std::string getJNISignature(double);
|
||||
std::string getJNISignature(const char*);
|
||||
std::string getJNISignature(const std::string&);
|
||||
|
||||
template <typename T>
|
||||
std::string getJNISignature(T x) {
|
||||
// This template should never be instantiated
|
||||
static_assert(sizeof(x) == 0, "Unsupported argument type");
|
||||
return "";
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
std::string getJNISignature(T x, Ts... xs) {
|
||||
return getJNISignature(x) + getJNISignature(xs...);
|
||||
}
|
||||
|
||||
|
||||
JNIEnv* getEnv(JavaVM* gJvm);
|
||||
jclass findClass(JNIEnv* env, jobject gClassLoader, jmethodID gFindClassMethod, const char* name);
|
||||
|
||||
// https://stackoverflow.com/a/26221725/9665729
|
||||
template<typename ... Args>
|
||||
std::string string_format( const std::string& format, Args ... args )
|
||||
{
|
||||
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
|
||||
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
|
||||
std::unique_ptr<char[]> buf( new char[ size ] );
|
||||
snprintf( buf.get(), size, format.c_str(), args ... );
|
||||
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
std::string longlong_to_string( unsigned long long value );
|
||||
#endif
|
|
@ -0,0 +1,85 @@
|
|||
enum BaseSceneLayerType {
|
||||
DebugMenuSceneLayer,
|
||||
CameraSceneLayer,
|
||||
WebSceneLayer,
|
||||
StartupSceneLayer,
|
||||
PrologueSceneLayer,
|
||||
AnotherQuestSceneLayer,
|
||||
TopSceneLayer,
|
||||
EventStoryRaidSceneLayer,
|
||||
EventBranchSceneLayer,
|
||||
EventSingleRaidSceneLayer,
|
||||
EventDungeonSceneLayer,
|
||||
EventRaidSceneLayer,
|
||||
QuestBattleSceneLayer,
|
||||
QuestUnitTestSceneLayer,
|
||||
EvolutionSceneLayer,
|
||||
MemoriaSceneLayer,
|
||||
GachaSceneLayer,
|
||||
StorySceneLayer,
|
||||
StoryViewerSceneLayer,
|
||||
Live2dViewerSceneLayer,
|
||||
MovieSceneLayer,
|
||||
DownloadSceneLayer,
|
||||
DebugSelectURLSceneLayer,
|
||||
QuestStoredDataSceneLayer,
|
||||
InputTextSceneLayer,
|
||||
LoadingSceneLayer,
|
||||
ErrorSceneLayer,
|
||||
NetworkErrorSceneLayer,
|
||||
TapSceneLayer,
|
||||
EmotionBoardSceneLayer,
|
||||
BaseSceneLayerTypeMaxValue
|
||||
};
|
||||
|
||||
char const* BaseSceneLayerTypeStrings[] {
|
||||
"DebugMenuSceneLayer",
|
||||
"CameraSceneLayer",
|
||||
"WebSceneLayer",
|
||||
"StartupSceneLayer",
|
||||
"PrologueSceneLayer",
|
||||
"AnotherQuestSceneLayer",
|
||||
"TopSceneLayer",
|
||||
"EventStoryRaidSceneLayer",
|
||||
"EventBranchSceneLayer",
|
||||
"EventSingleRaidSceneLayer",
|
||||
"EventDungeonSceneLayer",
|
||||
"EventRaidSceneLayer",
|
||||
"QuestBattleSceneLayer",
|
||||
"QuestUnitTestSceneLayer",
|
||||
"EvolutionSceneLayer",
|
||||
"MemoriaSceneLayer",
|
||||
"GachaSceneLayer",
|
||||
"StorySceneLayer",
|
||||
"StoryViewerSceneLayer",
|
||||
"Live2dViewerSceneLayer",
|
||||
"MovieSceneLayer",
|
||||
"DownloadSceneLayer",
|
||||
"DebugSelectURLSceneLayer",
|
||||
"QuestStoredDataSceneLayer",
|
||||
"InputTextSceneLayer",
|
||||
"LoadingSceneLayer",
|
||||
"ErrorSceneLayer",
|
||||
"NetworkErrorSceneLayer",
|
||||
"TapSceneLayer",
|
||||
"EmotionBoardSceneLayer"
|
||||
};
|
||||
|
||||
#if defined(__arm__)
|
||||
struct BaseSceneLayerInfo {
|
||||
char unk[24];
|
||||
BaseSceneLayerType layerType;
|
||||
};
|
||||
#elif defined(__aarch64__)
|
||||
struct BaseSceneLayerInfo {
|
||||
char unk[36];
|
||||
BaseSceneLayerType layerType;
|
||||
};
|
||||
#endif
|
||||
|
||||
enum UrlConfigResourceType {
|
||||
BaseUrl,
|
||||
TrunkUrl,
|
||||
ScenarioUrl,
|
||||
UrlConfigResourceTypeMaxValue
|
||||
};
|
|
@ -0,0 +1,93 @@
|
|||
#include <jni.h>
|
||||
#include "../Utils.h"
|
||||
#include "../Config.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "MagiaRest.h"
|
||||
|
||||
const char* restClient = "io/kamihama/magianative/RestClient";
|
||||
using json = nlohmann::json;
|
||||
|
||||
MagiaRest::MagiaRest(JavaVM* gJvm) {
|
||||
LOGD("Setting up MagiaRest.");
|
||||
env = getEnv(gJvm);
|
||||
klass = env->FindClass(restClient);
|
||||
jmethodID clientCtor = env->GetMethodID(klass, "<init>", "()V");
|
||||
magiaRestObj = env->NewObject(klass, clientCtor);
|
||||
LOGD("Finished setting up MagiaRest.");
|
||||
}
|
||||
|
||||
int MagiaRest::Endpoint() {
|
||||
const char* callHandshake = "GetEndpoint";
|
||||
std::string signature = "(I)Ljava/lang/String;";
|
||||
jmethodID messageid = env->GetMethodID(klass, callHandshake, signature.c_str());
|
||||
|
||||
LOGD("Calling GetEndpoint via JNI.");
|
||||
endpointJString = (jstring)env->CallObjectMethod(magiaRestObj, messageid, MT_VERSION);
|
||||
endpointChar = env->GetStringUTFChars(endpointJString, 0);
|
||||
|
||||
if (strcmp(endpointChar, "") == 0) {
|
||||
LOGW("Null response returned from endpoint, an error has occurred, or Kamihama is down.");
|
||||
return MAGIAREST_EMPTY;
|
||||
}
|
||||
LOGD("Successfully retrieved Endpoint JSON.");
|
||||
|
||||
if (json::accept(endpointChar)) {
|
||||
endpointValid = true;
|
||||
endpointJson = json::parse(endpointChar);
|
||||
|
||||
if (endpointJson["status"] != 200) {
|
||||
LOGW("Non-success result returned.");
|
||||
return MAGIAREST_ERROR;
|
||||
}
|
||||
}
|
||||
return endpointValid ? MAGIAREST_SUCCESS : MAGIAREST_EMPTY;
|
||||
}
|
||||
|
||||
size_t MagiaRest::EndpointStringLength() {
|
||||
if (endpointChar == NULL) {
|
||||
return MAGIAREST_EMPTY;
|
||||
}
|
||||
else {
|
||||
auto size = std::strlen(endpointChar);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
std::string MagiaRest::GetEndpointUrl() {
|
||||
if (endpointJson != NULL && endpointJson.contains("response") && endpointJson["response"].contains("endpoint")) {
|
||||
return endpointJson["response"]["endpoint"];
|
||||
}
|
||||
LOGW("No endpoint URL found in JSON response.");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string MagiaRest::GetEndpointError() {
|
||||
if (endpointJson != NULL && endpointJson.contains("message")) {
|
||||
return endpointJson["message"];
|
||||
}
|
||||
LOGW("No message found in JSON response.");
|
||||
return "";
|
||||
}
|
||||
int MagiaRest::GetEndpointVersion() {
|
||||
if (endpointJson != NULL && endpointJson.contains("response") && endpointJson["response"].contains("version")) {
|
||||
return (int)endpointJson["response"]["version"];
|
||||
}
|
||||
LOGW("No version number found in JSON response.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MagiaRest::GetMaxThreads() {
|
||||
if (endpointJson != NULL && endpointJson.contains("response") && endpointJson["response"].contains("max_threads")) {
|
||||
return (int)endpointJson["response"]["max_threads"];
|
||||
}
|
||||
LOGW("No version number found in JSON response.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MagiaRest::~MagiaRest() {
|
||||
if (endpointJString != NULL || endpointChar != NULL) {
|
||||
env->ReleaseStringUTFChars(endpointJString, endpointChar);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef MAGIAREST_H
|
||||
#define MAGIAREST_H
|
||||
#include <jni.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
#define MAGIAREST_EMPTY 0
|
||||
#define MAGIAREST_SUCCESS 1
|
||||
#define MAGIAREST_ERROR 2
|
||||
|
||||
// Rest class using JNI
|
||||
class MagiaRest {
|
||||
public:
|
||||
MagiaRest(JavaVM* gJvm);
|
||||
|
||||
int Endpoint();
|
||||
|
||||
size_t EndpointStringLength();
|
||||
|
||||
std::string GetEndpointUrl();
|
||||
|
||||
std::string GetEndpointError();
|
||||
int GetEndpointVersion();
|
||||
|
||||
int GetMaxThreads();
|
||||
|
||||
~MagiaRest();
|
||||
private:
|
||||
JNIEnv* env;
|
||||
jclass klass;
|
||||
jobject magiaRestObj;
|
||||
|
||||
jstring endpointJString = NULL;
|
||||
const char *endpointChar = NULL;
|
||||
|
||||
bool endpointValid = false;
|
||||
json endpointJson = NULL;
|
||||
|
||||
};
|
||||
|
||||
#endif
|