diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java index a696c718..214fa8e5 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java @@ -85,7 +85,7 @@ public static final class Config extends ConfigObject { public final ExeConf launch4j; - public final SignConf sign; + public final PostBuildTransformConf buildPostTransform; public final boolean compress; @@ -148,7 +148,7 @@ private Config(BlockConfigEntry block, Path coredir, LaunchServer server) { genMappings = block.getEntryValue("proguardPrintMappings", BooleanConfigEntry.class); mirrors = block.getEntry("mirrors", ListConfigEntry.class); launch4j = new ExeConf(block.getEntry("launch4J", BlockConfigEntry.class)); - sign = new SignConf(block.getEntry("signing", BlockConfigEntry.class), coredir); + buildPostTransform = new PostBuildTransformConf(block.getEntry("buildExtendedOperation", BlockConfigEntry.class), coredir); binaryName = block.getEntryValue("binaryName", StringConfigEntry.class); projectName = block.hasEntry("projectName") ? block.getEntryValue("projectName", StringConfigEntry.class) : "Minecraft"; compress = block.getEntryValue("compress", BooleanConfigEntry.class); @@ -185,16 +185,16 @@ public void verify() { public static class ExeConf extends ConfigObject { public final boolean enabled; - public String productName; - public String productVer; - public String fileDesc; - public String fileVer; - public String internalName; - public String copyright; - public String trademarks; + public final String productName; + public final String productVer; + public final String fileDesc; + public final String fileVer; + public final String internalName; + public final String copyright; + public final String trademarks; - public String txtFileVersion; - public String txtProductVersion; + public final String txtFileVersion; + public final String txtProductVersion; private ExeConf(BlockConfigEntry block) { super(block); @@ -243,30 +243,14 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO } } - public static class SignConf extends ConfigObject { + public static class PostBuildTransformConf extends ConfigObject { public final boolean enabled; - public String algo; - public Path key; - public boolean hasStorePass; - public String storepass; - public boolean hasPass; - public String pass; - public String keyalias; + public String script; - private SignConf(BlockConfigEntry block, Path coredir) { + private PostBuildTransformConf(BlockConfigEntry block, Path coredir) { super(block); enabled = block.getEntryValue("enabled", BooleanConfigEntry.class); - storepass = null; - pass = null; - if (enabled) { - algo = block.hasEntry("storeType") ? block.getEntryValue("storeType", StringConfigEntry.class) : "JKS"; - key = coredir.resolve(block.getEntryValue("keyFile", StringConfigEntry.class)); - hasStorePass = block.hasEntry("keyStorePass"); - if (hasStorePass) storepass = block.getEntryValue("keyStorePass", StringConfigEntry.class); - keyalias = block.getEntryValue("keyAlias", StringConfigEntry.class); - hasPass = block.hasEntry("keyPass"); - if (hasPass) pass = block.getEntryValue("keyPass", StringConfigEntry.class); - } + script = enabled && block.hasEntry("script") ? block.getEntryValue("script", StringConfigEntry.class) : null; } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/ProguardConf.java b/LaunchServer/src/main/java/ru/gravit/launchserver/ProguardConf.java index 65963f1d..ba2f7a39 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/ProguardConf.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/ProguardConf.java @@ -42,8 +42,8 @@ public ProguardConf(LaunchServer srv) { prepare(false); if (srv1.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'"); confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'"); - confStrs.add("-injar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + ".jar\'"); - confStrs.add("-outjar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-obf.jar\'"); + confStrs.add("-injar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-nonObf.jar\'"); + confStrs.add("-outjar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + ".jar\'"); confStrs.add("-classobfuscationdictionary \'" + words.toFile().getName() + "\'"); confStrs.add(readConf()); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java index 91c52d59..9f4b254e 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java @@ -9,6 +9,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; +import java.util.StringTokenizer; import java.util.Map.Entry; import java.util.zip.ZipEntry; import java.util.zip.ZipException; @@ -20,6 +21,8 @@ import ru.gravit.launcher.AutogenConfig; import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.utils.helper.CommonHelper; +import ru.gravit.utils.helper.EnvHelper; import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.SecurityHelper; @@ -115,12 +118,12 @@ private static ZipEntry newGuardEntry(String fileName) { public JARLauncherBinary(LaunchServer server) throws IOException { - super(server, server.dir.resolve(server.config.binaryName + ".jar"), - server.dir.resolve(server.config.binaryName + (server.config.sign.enabled ? "-sign.jar" : "-obf.jar"))); + super(server, server.dir.resolve(server.config.binaryName + "-nonObf.jar"), + server.dir.resolve(server.config.binaryName + (server.config.buildPostTransform.enabled ? ".jar" : "-obf.jar"))); runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR); guardDir = server.dir.resolve("guard"); initScriptFile = runtimeDir.resolve(Launcher.INIT_SCRIPT_FILE); - obfJar = server.config.sign.enabled ? server.dir.resolve(server.config.binaryName + "-obf.jar") + obfJar = server.config.buildPostTransform.enabled ? server.dir.resolve(server.config.binaryName + "-obf.jar") : syncBinaryFile; tryUnpackRuntime(); } @@ -176,22 +179,26 @@ public void build() throws IOException { } } } - if (server.config.sign.enabled) - signBuild(); + if (server.config.buildPostTransform.enabled) + transformedBuild(); } - private void signBuild() throws IOException { - try (SignerJar output = new SignerJar(IOHelper.newOutput(syncBinaryFile), - SignerJar.getStore(server.config.sign.key, server.config.sign.storepass, server.config.sign.algo), - server.config.sign.keyalias, server.config.sign.pass); - ZipInputStream input = new ZipInputStream(IOHelper.newInput(obfJar))) { - ZipEntry e = input.getNextEntry(); - while (e != null) { - output.addFileContents(e, input); - e = input.getNextEntry(); - - } - } + private void transformedBuild() throws IOException { + String cmd = CommonHelper.replace(server.config.buildPostTransform.script, "launcher-output", IOHelper.toAbsPathString(syncBinaryFile), "launcher-obf", IOHelper.toAbsPathString(obfJar), "launcher-nonObf", IOHelper.toAbsPathString(binaryFile)); + ProcessBuilder builder = new ProcessBuilder(); + builder.directory(IOHelper.toAbsPath(server.dir).toFile()); + builder.inheritIO(); + StringTokenizer st = new StringTokenizer(cmd); + String[] cmdarray = new String[st.countTokens()]; + for (int i = 0; st.hasMoreTokens(); i++) + cmdarray[i] = st.nextToken(); + builder.command(cmdarray); + Process proc = builder.start(); + try { + LogHelper.debug("Transformer process return code: " + proc.waitFor()); + } catch (InterruptedException e) { + LogHelper.error(e); + } } private void stdBuild() throws IOException { diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/SignerJar.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/SignerJar.java deleted file mode 100644 index 3786c46a..00000000 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/SignerJar.java +++ /dev/null @@ -1,442 +0,0 @@ -package ru.gravit.launchserver.binary; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Path; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Security; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.Manifest; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.CMSSignedData; -import org.bouncycastle.cms.CMSSignedDataGenerator; -import org.bouncycastle.cms.CMSTypedData; -import org.bouncycastle.cms.SignerInfoGenerator; -import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.DigestCalculatorProvider; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.bouncycastle.util.Store; - -import ru.gravit.utils.helper.IOHelper; - - -/** - * Generator of signed Jars. It stores some data in memory therefore it is not suited for creation of large files. The - * usage: - *
- * KeyStore keystore = KeyStore.getInstance("JKS");
- * keyStore.load(keystoreStream, "keystorePassword");
- * SignerJar jar = new SignerJar(out, keyStore, "keyAlias", "keyPassword");
- * signedJar.addManifestAttribute("Main-Class", "com.example.MainClass");
- * signedJar.addManifestAttribute("Application-Name", "Example");
- * signedJar.addManifestAttribute("Permissions", "all-permissions");
- * signedJar.addManifestAttribute("Codebase", "*");
- * signedJar.addFileContents("com/example/MainClass.class", clsData);
- * signedJar.addFileContents("JNLP-INF/APPLICATION.JNLP", generateJnlpContents());
- * signedJar.close();
- * 
- */ -public class SignerJar implements AutoCloseable { - /** - * Helper output stream that also sends the data to the given {@link com.google.common.hash.Hasher}. - */ - private static class HashingOutputStream extends OutputStream { - private final OutputStream out; - private final MessageDigest hasher; - - public HashingOutputStream(OutputStream out, MessageDigest hasher) { - this.out = out; - this.hasher = hasher; - } - - @Override - public void close() throws IOException { - out.close(); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void write(byte[] b) throws IOException { - out.write(b); - hasher.update(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - hasher.update(b, off, len); - } - - @Override - public void write(int b) throws IOException { - out.write(b); - hasher.update((byte) b); - } - } - - private static final String MANIFEST_FN = "META-INF/MANIFEST.MF"; - private static final String SIG_FN = "META-INF/SIGNUMO.SF"; - - private static final String SIG_RSA_FN = "META-INF/SIGNUMO.RSA"; - - private static final String hashFunctionName = "SHA-256"; - - public static KeyStore getStore(Path file, String storepass, String algo) throws IOException { - try { - KeyStore st = KeyStore.getInstance(algo); - st.load(IOHelper.newInput(file), storepass != null ? storepass.toCharArray() : null); - return st; - } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException e) { - throw new IOException(e); - } - } - - private static MessageDigest hasher() { - try { - return MessageDigest.getInstance(hashFunctionName); - } catch (NoSuchAlgorithmException e) { - return null; - } - } - - private final ZipOutputStream zos; - - private final KeyStore keyStore; - - private final String keyAlias; - - private final String password; - private final Map manifestAttributes; - private String manifestHash; - private String manifestMainHash; - - private final Map fileDigests; - - private final Map sectionDigests; - - /** - * Constructor. - * - * @param out the output stream to write JAR data to - * @param keyStore the key store to load given key from - * @param keyAlias the name of the key in the store, this key is used to sign the JAR - * @param keyPassword the password to access the key - */ - public SignerJar(OutputStream out, KeyStore keyStore, String keyAlias, String keyPassword) { - zos = new ZipOutputStream(out); - this.keyStore = keyStore; - this.keyAlias = keyAlias; - password = keyPassword; - - manifestAttributes = new LinkedHashMap<>(); - fileDigests = new LinkedHashMap<>(); - sectionDigests = new LinkedHashMap<>(); - } - - /** - * Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once - * the stream is closed. - * - * @param filename name of the file to add (use forward slash as a path separator) - * @param contents contents of the file - * @throws java.io.IOException - * @throws NullPointerException if any of the arguments is {@code null} - */ - public void addFileContents(String filename, byte[] contents) throws IOException { - zos.putNextEntry(new ZipEntry(filename)); - zos.write(contents); - zos.closeEntry(); - - String hashCode64 = Base64.getEncoder().encodeToString(hasher().digest(contents)); - fileDigests.put(filename, hashCode64); - } - - /** - * Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once - * the stream is closed. - * - * @param filename name of the file to add (use forward slash as a path separator) - * @param contents contents of the file - * @throws java.io.IOException - * @throws NullPointerException if any of the arguments is {@code null} - */ - public void addFileContents(String filename, InputStream contents) throws IOException { - zos.putNextEntry(new ZipEntry(filename)); - byte[] arr = IOHelper.toByteArray(contents); - zos.write(arr); - zos.closeEntry(); - - String hashCode64 = Base64.getEncoder().encodeToString(hasher().digest(arr)); - fileDigests.put(filename, hashCode64); - } - - /** - * Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once - * the stream is closed. - * - * @param entry name of the file to add (use forward slash as a path separator) - * @param contents contents of the file - * @throws java.io.IOException - * @throws NullPointerException if any of the arguments is {@code null} - */ - public void addFileContents(ZipEntry entry, byte[] contents) throws IOException { - zos.putNextEntry(entry); - zos.write(contents); - zos.closeEntry(); - - String hashCode64 = Base64.getEncoder().encodeToString(hasher().digest(contents)); - fileDigests.put(entry.getName(), hashCode64); - } - - /** - * Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once - * the stream is closed. - * - * @param entry name of the file to add (use forward slash as a path separator) - * @param contents contents of the file - * @throws java.io.IOException - * @throws NullPointerException if any of the arguments is {@code null} - */ - public void addFileContents(ZipEntry entry, InputStream contents) throws IOException { - zos.putNextEntry(entry); - byte[] arr = IOHelper.toByteArray(contents); - zos.write(arr); - zos.closeEntry(); - - String hashCode64 = Base64.getEncoder().encodeToString(hasher().digest(arr)); - fileDigests.put(entry.getName(), hashCode64); - } - - /** - * Adds a header to the manifest of the JAR. - * - * @param name name of the attribute, it is placed into the main section of the manifest file, it cannot be longer - * than {@value #MANIFEST_ATTR_MAX_LEN} bytes (in utf-8 encoding) - * @param value value of the attribute - */ - public void addManifestAttribute(String name, String value) { - manifestAttributes.put(name, value); - } - - - /** - * Closes the JAR file by writing the manifest and signature data to it and finishing the ZIP entries. It closes the - * underlying stream. - * - * @throws java.io.IOException - * @throws RuntimeException if the signing goes wrong - */ - @Override - public void close() throws IOException { - finish(); - zos.close(); - } - - /** - * Creates the beast that can actually sign the data. - */ - private CMSSignedDataGenerator createSignedDataGenerator() throws Exception { - Security.addProvider(new BouncyCastleProvider()); - - List certChain = new ArrayList<>(Arrays.asList(keyStore.getCertificateChain(keyAlias))); - Store certStore = new JcaCertStore(certChain); - Certificate cert = keyStore.getCertificate(keyAlias); - PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, password != null ? password.toCharArray() : null); - ContentSigner signer = new JcaContentSignerBuilder("SHA256WITHRSA").setProvider("BC").build(privateKey); - CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); - DigestCalculatorProvider dcp = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(); - SignerInfoGenerator sig = new JcaSignerInfoGeneratorBuilder(dcp).build(signer, (X509Certificate) cert); - generator.addSignerInfoGenerator(sig); - generator.addCertificates(certStore); - return generator; - } - - - /** - * Finishes the JAR file by writing the manifest and signature data to it and finishing the ZIP entries. It leaves the - * underlying stream open. - * - * @throws java.io.IOException - * @throws RuntimeException if the signing goes wrong - */ - public void finish() throws IOException { - writeManifest(); - byte sig[] = writeSigFile(); - writeSignature(sig); - zos.finish(); - } - - public ZipOutputStream getZos() { - return zos; - } - - /** - * Helper for {@link #writeManifest()} that creates the digest of one entry. - */ - private String hashEntrySection(String name, Attributes attributes) throws IOException { - Manifest manifest = new Manifest(); - manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); - ByteArrayOutputStream o = new ByteArrayOutputStream(); - manifest.write(o); - int emptyLen = o.toByteArray().length; - - manifest.getEntries().put(name, attributes); - - manifest.write(o); - byte[] ob = o.toByteArray(); - ob = Arrays.copyOfRange(ob, emptyLen, ob.length); - return Base64.getEncoder().encodeToString(hasher().digest(ob)); - } - - /** - * Helper for {@link #writeManifest()} that creates the digest of the main section. - */ - private String hashMainSection(Attributes attributes) throws IOException { - Manifest manifest = new Manifest(); - manifest.getMainAttributes().putAll(attributes); - MessageDigest hasher = hasher(); - SignerJar.HashingOutputStream o = new SignerJar.HashingOutputStream(new OutputStream() { - @Override - public String toString() { - return "NullOutputStream"; - } - - /** Discards the specified byte array. */ - @Override - public void write(byte[] b) { - } - - /** Discards the specified byte array. */ - @Override - public void write(byte[] b, int off, int len) { - } - - /** Discards the specified byte. */ - @Override - public void write(int b) { - } - }, hasher); - manifest.write(o); - return Base64.getEncoder().encodeToString(hasher.digest()); - } - - /** - * Returns the CMS signed data. - */ - private byte[] signSigFile(byte[] sigContents) throws Exception { - CMSSignedDataGenerator gen = createSignedDataGenerator(); - CMSTypedData cmsData = new CMSProcessableByteArray(sigContents); - CMSSignedData signedData = gen.generate(cmsData, true); - return signedData.getEncoded(); - } - - /** - * Writes the manifest to the JAR. It also calculates the digests that are required to be placed in the the signature - * file. - * - * @throws java.io.IOException - */ - private void writeManifest() throws IOException { - zos.putNextEntry(new ZipEntry(MANIFEST_FN)); - Manifest man = new Manifest(); - - // main section - Attributes mainAttributes = man.getMainAttributes(); - mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); - - for (Map.Entry entry : manifestAttributes.entrySet()) - mainAttributes.put(new Attributes.Name(entry.getKey()), entry.getValue()); - - // individual files sections - Attributes.Name digestAttr = new Attributes.Name(hashFunctionName + "-Digest"); - for (Map.Entry entry : fileDigests.entrySet()) { - Attributes attributes = new Attributes(); - man.getEntries().put(entry.getKey(), attributes); - attributes.put(digestAttr, entry.getValue()); - sectionDigests.put(entry.getKey(), hashEntrySection(entry.getKey(), attributes)); - } - - MessageDigest hasher = hasher(); - OutputStream out = new SignerJar.HashingOutputStream(zos, hasher); - man.write(out); - zos.closeEntry(); - - manifestHash = Base64.getEncoder().encodeToString(hasher.digest()); - manifestMainHash = hashMainSection(man.getMainAttributes()); - } - - /** - * Writes the .SIG file to the JAR. - * - * @return the contents of the file as bytes - */ - private byte[] writeSigFile() throws IOException { - zos.putNextEntry(new ZipEntry(SIG_FN)); - Manifest man = new Manifest(); - // main section - Attributes mainAttributes = man.getMainAttributes(); - mainAttributes.put(Attributes.Name.SIGNATURE_VERSION, "1.0"); - mainAttributes.put(new Attributes.Name(hashFunctionName + "-Digest-Manifest"), manifestHash); - mainAttributes.put(new Attributes.Name(hashFunctionName + "-Digest-Manifest-Main-Attributes"), manifestMainHash); - - // individual files sections - Attributes.Name digestAttr = new Attributes.Name(hashFunctionName + "-Digest"); - for (Map.Entry entry : sectionDigests.entrySet()) { - Attributes attributes = new Attributes(); - man.getEntries().put(entry.getKey(), attributes); - attributes.put(digestAttr, entry.getValue()); - } - - man.write(zos); - zos.closeEntry(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - man.write(baos); - return baos.toByteArray(); - } - - /** - * Signs the .SIG file and writes the signature (.RSA file) to the JAR. - * - * @throws java.io.IOException - * @throws RuntimeException if the signing failed - */ - private void writeSignature(byte[] sigFile) throws IOException { - zos.putNextEntry(new ZipEntry(SIG_RSA_FN)); - try { - byte[] signature = signSigFile(sigFile); - zos.write(signature); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException("Signing failed.", e); - } - zos.closeEntry(); - } -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/config.cfg b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/config.cfg index 8433f42c..51f09b3c 100644 --- a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/config.cfg +++ b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/config.cfg @@ -43,13 +43,9 @@ textureProviderConfig: { }; # Jar signing -signing: { +buildExtendedOperation: { enabled: false; - storeType: "JKS"; - keyFile: "sashok724.jks"; - keyStorePass: "PSP1004"; # You can remove if no store pass. - keyAlias: "sashok724"; - keyPass: "PSP1004"; # You can remove if no pass. + script: "java -jar myTransformer.jar %launcher-obf% %launcher-output% %launcher-nonObf%"; // The script to run }; # Binaries name diff --git a/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java index b0a7fc10..1d904f08 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java @@ -14,7 +14,6 @@ import java.util.List; public class ClientLauncherWrapper { - @LauncherAPI public static void main(String[] arguments) throws IOException, InterruptedException { LogHelper.printVersion("Launcher"); JVMHelper.checkStackTrace(ClientLauncherWrapper.class); diff --git a/Launcher/src/main/java/ru/gravit/launcher/JSApplication.java b/Launcher/src/main/java/ru/gravit/launcher/JSApplication.java index af005381..9c43985c 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/JSApplication.java +++ b/Launcher/src/main/java/ru/gravit/launcher/JSApplication.java @@ -5,7 +5,6 @@ import javafx.application.Application; import ru.gravit.launcher.LauncherAPI; -@LauncherAPI @SuppressWarnings("AbstractClassNeverImplemented") public abstract class JSApplication extends Application { private static final AtomicReference INSTANCE = new AtomicReference<>(); diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java index f4f03a8e..7bf4fa10 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java @@ -40,6 +40,7 @@ public final class UpdateRequest extends Request> public static final class State { @FunctionalInterface public interface Callback { + @LauncherAPI void call(State state); } diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java index 0d0533f2..6126ede8 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java @@ -609,7 +609,7 @@ public static void setSocketFlags(Socket socket) throws SocketException { } @LauncherAPI - public static String toAbs(Path path) { + public static String toAbsPathString(Path path) { return toAbsPath(path).toFile().getAbsolutePath(); }