This commit is contained in:
Tungstend 2024-01-11 15:35:04 +08:00
commit ea8b7f080f
8 changed files with 87 additions and 85 deletions

View File

@ -144,6 +144,7 @@ public class ModListPage extends FCLCommonPage implements ManageUI.VersionLoadab
add();
}
if (v == checkUpdateButton) {
checkUpdateButton.setFocusable(false);
checkUpdates();
}
if (v == refreshButton) {
@ -339,6 +340,7 @@ public class ModListPage extends FCLCommonPage implements ManageUI.VersionLoadab
return null;
})
.whenComplete(Schedulers.androidUIThread(), (result, exception) -> {
checkUpdateButton.setFocusable(true);
if (exception != null || result == null) {
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setCancelable(false);

View File

@ -130,7 +130,7 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
FCLTextView scaleFactorText = findViewById(R.id.scale_factor_text);
scaleFactorSeekbar.addProgressListener();
scaleFactorText.stringProperty().bind(Bindings.createStringBinding(() -> scaleFactorSeekbar.getProgress() + " %", scaleFactorSeekbar.percentProgressProperty()));
scaleFactorText.stringProperty().bind(Bindings.createStringBinding(() -> (int) (lastVersionSetting.getScaleFactor() * 100) + " %", scaleFactorSeekbar.percentProgressProperty()));
// add spinner data
ArrayList<Integer> javaVersionDataList = new ArrayList<>();

View File

@ -41,7 +41,9 @@ public class SettingUI extends FCLMultiPageUI implements TabLayout.OnTabSelected
@Override
public void onStart() {
super.onStart();
((VersionSettingPage) pageManager.getPageById(SettingPageManager.PAGE_ID_SETTING_GAME)).loadVersion(Profiles.getSelectedProfile(), null);
if (pageManager != null) {
((VersionSettingPage) pageManager.getPageById(SettingPageManager.PAGE_ID_SETTING_GAME)).loadVersion(Profiles.getSelectedProfile(), null);
}
}
@Override

View File

@ -29,6 +29,8 @@ import java.util.Map.Entry;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.tungsten.fclauncher.utils.FCLPath;
import com.tungsten.fclcore.R;
import com.tungsten.fclcore.util.Pair;
public final class NetworkUtils {
@ -84,8 +86,20 @@ public final class NetworkUtils {
return result;
}
private static boolean endsWithDomainSuffix(String host, String domainSuffix) {
return host.endsWith(domainSuffix.toLowerCase());
}
public static URLConnection createConnection(URL url) throws IOException {
URLConnection connection = url.openConnection();
String host = url.getHost().toLowerCase();
if (endsWithDomainSuffix(host, "d.pcs.baidu.com") || endsWithDomainSuffix(host, "baidupcs.com")) {
// Docs: https://alist.nn.ci/zh/guide/drivers/baidu.html
connection.setRequestProperty("User-Agent", "pan.baidu.com");
} else {
// Default
connection.setRequestProperty("User-Agent", "FCL/" + FCLPath.CONTEXT.getString(R.string.app_version));
}
connection.setUseCaches(false);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_version">auto_change_by_gradle</string>
</resources>

View File

@ -77,7 +77,6 @@ public class FCLBridge implements Serializable {
private boolean surfaceDestroyed;
private Handler handler;
private Thread thread;
private Thread fclLogThread;
static {
System.loadLibrary("xhook");
@ -123,15 +122,24 @@ public class FCLBridge implements Serializable {
this.handler = new Handler();
this.callback = callback;
this.surface = surface;
fclLogThread = new Thread(() -> {
receiveLog("invoke redirectStdio");
int errorCode = redirectStdio(getLogPath());
if (errorCode != 0) {
receiveLog("Can't exec redirectStdio! Error code: " + errorCode);
}
});
fclLogThread.setName("FCLLogThread");
fclLogThread.start();
setFCLBridge(this);
receiveLog("invoke redirectStdio");
int errorCode = redirectStdio(getLogPath());
if (errorCode != 0) {
receiveLog("Can't exec redirectStdio! Error code: " + errorCode);
}
receiveLog("invoke setLogPipeReady");
// set graphic output and event pipe
if (surface != null) {
handleWindow();
}
receiveLog("invoke setEventPipe");
setEventPipe();
// start
if (thread != null) {
thread.start();
}
}
public void pushEventMouseButton(int button, boolean press) {
@ -273,25 +281,6 @@ public class FCLBridge implements Serializable {
this.logPath = logPath;
}
public void setLogPipeReady() {
receiveLog("invoke setLogPipeReady");
handler.post(() -> {
receiveLog("invoke setFCLBridge");
setFCLBridge(this);
// set graphic output and event pipe
if (surface != null) {
handleWindow();
}
receiveLog("invoke setEventPipe");
setEventPipe();
// start
if (thread != null) {
thread.start();
}
});
}
public void receiveLog(String log) {
if (callback != null) {
callback.onLog(log);

View File

@ -12,6 +12,7 @@
#include <string.h>
#include <fcl_internal.h>
#include <sys/mman.h>
#include <pthread.h>
#define FULL_VERSION "1.8.0-internal"
#define DOT_VERSION "1.8"
@ -30,79 +31,69 @@ typedef void (*android_update_LD_LIBRARY_PATH_t)(const char*);
static volatile jobject exitTrap_bridge;
static volatile jmethodID exitTrap_method;
static JavaVM *exitTrap_jvm;
static bool logPipeReady = false;
static volatile jobject log_bridge;
static volatile jmethodID log_method;
static JavaVM *log_pipe_jvm;
jstring CStr2Jstring(JNIEnv *env, const char *buffer);
static int fclFd[2];
static pthread_t logger;
jstring CStr2Jstring(JNIEnv *env, const char *buffer) {
jsize len = strlen(buffer);
jclass strClass = (*env)->FindClass(env, "java/lang/String");
jstring encoding = (*env)->NewStringUTF(env, "UTF-8");
jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) buffer);
return (jstring) (*env)->NewObject(env, strClass, ctorID, bytes, encoding);
}
void fclLog(const char *buffer) {
if (logPipeReady) {
JNIEnv *env;
(*log_pipe_jvm)->AttachCurrentThread(log_pipe_jvm, &env, NULL);
(*env)->CallVoidMethod(env, log_bridge, log_method, CStr2Jstring(env, buffer));
(*log_pipe_jvm)->DetachCurrentThread(log_pipe_jvm);
}
}
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jobject jobject, jstring path) {
int fclFd[2];
if (pipe(fclFd) < 0) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to create log pipe!");
return 1;
}
if (dup2(fclFd[1], STDOUT_FILENO) != STDOUT_FILENO && dup2(fclFd[1], STDERR_FILENO) != STDERR_FILENO) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "failed to redirect stdio!");
return 2;
}
static void *logger_thread() {
JNIEnv *env;
JavaVM *vm = fcl->android_jvm;
(*vm)->AttachCurrentThread(vm, &env, NULL);
char buffer[1024];
jclass bridge = (*env) -> FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge");
jmethodID method_setLogPipeReady = (*env) -> GetMethodID(env, bridge, "setLogPipeReady", "()V");
if (!method_setLogPipeReady) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find setLogPipeReady method!");
return 3;
}
fcl->logFile = fdopen(fclFd[1], "a");
FCL_INTERNAL_LOG("Log pipe ready.");
(*env) -> CallVoidMethod(env, jobject, method_setLogPipeReady);
log_method = (*env) -> GetMethodID(env, bridge, "receiveLog", "(Ljava/lang/String;)V");
if (!log_method) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find receive method!");
return 4;
}
log_bridge = (*env)->NewGlobalRef(env, jobject);
(*env)->GetJavaVM(env, &log_pipe_jvm);
logPipeReady = true;
ssize_t _s;
jstring str;
while (1) {
memset(buffer, '\0', sizeof(buffer));
ssize_t _s = read(fclFd[0], buffer, sizeof(buffer) - 1);
_s = read(fclFd[0], buffer, sizeof(buffer) - 1);
if (_s < 0) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to read log!");
close(fclFd[0]);
close(fclFd[1]);
return 5;
(*vm)->DetachCurrentThread(vm);
return NULL;
} else {
buffer[_s] = '\0';
}
if (buffer[0] == '\0')
continue;
else {
(*env)->CallVoidMethod(env, jobject, log_method, CStr2Jstring(env, buffer));
str = (*env)->NewStringUTF(env, buffer);
(*env)->CallVoidMethod(env, fcl->object_FCLBridge, log_method, str);
(*env)->DeleteLocalRef(env, str);
}
}
}
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jobject jobject, jstring path) {
setvbuf(stdout, 0, _IOLBF, 0);
setvbuf(stderr, 0, _IONBF, 0);
if (pipe(fclFd) < 0) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to create log pipe!");
return 1;
}
if (dup2(fclFd[1], STDOUT_FILENO) != STDOUT_FILENO &&
dup2(fclFd[1], STDERR_FILENO) != STDERR_FILENO) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "failed to redirect stdio!");
return 2;
}
jclass bridge = (*env) -> FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge");
log_method = (*env) -> GetMethodID(env, bridge, "receiveLog", "(Ljava/lang/String;)V");
if (!log_method) {
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find receive method!");
return 4;
}
fcl->logFile = fdopen(fclFd[1], "a");
FCL_INTERNAL_LOG("Log pipe ready.");
(*env)->GetJavaVM(env, &log_pipe_jvm);
int result = pthread_create(&logger, 0, logger_thread, 0);
if (result != 0){
return 5;
}
pthread_detach(logger);
return 0;
}
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_chdir(JNIEnv* env, jobject jobject, jstring path) {
char const* dir = (*env)->GetStringUTFChars(env, path, 0);

View File

@ -14,7 +14,7 @@
"text": "支持 NeoForge\n支持 Jar 文件执行\n更好的模组下载\n修复一些错误详情见 Github若无法下载或下载速度过慢请使用网盘下载。"
}
],
"netdiskUrl": "https://www.123pan.com/s/AVu2jv-oB80A.html",
"netdiskUrl": "https://alist.8mi.tech/FCL",
"url": "https://github.com/FCL-Team/FoldCraftLauncher/releases/download/1.1.2/FCL-release-1.1.2.apk"
}
]