Merge pull request #3 from GravitLauncher/dev

Dev
This commit is contained in:
JoshO 2019-06-02 02:00:30 +05:00 committed by GitHub
commit 444fdbb742
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 280 additions and 231 deletions

View file

@ -272,8 +272,8 @@ public static class ExeConf {
public String txtFileVersion; public String txtFileVersion;
public String txtProductVersion; public String txtProductVersion;
} }
public static class NettyUpdatesBind
{ public static class NettyUpdatesBind {
public String url; public String url;
public boolean zip; public boolean zip;
} }

View file

@ -78,7 +78,7 @@ private void setConfig() {
// Prepare JRE // Prepare JRE
Jre jre = new Jre(); Jre jre = new Jre();
jre.setMinVersion("1.8.0"); jre.setMinVersion("1.8.0");
if(server.config.launch4j.setMaxVersion) if (server.config.launch4j.setMaxVersion)
jre.setMaxVersion(server.config.launch4j.maxVersion); jre.setMaxVersion(server.config.launch4j.maxVersion);
jre.setRuntimeBits(Jre.RUNTIME_BITS_64_AND_32); jre.setRuntimeBits(Jre.RUNTIME_BITS_64_AND_32);
jre.setJdkPreference(Jre.JDK_PREFERENCE_PREFER_JRE); jre.setJdkPreference(Jre.JDK_PREFERENCE_PREFER_JRE);

View file

@ -42,11 +42,11 @@ public JARLauncherBinary(LaunchServer server) throws IOException {
public void init() { public void init() {
tasks.add(new PrepareBuildTask(server)); tasks.add(new PrepareBuildTask(server));
tasks.add(new MainBuildTask(server)); tasks.add(new MainBuildTask(server));
if(server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server)); if (server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server));
tasks.add(new ProGuardBuildTask(server)); tasks.add(new ProGuardBuildTask(server));
tasks.add(new AdditionalFixesApplyTask(server)); tasks.add(new AdditionalFixesApplyTask(server));
tasks.add(new RadonBuildTask(server)); tasks.add(new RadonBuildTask(server));
if(!server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server)); if (!server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server));
} }
@Override @Override

View file

@ -137,7 +137,7 @@ public Path process(Path inputJar) throws IOException {
jaConfigurator.setGuardType(server.config.launcher.guardType); jaConfigurator.setGuardType(server.config.launcher.guardType);
jaConfigurator.setWarningMissArchJava(server.config.isWarningMissArchJava); jaConfigurator.setWarningMissArchJava(server.config.isWarningMissArchJava);
jaConfigurator.setEnv(server.config.env); jaConfigurator.setEnv(server.config.env);
if(server.runtime.oemUnlockKey == null) server.runtime.oemUnlockKey = SecurityHelper.randomStringToken(); if (server.runtime.oemUnlockKey == null) server.runtime.oemUnlockKey = SecurityHelper.randomStringToken();
jaConfigurator.setOemUnlockKey(server.runtime.oemUnlockKey); jaConfigurator.setOemUnlockKey(server.runtime.oemUnlockKey);
server.buildHookManager.registerAllClientModuleClass(jaConfigurator); server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
reader.getCp().add(new JarFile(inputJar.toFile())); reader.getCp().add(new JarFile(inputJar.toFile()));

View file

@ -40,8 +40,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
} }
String url = LaunchServer.server.config.netty.downloadURL.replace("%dirname%", dirName); String url = LaunchServer.server.config.netty.downloadURL.replace("%dirname%", dirName);
boolean zip = false; boolean zip = false;
if (server.config.netty.bindings.get(dirName) != null) if (server.config.netty.bindings.get(dirName) != null) {
{
LaunchServer.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName); LaunchServer.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName);
url = bind.url; url = bind.url;
zip = bind.zip; zip = bind.zip;

View file

@ -41,7 +41,7 @@ pack project(':LauncherAuthlib')
bundle 'com.jfoenix:jfoenix:8.0.8' bundle 'com.jfoenix:jfoenix:8.0.8'
bundle 'de.jensd:fontawesomefx:8.9' bundle 'de.jensd:fontawesomefx:8.9'
bundle 'org.apache.httpcomponents:httpclient:4.5.7' bundle 'org.apache.httpcomponents:httpclient:4.5.7'
pack 'io.netty:netty-all:4.1.36.Final' pack 'io.netty:netty-codec-http:4.1.36.Final'
pack 'org.ow2.asm:asm-tree:7.1' pack 'org.ow2.asm:asm-tree:7.1'
} }

View file

@ -1,14 +1,11 @@
/*-- DrLeonardo Design --*/ /*-- DrLeonardo Design --*/
#overlay > #description {
#overlay>#description {
-fx-font-size: 12pt; -fx-font-size: 12pt;
-fx-text-fill: #fff; -fx-text-fill: #fff;
-fx-wrap-text: true; -fx-wrap-text: true;
} }
#overlay>#description.error { #overlay > #description.error {
-fx-text-fill: #CE5757; -fx-text-fill: red;
} }
/*-- DrLeonardo Design --*/ /*-- DrLeonardo Design --*/

View file

@ -13,60 +13,44 @@
<!-- DrLeonardo Design --> <!-- DrLeonardo Design -->
<Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201" <Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<Pane id="holder" prefHeight="450.0" prefWidth="694.0"> <Pane id="holder" prefHeight="450.0" prefWidth="694.0">
<children> <children>
<JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0" <JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0" text="Автовход на сервер" unCheckedColor="#909090" />
text="Автовход на сервер" unCheckedColor="#909090"/> <Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер" wrappingWidth="636.9999872148037" y="15.0" />
<Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0" <JFXCheckBox fx:id="fullScreen" checkedColor="#5fd97a" layoutX="13.0" layoutY="244.0" text="Клиент в полный экран" unCheckedColor="#909090" />
text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер" <Text fill="#8c8c8c" layoutX="40.0" layoutY="261.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение данной функции позволяет запустить игру сразу в полноэкранном режиме" wrappingWidth="636.9999872148037" y="15.0" />
wrappingWidth="636.9999872148037" y="15.0"/> <JFXCheckBox id="debug" checkedColor="#5fd97a" layoutX="13.0" layoutY="183.0" text="Режим Отладки" unCheckedColor="#909090" />
<JFXCheckBox fx:id="fullScreen" checkedColor="#5fd97a" layoutX="13.0" layoutY="260.0" <Text fill="#8c8c8c" layoutX="40.0" layoutY="198.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Режим отладки позволяет просмотреть лог запуска и работы программы в реальном времени прямо из лаунчера, что упрощает поиск нужной информации" wrappingWidth="637.0000016447157" y="15.0" />
text="Клиент в полный экран" unCheckedColor="#909090"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="277.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Включение данной функции позволяет запустить игру сразу в полноэкранном режиме"
wrappingWidth="636.9999872148037" y="15.0"/>
<JFXCheckBox id="debug" checkedColor="#5fd97a" layoutX="13.0" layoutY="193.0" text="Режим Отладки"
unCheckedColor="#909090"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="208.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Режим отладки позволяет просмотреть лог запуска и работы программы в реальном времени прямо из лаунчера, что упрощает поиск нужной информации"
wrappingWidth="637.0000016447157" y="15.0"/>
<TextFlow layoutX="126.0" layoutY="15.0" prefHeight="16.0" prefWidth="112.0"> <TextFlow layoutX="126.0" layoutY="15.0" prefHeight="16.0" prefWidth="112.0">
<Text fx:id="ramLabel"/> <Text fx:id="ramLabel" />
</TextFlow> </TextFlow>
<JFXButton fx:id="deleteDir" layoutX="370.0" layoutY="380.0" prefHeight="25.0" prefWidth="245.0" <JFXButton fx:id="deleteDir" layoutX="370.0" layoutY="380.0" prefHeight="25.0" prefWidth="245.0" text="Удалить клиенты" textAlignment="CENTER" wrapText="true" />
text="Удалить клиенты" textAlignment="CENTER" wrapText="true"/> <JFXButton fx:id="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0" text="Сменить директорию загрузки" textAlignment="CENTER" wrapText="true" />
<JFXButton fx:id="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0" <Hyperlink id="dirLabel" alignment="BASELINE_LEFT" layoutX="201.0" layoutY="420.0" prefHeight="30.0" prefWidth="493.0" text="C:/Users" />
text="Сменить директорию загрузки" textAlignment="CENTER" wrapText="true"/> <JFXButton fx:id="apply" defaultButton="true" layoutX="530.0" layoutY="380.0" prefHeight="23.0" prefWidth="100.0" text="Применить" />
<Hyperlink id="dirLabel" alignment="BASELINE_LEFT" layoutX="201.0" layoutY="420.0" prefHeight="30.0"
prefWidth="493.0" text="C:/Users"/>
<JFXButton fx:id="apply" defaultButton="true" layoutX="530.0" layoutY="380.0" prefHeight="23.0"
prefWidth="100.0" text="Применить"/>
<Text layoutX="16.0" layoutY="28.0">Выделение памяти:</Text> <Text layoutX="16.0" layoutY="28.0">Выделение памяти:</Text>
<JFXSlider fx:id="ramSlider" layoutX="14.0" layoutY="76.0" prefHeight="14.0" prefWidth="663.0"/> <JFXSlider fx:id="ramSlider" layoutX="14.0" layoutY="76.0" prefHeight="14.0" prefWidth="663.0" />
<Pane fx:id="transferDialog" prefHeight="425.0" prefWidth="694.0" visible="false"> <Pane fx:id="transferDialog" prefHeight="425.0" prefWidth="694.0" visible="false">
<children> <children>
<Text fill="WHITE" layoutX="147.0" layoutY="198.0" strokeType="OUTSIDE" strokeWidth="0.0" <Text fill="WHITE" layoutX="147.0" layoutY="198.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Перенести все данные в новую директорию?" wrappingWidth="400.13671875">
text="Перенести все данные в новую директорию?" wrappingWidth="400.13671875">
<font> <font>
<Font size="19.0"/> <Font size="19.0" />
</font> </font>
</Text> </Text>
<JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false" <JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="124.0" text="Да, перенести!" />
prefHeight="25.0" prefWidth="124.0" text="Да, перенести!"/> <JFXButton fx:id="cancelTransfer" layoutX="379.0" layoutY="226.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="124.0" text="Нет, не нужно." />
<JFXButton fx:id="cancelTransfer" layoutX="379.0" layoutY="226.0" mnemonicParsing="false"
prefHeight="25.0" prefWidth="124.0" text="Нет, не нужно."/>
</children> </children>
</Pane> </Pane>
<Line endX="594.0" layoutX="100.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" <Line endX="594.0" layoutX="100.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" />
styleClass="lineHead"/> <JFXCheckBox fx:id="featureStore" checkedColor="#5fd97a" layoutX="13.0" layoutY="292.0" text="Поиск файлов в других клиентах" unCheckedColor="#909090" />
<Text fill="#8c8c8c" layoutX="40.0" layoutY="309.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Используется для экономии вашего трафика, аналогичные файлы будут скопированы с других игровых клиентов" wrappingWidth="636.9999872148037" y="15.0" />
</children> </children>
</Pane> </Pane>
</children> </children>
<stylesheets> <stylesheets>
<URL value="@settings.css"/> <URL value="@settings.css" />
<URL value="@../../styles.css"/> <URL value="@../../styles.css" />
</stylesheets> </stylesheets>
</Pane> </Pane>

View file

@ -33,6 +33,11 @@ var settingsOverlay = {
} }
}); });
var featureStore = holder.lookup("#featureStore");
featureStore.setSelected(settings.featureStore);
featureStore.selectedProperty()["addListener(javafx.beans.value.ChangeListener)"](
function(o, ov, nv) settings.featureStore = nv);
var fullScreenBox = holder.lookup("#fullScreen"); var fullScreenBox = holder.lookup("#fullScreen");
fullScreenBox.setSelected(settings.fullScreen); fullScreenBox.setSelected(settings.fullScreen);
fullScreenBox.selectedProperty()["addListener(javafx.beans.value.ChangeListener)"]( fullScreenBox.selectedProperty()["addListener(javafx.beans.value.ChangeListener)"](
@ -145,7 +150,7 @@ LogHelper.debug("Dir: %s", DirBridge.dir);
var cliParams = { var cliParams = {
login: null, password: null, profile: -1, autoLogin: false, login: null, password: null, profile: -1, autoLogin: false,
updatesDir: null, autoEnter: null, fullScreen: null, ram: -1, updatesDir: null, autoEnter: null, fullScreen: null, ram: -1,
offline: false, offline: false, featureStore: null,
init: function(params) { init: function(params) {
var named = params.getNamed(); var named = params.getNamed();
@ -167,6 +172,10 @@ var cliParams = {
if (autoEnter !== null) { if (autoEnter !== null) {
cliParams.autoEnter = java.lang.Boolean.parseBoolean(autoEnter); cliParams.autoEnter = java.lang.Boolean.parseBoolean(autoEnter);
} }
var featureStore = named.get("featureStore");
if (featureStore !== null) {
cliParams.featureStore = java.lang.Boolean.parseBoolean(featureStore);
}
var fullScreen = named.get("fullScreen"); var fullScreen = named.get("fullScreen");
if (fullScreen !== null) { if (fullScreen !== null) {
cliParams.fullScreen = java.lang.Boolean.parseBoolean(fullScreen); cliParams.fullScreen = java.lang.Boolean.parseBoolean(fullScreen);
@ -175,7 +184,6 @@ var cliParams = {
if (ram !== null) { if (ram !== null) {
cliParams.ram = java.lang.Integer.parseInt(ram); cliParams.ram = java.lang.Integer.parseInt(ram);
} }
var offline = named.get("offline"); var offline = named.get("offline");
if (offline !== null) { if (offline !== null) {
cliParams.offline = java.lang.Boolean.parseBoolean(offline); cliParams.offline = java.lang.Boolean.parseBoolean(offline);
@ -192,19 +200,20 @@ var cliParams = {
if (cliParams.profile >= 0) { if (cliParams.profile >= 0) {
settings.profile = cliParams.profile; settings.profile = cliParams.profile;
} }
if (cliParams.updatesDir !== null) { if (cliParams.updatesDir !== null) {
} }
if (cliParams.autoEnter !== null) { if (cliParams.autoEnter !== null) {
settings.autoLogin = cliParams.autoEnter; settings.autoLogin = cliParams.autoEnter;
} }
if (cliParams.featureStore !== null) {
settings.featureStore = cliParams.featureStore;
}
if (cliParams.fullScreen !== null) { if (cliParams.fullScreen !== null) {
settings.fullScreen = cliParams.fullScreen; settings.fullScreen = cliParams.fullScreen;
} }
if (cliParams.ram >= 0) { if (cliParams.ram >= 0) {
settingsOverlay.setRAM(cliParams.ram); settingsOverlay.setRAM(cliParams.ram);
} }
if (cliParams.offline !== null) { if (cliParams.offline !== null) {
settings.offline = cliParams.offline; settings.offline = cliParams.offline;
} }

View file

@ -20,7 +20,7 @@ #overlay > #description.error {
} }
.downloadPane { .downloadPane {
-fx-background-color: rgba(0, 0, 0, 0.1); -fx-background-color: rgba(0, 0, 0, 0.2);
} }
/* Progress bar */ /* Progress bar */

View file

@ -18,9 +18,9 @@
<Pane id="optionsPane" prefHeight="450.0" prefWidth="692.0" styleClass="optionsPane"> <Pane id="optionsPane" prefHeight="450.0" prefWidth="692.0" styleClass="optionsPane">
<children> <children>
<Line endX="595.0" layoutX="100.0" layoutY="46.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" /> <Line endX="595.0" layoutX="100.0" layoutY="46.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" />
<ScrollPane id="modlist" layoutY="46.0" prefHeight="402.0" prefWidth="693.0"> <ScrollPane id="modlist" layoutY="46.0" prefHeight="404.0" prefWidth="693.0">
<content> <content>
<VBox prefHeight="397.0" prefWidth="678.0"> <VBox prefHeight="394.0" prefWidth="678.0">
<children> <children>
</children> </children>
<padding> <padding>

View file

@ -131,17 +131,18 @@ var options = {
} }
options.update(); options.update();
}); });
testMod.setFocusTraversable(false);
checkBoxList.add(testMod); checkBoxList.add(testMod);
testMod.getStyleClass().add("modname"); testMod.getStyleClass().add("modname");
if(modDescription != "") { if(modDescription != "") {
textDescr = new javafx.scene.text.Text(modDescription); textDescr = new javafx.scene.text.Text(modDescription);
if(subLevel > 1) { if(subLevel > 1) {
for(var i = 1; i < subLevel; i++){ for(var i = 1; i < subLevel; i++){
textDescr.setWrappingWidth(630-(25*i)); textDescr.setWrappingWidth(620-(25*i));
textDescr.setTranslateX(25+(25*i)); textDescr.setTranslateX(25+(25*i));
} }
} else { } else {
textDescr.setWrappingWidth(630); textDescr.setWrappingWidth(620);
textDescr.setTranslateX(25); textDescr.setTranslateX(25);
} }
textDescr.setTextAlignment(javafx.scene.text.TextAlignment.JUSTIFY); textDescr.setTextAlignment(javafx.scene.text.TextAlignment.JUSTIFY);

View file

@ -0,0 +1,22 @@
package ru.gravit.launcher.bridge;
import ru.gravit.launcher.LauncherAPI;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@LauncherAPI
public class GravitGuardBridge {
@LauncherAPI
public static native void callGuard();
@LauncherAPI
public static int sendHTTPRequest(String strurl) throws IOException {
URL url = new URL(strurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Language", "en-US");
return connection.getResponseCode();
}
}

View file

@ -33,47 +33,40 @@ public void preDiff(UpdateRequest request, UpdateRequestEvent e) {
@Override @Override
public void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff diff) throws IOException { public void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff diff) throws IOException {
if(e.zip) return; if (e.zip) return;
if(SettingsManager.settings.featureStore) if (SettingsManager.settings.featureStore) {
{
LogHelper.info("Enabled HStore feature. Find"); LogHelper.info("Enabled HStore feature. Find");
AtomicReference<NewLauncherSettings.HashedStoreEntry> lastEn = new AtomicReference<>(null); AtomicReference<NewLauncherSettings.HashedStoreEntry> lastEn = new AtomicReference<>(null);
//ArrayList<String> removed = new ArrayList<>(); //ArrayList<String> removed = new ArrayList<>();
diff.mismatch.walk(File.separator, (path, name, entry) -> { diff.mismatch.walk(File.separator, (path, name, entry) -> {
if(entry.getType() == HashedEntry.Type.DIR) { if (entry.getType() == HashedEntry.Type.DIR) {
Files.createDirectories(request.getDir().resolve(path)); Files.createDirectories(request.getDir().resolve(path));
return HashedDir.WalkAction.CONTINUE; return HashedDir.WalkAction.CONTINUE;
} }
HashedFile file = (HashedFile) entry; HashedFile file = (HashedFile) entry;
//Первый экспериментальный способ - честно обходим все возможные Store //Первый экспериментальный способ - честно обходим все возможные Store
Path ret = null; Path ret = null;
if(lastEn.get() == null) if (lastEn.get() == null) {
{ for (NewLauncherSettings.HashedStoreEntry en : SettingsManager.settings.lastHDirs) {
for(NewLauncherSettings.HashedStoreEntry en : SettingsManager.settings.lastHDirs)
{
ret = tryFind(en, file); ret = tryFind(en, file);
if(ret != null) { if (ret != null) {
lastEn.set(en); lastEn.set(en);
break; break;
} }
} }
} } else {
else {
ret = tryFind(lastEn.get(), file); ret = tryFind(lastEn.get(), file);
} }
if(ret == null) if (ret == null) {
{ for (NewLauncherSettings.HashedStoreEntry en : SettingsManager.settings.lastHDirs) {
for(NewLauncherSettings.HashedStoreEntry en : SettingsManager.settings.lastHDirs)
{
ret = tryFind(en, file); ret = tryFind(en, file);
if(ret != null) { if (ret != null) {
lastEn.set(en); lastEn.set(en);
break; break;
} }
} }
} }
if(ret != null) if (ret != null) {
{
//Еще раз проверим корректность хеша //Еще раз проверим корректность хеша
//Возможно эта проверка избыточна //Возможно эта проверка избыточна
//if(file.isSame(ret, true)) //if(file.isSame(ret, true))
@ -82,8 +75,7 @@ public void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff
LogHelper.debug("Copy file %s to %s", ret.toAbsolutePath().toString(), source.toAbsolutePath().toString()); LogHelper.debug("Copy file %s to %s", ret.toAbsolutePath().toString(), source.toAbsolutePath().toString());
//Let's go! //Let's go!
Files.copy(ret, source); Files.copy(ret, source);
try(InputStream input = IOHelper.newInput(ret)) try (InputStream input = IOHelper.newInput(ret)) {
{
IOHelper.transfer(input, source); IOHelper.transfer(input, source);
} }
entry.flag = true; entry.flag = true;
@ -94,25 +86,22 @@ public void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff
}); });
} }
} }
public Path tryFind(NewLauncherSettings.HashedStoreEntry en, HashedFile file) throws IOException
{ public Path tryFind(NewLauncherSettings.HashedStoreEntry en, HashedFile file) throws IOException {
AtomicReference<Path> ret = new AtomicReference<>(null); AtomicReference<Path> ret = new AtomicReference<>(null);
en.hdir.walk(File.separator, (path, name, entry) -> { en.hdir.walk(File.separator, (path, name, entry) -> {
if(entry.getType() == HashedEntry.Type.DIR) return HashedDir.WalkAction.CONTINUE; if (entry.getType() == HashedEntry.Type.DIR) return HashedDir.WalkAction.CONTINUE;
HashedFile tfile = (HashedFile) entry; HashedFile tfile = (HashedFile) entry;
if(tfile.isSame(file)) if (tfile.isSame(file)) {
{
LogHelper.dev("[DIR:%s] Found file %s in %s", en.name, name, path); LogHelper.dev("[DIR:%s] Found file %s in %s", en.name, name, path);
Path tdir = Paths.get(en.fullPath).resolve(path); Path tdir = Paths.get(en.fullPath).resolve(path);
try { try {
if(tfile.isSame(tdir, true)) if (tfile.isSame(tdir, true)) {
{
LogHelper.dev("[DIR:%s] Confirmed file %s in %s", en.name, name, path); LogHelper.dev("[DIR:%s] Confirmed file %s in %s", en.name, name, path);
ret.set(tdir); ret.set(tdir);
return HashedDir.WalkAction.STOP; return HashedDir.WalkAction.STOP;
} }
} catch (IOException e) } catch (IOException e) {
{
LogHelper.error("Check file error %s %s", e.getClass().getName(), e.getMessage()); LogHelper.error("Check file error %s %s", e.getClass().getName(), e.getMessage());
} }
} }

View file

@ -19,15 +19,12 @@ public String getUsageDescription() {
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 2); verifyArgs(args, 2);
boolean enabled = Boolean.valueOf(args[1]); boolean enabled = Boolean.valueOf(args[1]);
switch (args[0]) switch (args[0]) {
{ case "store": {
case "store":
{
SettingsManager.settings.featureStore = enabled; SettingsManager.settings.featureStore = enabled;
break; break;
} }
default: default: {
{
LogHelper.info("Features: [store]"); LogHelper.info("Features: [store]");
return; return;
} }

View file

@ -26,20 +26,16 @@ public void invoke(String... args) throws Exception {
int ind = 1; int ind = 1;
int index = Integer.valueOf(args[0]); int index = Integer.valueOf(args[0]);
boolean overwrite = Boolean.valueOf(args[1]); boolean overwrite = Boolean.valueOf(args[1]);
for(NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) for (NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) {
{ if (ind == index) {
if(ind == index)
{
LogHelper.info("Copy [%d] FullPath: %s name: %s", ind, e.fullPath, e.name); LogHelper.info("Copy [%d] FullPath: %s name: %s", ind, e.fullPath, e.name);
Path path = Paths.get(e.fullPath); Path path = Paths.get(e.fullPath);
if(!Files.isDirectory(path)) if (!Files.isDirectory(path)) {
{
LogHelper.error("Directory %s not found", path.toAbsolutePath().toString()); LogHelper.error("Directory %s not found", path.toAbsolutePath().toString());
return; return;
} }
Path target = Paths.get(SettingsManager.settings.updatesDirPath).resolve(e.name); Path target = Paths.get(SettingsManager.settings.updatesDirPath).resolve(e.name);
if(Files.exists(target) && !overwrite) if (Files.exists(target) && !overwrite) {
{
LogHelper.error("Directory %s found, flag overwrite not found", target.toAbsolutePath().toString()); LogHelper.error("Directory %s found, flag overwrite not found", target.toAbsolutePath().toString());
return; return;
} }

View file

@ -26,20 +26,16 @@ public void invoke(String... args) throws Exception {
verifyArgs(args, 1); verifyArgs(args, 1);
int ind = 1; int ind = 1;
int index = Integer.valueOf(args[0]); int index = Integer.valueOf(args[0]);
for(NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) for (NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) {
{ if (ind == index) {
if(ind == index)
{
LogHelper.info("Copy [%d] FullPath: %s name: %s", ind, e.fullPath, e.name); LogHelper.info("Copy [%d] FullPath: %s name: %s", ind, e.fullPath, e.name);
Path path = Paths.get(e.fullPath); Path path = Paths.get(e.fullPath);
if(!Files.isDirectory(path)) if (!Files.isDirectory(path)) {
{
LogHelper.error("Directory %s not found", path.toAbsolutePath().toString()); LogHelper.error("Directory %s not found", path.toAbsolutePath().toString());
return; return;
} }
Path target = Paths.get(SettingsManager.settings.updatesDirPath).resolve(e.name); Path target = Paths.get(SettingsManager.settings.updatesDirPath).resolve(e.name);
if(Files.exists(target)) if (Files.exists(target)) {
{
LogHelper.error("Directory %s already exists", target.toAbsolutePath().toString()); LogHelper.error("Directory %s already exists", target.toAbsolutePath().toString());
return; return;
} }

View file

@ -19,8 +19,7 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
int ind = 1; int ind = 1;
for(NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) for (NewLauncherSettings.HashedStoreEntry e : SettingsManager.settings.lastHDirs) {
{
LogHelper.info("[%d] FullPath: %s name: %s", ind, e.fullPath, e.name); LogHelper.info("[%d] FullPath: %s name: %s", ind, e.fullPath, e.name);
ind++; ind++;
} }

View file

@ -0,0 +1,94 @@
package ru.gravit.launcher.guard;
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launcher.bridge.GravitGuardBridge;
import ru.gravit.launcher.client.ClientLauncher;
import ru.gravit.launcher.client.ClientLauncherContext;
import ru.gravit.launcher.client.DirBridge;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.JVMHelper;
import ru.gravit.utils.helper.UnpackHelper;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
//Используется для всех типов защит, совместимых с новым GravitGuard API
public class LauncherGravitGuard implements LauncherGuardInterface {
public String protectToken;
public Path javaBinPath;
@Override
public String getName() {
return "wrapper";
}
@Override
public Path getJavaBinPath() {
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
String projectName = Launcher.getConfig().projectname;
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
} else if (ClientLauncher.getJavaBinPath() != null) {
javaBinPath = ClientLauncher.getJavaBinPath();
String projectName = Launcher.getConfig().projectname;
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
} else
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
}
@Override
public int getClientJVMBits() {
return JVMHelper.JVM_BITS;
}
@Override
public void init(boolean clientInstance) {
try {
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
String projectName = Launcher.getConfig().projectname;
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll";
UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"), DirBridge.getGuardDir().resolve(wrapperUnpackName));
UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"), DirBridge.getGuardDir().resolve(antiInjectName));
} catch (IOException e) {
throw new SecurityException(e);
}
if (clientInstance) GravitGuardBridge.callGuard();
}
@Override
public void addCustomParams(ClientLauncherContext context) {
Collections.addAll(context.args, "-Djava.class.path=".concat(context.pathLauncher));
}
@Override
public void addCustomEnv(ClientLauncherContext context) {
Map<String, String> env = context.builder.environment();
if (javaBinPath == null)
env.put("JAVA_HOME", System.getProperty("java.home"));
else
env.put("JAVA_HOME", javaBinPath.toAbsolutePath().toString());
LauncherConfig config = Launcher.getConfig();
env.put("GUARD_BRIDGE", GravitGuardBridge.class.getName());
env.put("GUARD_USERNAME", context.playerProfile.username);
env.put("GUARD_PUBLICKEY", config.publicKey.getModulus().toString(16));
env.put("GUARD_PROJECTNAME", config.projectname);
if (protectToken != null)
env.put("GUARD_TOKEN", protectToken);
if (config.guardLicenseName != null)
env.put("GUARD_LICENSE_NAME", config.guardLicenseName);
if (config.guardLicenseKey != null) {
env.put("GUARD_LICENSE_KEY", config.guardLicenseKey);
}
}
@Override
public void setProtectToken(String token) {
protectToken = token;
}
}

View file

@ -11,6 +11,10 @@ public class LauncherGuardManager {
public static void initGuard(boolean clientInstance) { public static void initGuard(boolean clientInstance) {
LauncherConfig config = Launcher.getConfig(); LauncherConfig config = Launcher.getConfig();
switch (config.guardType) { switch (config.guardType) {
case "gravitguard": {
guard = new LauncherGravitGuard();
break;
}
case "wrapper": { case "wrapper": {
guard = new LauncherWrapperGuard(); guard = new LauncherWrapperGuard();
break; break;

View file

@ -25,8 +25,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
String fullPath = input.readString(1024); String fullPath = input.readString(1024);
HashedDir dir = new HashedDir(input); HashedDir dir = new HashedDir(input);
settings.lastHDirs.add(new NewLauncherSettings.HashedStoreEntry(dir, dirName, fullPath)); settings.lastHDirs.add(new NewLauncherSettings.HashedStoreEntry(dir, dirName, fullPath));
} catch (IOException e) } catch (IOException e) {
{
LogHelper.error("Skip file %s exception: %s", file.toAbsolutePath().toString(), e.getMessage()); LogHelper.error("Skip file %s exception: %s", file.toAbsolutePath().toString(), e.getMessage());
} }
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
@ -61,10 +60,8 @@ public void setConfig(NewLauncherSettings config) {
settings = config; settings = config;
if (settings.updatesDirPath != null) if (settings.updatesDirPath != null)
settings.updatesDir = Paths.get(settings.updatesDirPath); settings.updatesDir = Paths.get(settings.updatesDirPath);
if(settings.consoleUnlockKey != null && !ConsoleManager.isConsoleUnlock) if (settings.consoleUnlockKey != null && !ConsoleManager.isConsoleUnlock) {
{ if (ConsoleManager.checkUnlockKey(settings.consoleUnlockKey)) {
if(ConsoleManager.checkUnlockKey(settings.consoleUnlockKey))
{
ConsoleManager.unlock(); ConsoleManager.unlock();
LogHelper.info("Console auto unlocked"); LogHelper.info("Console auto unlocked");
} }
@ -81,7 +78,7 @@ public void loadHDirStore(Path storePath) throws IOException {
public void saveHDirStore(Path storeProjectPath) throws IOException { public void saveHDirStore(Path storeProjectPath) throws IOException {
Files.createDirectories(storeProjectPath); Files.createDirectories(storeProjectPath);
for (NewLauncherSettings.HashedStoreEntry e : settings.lastHDirs) { for (NewLauncherSettings.HashedStoreEntry e : settings.lastHDirs) {
if(!e.needSave) continue; if (!e.needSave) continue;
Path file = storeProjectPath.resolve(e.name.concat(".bin")); Path file = storeProjectPath.resolve(e.name.concat(".bin"));
if (!Files.exists(file)) Files.createFile(file); if (!Files.exists(file)) Files.createFile(file);
try (HOutput output = new HOutput(IOHelper.newOutput(file))) { try (HOutput output = new HOutput(IOHelper.newOutput(file))) {

View file

@ -4,5 +4,5 @@
dependencies { dependencies {
compile project(':LauncherCore') compile project(':LauncherCore')
compileOnly 'org.apache.httpcomponents:httpclient:4.5.7' compileOnly 'org.apache.httpcomponents:httpclient:4.5.7'
compileOnly 'io.netty:netty-all:4.1.36.Final' compileOnly 'io.netty:netty-codec-http:4.1.36.Final'
} }

View file

@ -33,7 +33,7 @@ public JsonConfigurable(Type type, Path configPath) {
@LauncherAPI @LauncherAPI
public void saveConfig(Path configPath) throws IOException { public void saveConfig(Path configPath) throws IOException {
try (BufferedWriter writer = IOHelper.newWriter(configPath)) { try (BufferedWriter writer = IOHelper.newWriter(configPath)) {
Launcher.gsonManager.gson.toJson(getConfig(), type, writer); Launcher.gsonManager.configGson.toJson(getConfig(), type, writer);
} }
} }
@ -41,7 +41,7 @@ public void saveConfig(Path configPath) throws IOException {
public void loadConfig(Path configPath) throws IOException { public void loadConfig(Path configPath) throws IOException {
if (generateConfigIfNotExists(configPath)) return; if (generateConfigIfNotExists(configPath)) return;
try (BufferedReader reader = IOHelper.newReader(configPath)) { try (BufferedReader reader = IOHelper.newReader(configPath)) {
setConfig(Launcher.gsonManager.gson.fromJson(reader, type)); setConfig(Launcher.gsonManager.configGson.fromJson(reader, type));
} }
} }

View file

@ -62,6 +62,7 @@ public void download(String base, List<DownloadTask> applies, Path dstDirFile, D
} }
} }
} }
public void downloadZip(String base, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException { public void downloadZip(String base, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException {
/*try (CloseableHttpClient httpclient = HttpClients.custom() /*try (CloseableHttpClient httpclient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy()) .setRedirectStrategy(new LaxRedirectStrategy())
@ -132,23 +133,18 @@ public FileDownloadResponseHandler(Path target, DownloadCallback callback, Downl
@Override @Override
public Path handleResponse(HttpResponse response) throws IOException { public Path handleResponse(HttpResponse response) throws IOException {
InputStream source = response.getEntity().getContent(); InputStream source = response.getEntity().getContent();
if(zip) if (zip) {
{ try (ZipInputStream input = IOHelper.newZipInput(source)) {
try(ZipInputStream input = IOHelper.newZipInput(source))
{
ZipEntry entry = input.getNextEntry(); ZipEntry entry = input.getNextEntry();
while(entry != null) while (entry != null) {
{ if (entry.isDirectory()) {
if(entry.isDirectory())
{
entry = input.getNextEntry(); entry = input.getNextEntry();
continue; continue;
} }
long size = entry.getSize(); long size = entry.getSize();
String filename = entry.getName(); String filename = entry.getName();
Path target = this.target.resolve(filename); Path target = this.target.resolve(filename);
if(callback != null) if (callback != null) {
{
callback.stateChanged(entry.getName(), 0, entry.getSize()); callback.stateChanged(entry.getName(), 0, entry.getSize());
} }
LogHelper.dev("Resolved filename %s to %s", filename, target.toAbsolutePath().toString()); LogHelper.dev("Resolved filename %s to %s", filename, target.toAbsolutePath().toString());

View file

@ -1,60 +0,0 @@
package ru.gravit.launcher.request;
import ru.gravit.launcher.hasher.HashedEntry;
import ru.gravit.launcher.serialize.HInput;
import ru.gravit.launcher.serialize.HOutput;
import ru.gravit.launcher.serialize.stream.EnumSerializer;
import ru.gravit.launcher.serialize.stream.StreamObject;
import ru.gravit.utils.helper.IOHelper;
import java.io.IOException;
public final class UpdateAction extends StreamObject {
public enum Type implements EnumSerializer.Itf {
CD(1), CD_BACK(2), GET(3), FINISH(255);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
public static Type read(HInput input) throws IOException {
return SERIALIZER.read(input);
}
private final int n;
Type(int n) {
this.n = n;
}
@Override
public int getNumber() {
return n;
}
}
public static final UpdateAction CD_BACK = new UpdateAction(Type.CD_BACK, null, null);
public static final UpdateAction FINISH = new UpdateAction(Type.FINISH, null, null);
// Instance
public final Type type;
public final String name;
public final HashedEntry entry;
public UpdateAction(HInput input) throws IOException {
type = Type.read(input);
name = type == Type.CD || type == Type.GET ? IOHelper.verifyFileName(input.readString(255)) : null;
entry = null;
}
public UpdateAction(Type type, String name, HashedEntry entry) {
this.type = type;
this.name = name;
this.entry = entry;
}
@Override
public void write(HOutput output) throws IOException {
EnumSerializer.write(output, type);
if (type == Type.CD || type == Type.GET)
output.writeString(name, 255);
}
}

View file

@ -27,15 +27,20 @@
import java.util.Objects; import java.util.Objects;
public final class UpdateRequest extends Request<UpdateRequestEvent> implements RequestInterface { public final class UpdateRequest extends Request<UpdateRequestEvent> implements RequestInterface {
public interface UpdateController public interface UpdateController {
{
void preUpdate(UpdateRequest request, UpdateRequestEvent e) throws IOException; void preUpdate(UpdateRequest request, UpdateRequestEvent e) throws IOException;
void preDiff(UpdateRequest request, UpdateRequestEvent e) throws IOException; void preDiff(UpdateRequest request, UpdateRequestEvent e) throws IOException;
void postDiff(UpdateRequest request, UpdateRequestEvent e,HashedDir.Diff diff) throws IOException;
void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff diff) throws IOException;
void preDownload(UpdateRequest request, UpdateRequestEvent e, List<ListDownloader.DownloadTask> adds) throws IOException; void preDownload(UpdateRequest request, UpdateRequestEvent e, List<ListDownloader.DownloadTask> adds) throws IOException;
void postDownload(UpdateRequest request, UpdateRequestEvent e) throws IOException; void postDownload(UpdateRequest request, UpdateRequestEvent e) throws IOException;
void postUpdate(UpdateRequest request, UpdateRequestEvent e) throws IOException; void postUpdate(UpdateRequest request, UpdateRequestEvent e) throws IOException;
} }
private static UpdateController controller; private static UpdateController controller;
public static void setController(UpdateController controller) { public static void setController(UpdateController controller) {
@ -184,18 +189,17 @@ public double getTotalSizeMiB() {
public UpdateRequestEvent requestDo(StandartClientWebSocketService service) throws Exception { public UpdateRequestEvent requestDo(StandartClientWebSocketService service) throws Exception {
LogHelper.debug("Start update request"); LogHelper.debug("Start update request");
UpdateRequestEvent e = (UpdateRequestEvent) service.sendRequest(this); UpdateRequestEvent e = (UpdateRequestEvent) service.sendRequest(this);
if(controller != null) controller.preUpdate(this, e); if (controller != null) controller.preUpdate(this, e);
LogHelper.debug("Start update"); LogHelper.debug("Start update");
Launcher.profile.pushOptionalFile(e.hdir, !Launcher.profile.isUpdateFastCheck()); Launcher.profile.pushOptionalFile(e.hdir, !Launcher.profile.isUpdateFastCheck());
if(controller != null) controller.preDiff(this, e); if (controller != null) controller.preDiff(this, e);
HashedDir.Diff diff = e.hdir.diff(localDir, matcher); HashedDir.Diff diff = e.hdir.diff(localDir, matcher);
if(controller != null) controller.postDiff(this, e, diff); if (controller != null) controller.postDiff(this, e, diff);
final List<ListDownloader.DownloadTask> adds = new ArrayList<>(); final List<ListDownloader.DownloadTask> adds = new ArrayList<>();
if(controller != null) controller.preDownload(this, e, adds); if (controller != null) controller.preDownload(this, e, adds);
diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> { diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> {
if (entry.getType().equals(HashedEntry.Type.FILE)) { if (entry.getType().equals(HashedEntry.Type.FILE)) {
if(!entry.flag) if (!entry.flag) {
{
HashedFile file = (HashedFile) entry; HashedFile file = (HashedFile) entry;
totalSize += file.size; totalSize += file.size;
adds.add(new ListDownloader.DownloadTask(path, file.size)); adds.add(new ListDownloader.DownloadTask(path, file.size));
@ -214,17 +218,14 @@ public UpdateRequestEvent requestDo(StandartClientWebSocketService service) thro
updateState("UnknownFile", 0L, 100); updateState("UnknownFile", 0L, 100);
ListDownloader listDownloader = new ListDownloader(); ListDownloader listDownloader = new ListDownloader();
LogHelper.info("Download %s to %s", dirName, dir.toAbsolutePath().toString()); LogHelper.info("Download %s to %s", dirName, dir.toAbsolutePath().toString());
if(e.zip && !adds.isEmpty()) if (e.zip && !adds.isEmpty()) {
{
listDownloader.downloadZip(e.url, dir, this::updateState, (add) -> totalDownloaded += add); listDownloader.downloadZip(e.url, dir, this::updateState, (add) -> totalDownloaded += add);
} } else {
else
{
listDownloader.download(e.url, adds, dir, this::updateState, (add) -> totalDownloaded += add); listDownloader.download(e.url, adds, dir, this::updateState, (add) -> totalDownloaded += add);
} }
if(controller != null) controller.postDownload(this, e); if (controller != null) controller.postDownload(this, e);
deleteExtraDir(dir, diff.extra, diff.extra.flag); deleteExtraDir(dir, diff.extra, diff.extra.flag);
if(controller != null) controller.postUpdate(this, e); if (controller != null) controller.postUpdate(this, e);
LogHelper.debug("Update success"); LogHelper.debug("Update success");
return e; return e;
} }

View file

@ -63,7 +63,7 @@ public ResultInterface get() throws InterruptedException, ExecutionException {
} }
ResultInterface result = event.result; ResultInterface result = event.result;
waitEventHandler.requests.remove(event); waitEventHandler.requests.remove(event);
if (event.result.getType().equals("error")) { if (event.result.getType().equals("error") || event.result.getType().equals("exception")) {
ErrorRequestEvent errorRequestEvent = (ErrorRequestEvent) event.result; ErrorRequestEvent errorRequestEvent = (ErrorRequestEvent) event.result;
throw new ExecutionException(new RequestException(errorRequestEvent.error)); throw new ExecutionException(new RequestException(errorRequestEvent.error));
} }
@ -80,7 +80,7 @@ public ResultInterface get(long timeout, TimeUnit unit) throws InterruptedExcept
} }
ResultInterface result = event.result; ResultInterface result = event.result;
waitEventHandler.requests.remove(event); waitEventHandler.requests.remove(event);
if (event.result.getType().equals("error")) { if (event.result.getType().equals("error") || event.result.getType().equals("exception")) {
ErrorRequestEvent errorRequestEvent = (ErrorRequestEvent) event.result; ErrorRequestEvent errorRequestEvent = (ErrorRequestEvent) event.result;
throw new ExecutionException(new RequestException(errorRequestEvent.error)); throw new ExecutionException(new RequestException(errorRequestEvent.error));
} }

View file

@ -342,8 +342,8 @@ public void walk(CharSequence separator, WalkCallback callback) throws IOExcepti
String append = ""; String append = "";
walk(append, separator, callback, true); walk(append, separator, callback, true);
} }
public enum WalkAction
{ public enum WalkAction {
STOP, CONTINUE STOP, CONTINUE
} }
@ -356,24 +356,21 @@ private WalkAction walk(String append, CharSequence separator, WalkCallback call
for (Map.Entry<String, HashedEntry> entry : map.entrySet()) { for (Map.Entry<String, HashedEntry> entry : map.entrySet()) {
HashedEntry e = entry.getValue(); HashedEntry e = entry.getValue();
if (e.getType() == Type.FILE) { if (e.getType() == Type.FILE) {
if (noSeparator) if (noSeparator) {
{
WalkAction a = callback.walked(append + entry.getKey(), entry.getKey(), e); WalkAction a = callback.walked(append + entry.getKey(), entry.getKey(), e);
if(a == WalkAction.STOP) return a; if (a == WalkAction.STOP) return a;
} } else {
else
{
WalkAction a = callback.walked(append + separator + entry.getKey(), entry.getKey(), e); WalkAction a = callback.walked(append + separator + entry.getKey(), entry.getKey(), e);
if(a == WalkAction.STOP) return a; if (a == WalkAction.STOP) return a;
} }
} else { } else {
String newAppend; String newAppend;
if (noSeparator) newAppend = append + entry.getKey(); if (noSeparator) newAppend = append + entry.getKey();
else newAppend = append + separator + entry.getKey(); else newAppend = append + separator + entry.getKey();
WalkAction a = callback.walked(newAppend, entry.getKey(), e); WalkAction a = callback.walked(newAppend, entry.getKey(), e);
if(a == WalkAction.STOP) return a; if (a == WalkAction.STOP) return a;
a = ((HashedDir) e).walk(newAppend, separator, callback, false); a = ((HashedDir) e).walk(newAppend, separator, callback, false);
if(a == WalkAction.STOP) return a; if (a == WalkAction.STOP) return a;
} }
} }
return WalkAction.CONTINUE; return WalkAction.CONTINUE;

View file

@ -4,6 +4,7 @@
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ru.gravit.launcher.hasher.HashedEntry; import ru.gravit.launcher.hasher.HashedEntry;
import ru.gravit.launcher.hasher.HashedEntryAdapter; import ru.gravit.launcher.hasher.HashedEntryAdapter;
import ru.gravit.utils.helper.CommonHelper;
public class GsonManager { public class GsonManager {
public GsonBuilder gsonBuilder; public GsonBuilder gsonBuilder;
@ -12,8 +13,8 @@ public class GsonManager {
public Gson configGson; public Gson configGson;
public void initGson() { public void initGson() {
gsonBuilder = new GsonBuilder(); gsonBuilder = CommonHelper.newBuilder();
configGsonBuilder = new GsonBuilder(); configGsonBuilder = CommonHelper.newBuilder();
configGsonBuilder.setPrettyPrinting(); configGsonBuilder.setPrettyPrinting();
registerAdapters(gsonBuilder); registerAdapters(gsonBuilder);
registerAdapters(configGsonBuilder); registerAdapters(configGsonBuilder);

View file

@ -17,7 +17,7 @@ public final class Version {
public final Type release; public final Type release;
public static final int MAJOR = 5; public static final int MAJOR = 5;
public static final int MINOR = 0; public static final int MINOR = 0;
public static final int PATCH = 1; public static final int PATCH = 2;
public static final int BUILD = 1; public static final int BUILD = 1;
public static final Version.Type RELEASE = Version.Type.STABLE; public static final Version.Type RELEASE = Version.Type.STABLE;

View file

@ -6,6 +6,18 @@
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.util.Base64;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Locale; import java.util.Locale;
@ -120,4 +132,23 @@ public static String[] parseCommand(CharSequence line) throws CommandException {
// Return result as array // Return result as array
return result.toArray(new String[0]); return result.toArray(new String[0]);
} }
@LauncherAPI
public static GsonBuilder newBuilder() {
return new GsonBuilder().registerTypeHierarchyAdapter(byte[].class,
ByteArrayToBase64TypeAdapter.INSTANCE);
}
private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
private static final ByteArrayToBase64TypeAdapter INSTANCE = new ByteArrayToBase64TypeAdapter();
private Base64.Decoder decoder = Base64.getUrlDecoder();
private Base64.Encoder encoder = Base64.getUrlEncoder();
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return decoder.decode(json.getAsString());
}
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(encoder.encodeToString(src));
}
}
} }

View file

@ -113,8 +113,7 @@ public static void debug(String format, Object... args) {
@LauncherAPI @LauncherAPI
public static void dev(String format, Object... args) { public static void dev(String format, Object... args) {
if(isDevEnabled()) if (isDevEnabled()) {
{
dev(String.format(format, args)); dev(String.format(format, args));
} }
} }

View file

@ -29,7 +29,7 @@
dependencies { dependencies {
pack project(':LauncherAuthlib') pack project(':LauncherAuthlib')
pack 'org.apache.httpcomponents:httpclient:4.5.7' pack 'org.apache.httpcomponents:httpclient:4.5.7'
pack 'io.netty:netty-all:4.1.36.Final' pack 'io.netty:netty-codec-http:4.1.36.Final'
} }
shadowJar { shadowJar {

@ -1 +1 @@
Subproject commit baf1e7fb820fd1f4a1031e517fea03632f9e57e6 Subproject commit 5c3aa4d10e6973799315c5befed2ecb7cd98b203