Skip to content

Commit

Permalink
GuiTask Reconstruction
Browse files Browse the repository at this point in the history
  • Loading branch information
isHarryh committed Nov 19, 2023
1 parent 305243e commit cb06cba
Show file tree
Hide file tree
Showing 16 changed files with 1,385 additions and 980 deletions.
720 changes: 320 additions & 400 deletions assets/UI/Homepage.fxml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions core/src/cn/harryh/arkpets/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ public final class Const {
public static final String startupTarget = "ArkPets.exe";
public static final String startUpScript = "ArkPetsStartupService.vbs";

// Changeable constants
public static boolean isHttpsTrustAll = false;
public static boolean isUpdateAvailable = false;
public static boolean isDatasetIncompatible = false;
public static boolean isNewcomer = false;


/** Paths presets definition class.
*/
Expand Down
2 changes: 1 addition & 1 deletion core/src/cn/harryh/arkpets/transitions/Transition.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ public final void setToStart() {

@Override
public String toString() {
return getClass().getName() + " [" + start + ", " + end + ']';
return getClass().getSimpleName() + " [" + start + ", " + end + ']';
}
}
7 changes: 4 additions & 3 deletions desktop/src/cn/harryh/arkpets/ArkHomeFX.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Objects;

import static cn.harryh.arkpets.Const.*;
import cn.harryh.arkpets.utils.PopupUtils.*;


/** ArkPets Homepage the JavaFX app.
Expand Down Expand Up @@ -54,10 +55,10 @@ public void start(Stage stage) throws Exception {
Thread.sleep(100);
startArkPets();
Thread.sleep(1200);
if (ctrl.isNewcomer && !ctrl.trayExitHandbook.hasShown()) {
if (isNewcomer && !ctrl.trayExitHandbook.hasShown()) {
// Show handbook.
PopupUtils.Handbook b = ctrl.trayExitHandbook;
ctrl.popNotice(b.getIcon(), b.getTitle(), b.getHeader(), b.getContent(), null).show();
Handbook b = ctrl.trayExitHandbook;
DialogUtil.createCommonDialog(ctrl.root, b.getIcon(), b.getTitle(), b.getHeader(), b.getContent(), null).show();
b.setShown();
}
} catch (InterruptedException ignored) {
Expand Down
615 changes: 52 additions & 563 deletions desktop/src/cn/harryh/arkpets/controllers/Homepage.java

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions desktop/src/cn/harryh/arkpets/guitasks/CheckAppUpdateTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/** Copyright (c) 2022-2023, Harry Huang
* At GPL-3.0 License
*/
package cn.harryh.arkpets.guitasks;

import cn.harryh.arkpets.Const;
import cn.harryh.arkpets.utils.IOUtils;
import cn.harryh.arkpets.utils.Logger;
import cn.harryh.arkpets.utils.Version;
import com.alibaba.fastjson.JSONObject;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.nio.file.Files;
import java.util.Objects;

import static cn.harryh.arkpets.Const.PathConfig;
import static cn.harryh.arkpets.Const.appVersion;
import static cn.harryh.arkpets.utils.PopupUtils.*;


public class CheckAppUpdateTask extends FetchRemoteTask {
public CheckAppUpdateTask(StackPane root, GuiTaskStyle style, String sourceStr) {
super(root,
style,
PathConfig.urlApi + "?type=queryVersion&cliVer=" + appVersion + "&source=" + sourceStr,
PathConfig.tempQueryVersionCachePath,
Const.isHttpsTrustAll);

try {
Files.createDirectories(new File(PathConfig.tempDirPath).toPath());
} catch (Exception e) {
Logger.warn("Task", "Failed to create temp dir.");
throw new RuntimeException(e);
}
}

@Override
protected String getHeader() {
return "正在下载软件版本信息...";
}

@Override
protected void onSucceeded(boolean result) {
// When finished downloading the latest app ver-info:
try {
// Try to parse the latest app ver-info
JSONObject queryVersionResult = Objects.requireNonNull(JSONObject.parseObject(IOUtils.FileUtil.readByte(new File(PathConfig.tempQueryVersionCachePath))));
// TODO show in-test version
if (queryVersionResult.getString("msg").equals("success")) {
// If the response status is "success":
int[] stableVersionResult = queryVersionResult.getJSONObject("data").getObject("stableVersion", int[].class);
Version stableVersion = new Version(stableVersionResult);
if (appVersion.lessThan(stableVersion)) {
// On update is available:
Const.isUpdateAvailable = true;
if (style != GuiTaskStyle.HIDDEN)
DialogUtil.createCommonDialog(root,
IconUtil.getIcon(IconUtil.ICON_INFO_ALT, COLOR_INFO),
"检查软件更新",
"检测到软件有新的版本!",
"当前版本 " + appVersion + " 可更新到 " + stableVersion + "\n请访问ArkPets官网或GitHub下载新的安装包。",
null).show();
} else {
// On up-to-dated:
Const.isUpdateAvailable = false;
if (style != GuiTaskStyle.HIDDEN)
DialogUtil.createCommonDialog(root,
IconUtil.getIcon(IconUtil.ICON_SUCCESS_ALT, COLOR_SUCCESS),
"检查软件更新",
"尚未发现新的正式版本。",
"当前版本 " + appVersion + " 已是最新",
null).show();
}
Logger.info("Checker", "Application version check finished, newest: " + stableVersion);
} else {
// On API failed:
Logger.warn("Checker", "Application version check failed (api failed)");
if (style != GuiTaskStyle.HIDDEN)
DialogUtil.createCommonDialog(root,
IconUtil.getIcon(IconUtil.ICON_DANGER_ALT, COLOR_DANGER),
"检查软件更新",
"服务器返回了无效的消息。",
"可能是兼容性问题或服务器不可用。\n您可以访问ArkPets官网或GitHub仓库以查看是否有新版本。",
null).show();
}
} catch (Exception e) {
// On parsing failed:
Logger.error("Checker", "Application version check failed unexpectedly, details see below.", e);
if (style != GuiTaskStyle.HIDDEN)
DialogUtil.createErrorDialog(root, e).show();
}
}
}
110 changes: 110 additions & 0 deletions desktop/src/cn/harryh/arkpets/guitasks/CheckModelUpdateTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/** Copyright (c) 2022-2023, Harry Huang
* At GPL-3.0 License
*/
package cn.harryh.arkpets.guitasks;

import cn.harryh.arkpets.Const;
import cn.harryh.arkpets.utils.IOUtils;
import cn.harryh.arkpets.utils.Logger;
import com.alibaba.fastjson.JSONObject;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import static cn.harryh.arkpets.Const.PathConfig;
import static cn.harryh.arkpets.Const.charsetDefault;
import static cn.harryh.arkpets.utils.PopupUtils.*;


public class CheckModelUpdateTask extends FetchGitHubRemoteTask {
public CheckModelUpdateTask(StackPane root, GuiTaskStyle style) {
super(
root,
style,
PathConfig.urlModelsData,
PathConfig.tempDirPath + PathConfig.fileModelsDataPath,
Const.isHttpsTrustAll,
false);

try {
Files.createDirectories(new File(PathConfig.tempDirPath).toPath());
} catch (Exception e) {
Logger.warn("Task", "Failed to create temp dir.");
throw new RuntimeException(e);
}
}

@Override
protected String getHeader() {
return "正在下载模型版本信息...";
}

@Override
protected void onSucceeded(boolean result) {
// When finished downloading the remote repo models info:
try {
String versionDescription;
try {
// Try to parse the remote repo models info
JSONObject newModelsDataset = JSONObject.parseObject(IOUtils.FileUtil.readString(new File(PathConfig.tempDirPath + PathConfig.fileModelsDataPath), charsetDefault));
versionDescription = newModelsDataset.getString("gameDataVersionDescription");
} catch (Exception e) {
// When failed to parse the remote repo models info
versionDescription = "unknown";
Logger.error("Checker", "Unable to parse remote model repo version, details see below.", e);
DialogUtil.createCommonDialog(
root,
IconUtil.getIcon(IconUtil.ICON_WARNING_ALT, COLOR_WARNING),
"检查模型更新",
"无法判断模型仓库版本。",
"因发生错误,无法解析远程模型仓库的版本。",
null).show();
}
// When finished parsing the remote models info:
// TODO do judgment more precisely
// Compare the remote models info and the local models info by their MD5

if (IOUtils.FileUtil.getMD5(new File(PathConfig.fileModelsDataPath)).equals(IOUtils.FileUtil.getMD5(new File(PathConfig.tempDirPath + PathConfig.fileModelsDataPath)))) {
Logger.info("Checker", "Model repo version check finished (up-to-dated)");
DialogUtil.createCommonDialog(
root,
IconUtil.getIcon(IconUtil.ICON_SUCCESS_ALT, COLOR_SUCCESS),
"检查模型更新", "当前模型版本与远程仓库一致。",
"无需进行模型仓库更新。",
"提示:远程模型仓库的版本不一定和游戏官方是同步更新的。\n模型仓库版本描述:\n" + versionDescription).show();
} else {
// If the result of comparison is "not the same"
String oldVersionDescription;
try {
// Try to parse the local repo models info
JSONObject oldModelsDataset = JSONObject.parseObject(IOUtils.FileUtil.readString(new File(PathConfig.fileModelsDataPath), charsetDefault));
oldVersionDescription = oldModelsDataset.getString("gameDataVersionDescription");
} catch (Exception e) {
// When failed to parse the remote local models info
oldVersionDescription = "unknown";
Logger.error("Checker", "Unable to parse local model repo version, details see below.", e);
DialogUtil.createCommonDialog(
root,
IconUtil.getIcon(IconUtil.ICON_WARNING_ALT, COLOR_WARNING),
"检查模型更新",
"无法判断模型仓库版本。",
"因发生错误,无法解析本地模型仓库的版本。",
null).show();
}
DialogUtil.createCommonDialog(
root,
IconUtil.getIcon(IconUtil.ICON_INFO_ALT, COLOR_INFO),
"检查模型更新", "本地模型版本与远程仓库有差异。",
"可以重新下载模型,即可更新模型版本。",
"远程模型仓库版本描述:\n" + versionDescription + "\n\n本地模型仓库版本描述:\n" + oldVersionDescription).show();
Logger.info("Checker", "Model repo version check finished (not up-to-dated)");
}
} catch (IOException e) {
Logger.error("Checker", "Model repo version check failed unexpectedly, details see below.", e);
if (style != GuiTaskStyle.HIDDEN)
DialogUtil.createErrorDialog(root, e).show();
}
}
}
38 changes: 38 additions & 0 deletions desktop/src/cn/harryh/arkpets/guitasks/DownloadModelsTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/** Copyright (c) 2022-2023, Harry Huang
* At GPL-3.0 License
*/
package cn.harryh.arkpets.guitasks;

import cn.harryh.arkpets.Const;
import cn.harryh.arkpets.utils.Logger;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.nio.file.Files;

import static cn.harryh.arkpets.Const.PathConfig;


public class DownloadModelsTask extends FetchGitHubRemoteTask {
public DownloadModelsTask(StackPane root, GuiTaskStyle style) {
super(
root,
style,
PathConfig.urlModelsZip,
PathConfig.tempModelsZipCachePath,
Const.isHttpsTrustAll,
true);

try {
Files.createDirectories(new File(PathConfig.tempDirPath).toPath());
} catch (Exception e) {
Logger.warn("Task", "Failed to create temp dir.");
throw new RuntimeException(e);
}
}

@Override
protected String getHeader() {
return "正在下载模型资源文件...";
}
}
99 changes: 99 additions & 0 deletions desktop/src/cn/harryh/arkpets/guitasks/FetchGitHubRemoteTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/** Copyright (c) 2022-2023, Harry Huang
* At GPL-3.0 License
*/
package cn.harryh.arkpets.guitasks;

import cn.harryh.arkpets.utils.Logger;
import cn.harryh.arkpets.utils.NetUtils;
import cn.harryh.arkpets.utils.PopupUtils;
import javafx.concurrent.Task;
import javafx.scene.layout.StackPane;

import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;

import static cn.harryh.arkpets.Const.httpBufferSizeDefault;
import static cn.harryh.arkpets.Const.httpTimeoutDefault;


abstract public class FetchGitHubRemoteTask extends GuiTask {
protected final String remotePathSuffix;
protected final String destPath;
protected final boolean isArchive;
protected final boolean isHttpsTrustAll;

public FetchGitHubRemoteTask(StackPane root, GuiTaskStyle style, String remotePathSuffix, String destPath, boolean isHttpsTrustAll, boolean isArchive) {
super(root, style);
this.remotePathSuffix = remotePathSuffix;
this.destPath = destPath;
this.isArchive = isArchive;
this.isHttpsTrustAll = isHttpsTrustAll;
}

@Override
protected Task<Boolean> getTask() {
return new Task<>() {
@Override
protected Boolean call() throws Exception {
this.updateMessage("正在选择最佳线路");
Logger.info("Network", "Testing real delay");
NetUtils.GitHubSource[] sources = NetUtils.GitHubSource.sortByOverallAvailability(NetUtils.ghSources);
NetUtils.GitHubSource source = sources[0];

Logger.info("Network", "Selected the most available source \"" + source.tag + "\" (" + source.delay + "ms)");
String remotePath = (isArchive ? source.archivePreUrl : source.rawPreUrl) + remotePathSuffix;

Logger.info("Network", "Fetching " + remotePath + " to " + destPath);
this.updateMessage("正在尝试与 " + source.tag + " 建立连接");

BufferedInputStream bis = null;
BufferedOutputStream bos = null;
File file = new File(destPath);
URL urlFile = new URL(remotePath);
HttpsURLConnection connection = NetUtils.ConnectionUtil.createHttpsConnection(urlFile, httpTimeoutDefault, httpTimeoutDefault, isHttpsTrustAll);

try {
bis = new BufferedInputStream(connection.getInputStream(), httpBufferSizeDefault);
bos = new BufferedOutputStream(Files.newOutputStream(file.toPath()), httpBufferSizeDefault);
int len = httpBufferSizeDefault;
long sum = 0;
long max = connection.getContentLengthLong();
byte[] bytes = new byte[len];
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
sum += len;
this.updateMessage("当前已下载:" + NetUtils.getFormattedSizeString(sum));
this.updateProgress(sum, max);
if (this.isCancelled()) {
this.updateMessage("下载进程已被取消");
break;
}
}
this.updateProgress(max, max);
bos.flush();
Logger.info("Network", "Fetched to " + destPath + " , size: " + sum);
} finally {
try {
connection.getInputStream().close();
if (bis != null)
bis.close();
if (bos != null)
bos.close();
} catch (Exception ignored) {
}
}
return this.isDone() && !this.isCancelled();
}
};
}

@Override
protected void onFailed(Throwable e) {
if (style != GuiTaskStyle.HIDDEN)
PopupUtils.DialogUtil.createErrorDialog(root, e).show();
}
}
Loading

0 comments on commit cb06cba

Please sign in to comment.