Compare commits
2 Commits
3c723bd443
...
17f08c5f06
| Author | SHA1 | Date | |
|---|---|---|---|
| 17f08c5f06 | |||
| 051f0b3ca1 |
1
.idea/.gitignore
generated
vendored
1
.idea/.gitignore
generated
vendored
@ -2,3 +2,4 @@
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
/developer-tools.xml
|
||||
/CopilotChatHistory.xml
|
||||
|
||||
@ -29,17 +29,16 @@ public class APISetting {
|
||||
private DynamicList splashes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2022-12-01 15:59
|
||||
* @since 2022-12-01 15:59
|
||||
*/
|
||||
@Data
|
||||
public static class DynamicList {
|
||||
|
||||
/** 激活的标语 */
|
||||
private String active;
|
||||
/** 常驻的资源 */
|
||||
private String permanent;
|
||||
|
||||
/** 标语列表 */
|
||||
/** 资源列表 */
|
||||
private List<String> list;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ package cn.forevermc.launcher.service;
|
||||
import cn.forevermc.launcher.bean.APISetting;
|
||||
import cn.forevermc.launcher.util.Resources;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.imyeyu.fx.task.RunAsync;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import com.imyeyu.inject.annotation.InvokeForInjected;
|
||||
@ -15,6 +15,7 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hc.client5.http.fluent.Request;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -49,7 +50,8 @@ public class APISettingService {
|
||||
for (APISetting.Key key : APISetting.Key.values()) {
|
||||
reqArgs.put(key, null);
|
||||
}
|
||||
Map<APISetting.Key, String> data = TimiRequest.<Map<APISetting.Key, String>>wrap(Request.post(API).bodyString(gson.toJson(reqArgs), ContentType.APPLICATION_JSON)).result();
|
||||
Request request = Request.post(API).connectTimeout(Timeout.ofSeconds(8)).bodyString(gson.toJson(reqArgs), ContentType.APPLICATION_JSON);
|
||||
Map<APISetting.Key, String> data = TimiRequest.wrap(request).resultAs(new TypeToken<>() {});
|
||||
setting.setBg(gson.fromJson(data.get(APISetting.Key.FMC_BG), APISetting.DynamicList.class));
|
||||
setting.setBgm(gson.fromJson(data.get(APISetting.Key.FMC_BGM), APISetting.DynamicList.class));
|
||||
setting.setSplashes(gson.fromJson(data.get(APISetting.Key.FMC_SPLASHES), APISetting.DynamicList.class));
|
||||
|
||||
@ -108,7 +108,7 @@ public class BGMService implements OS.FileSystem {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String active = setting.getBgm().getActive();
|
||||
String active = setting.getBgm().getPermanent();
|
||||
if (TimiJava.isNotEmpty(active)) {
|
||||
if (cacheList.containsKey(active)) {
|
||||
map.put(active, new Media(cacheList.get(active).toURI().toURL().toExternalForm()));
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
package cn.forevermc.launcher.service;
|
||||
|
||||
import cn.forevermc.launcher.bean.APISetting;
|
||||
import cn.forevermc.launcher.util.Resources;
|
||||
import com.google.gson.Gson;
|
||||
import com.imyeyu.fx.task.RunAsync;
|
||||
import com.imyeyu.fx.listener.NewValueListener;
|
||||
import com.imyeyu.fx.task.RunAsyncDaemon;
|
||||
import com.imyeyu.fx.utils.BgImage;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import com.imyeyu.inject.annotation.InvokeForInjected;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.CallbackArg;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.network.FileRequest;
|
||||
import com.imyeyu.utils.OS;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@ -18,15 +20,13 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Background;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hc.client5.http.fluent.Request;
|
||||
|
||||
import javax.naming.NoPermissionException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态背景地址获取服务
|
||||
@ -47,82 +47,85 @@ public class BGService implements OS.FileSystem {
|
||||
private Gson gson;
|
||||
|
||||
private final ObjectProperty<Background> value;
|
||||
private final Map<String, File> cacheList = new HashMap<>();
|
||||
|
||||
public BGService() {
|
||||
value = new SimpleObjectProperty<>();
|
||||
setValue(IO.resourceToInputStream(getClass(), "assets/img/bg.png"));
|
||||
}
|
||||
|
||||
@InvokeForInjected
|
||||
private void injected() {
|
||||
try {
|
||||
{
|
||||
File[] files = IO.dir(CACHE_PATH).listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
cacheList.put(files[i].getName(), files[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TimiJava.isNotEmpty(cacheList)) {
|
||||
List<File> files = new ArrayList<>(cacheList.values());
|
||||
Collections.shuffle(files);
|
||||
setValue(IO.getInputStream(files.get(0)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new RunAsyncDaemon<InputStream>(3000) {
|
||||
|
||||
// 从缓存随机抽取
|
||||
apiSettingService.valueProperty().addListener((obs, o, setting) -> {
|
||||
if (setting == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String active = setting.getBg().getActive();
|
||||
if (TimiJava.isNotEmpty(active)) {
|
||||
if (cacheList.containsKey(active)) {
|
||||
setValue(IO.getInputStream(cacheList.get(active)));
|
||||
} else {
|
||||
fetch(active, active, this::setValue);
|
||||
}
|
||||
} else {
|
||||
List<String> list = setting.getBg().getList();
|
||||
if (TimiJava.isNotEmpty(list)){
|
||||
Collections.shuffle(list);
|
||||
String shuffleMongoId = list.get(0);
|
||||
if (cacheList.containsKey(shuffleMongoId)) {
|
||||
setValue(IO.getInputStream(cacheList.get(shuffleMongoId)));
|
||||
} else {
|
||||
fetch(shuffleMongoId, shuffleMongoId, this::setValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
private final Object lock = new Object();
|
||||
|
||||
private void setValue(InputStream stream) {
|
||||
value.set(new BgImage(new Image(stream, -1, -1, false, false)).cover().build());
|
||||
}
|
||||
|
||||
private void fetch(String mongoId, String fileName, CallbackArg<InputStream> callback) {
|
||||
new RunAsync<InputStream>() {
|
||||
private APISetting.DynamicList bgList = null;
|
||||
|
||||
@Override
|
||||
protected InputStream call() throws Exception {
|
||||
File file = IO.file(CACHE_PATH + SEP + fileName);
|
||||
FileRequest.get(Resources.TIMI_SERVER_API + "/attachment/read/" + mongoId).toFile(file);
|
||||
cacheList.put(mongoId, file);
|
||||
return IO.getInputStream(file);
|
||||
if (apiSettingService.getValue() == null) {
|
||||
apiSettingService.valueProperty().addListener((NewValueListener<APISetting>) apiSetting -> {
|
||||
bgList = apiSetting.getBg();
|
||||
synchronized (lock) {
|
||||
lock.notifyAll();
|
||||
}
|
||||
});
|
||||
// 等待配置
|
||||
log.info("waiting apiSetting");
|
||||
synchronized (lock) {
|
||||
lock.wait(2000);
|
||||
}
|
||||
TimiException.required(bgList, "not found bgList");
|
||||
} else {
|
||||
bgList = apiSettingService.getValue().getBg();
|
||||
}
|
||||
List<File> fileList = IO.listFile(IO.dir(CACHE_PATH));
|
||||
for (File file : fileList) {
|
||||
if (!bgList.getList().contains(file.getName())) {
|
||||
// 删除过时的背景
|
||||
log.info("delete bg {}", file.getName());
|
||||
IO.destroy(file);
|
||||
}
|
||||
}
|
||||
for (String item : bgList.getList()) {
|
||||
IO.file(IO.fitPath(CACHE_PATH) + item, newFile -> {
|
||||
// 下载新的背景
|
||||
try {
|
||||
log.info("download new bg {}", item);
|
||||
FileRequest.get(Resources.TIMI_SERVER_API + "/attachment/download/" + item).toFile(newFile);
|
||||
} catch (IOException | NoPermissionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
String result = bgList.getPermanent(); // 常驻背景
|
||||
if (TimiJava.isEmpty(result)) {
|
||||
// 随机背景
|
||||
Collections.shuffle(bgList.getList());
|
||||
result = bgList.getList().getFirst();
|
||||
}
|
||||
return IO.getInputStream(IO.fitPath(CACHE_PATH) + result);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(InputStream stream) {
|
||||
callback.handler(stream);
|
||||
if (!isTimeout) {
|
||||
setValue(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Throwable e) {
|
||||
log.error("BGService", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTimeout() {
|
||||
// 内置背景
|
||||
setValue(IO.resourceToInputStream(getClass(), "assets/img/bg.png"));
|
||||
}
|
||||
|
||||
private void setValue(InputStream stream) {
|
||||
value.set(new BgImage(new Image(stream, -1, -1, false, false)).cover().build());
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@ -137,11 +137,11 @@ public class FMCLoginService implements OS.FileSystem {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
{
|
||||
String data = TimiRequest.<String>get(SETTING_API + "/FMC_LOGIN_FABRIC").result();
|
||||
String data = TimiRequest.get(SETTING_API + "/FMC_LOGIN_FABRIC").resultAs(String.class);
|
||||
loginModMapTemp = gson.fromJson(data, new TypeToken<Map<String, String>>() {}.getType());
|
||||
}
|
||||
{
|
||||
List<FabricAPI> data = TimiRequest.<List<FabricAPI>>get(MIRROR_API + "/FabricAPI").result();
|
||||
List<FabricAPI> data = TimiRequest.get(MIRROR_API + "/FabricAPI").resultAs(new TypeToken<>() {});
|
||||
fabricAPIMapTemp = data.stream().collect(Collectors.toMap(FabricAPI::getMinecraftVer, item -> item));
|
||||
}
|
||||
return null;
|
||||
@ -214,19 +214,17 @@ public class FMCLoginService implements OS.FileSystem {
|
||||
TokenRequest request = new TokenRequest();
|
||||
request.setUser(user);
|
||||
request.setPassword(password);
|
||||
return TimiRequest.<TokenResponse>wrap(Request.post(LOGIN_TOKEN_API).bodyString(gson.toJson(request), ContentType.APPLICATION_JSON)).result();
|
||||
return TimiRequest.wrap(Request.post(LOGIN_TOKEN_API).bodyString(gson.toJson(request), ContentType.APPLICATION_JSON)).resultAs(TokenResponse.class);
|
||||
}
|
||||
|
||||
public List<MinecraftPlayer> listBoundPlayer(String token) throws Exception {
|
||||
return TimiRequest.<List<MinecraftPlayer>>wrap(Request.get(LIST_PLAYER_API).addHeader("Token", token)).result();
|
||||
return TimiRequest.wrap(Request.get(LIST_PLAYER_API).addHeader("Token", token)).resultAs(new TypeToken<>() {});
|
||||
}
|
||||
|
||||
public TokenResponse doLogin(MinecraftPlayer player, String token) throws Exception {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("playerId", player.id);
|
||||
return TimiRequest.<TokenResponse>wrap(Request.get(LIST_PLAYER_API)
|
||||
.addHeader("Token", token)
|
||||
.bodyString(gson.toJson(map), ContentType.APPLICATION_JSON)).result();
|
||||
return TimiRequest.wrap(Request.get(LIST_PLAYER_API).addHeader("Token", token).bodyString(gson.toJson(map), ContentType.APPLICATION_JSON)).resultAs(TokenResponse.class);
|
||||
}
|
||||
|
||||
private boolean hasMod(Game game, String name) {
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
package cn.forevermc.launcher.service;
|
||||
|
||||
import cn.forevermc.launcher.bean.APISetting;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import com.imyeyu.inject.annotation.InvokeForInjected;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@ -39,12 +39,12 @@ public class SplashService {
|
||||
return;
|
||||
}
|
||||
APISetting.DynamicList splashes = setting.getSplashes();
|
||||
if (TimiJava.isNotEmpty(splashes.getActive())) {
|
||||
value.set(splashes.getActive());
|
||||
if (TimiJava.isNotEmpty(splashes.getPermanent())) {
|
||||
value.set(splashes.getPermanent());
|
||||
return;
|
||||
}
|
||||
Collections.shuffle(splashes.getList());
|
||||
value.set(splashes.getList().get(0));
|
||||
value.set(splashes.getList().getFirst());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,10 @@ import cn.forevermc.launcher.bean.Page;
|
||||
import cn.forevermc.launcher.service.BGService;
|
||||
import cn.forevermc.launcher.service.PageService;
|
||||
import cn.forevermc.launcher.util.Resources;
|
||||
import com.imyeyu.fx.utils.BgImage;
|
||||
import com.imyeyu.inject.annotation.Component;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import com.imyeyu.inject.annotation.InvokeForInjected;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.event.EventHandler;
|
||||
@ -13,10 +17,6 @@ import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import com.imyeyu.fx.utils.BgImage;
|
||||
import com.imyeyu.inject.annotation.Component;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import com.imyeyu.inject.annotation.InvokeForInjected;
|
||||
|
||||
/**
|
||||
* 根布局
|
||||
@ -92,7 +92,7 @@ public class RootLayout extends StackPane {
|
||||
return bgService.getValue();
|
||||
}
|
||||
return legacyBG;
|
||||
}, launchGame.newUIProperty(), pageService.activatedPageProperty()));
|
||||
}, launchGame.newUIProperty(), pageService.activatedPageProperty(), bgService.valueProperty()));
|
||||
BooleanBinding withOutBlur = pageService.activatedPageProperty().isEqualTo(Page.MENU).or(launchGame.newUIProperty().not());
|
||||
bg.effectProperty().bind(Bindings.when(withOutBlur).then((GaussianBlur) null).otherwise(new GaussianBlur(16)));
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.forevermc.launcher.view.pages;
|
||||
import cn.forevermc.launcher.ForeverMC;
|
||||
import cn.forevermc.launcher.bean.ComponentSize;
|
||||
import cn.forevermc.launcher.bean.Game;
|
||||
import cn.forevermc.launcher.service.BGService;
|
||||
import cn.forevermc.launcher.util.Resources;
|
||||
import cn.forevermc.launcher.view.components.AbstractPane;
|
||||
import cn.forevermc.launcher.view.components.LoginTypeSelector;
|
||||
@ -10,6 +11,11 @@ import cn.forevermc.launcher.view.components.control.MCButton;
|
||||
import cn.forevermc.launcher.view.components.control.MCLabel;
|
||||
import cn.forevermc.launcher.view.components.control.MCPasswordField;
|
||||
import cn.forevermc.launcher.view.components.control.MCTextField;
|
||||
import com.imyeyu.fx.icon.TimiFXIcon;
|
||||
import com.imyeyu.fx.ui.TimiFXUI;
|
||||
import com.imyeyu.fx.utils.BgFill;
|
||||
import com.imyeyu.fx.utils.Row;
|
||||
import com.imyeyu.inject.annotation.Inject;
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
@ -17,18 +23,12 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.VPos;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
import com.imyeyu.fx.icon.TimiFXIcon;
|
||||
import com.imyeyu.fx.ui.TimiFXUI;
|
||||
import com.imyeyu.fx.utils.BgFill;
|
||||
import com.imyeyu.fx.utils.Row;
|
||||
|
||||
/**
|
||||
* 菜单面板
|
||||
@ -38,6 +38,9 @@ import com.imyeyu.fx.utils.Row;
|
||||
*/
|
||||
public abstract class MenuPane extends AbstractPane {
|
||||
|
||||
@Inject
|
||||
private BGService bgService;
|
||||
|
||||
protected final Canvas splashCanvas;
|
||||
protected final MCLabel launchGameLabel;
|
||||
protected final MCButton fmcAccount, fmcServer, launchGameSelect, launch, option, exit, langSelect, about;
|
||||
@ -181,12 +184,12 @@ public abstract class MenuPane extends AbstractPane {
|
||||
welcomeFT.setNode(transitionPane);
|
||||
welcomeFT.setFromValue(1);
|
||||
welcomeFT.setToValue(0);
|
||||
welcomeFT.setDelay(Duration.millis(2000));
|
||||
welcomeFT.setDelay(Duration.millis(1000));
|
||||
welcomeFT.setOnFinished(e -> {
|
||||
root.getChildren().remove(transitionPane);
|
||||
isFirstShow = false;
|
||||
});
|
||||
welcomeFT.play();
|
||||
bgService.valueProperty().addListener((obs, o, n) -> welcomeFT.play());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user