forked from chinosk/gkms-local
add plugin init progress
This commit is contained in:
parent
c28e05e271
commit
c810a27ba2
|
@ -47,6 +47,18 @@
|
|||
#include "../../GakumasLocalify/Log.h"
|
||||
#include "../../GakumasLocalify/Misc.hpp"
|
||||
|
||||
class UnityResolveProgress final {
|
||||
public:
|
||||
struct Progress {
|
||||
long current = 0;
|
||||
long total = 1;
|
||||
};
|
||||
|
||||
static bool startInit;
|
||||
static Progress assembliesProgress;
|
||||
static Progress classProgress;
|
||||
};
|
||||
|
||||
class UnityResolve final {
|
||||
public:
|
||||
struct Assembly;
|
||||
|
@ -284,9 +296,11 @@ public:
|
|||
hmodule_ = hmodule;
|
||||
|
||||
if (mode_ == Mode::Il2Cpp) {
|
||||
UnityResolveProgress::startInit = true;
|
||||
pDomain = Invoke<void*>("il2cpp_domain_get");
|
||||
Invoke<void*>("il2cpp_thread_attach", pDomain);
|
||||
ForeachAssembly();
|
||||
UnityResolveProgress::startInit = false;
|
||||
}
|
||||
else {
|
||||
pDomain = Invoke<void*>("mono_get_root_domain");
|
||||
|
@ -561,7 +575,11 @@ private:
|
|||
if (mode_ == Mode::Il2Cpp) {
|
||||
size_t nrofassemblies = 0;
|
||||
const auto assemblies = Invoke<void**>("il2cpp_domain_get_assemblies", pDomain, &nrofassemblies);
|
||||
|
||||
UnityResolveProgress::assembliesProgress.total = nrofassemblies;
|
||||
|
||||
for (auto i = 0; i < nrofassemblies; i++) {
|
||||
UnityResolveProgress::assembliesProgress.current = i + 1;
|
||||
const auto ptr = assemblies[i];
|
||||
if (ptr == nullptr) continue;
|
||||
auto assembly = new Assembly{ .address = ptr };
|
||||
|
@ -594,7 +612,9 @@ private:
|
|||
// 遍历类
|
||||
if (mode_ == Mode::Il2Cpp) {
|
||||
const auto count = Invoke<int>("il2cpp_image_get_class_count", image);
|
||||
UnityResolveProgress::classProgress.total = count;
|
||||
for (auto i = 0; i < count; i++) {
|
||||
UnityResolveProgress::classProgress.current = i + 1;
|
||||
const auto pClass = Invoke<void*>("il2cpp_image_get_class", image, i);
|
||||
if (pClass == nullptr) continue;
|
||||
const auto pAClass = new Class();
|
||||
|
|
|
@ -15,6 +15,10 @@ JavaVM* g_javaVM = nullptr;
|
|||
jclass g_gakumasHookMainClass = nullptr;
|
||||
jmethodID showToastMethodId = nullptr;
|
||||
|
||||
bool UnityResolveProgress::startInit = false;
|
||||
UnityResolveProgress::Progress UnityResolveProgress::assembliesProgress{};
|
||||
UnityResolveProgress::Progress UnityResolveProgress::classProgress{};
|
||||
|
||||
namespace
|
||||
{
|
||||
class AndroidHookInstaller : public GakumasLocal::HookInstaller
|
||||
|
@ -114,8 +118,37 @@ Java_io_github_chinosk_gakumas_localify_GakumasHookMain_loadConfig(JNIEnv *env,
|
|||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_io_github_chinosk_gakumas_localify_GakumasHookMain_pluginCallbackLooper(JNIEnv *env,
|
||||
jclass clazz) {
|
||||
GakumasLocal::Log::ToastLoop(env, clazz);
|
||||
|
||||
if (UnityResolveProgress::startInit) {
|
||||
return 9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_github_chinosk_gakumas_localify_models_NativeInitProgress_pluginInitProgressLooper(
|
||||
JNIEnv *env, jclass clazz, jobject progress) {
|
||||
|
||||
// jclass progressClass = env->GetObjectClass(progress);
|
||||
|
||||
static jfieldID startInitFieldID = env->GetStaticFieldID(clazz, "startInit", "Z");
|
||||
|
||||
static jmethodID setAssembliesProgressDataMethodID = env->GetMethodID(clazz, "setAssembliesProgressData", "(JJ)V");
|
||||
static jmethodID setClassProgressDataMethodID = env->GetMethodID(clazz, "setClassProgressData", "(JJ)V");
|
||||
|
||||
// jboolean startInit = env->GetStaticBooleanField(clazz, startInitFieldID);
|
||||
|
||||
env->SetStaticBooleanField(clazz, startInitFieldID, UnityResolveProgress::startInit);
|
||||
|
||||
env->CallVoidMethod(progress, setAssembliesProgressDataMethodID,
|
||||
UnityResolveProgress::assembliesProgress.current, UnityResolveProgress::assembliesProgress.total);
|
||||
env->CallVoidMethod(progress, setClassProgressDataMethodID,
|
||||
UnityResolveProgress::classProgress.current, UnityResolveProgress::classProgress.total);
|
||||
|
||||
}
|
|
@ -34,7 +34,9 @@ import java.util.Locale
|
|||
import kotlin.system.measureTimeMillis
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.FileHotUpdater
|
||||
import io.github.chinosk.gakumas.localify.mainUtils.json
|
||||
import io.github.chinosk.gakumas.localify.models.NativeInitProgress
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfig
|
||||
import io.github.chinosk.gakumas.localify.ui.game_attach.InitProgressUI
|
||||
|
||||
val TAG = "GakumasLocalify"
|
||||
|
||||
|
@ -49,6 +51,7 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||
|
||||
private var getConfigError: Exception? = null
|
||||
private var externalFilesChecked: Boolean = false
|
||||
private var gameActivity: Activity? = null
|
||||
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
// if (lpparam.packageName == "io.github.chinosk.gakumas.localify") {
|
||||
|
@ -135,6 +138,7 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||
super.beforeHookedMethod(param)
|
||||
Log.d(TAG, "onStart")
|
||||
val currActivity = param.thisObject as Activity
|
||||
gameActivity = currActivity
|
||||
if (getConfigError != null) {
|
||||
showGetConfigFailed(currActivity)
|
||||
}
|
||||
|
@ -148,6 +152,7 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
Log.d(TAG, "onResume")
|
||||
val currActivity = param.thisObject as Activity
|
||||
gameActivity = currActivity
|
||||
if (getConfigError != null) {
|
||||
showGetConfigFailed(currActivity)
|
||||
}
|
||||
|
@ -206,9 +211,30 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||
private fun startLoop() {
|
||||
GlobalScope.launch {
|
||||
val interval = 1000L / 30
|
||||
var lastFrameStartInit = NativeInitProgress.startInit
|
||||
val initProgressUI = InitProgressUI()
|
||||
|
||||
while (isActive) {
|
||||
val timeTaken = measureTimeMillis {
|
||||
pluginCallbackLooper()
|
||||
val returnValue = pluginCallbackLooper() // plugin main thread loop
|
||||
if (returnValue == 9) {
|
||||
NativeInitProgress.startInit = true
|
||||
}
|
||||
|
||||
if (NativeInitProgress.startInit) { // if init, update data
|
||||
NativeInitProgress.pluginInitProgressLooper(NativeInitProgress)
|
||||
gameActivity?.let { initProgressUI.updateData(it) }
|
||||
}
|
||||
|
||||
if ((gameActivity != null) && (lastFrameStartInit != NativeInitProgress.startInit)) { // change status
|
||||
if (NativeInitProgress.startInit) {
|
||||
initProgressUI.createView(gameActivity!!)
|
||||
}
|
||||
else {
|
||||
initProgressUI.finishLoad(gameActivity!!)
|
||||
}
|
||||
}
|
||||
lastFrameStartInit = NativeInitProgress.startInit
|
||||
}
|
||||
delay(interval - timeTaken)
|
||||
}
|
||||
|
@ -413,7 +439,7 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
external fun pluginCallbackLooper()
|
||||
external fun pluginCallbackLooper(): Int
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package io.github.chinosk.gakumas.localify.models
|
||||
|
||||
data class ProgressData(
|
||||
var current: Long = 0,
|
||||
var total: Long = 1
|
||||
)
|
||||
|
||||
object NativeInitProgress {
|
||||
var assembliesProgress = ProgressData()
|
||||
var classProgress = ProgressData()
|
||||
var startInit: Boolean = false
|
||||
|
||||
fun setAssembliesProgressData(current: Long, total: Long) {
|
||||
assembliesProgress.current = current
|
||||
assembliesProgress.total = total
|
||||
}
|
||||
|
||||
fun setClassProgressData(current: Long, total: Long) {
|
||||
classProgress.current = current
|
||||
classProgress.total = total
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
external fun pluginInitProgressLooper(progress: NativeInitProgress)
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package io.github.chinosk.gakumas.localify.ui.game_attach
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.graphics.drawable.ShapeDrawable
|
||||
import android.graphics.drawable.shapes.RectShape
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import io.github.chinosk.gakumas.localify.TAG
|
||||
import io.github.chinosk.gakumas.localify.models.NativeInitProgress
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class InitProgressUI {
|
||||
private var uiCreated = false
|
||||
private lateinit var rootView: ViewGroup
|
||||
private lateinit var container: LinearLayout
|
||||
private lateinit var assembliesProgressBar: ProgressBar
|
||||
private lateinit var classProgressBar: ProgressBar
|
||||
private lateinit var titleText: TextView
|
||||
private lateinit var assembliesProgressText: TextView
|
||||
private lateinit var classProgressText: TextView
|
||||
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun createView(context: Context) {
|
||||
if (uiCreated) return
|
||||
uiCreated = true
|
||||
val activity = context as? Activity ?: return
|
||||
rootView = activity.findViewById<ViewGroup>(android.R.id.content)
|
||||
|
||||
container = LinearLayout(context).apply {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
gravity = Gravity.TOP or Gravity.END
|
||||
marginEnd = 20
|
||||
marginStart = 20
|
||||
topMargin = 100
|
||||
}
|
||||
setBackgroundColor(Color.WHITE)
|
||||
setPadding(20, 20, 20, 20)
|
||||
}
|
||||
|
||||
// Set up the container layout
|
||||
assembliesProgressBar = ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal).apply {
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
topMargin = 20
|
||||
}
|
||||
max = 100
|
||||
}
|
||||
|
||||
// Set up the class progress bar
|
||||
classProgressBar = ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal).apply {
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
topMargin = 20
|
||||
}
|
||||
max = 100
|
||||
}
|
||||
|
||||
assembliesProgressBar.progressTintList = ColorStateList.valueOf(Color.parseColor("#FFF89400"))
|
||||
classProgressBar.progressTintList = ColorStateList.valueOf(Color.parseColor("#FFF89400"))
|
||||
|
||||
// Set up the text views
|
||||
titleText = TextView(context).apply {
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
topMargin = 20
|
||||
gravity = Gravity.CENTER_HORIZONTAL
|
||||
}
|
||||
setTextColor(Color.BLACK)
|
||||
text = "Initializing Plugins"
|
||||
textSize = 20f
|
||||
setTypeface(typeface, Typeface.BOLD)
|
||||
}
|
||||
|
||||
val textLayout = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
topMargin = 20
|
||||
}
|
||||
|
||||
assembliesProgressText = TextView(context).apply {
|
||||
layoutParams = textLayout
|
||||
setTextColor(Color.BLACK)
|
||||
}
|
||||
|
||||
classProgressText = TextView(context).apply {
|
||||
layoutParams = textLayout
|
||||
setTextColor(Color.BLACK)
|
||||
}
|
||||
|
||||
// Add container to the root view
|
||||
context.runOnUiThread {
|
||||
// Add views to the container
|
||||
container.addView(titleText)
|
||||
container.addView(assembliesProgressText)
|
||||
container.addView(assembliesProgressBar)
|
||||
container.addView(classProgressText)
|
||||
container.addView(classProgressBar)
|
||||
|
||||
rootView.addView(container)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun finishLoad(context: Activity) {
|
||||
if (!uiCreated) return
|
||||
uiCreated = false
|
||||
GlobalScope.launch {
|
||||
context.runOnUiThread {
|
||||
assembliesProgressBar.progressTintList = ColorStateList.valueOf(Color.parseColor("#FF28B463"))
|
||||
classProgressBar.progressTintList = ColorStateList.valueOf(Color.parseColor("#FF28B463"))
|
||||
titleText.text = "Finished"
|
||||
}
|
||||
delay(1500L)
|
||||
context.runOnUiThread {
|
||||
rootView.removeView(container)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeView(context: Activity) {
|
||||
if (!uiCreated) return
|
||||
uiCreated = false
|
||||
context.runOnUiThread {
|
||||
rootView.removeView(container)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun updateData(context: Activity) {
|
||||
if (!uiCreated) return
|
||||
//return
|
||||
|
||||
context.runOnUiThread {
|
||||
val assembliesProgress = NativeInitProgress.assembliesProgress
|
||||
val classProgress = NativeInitProgress.classProgress
|
||||
|
||||
assembliesProgressText.text = "${assembliesProgress.current}/${assembliesProgress.total}"
|
||||
classProgressText.text = "${classProgress.current}/${classProgress.total}"
|
||||
|
||||
assembliesProgressBar.setProgress((assembliesProgress.current * 100 / assembliesProgress.total).toInt(), true)
|
||||
classProgressBar.setProgress((classProgress.current * 100 / classProgress.total).toInt(), true)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue