reduce 'return null'

This commit is contained in:
huangyuhui
2018-02-07 21:01:09 +08:00
parent 35047477fe
commit 5607298898
25 changed files with 111 additions and 105 deletions

View File

@@ -39,6 +39,7 @@ import java.net.Proxy;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional;
public final class AccountHelper { public final class AccountHelper {
public static final AccountHelper INSTANCE = new AccountHelper(); public static final AccountHelper INSTANCE = new AccountHelper();
@@ -155,9 +156,9 @@ public final class AccountHelper {
if (profile == null) return; if (profile == null) return;
String name = profile.getName(); String name = profile.getName();
if (name == null) return; if (name == null) return;
ProfileTexture texture = account.getSkin(profile); Optional<ProfileTexture> texture = account.getSkin(profile);
if (texture == null) return; if (!texture.isPresent()) return;
String url = texture.getUrl(); String url = texture.get().getUrl();
File file = getSkinFile(name); File file = getSkinFile(name);
if (!refresh && file.exists()) if (!refresh && file.exists())
return; return;

View File

@@ -135,6 +135,11 @@ public class HMCLGameRepository extends DefaultGameRepository {
} }
} }
/**
* Create new version setting if version id has no version setting.
* @param id the version id.
* @return new version setting, null if given version does not exist.
*/
public VersionSetting createVersionSetting(String id) { public VersionSetting createVersionSetting(String id) {
if (!hasVersion(id)) if (!hasVersion(id))
return null; return null;

View File

@@ -86,9 +86,8 @@ public class HMCLModpackExportTask extends TaskResult<ZipEngine> {
}); });
Version mv = repository.getVersion(version).resolve(repository); Version mv = repository.getVersion(version).resolve(repository);
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version)); String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version))
if (gameVersion == null) .orElseThrow(() -> new IllegalStateException("Cannot parse the version of " + version));
throw new IllegalStateException("Cannot parse the version of " + version);
zip.putTextFile(Constants.GSON.toJson(mv.setJar(gameVersion)), "minecraft/pack.json"); // Making "jar" to gameVersion is to be compatible with old HMCL. zip.putTextFile(Constants.GSON.toJson(mv.setJar(gameVersion)), "minecraft/pack.json"); // Making "jar" to gameVersion is to be compatible with old HMCL.
zip.putTextFile(Constants.GSON.toJson(modpack.setGameVersion(gameVersion)), "modpack.json"); // Newer HMCL only reads 'gameVersion' field. zip.putTextFile(Constants.GSON.toJson(modpack.setGameVersion(gameVersion)), "modpack.json"); // Newer HMCL only reads 'gameVersion' field.
} }

View File

@@ -156,7 +156,7 @@ public final class LauncherHelper {
private static void checkGameState(Profile profile, VersionSetting setting, Version version, Runnable onAccept) throws InterruptedException { private static void checkGameState(Profile profile, VersionSetting setting, Version version, Runnable onAccept) throws InterruptedException {
boolean flag = false, suggest = true; boolean flag = false, suggest = true;
VersionNumber gameVersion = VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version))); VersionNumber gameVersion = VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse("Unknown"));
JavaVersion java = setting.getJavaVersion(); JavaVersion java = setting.getJavaVersion();
if (java == null) { if (java == null) {
Controllers.dialog(Main.i18n("launch.wrong_javadir"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept); Controllers.dialog(Main.i18n("launch.wrong_javadir"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept);

View File

@@ -27,6 +27,7 @@ import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.Pair;
import java.util.Map; import java.util.Map;
import java.util.Optional;
/** /**
* @author huangyuhui * @author huangyuhui
@@ -52,14 +53,19 @@ public final class Accounts {
account.getProperties().put("character", character); account.getProperties().put("character", character);
} }
public static String getCurrentCharacter(Account account) { public static boolean hasCurrentCharacter(Account account) {
return Lang.get(account.getProperties(), "character", String.class, null); return Lang.get(account.getProperties(), "character", String.class, null) != null;
} }
public static String getCurrentCharacter(Map<Object, Object> storage) { public static String getCurrentCharacter(Account account) {
Map properties = Lang.get(storage, "properties", Map.class, null); return Lang.get(account.getProperties(), "character", String.class)
if (properties == null) return null; .orElseThrow(() -> new IllegalArgumentException("Account " + account + " has not set current character."));
return Lang.get(properties, "character", String.class, null); }
public static Optional<String> getCurrentCharacter(Map<Object, Object> storage) {
Optional<Map> properties = Lang.get(storage, "properties", Map.class);
if (!properties.isPresent()) return Optional.empty();
return Lang.get(properties.get(), "character", String.class);
} }
static String getAccountId(Account account) { static String getAccountId(Account account) {

View File

@@ -126,6 +126,11 @@ public final class Profile {
return vs == null || vs.isUsesGlobal(); return vs == null || vs.isUsesGlobal();
} }
/**
* Make version use self version settings instead of the global one.
* @param id the version id.
* @return specialized version setting, null if given version does not exist.
*/
public VersionSetting specializeVersionSetting(String id) { public VersionSetting specializeVersionSetting(String id) {
VersionSetting vs = repository.getVersionSetting(id); VersionSetting vs = repository.getVersionSetting(id);
if (vs == null) if (vs == null)

View File

@@ -66,9 +66,9 @@ public class Settings {
{ {
for (Map<Object, Object> settings : SETTINGS.getAccounts()) { for (Map<Object, Object> settings : SETTINGS.getAccounts()) {
String characterName = Accounts.getCurrentCharacter(settings); Optional<String> characterName = Accounts.getCurrentCharacter(settings);
AccountFactory factory = Accounts.ACCOUNT_FACTORY.get(Lang.get(settings, "type", String.class, "")); AccountFactory factory = Accounts.ACCOUNT_FACTORY.get(Lang.get(settings, "type", String.class, ""));
if (factory == null || characterName == null) { if (factory == null || !characterName.isPresent()) {
// unrecognized account type, so remove it. // unrecognized account type, so remove it.
SETTINGS.getAccounts().remove(settings); SETTINGS.getAccounts().remove(settings);
continue; continue;

View File

@@ -488,7 +488,7 @@ public final class VersionSetting {
.setJavaArgs(getJavaArgs()) .setJavaArgs(getJavaArgs())
.setMaxMemory(getMaxMemory()) .setMaxMemory(getMaxMemory())
.setMinMemory(getMinMemory()) .setMinMemory(getMinMemory())
.setMetaspace(StringUtils.parseInt(getPermSize())) .setMetaspace(Lang.toIntOrNull(getPermSize()))
.setWidth(getWidth()) .setWidth(getWidth())
.setHeight(getHeight()) .setHeight(getHeight())
.setFullscreen(isFullscreen()) .setFullscreen(isFullscreen())

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui;
import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.concurrency.JFXUtilities;
import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.auth.MultiCharacterSelector;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
import org.jackhuang.hmcl.task.SilentException; import org.jackhuang.hmcl.task.SilentException;
@@ -47,6 +48,6 @@ public final class DialogController {
latch.await(); latch.await();
return Optional.ofNullable(res.get()).orElseThrow(SilentException::new); return Optional.ofNullable(res.get()).orElseThrow(SilentException::new);
} }
return null; return account.logIn(MultiCharacterSelector.DEFAULT);
} }
} }

View File

@@ -31,6 +31,7 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.download.InstallerWizardProvider; import org.jackhuang.hmcl.ui.download.InstallerWizardProvider;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
public class InstallerController { public class InstallerController {
@@ -85,11 +86,11 @@ public class InstallerController {
@FXML @FXML
private void onAdd() { private void onAdd() {
String gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)); Optional<String> gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version));
if (gameVersion == null) if (!gameVersion.isPresent())
Controllers.dialog("version.cannot_read"); Controllers.dialog("version.cannot_read");
else else
Controllers.getDecorator().startWizard(new InstallerWizardProvider(profile, gameVersion, version, forge, liteLoader, optiFine)); Controllers.getDecorator().startWizard(new InstallerWizardProvider(profile, gameVersion.get(), version, forge, liteLoader, optiFine));
} }
} }

View File

@@ -184,7 +184,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
List<Node> children = new LinkedList<>(); List<Node> children = new LinkedList<>();
List<Version> versions = new LinkedList<>(profile.getRepository().getVersions()); List<Version> versions = new LinkedList<>(profile.getRepository().getVersions());
for (Version version : versions) { for (Version version : versions) {
children.add(buildNode(profile, version.getId(), Lang.nonNull(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version.getId())), "Unknown"))); children.add(buildNode(profile, version.getId(), GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version.getId())).orElse("Unknown")));
} }
FXUtils.resetChildren(masonryPane, children); FXUtils.resetChildren(masonryPane, children);
} }

View File

@@ -144,8 +144,10 @@ public final class YggdrasilAccount extends Account {
} }
private void logIn1(URL url, Object input, Proxy proxy) throws AuthenticationException { private void logIn1(URL url, Object input, Proxy proxy) throws AuthenticationException {
AuthenticationResponse response = makeRequest(url, input, proxy); AuthenticationResponse response = makeRequest(url, input, proxy)
if (response == null || !clientToken.equals(response.getClientToken())) .orElseThrow(() -> new AuthenticationException("Server response empty"));
if (!clientToken.equals(response.getClientToken()))
throw new AuthenticationException("Client token changed"); throw new AuthenticationException("Client token changed");
if (response.getSelectedProfile() != null) if (response.getSelectedProfile() != null)
@@ -205,12 +207,12 @@ public final class YggdrasilAccount extends Account {
return result; return result;
} }
private AuthenticationResponse makeRequest(URL url, Object input, Proxy proxy) throws AuthenticationException { private Optional<AuthenticationResponse> makeRequest(URL url, Object input, Proxy proxy) throws AuthenticationException {
try { try {
String jsonResult = input == null ? NetworkUtils.doGet(url, proxy) : NetworkUtils.doPost(url, GSON.toJson(input), "application/json", proxy); String jsonResult = input == null ? NetworkUtils.doGet(url, proxy) : NetworkUtils.doPost(url, GSON.toJson(input), "application/json", proxy);
AuthenticationResponse response = GSON.fromJson(jsonResult, AuthenticationResponse.class); AuthenticationResponse response = GSON.fromJson(jsonResult, AuthenticationResponse.class);
if (response == null) if (response == null)
return null; return Optional.empty();
if (!StringUtils.isBlank(response.getError())) { if (!StringUtils.isBlank(response.getError())) {
if (response.getErrorMessage() != null) if (response.getErrorMessage() != null)
if (response.getErrorMessage().contains("Invalid credentials")) if (response.getErrorMessage().contains("Invalid credentials"))
@@ -222,7 +224,7 @@ public final class YggdrasilAccount extends Account {
throw new AuthenticationException(response.getError() + ": " + response.getErrorMessage()); throw new AuthenticationException(response.getError() + ": " + response.getErrorMessage());
} }
return response; return Optional.of(response);
} catch (IOException e) { } catch (IOException e) {
throw new ServerDisconnectException(e); throw new ServerDisconnectException(e);
} catch (JsonParseException e) { } catch (JsonParseException e) {
@@ -242,22 +244,22 @@ public final class YggdrasilAccount extends Account {
} }
} }
public ProfileTexture getSkin(GameProfile profile) throws IOException, JsonParseException { public Optional<ProfileTexture> getSkin(GameProfile profile) throws IOException, JsonParseException {
if (StringUtils.isBlank(userId)) if (StringUtils.isBlank(userId))
throw new IllegalStateException("Not logged in"); throw new IllegalStateException("Not logged in");
ProfileResponse response = GSON.fromJson(NetworkUtils.doGet(NetworkUtils.toURL(BASE_PROFILE + UUIDTypeAdapter.fromUUID(profile.getId()))), ProfileResponse.class); ProfileResponse response = GSON.fromJson(NetworkUtils.doGet(NetworkUtils.toURL(BASE_PROFILE + UUIDTypeAdapter.fromUUID(profile.getId()))), ProfileResponse.class);
if (response.getProperties() == null) return null; if (response.getProperties() == null) return Optional.empty();
Property textureProperty = response.getProperties().get("textures"); Property textureProperty = response.getProperties().get("textures");
if (textureProperty == null) return null; if (textureProperty == null) return Optional.empty();
TextureResponse texture; TextureResponse texture;
String json = new String(Base64.getDecoder().decode(textureProperty.getValue()), Charsets.UTF_8); String json = new String(Base64.getDecoder().decode(textureProperty.getValue()), Charsets.UTF_8);
texture = GSON.fromJson(json, TextureResponse.class); texture = GSON.fromJson(json, TextureResponse.class);
if (texture == null || texture.getTextures() == null) if (texture == null || texture.getTextures() == null)
return null; return Optional.empty();
return texture.getTextures().get(ProfileTexture.Type.SKIN); return Optional.ofNullable(texture.getTextures().get(ProfileTexture.Type.SKIN));
} }
@Override @Override

View File

@@ -27,10 +27,7 @@ import org.jackhuang.hmcl.util.NetworkUtils;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.VersionNumber; import org.jackhuang.hmcl.util.VersionNumber;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/** /**
* *
@@ -62,8 +59,8 @@ public final class ForgeVersionList extends VersionList<Void> {
versions.clear(); versions.clear();
for (Map.Entry<String, int[]> entry : root.getGameVersions().entrySet()) { for (Map.Entry<String, int[]> entry : root.getGameVersions().entrySet()) {
String gameVersion = VersionNumber.parseVersion(entry.getKey()); Optional<String> gameVersion = VersionNumber.parseVersion(entry.getKey());
if (gameVersion == null) if (!gameVersion.isPresent())
continue; continue;
for (int v : entry.getValue()) { for (int v : entry.getValue()) {
ForgeVersion version = root.getNumber().get(v); ForgeVersion version = root.getNumber().get(v);
@@ -80,7 +77,7 @@ public final class ForgeVersionList extends VersionList<Void> {
if (jar == null) if (jar == null)
continue; continue;
versions.put(gameVersion, new RemoteVersion<>( versions.put(gameVersion.get(), new RemoteVersion<>(
version.getGameVersion(), version.getVersion(), jar, null version.getGameVersion(), version.getVersion(), jar, null
)); ));
} }

View File

@@ -28,6 +28,7 @@ import org.jackhuang.hmcl.util.VersionNumber;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
/** /**
* *
@@ -55,10 +56,10 @@ public final class GameVersionList extends VersionList<GameRemoteVersionTag> {
GameRemoteVersions root = Constants.GSON.fromJson(task.getResult(), GameRemoteVersions.class); GameRemoteVersions root = Constants.GSON.fromJson(task.getResult(), GameRemoteVersions.class);
for (GameRemoteVersion remoteVersion : root.getVersions()) { for (GameRemoteVersion remoteVersion : root.getVersions()) {
String gameVersion = VersionNumber.parseVersion(remoteVersion.getGameVersion()); Optional<String> gameVersion = VersionNumber.parseVersion(remoteVersion.getGameVersion());
if (gameVersion == null) if (!gameVersion.isPresent())
continue; continue;
versions.put(gameVersion, new RemoteVersion<>( versions.put(gameVersion.get(), new RemoteVersion<>(
remoteVersion.getGameVersion(), remoteVersion.getGameVersion(),
remoteVersion.getGameVersion(), remoteVersion.getGameVersion(),
remoteVersion.getUrl(), remoteVersion.getUrl(),

View File

@@ -64,10 +64,7 @@ public final class LiteLoaderInstallTask extends TaskResult<Version> {
if (!liteLoaderVersionList.isLoaded()) if (!liteLoaderVersionList.isLoaded())
dependents.add(liteLoaderVersionList.refreshAsync(dependencyManager.getDownloadProvider()) dependents.add(liteLoaderVersionList.refreshAsync(dependencyManager.getDownloadProvider())
.then(s -> { .then(Task.of(this::doRemote)));
doRemote();
return null;
}));
else else
doRemote(); doRemote();
} }

View File

@@ -38,6 +38,7 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Optional;
/** /**
* *
@@ -67,11 +68,11 @@ public final class LiteLoaderVersionList extends VersionList<LiteLoaderRemoteVer
for (Map.Entry<String, LiteLoaderGameVersions> entry : root.getVersions().entrySet()) { for (Map.Entry<String, LiteLoaderGameVersions> entry : root.getVersions().entrySet()) {
String gameVersion = entry.getKey(); String gameVersion = entry.getKey();
LiteLoaderGameVersions liteLoader = entry.getValue(); LiteLoaderGameVersions liteLoader = entry.getValue();
String gg = VersionNumber.parseVersion(gameVersion); Optional<String> gg = VersionNumber.parseVersion(gameVersion);
if (gg == null) if (!gg.isPresent())
continue; continue;
doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false); doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false);
doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true); doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true);
} }
} }

View File

@@ -66,8 +66,8 @@ public final class OptiFineBMCLVersionList extends VersionList<Void> {
if (StringUtils.isBlank(element.getGameVersion())) if (StringUtils.isBlank(element.getGameVersion()))
continue; continue;
String gameVersion = VersionNumber.parseVersion(element.getGameVersion()); VersionNumber.parseVersion(element.getGameVersion())
versions.put(gameVersion, new RemoteVersion<>(gameVersion, version, mirror, null)); .ifPresent(gameVersion -> versions.put(gameVersion, new RemoteVersion<>(gameVersion, version, mirror, null)));
} }
} }
}; };

View File

@@ -62,10 +62,7 @@ public final class OptiFineInstallTask extends TaskResult<Version> {
if (!optiFineVersionList.isLoaded()) if (!optiFineVersionList.isLoaded())
dependents.add(optiFineVersionList.refreshAsync(dependencyManager.getDownloadProvider()) dependents.add(optiFineVersionList.refreshAsync(dependencyManager.getDownloadProvider())
.then(s -> { .then(Task.of(this::doRemote)));
doRemote();
return null;
}));
else else
doRemote(); doRemote();
} }

View File

@@ -19,10 +19,7 @@ package org.jackhuang.hmcl.game;
import org.jackhuang.hmcl.util.Immutable; import org.jackhuang.hmcl.util.Immutable;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
/** /**
* *
@@ -49,20 +46,20 @@ public final class CompatibilityRule {
this.features = features; this.features = features;
} }
public Action getAppliedAction(Map<String, Boolean> supportedFeatures) { public Optional<Action> getAppliedAction(Map<String, Boolean> supportedFeatures) {
if (os != null && !os.allow()) if (os != null && !os.allow())
return null; return Optional.empty();
if (features != null) if (features != null)
for (Map.Entry<String, Boolean> entry : features.entrySet()) for (Map.Entry<String, Boolean> entry : features.entrySet())
if (!Objects.equals(supportedFeatures.get(entry.getKey()), entry.getValue())) if (!Objects.equals(supportedFeatures.get(entry.getKey()), entry.getValue()))
return null; return Optional.empty();
return action; return Optional.ofNullable(action);
} }
public static boolean appliesToCurrentEnvironment(Collection<CompatibilityRule> rules) { public static boolean appliesToCurrentEnvironment(Collection<CompatibilityRule> rules) {
return appliesToCurrentEnvironment(rules, Collections.EMPTY_MAP); return appliesToCurrentEnvironment(rules, Collections.emptyMap());
} }
public static boolean appliesToCurrentEnvironment(Collection<CompatibilityRule> rules, Map<String, Boolean> features) { public static boolean appliesToCurrentEnvironment(Collection<CompatibilityRule> rules, Map<String, Boolean> features) {
@@ -71,9 +68,9 @@ public final class CompatibilityRule {
Action action = Action.DISALLOW; Action action = Action.DISALLOW;
for (CompatibilityRule rule : rules) { for (CompatibilityRule rule : rules) {
Action thisAction = rule.getAppliedAction(features); Optional<Action> thisAction = rule.getAppliedAction(features);
if (thisAction != null) if (thisAction.isPresent())
action = thisAction; action = thisAction.get();
} }
return action == Action.ALLOW; return action == Action.ALLOW;

View File

@@ -24,6 +24,7 @@ import org.jackhuang.hmcl.util.IOUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
/** /**
* @author huangyuhui * @author huangyuhui
@@ -51,31 +52,31 @@ public final class GameVersion {
return -1; return -1;
} }
private static String getVersionOfOldMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException { private static Optional<String> getVersionOfOldMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry)); byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
byte[] bytes = "Minecraft Minecraft ".getBytes(Charsets.US_ASCII); byte[] bytes = "Minecraft Minecraft ".getBytes(Charsets.US_ASCII);
int j = matchArray(tmp, bytes); int j = matchArray(tmp, bytes);
if (j < 0) if (j < 0)
return null; return Optional.empty();
int i = j + bytes.length; int i = j + bytes.length;
if ((j = lessThan32(tmp, i)) < 0) if ((j = lessThan32(tmp, i)) < 0)
return null; return Optional.empty();
return new String(tmp, i, j - i, Charsets.US_ASCII); return Optional.of(new String(tmp, i, j - i, Charsets.US_ASCII));
} }
private static String getVersionOfNewMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException { private static Optional<String> getVersionOfNewMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry)); byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
byte[] str = "-server.txt".getBytes(Charsets.US_ASCII); byte[] str = "-server.txt".getBytes(Charsets.US_ASCII);
int j = matchArray(tmp, str); int j = matchArray(tmp, str);
if (j < 0) return null; if (j < 0) return Optional.empty();
int i = j + str.length; int i = j + str.length;
i += 11; i += 11;
j = lessThan32(tmp, i); j = lessThan32(tmp, i);
if (j < 0) return null; if (j < 0) return Optional.empty();
String result = new String(tmp, i, j - i, Charsets.US_ASCII); String result = new String(tmp, i, j - i, Charsets.US_ASCII);
char ch = result.charAt(0); char ch = result.charAt(0);
@@ -83,7 +84,7 @@ public final class GameVersion {
if (ch < '0' || ch > '9') { if (ch < '0' || ch > '9') {
str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes(Charsets.US_ASCII); str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes(Charsets.US_ASCII);
j = matchArray(tmp, str); j = matchArray(tmp, str);
if (j < 0) return null; if (j < 0) return Optional.empty();
i = -1; i = -1;
while (j > 0) { while (j > 0) {
if (tmp[j] >= 48 && tmp[j] <= 57) { if (tmp[j] >= 48 && tmp[j] <= 57) {
@@ -92,21 +93,21 @@ public final class GameVersion {
} }
j--; j--;
} }
if (i == -1) return null; if (i == -1) return Optional.empty();
int k = i; int k = i;
if (tmp[i + 1] >= (int) 'a' && tmp[i + 1] <= (int) 'z') if (tmp[i + 1] >= (int) 'a' && tmp[i + 1] <= (int) 'z')
i++; i++;
while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z') while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z')
k--; k--;
k++; k++;
return new String(tmp, k, i - k + 1, Charsets.US_ASCII); return Optional.of(new String(tmp, k, i - k + 1, Charsets.US_ASCII));
} }
return result; return Optional.of(result);
} }
public static String minecraftVersion(File file) { public static Optional<String> minecraftVersion(File file) {
if (file == null || !file.exists() || !file.isFile() || !file.canRead()) if (file == null || !file.exists() || !file.isFile() || !file.canRead())
return null; return Optional.empty();
ZipFile f = null; ZipFile f = null;
try { try {
@@ -119,9 +120,9 @@ public final class GameVersion {
ZipArchiveEntry minecraftserver = f.getEntry("net/minecraft/server/MinecraftServer.class"); ZipArchiveEntry minecraftserver = f.getEntry("net/minecraft/server/MinecraftServer.class");
if ((main != null) && (minecraftserver != null)) if ((main != null) && (minecraftserver != null))
return getVersionOfNewMinecraft(f, minecraftserver); return getVersionOfNewMinecraft(f, minecraftserver);
return null; return Optional.empty();
} catch (IOException e) { } catch (IOException e) {
return null; return Optional.empty();
} finally { } finally {
IOUtils.closeQuietly(f); IOUtils.closeQuietly(f);
} }

View File

@@ -123,7 +123,7 @@ public final class CurseManifest {
if (manifest == null) if (manifest == null)
throw new JsonParseException("`manifest.json` not found. Not a valid Curse modpack."); throw new JsonParseException("`manifest.json` not found. Not a valid Curse modpack.");
return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(), return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(),
Optional.ofNullable(CompressingUtils.readTextZipEntryQuietly(f, "modlist.html")).orElse( "No description"), manifest); CompressingUtils.readTextZipEntryQuietly(f, "modlist.html").orElse( "No description"), manifest);
} }
public static final String MINECRAFT_MODPACK = "minecraftModpack"; public static final String MINECRAFT_MODPACK = "minecraftModpack";

View File

@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.mod;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import java.io.File; import java.io.File;
@@ -66,17 +67,17 @@ public final class MultiMCInstanceConfiguration {
javaPath = p.getProperty("JavaPath"); javaPath = p.getProperty("JavaPath");
jvmArgs = p.getProperty("JvmArgs"); jvmArgs = p.getProperty("JvmArgs");
fullscreen = Boolean.parseBoolean(p.getProperty("LaunchMaximized")); fullscreen = Boolean.parseBoolean(p.getProperty("LaunchMaximized"));
maxMemory = StringUtils.parseInt(p.getProperty("MaxMemAlloc")); maxMemory = Lang.toIntOrNull(p.getProperty("MaxMemAlloc"));
minMemory = StringUtils.parseInt(p.getProperty("MinMemAlloc")); minMemory = Lang.toIntOrNull(p.getProperty("MinMemAlloc"));
height = StringUtils.parseInt(p.getProperty("MinecraftWinHeight")); height = Lang.toIntOrNull(p.getProperty("MinecraftWinHeight"));
width = StringUtils.parseInt(p.getProperty("MinecraftWinWidth")); width = Lang.toIntOrNull(p.getProperty("MinecraftWinWidth"));
overrideCommands = Boolean.parseBoolean(p.getProperty("OverrideCommands")); overrideCommands = Boolean.parseBoolean(p.getProperty("OverrideCommands"));
overrideConsole = Boolean.parseBoolean(p.getProperty("OverrideConsole")); overrideConsole = Boolean.parseBoolean(p.getProperty("OverrideConsole"));
overrideJavaArgs = Boolean.parseBoolean(p.getProperty("OverrideJavaArgs")); overrideJavaArgs = Boolean.parseBoolean(p.getProperty("OverrideJavaArgs"));
overrideJavaLocation = Boolean.parseBoolean(p.getProperty("OverrideJavaLocation")); overrideJavaLocation = Boolean.parseBoolean(p.getProperty("OverrideJavaLocation"));
overrideMemory = Boolean.parseBoolean(p.getProperty("OverrideMemory")); overrideMemory = Boolean.parseBoolean(p.getProperty("OverrideMemory"));
overrideWindow = Boolean.parseBoolean(p.getProperty("OverrideWindow")); overrideWindow = Boolean.parseBoolean(p.getProperty("OverrideWindow"));
permGen = StringUtils.parseInt(p.getProperty("PermGen")); permGen = Lang.toIntOrNull(p.getProperty("PermGen"));
postExitCommand = p.getProperty("PostExitCommand"); postExitCommand = p.getProperty("PostExitCommand");
preLaunchCommand = p.getProperty("PreLaunchCommand"); preLaunchCommand = p.getProperty("PreLaunchCommand");
showConsole = Boolean.parseBoolean(p.getProperty("ShowConsole")); showConsole = Boolean.parseBoolean(p.getProperty("ShowConsole"));

View File

@@ -24,6 +24,7 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import java.io.*; import java.io.*;
import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
@@ -217,11 +218,11 @@ public final class CompressingUtils {
* @param name the location of the text in zip file, something like A/B/C/D.txt * @param name the location of the text in zip file, something like A/B/C/D.txt
* @return the content of given file. * @return the content of given file.
*/ */
public static String readTextZipEntryQuietly(File file, String name) { public static Optional<String> readTextZipEntryQuietly(File file, String name) {
try { try {
return readTextZipEntry(file, name); return Optional.of(readTextZipEntry(file, name));
} catch (IOException e) { } catch (IOException e) {
return null; return Optional.empty();
} }
} }
} }

View File

@@ -207,14 +207,4 @@ public final class StringUtils {
return result; return result;
} }
public static Integer parseInt(String str) {
if (str == null)
return null;
try {
return Integer.parseInt(str);
} catch (NumberFormatException ex) {
return null;
}
}
} }

View File

@@ -19,6 +19,8 @@ package org.jackhuang.hmcl.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
/** /**
* The formatted version number represents a version string. * The formatted version number represents a version string.
@@ -53,6 +55,7 @@ public abstract class VersionNumber implements Comparable<VersionNumber> {
} }
public static VersionNumber asVersion(String version) { public static VersionNumber asVersion(String version) {
Objects.requireNonNull(version);
try { try {
return asIntVersionNumber(version); return asIntVersionNumber(version);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@@ -60,13 +63,13 @@ public abstract class VersionNumber implements Comparable<VersionNumber> {
} }
} }
public static String parseVersion(String str) { public static Optional<String> parseVersion(String str) {
if (str.chars().anyMatch(it -> it != '.' && (it < '0' || it > '9')) || StringUtils.isBlank(str)) if (str.chars().anyMatch(it -> it != '.' && (it < '0' || it > '9')) || StringUtils.isBlank(str))
return null; return Optional.empty();
String[] s = str.split("\\."); String[] s = str.split("\\.");
for (String i : s) for (String i : s)
if (StringUtils.isBlank(i)) if (StringUtils.isBlank(i))
return null; return Optional.empty();
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
int last = s.length - 1; int last = s.length - 1;
for (int i = s.length - 1; i >= 0; --i) for (int i = s.length - 1; i >= 0; --i)
@@ -74,6 +77,6 @@ public abstract class VersionNumber implements Comparable<VersionNumber> {
last = i; last = i;
for (int i = 0; i < last; ++i) for (int i = 0; i < last; ++i)
builder.append(s[i]).append("."); builder.append(s[i]).append(".");
return builder.append(s[last]).toString(); return Optional.of(builder.append(s[last]).toString());
} }
} }