mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
Фикс опциональных модов
This commit is contained in:
parent
19fa135a61
commit
005507a3a3
7 changed files with 89 additions and 94 deletions
|
@ -68,7 +68,7 @@ public void build() throws IOException {
|
|||
|
||||
private void setConfig() {
|
||||
Config config = new Config();
|
||||
// Set string options
|
||||
// Set file options
|
||||
config.setChdir(".");
|
||||
config.setErrTitle("JVM Error");
|
||||
config.setDownloadUrl(DOWNLOAD_URL);
|
||||
|
|
|
@ -68,7 +68,7 @@ private static String[] parse(CharSequence line) throws CommandException {
|
|||
if (wasQuoted || builder.length() > 0)
|
||||
result.add(builder.toString());
|
||||
|
||||
// Reset string builder
|
||||
// Reset file builder
|
||||
wasQuoted = false;
|
||||
builder.setLength(0);
|
||||
continue;
|
||||
|
|
|
@ -93,38 +93,22 @@ var options = {
|
|||
nodelist.forEach(function(node,i,arr) {
|
||||
holder.getChildren().remove(node);
|
||||
});
|
||||
var profile = profilesList[serverHolder.old].object;
|
||||
var profile = profilesList[serverHolder.old];
|
||||
var list = profile.getOptional();
|
||||
var checkBoxList = new java.util.ArrayList;
|
||||
var modConfigKeys = Object.keys(optModNames.modInfo);
|
||||
var dModsIds = [];
|
||||
|
||||
modConfigKeys.forEach(function(key, id) {//По умолчанию индекс у ветви = 1. Выставляем его у всех неуказанных.
|
||||
if(optModNames.modInfo[key].subTreeLevel == null)
|
||||
optModNames.modInfo[key].subTreeLevel = 1;
|
||||
});
|
||||
|
||||
for (var ik = 0, l = modConfigKeys.length + 1; ik <= l; ik++) {
|
||||
list.forEach(function(modFile) {
|
||||
if((modConfigKeys[ik] === modFile.string) || (ik == modConfigKeys.length+1 && dModsIds.indexOf(modFile.string) == -1)) {
|
||||
dModsIds.push(modFile.string);
|
||||
|
||||
var modName = modFile.string, modDescription = "", subLevel = 1;
|
||||
if(optModNames.modInfo[modFile.string] != null){//Есть ли хоть какое-нибудь представление описания модификации?
|
||||
var optModN = optModNames.modInfo[modFile.string];
|
||||
if(optModN.name != null)//Есть ли у модификации имя?
|
||||
modName = optModN.name;
|
||||
if(optModN.description != null) //Есть ли описание?
|
||||
modDescription = optModN.description;
|
||||
if(optModN.subTreeLevel != null && optModN.subTreeLevel > 1)//Это суб-модификация?
|
||||
subLevel = optModN.subTreeLevel;
|
||||
} else if(optModNames.optAutoModName) {
|
||||
//Попытка автоматически создать представляемое имя модификации.
|
||||
modName = modName.replace(new RegExp("(.*?(\/))",'g'),'');
|
||||
modName = modName.replace(new RegExp("(-|_|[\\d]|\\+).*",'g'),'');
|
||||
//Первая буква - заглавная
|
||||
modName = modName[0].toUpperCase() + modName.slice(1);
|
||||
}
|
||||
var modName = modFile.file, modDescription = "", subLevel = 1;
|
||||
|
||||
if(modFile.name != null)//Есть ли у модификации имя?
|
||||
modName = modFile.name;
|
||||
if(modFile.info != null) //Есть ли описание?
|
||||
modDescription = modFile.info;
|
||||
if(modFile.subTreeLevel != null && modFile.subTreeLevel > 1)//Это суб-модификация?
|
||||
subLevel = modFile.subTreeLevel;
|
||||
var testMod = new javafx.scene.control.CheckBox(modName);
|
||||
|
||||
if(subLevel > 1)
|
||||
|
@ -136,15 +120,15 @@ var options = {
|
|||
var isSelected = event.getSource().isSelected();
|
||||
if(isSelected)
|
||||
{
|
||||
profile.markOptional(modFile.string);
|
||||
LogHelper.debug("Selected mod %s", modFile.string);
|
||||
options.treeToggle(true, modFile.string);
|
||||
profile.markOptional(modFile.file);
|
||||
LogHelper.debug("Selected mod %s", modFile.file);
|
||||
options.treeToggle(true, modFile.file);
|
||||
}
|
||||
else
|
||||
{
|
||||
profile.unmarkOptional(modFile.string);
|
||||
LogHelper.debug("Unselected mod %s", modFile.string);
|
||||
options.treeToggle(false, modFile.string);
|
||||
profile.unmarkOptional(modFile.file);
|
||||
LogHelper.debug("Unselected mod %s", modFile.file);
|
||||
options.treeToggle(false, modFile.file);
|
||||
}
|
||||
options.update();
|
||||
});
|
||||
|
@ -168,31 +152,27 @@ var options = {
|
|||
sep = new javafx.scene.control.Separator();
|
||||
sep.getStyleClass().add("separator");
|
||||
checkBoxList.add(sep);
|
||||
}
|
||||
});
|
||||
}
|
||||
holder.getChildren().clear();
|
||||
holder.getChildren().addAll(checkBoxList);
|
||||
},
|
||||
treeToggle: function(enable, ImodFile) {
|
||||
var profile = profilesList[serverHolder.old].object;
|
||||
if(optModNames.modInfo[ImodFile] != null) {
|
||||
var modInfo = optModNames.modInfo[ImodFile];
|
||||
var modList = optModNames.modInfo;
|
||||
var modIDs = Object.keys(modList);
|
||||
var profile = profilesList[serverHolder.old];
|
||||
var modInfo = profile.getOptionalFile(ImodFile);
|
||||
var modList = profile.getOptional();
|
||||
|
||||
if(modInfo.subTreeLevel != null) {
|
||||
|
||||
if(modInfo.subTreeLevel >= 1){//Отключение core-модификации
|
||||
var stop = false;
|
||||
modIDs.forEach(function(key, id) {
|
||||
if(modList[key] != null && modList[key].subTreeLevel != null) {
|
||||
if( modList[key].subTreeLevel > modInfo.subTreeLevel && modIDs.indexOf(key) > modIDs.indexOf(ImodFile) && enable == false && stop == false) {
|
||||
if(options.modExists(key)){
|
||||
profile.unmarkOptional(key);
|
||||
LogHelper.debug("Unselected subMod %s", key);
|
||||
modList.forEach(function(elem, id) {
|
||||
if(elem != null && elem.subTreeLevel != null) {
|
||||
if( elem.subTreeLevel > modInfo.subTreeLevel && enable == false && stop == false) {
|
||||
if(options.modExists(elem.file)){
|
||||
profile.unmarkOptional(elem.file);
|
||||
LogHelper.debug("Unselected subMod %s", elem.file);
|
||||
}
|
||||
} else if(modIDs.indexOf(key) > modIDs.indexOf(ImodFile) && modList[key].subTreeLevel <= modInfo.subTreeLevel && stop == false) {
|
||||
} else if(elem.subTreeLevel <= modInfo.subTreeLevel && stop == false) {
|
||||
//LogHelper.debug("STOP disable!! " + key);
|
||||
stop = true;
|
||||
}
|
||||
|
@ -201,27 +181,26 @@ var options = {
|
|||
}
|
||||
|
||||
if(modInfo.onlyOne == true){//Включение onlyOne-модификации (Все onlyOne-модификации с той же группой будут отключены. К примеру 2 миникарты)
|
||||
modIDs.forEach(function(key, id) {
|
||||
if(modList[key] != null && modList[key].onlyOneGroup != null) {
|
||||
if(modList[key].onlyOneGroup == modInfo.onlyOneGroup && modList[key].onlyOne == true && enable == true && key != ImodFile) {
|
||||
if(options.modExists(key)) {
|
||||
profile.unmarkOptional(key);
|
||||
LogHelper.debug("Unselected Mod (onlyOne toggle) %s", key);
|
||||
modList.forEach(function(elem, id) {
|
||||
if(elem != null && elem.onlyOneGroup != null) {
|
||||
if(elem.onlyOneGroup == modInfo.onlyOneGroup && elem.onlyOne == true && enable == true && key != ImodFile) {
|
||||
if(options.modExists(elem.file)) {
|
||||
profile.unmarkOptional(elem.file);
|
||||
LogHelper.debug("Unselected Mod (onlyOne toggle) %s", elem.file);
|
||||
}
|
||||
options.treeToggle(false, key); //И все его подмодификации канут в Лету..
|
||||
options.treeToggle(false, elem.file); //И все его подмодификации канут в Лету..
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(modInfo.subTreeLevel > 1){//Включение суб-модификации (Без core суб-моды работать не будут, так что его нужно включать) (Включаем всю ветку зависимости)
|
||||
var reverseModList = Object.keys(modList).reverse();
|
||||
var tsl = modInfo.subTreeLevel-1;
|
||||
reverseModList.forEach(function(key, id) {
|
||||
if(modList[key] != null && modList[key].subTreeLevel != null) {
|
||||
if(modList[key].subTreeLevel == tsl && modIDs.indexOf(key) < modIDs.indexOf(ImodFile) && enable == true) {
|
||||
if(options.modExists(key)) {
|
||||
profile.markOptional(key);
|
||||
modList.forEach(function(elem, id) {
|
||||
if(elem != null && elem.subTreeLevel != null) {
|
||||
if(elem.subTreeLevel == tsl && enable == true) {
|
||||
if(options.modExists(elem)) {
|
||||
profile.markOptional(elem.file);
|
||||
LogHelper.debug("Selected coreMod %s", key);
|
||||
}
|
||||
options.treeToggle(true, key); //Для срабатывания onlyOne-модификаций.
|
||||
|
@ -232,14 +211,13 @@ var options = {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
modExists: function(key){
|
||||
var profile = profilesList[serverHolder.old].object;
|
||||
var profile = profilesList[serverHolder.old];
|
||||
var list = profile.getOptional();
|
||||
var result = false;
|
||||
list.forEach(function(modFile) {
|
||||
if(modFile.string === key) {
|
||||
if(modFile.file === key) {
|
||||
result = true;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ public static final class Params extends StreamObject {
|
|||
@LauncherAPI
|
||||
public final PlayerProfile pp;
|
||||
@LauncherAPI
|
||||
public final Set<ClientProfile.MarkedString> updateOptional;
|
||||
public final Set<ClientProfile.OptionalFile> updateOptional;
|
||||
@LauncherAPI
|
||||
public final String accessToken;
|
||||
@LauncherAPI
|
||||
|
@ -86,7 +86,7 @@ public Params(byte[] launcherDigest, Path assetDir, Path clientDir, PlayerProfil
|
|||
boolean autoEnter, boolean fullScreen, int ram, int width, int height) {
|
||||
this.launcherDigest = launcherDigest.clone();
|
||||
this.updateOptional = new HashSet<>();
|
||||
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||
for (ClientProfile.OptionalFile s : Launcher.profile.getOptional()) {
|
||||
if (s.mark) updateOptional.add(s);
|
||||
}
|
||||
// Client paths
|
||||
|
@ -111,7 +111,7 @@ public Params(HInput input) throws Exception {
|
|||
updateOptional = new HashSet<>();
|
||||
int len = input.readLength(128);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
updateOptional.add(new ClientProfile.MarkedString(input.readString(512), true));
|
||||
updateOptional.add(new ClientProfile.OptionalFile(input.readString(512), true));
|
||||
}
|
||||
// Client params
|
||||
pp = new PlayerProfile(input);
|
||||
|
@ -132,8 +132,8 @@ public void write(HOutput output) throws IOException {
|
|||
output.writeString(assetDir.toString(), 0);
|
||||
output.writeString(clientDir.toString(), 0);
|
||||
output.writeLength(updateOptional.size(), 128);
|
||||
for (ClientProfile.MarkedString s : updateOptional) {
|
||||
output.writeString(s.string, 512);
|
||||
for (ClientProfile.OptionalFile s : updateOptional) {
|
||||
output.writeString(s.file, 512);
|
||||
}
|
||||
// Client params
|
||||
pp.write(output);
|
||||
|
@ -459,9 +459,9 @@ public static void main(String... args) throws Throwable {
|
|||
// Verify current state of all dirs
|
||||
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
||||
HashedDir hdir = clientHDir.object;
|
||||
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||
for (ClientProfile.OptionalFile s : Launcher.profile.getOptional()) {
|
||||
if (params.updateOptional.contains(s)) s.mark = true;
|
||||
else hdir.removeR(s.string);
|
||||
else hdir.removeR(s.file);
|
||||
}
|
||||
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
||||
verifyHDir(params.clientDir, hdir, clientMatcher, digest);
|
||||
|
@ -498,9 +498,9 @@ public void launchLocal(SignedObjectHolder<HashedDir> assetHDir, SignedObjectHol
|
|||
// Verify current state of all dirs
|
||||
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
||||
HashedDir hdir = clientHDir.object;
|
||||
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||
for (ClientProfile.OptionalFile s : Launcher.profile.getOptional()) {
|
||||
if (params.updateOptional.contains(s)) s.mark = true;
|
||||
else hdir.removeR(s.string);
|
||||
else hdir.removeR(s.file);
|
||||
}
|
||||
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
||||
verifyHDir(params.clientDir, hdir, clientMatcher, digest);
|
||||
|
|
|
@ -130,7 +130,7 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE
|
|||
// Verify all parts
|
||||
String magic = splitted[0];
|
||||
if (!magic.equals(LEGACY_PING_HOST_MAGIC))
|
||||
throw new IOException("Magic string mismatch: " + magic);
|
||||
throw new IOException("Magic file mismatch: " + magic);
|
||||
int protocol = Integer.parseInt(splitted[1]);
|
||||
if (protocol != version.protocol)
|
||||
throw new IOException("Protocol mismatch: " + protocol);
|
||||
|
|
|
@ -94,19 +94,29 @@ public String toString() {
|
|||
@LauncherAPI
|
||||
private int serverPort;
|
||||
|
||||
public static class MarkedString {
|
||||
public static class OptionalFile {
|
||||
@LauncherAPI
|
||||
public String string;
|
||||
public String file;
|
||||
@LauncherAPI
|
||||
public boolean mark;
|
||||
@LauncherAPI
|
||||
public String name;
|
||||
@LauncherAPI
|
||||
public String info;
|
||||
@LauncherAPI
|
||||
public int sunTreeLevel = 1;
|
||||
@LauncherAPI
|
||||
public boolean onlyOne = false;
|
||||
@LauncherAPI
|
||||
public int onlyOneGroup = 1;
|
||||
|
||||
public MarkedString(String string, boolean mark) {
|
||||
this.string = string;
|
||||
public OptionalFile(String file, boolean mark) {
|
||||
this.file = file;
|
||||
this.mark = mark;
|
||||
}
|
||||
|
||||
public MarkedString(String string) {
|
||||
this.string = string;
|
||||
public OptionalFile(String file) {
|
||||
this.file = file;
|
||||
this.mark = false;
|
||||
}
|
||||
|
||||
|
@ -114,13 +124,13 @@ public MarkedString(String string) {
|
|||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MarkedString that = (MarkedString) o;
|
||||
return Objects.equals(string, that.string);
|
||||
OptionalFile that = (OptionalFile) o;
|
||||
return Objects.equals(file, that.file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(string);
|
||||
return Objects.hash(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +144,7 @@ public int hashCode() {
|
|||
@LauncherAPI
|
||||
private final List<String> updateVerify = new ArrayList<>();
|
||||
@LauncherAPI
|
||||
private final Set<MarkedString> updateOptional = new HashSet<>();
|
||||
private final Set<OptionalFile> updateOptional = new HashSet<>();
|
||||
@LauncherAPI
|
||||
private boolean updateFastCheck;
|
||||
@LauncherAPI
|
||||
|
@ -221,9 +231,16 @@ public String getServerAddress() {
|
|||
}
|
||||
|
||||
@LauncherAPI
|
||||
public Set<MarkedString> getOptional() {
|
||||
public Set<OptionalFile> getOptional() {
|
||||
return updateOptional;
|
||||
}
|
||||
@LauncherAPI
|
||||
public OptionalFile getOptionalFile(String file)
|
||||
{
|
||||
for(OptionalFile f : updateOptional)
|
||||
if(f.file.equals(file)) return f;
|
||||
return null;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public Collection<String> getShared() {
|
||||
|
@ -232,25 +249,25 @@ public Collection<String> getShared() {
|
|||
|
||||
@LauncherAPI
|
||||
public void markOptional(String opt) {
|
||||
if (!updateOptional.contains(new MarkedString(opt)))
|
||||
if (!updateOptional.contains(new OptionalFile(opt)))
|
||||
throw new SecurityException(String.format("Optional mod %s not found in optionalList", opt));
|
||||
updateOptional.forEach(e -> {
|
||||
if (e.string.equals(opt)) e.mark = true;
|
||||
if (e.file.equals(opt)) e.mark = true;
|
||||
});
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public void unmarkOptional(String opt) {
|
||||
if (!updateOptional.contains(new MarkedString(opt)))
|
||||
if (!updateOptional.contains(new OptionalFile(opt)))
|
||||
throw new SecurityException(String.format("Optional mod %s not found in optionalList", opt));
|
||||
updateOptional.forEach(e -> {
|
||||
if (e.string.equals(opt)) e.mark = false;
|
||||
if (e.file.equals(opt)) e.mark = false;
|
||||
});
|
||||
}
|
||||
|
||||
public void pushOptional(HashedDir dir, boolean digest) throws IOException {
|
||||
for (MarkedString opt : updateOptional) {
|
||||
if (!opt.mark) dir.removeR(opt.string);
|
||||
for (OptionalFile opt : updateOptional) {
|
||||
if (!opt.mark) dir.removeR(opt.file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ private static String ansiFormatVersion(String product) {
|
|||
fgBright(Color.CYAN).a(product). // Product
|
||||
fgBright(Color.WHITE).a(" v").fgBright(Color.BLUE).a(Launcher.getVersion().toString()). // Version
|
||||
fgBright(Color.WHITE).a(" (build #").fgBright(Color.RED).a(Launcher.getVersion().build).fgBright(Color.WHITE).a(')'). // Build#
|
||||
reset().toString(); // To string
|
||||
reset().toString(); // To file
|
||||
}
|
||||
|
||||
private static String ansiFormatLicense(String product) {
|
||||
|
@ -261,7 +261,7 @@ private static String ansiFormatLicense(String product) {
|
|||
fgBright(Color.CYAN).a(product). // Product
|
||||
fgBright(Color.WHITE).a(" GPLv3").fgBright(Color.WHITE).a(". SourceCode: "). // Version
|
||||
fgBright(Color.YELLOW).a("https://github.com/GravitLauncher/Launcher").
|
||||
reset().toString(); // To string
|
||||
reset().toString(); // To file
|
||||
}
|
||||
|
||||
private static String formatLog(Level level, String message, String dateTime, boolean sub) {
|
||||
|
|
Loading…
Reference in a new issue