3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
*.iml
 | 
			
		||||
.idea/
 | 
			
		||||
target/
 | 
			
		||||
target/
 | 
			
		||||
.fastRequest
 | 
			
		||||
							
								
								
									
										2
									
								
								block_url_keywords
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								block_url_keywords
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
https://account.jetbrains.com/lservice/rpc/validateKey.action
 | 
			
		||||
116.62.33.138
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
from cryptography import x509
 | 
			
		||||
from cryptography.hazmat.backends import default_backend
 | 
			
		||||
from cryptography.hazmat.primitives import hashes, serialization
 | 
			
		||||
from cryptography.hazmat.primitives.asymmetric import rsa
 | 
			
		||||
from cryptography.x509.oid import NameOID
 | 
			
		||||
 | 
			
		||||
one_day = datetime.timedelta(days=1)
 | 
			
		||||
ten_day = datetime.timedelta(days=3650)
 | 
			
		||||
today = datetime.datetime.today()
 | 
			
		||||
yesterday = today - one_day
 | 
			
		||||
tomorrow = today + ten_day
 | 
			
		||||
 | 
			
		||||
private_key = rsa.generate_private_key(
 | 
			
		||||
    public_exponent=65537,
 | 
			
		||||
    key_size=4096,
 | 
			
		||||
    backend=default_backend()
 | 
			
		||||
)
 | 
			
		||||
public_key = private_key.public_key()
 | 
			
		||||
builder = x509.CertificateBuilder()
 | 
			
		||||
 | 
			
		||||
builder = builder.subject_name(x509.Name([
 | 
			
		||||
    x509.NameAttribute(NameOID.COMMON_NAME, 'Novice'),
 | 
			
		||||
]))
 | 
			
		||||
builder = builder.issuer_name(x509.Name([
 | 
			
		||||
    x509.NameAttribute(NameOID.COMMON_NAME, 'JetProfile CA'),
 | 
			
		||||
]))
 | 
			
		||||
builder = builder.not_valid_before(yesterday)
 | 
			
		||||
builder = builder.not_valid_after(tomorrow)
 | 
			
		||||
builder = builder.serial_number(x509.random_serial_number())
 | 
			
		||||
builder = builder.public_key(public_key)
 | 
			
		||||
 | 
			
		||||
certificate = builder.sign(
 | 
			
		||||
    private_key=private_key, algorithm=hashes.SHA256(),
 | 
			
		||||
    backend=default_backend()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
private_bytes = private_key.private_bytes(
 | 
			
		||||
    encoding=serialization.Encoding.PEM,
 | 
			
		||||
    format=serialization.PrivateFormat.TraditionalOpenSSL,
 | 
			
		||||
    encryption_algorithm=serialization.NoEncryption())
 | 
			
		||||
public_bytes = certificate.public_bytes(
 | 
			
		||||
    encoding=serialization.Encoding.PEM)
 | 
			
		||||
with open("ca.key", "wb") as fout:
 | 
			
		||||
    fout.write(private_bytes)
 | 
			
		||||
with open("ca.crt", "wb") as fout:
 | 
			
		||||
    fout.write(public_bytes)
 | 
			
		||||
@@ -13,8 +13,8 @@
 | 
			
		||||
    <artifactId>jetbra-agent</artifactId>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <maven.compiler.source>17</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>17</maven.compiler.target>
 | 
			
		||||
        <maven.compiler.source>1.8</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>1.8</maven.compiler.target>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
    </properties>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
@@ -29,6 +29,13 @@
 | 
			
		||||
            <artifactId>byte-buddy-agent</artifactId>
 | 
			
		||||
            <version>1.14.8</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
            <artifactId>maven-assembly-plugin</artifactId>
 | 
			
		||||
            <version>3.3.0</version>
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,15 +11,18 @@ public class AgentMain {
 | 
			
		||||
    public static void premain(String agentArgs, Instrumentation inst) throws Exception {
 | 
			
		||||
        printLogo();
 | 
			
		||||
        AgentBuilder agentBuilder = newAgentBuilder();
 | 
			
		||||
        agentBuilder.type(ElementMatchers.named("java.security.cert.PKIXBuilderParameters"))
 | 
			
		||||
        agentBuilder
 | 
			
		||||
                .type(ElementMatchers.named("java.security.cert.PKIXBuilderParameters"))
 | 
			
		||||
                .transform((builder, typeDescription, classLoader, module, protectionDomain) -> builder
 | 
			
		||||
                        .visit(Advice.to(PKIXBuilderParametersAdvice.class)
 | 
			
		||||
                                .on(ElementMatchers.isConstructor().and(ElementMatchers.takesArgument(0, Set.class)))))
 | 
			
		||||
                .asTerminalTransformation()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                .type(ElementMatchers.named("sun.net.www.http.HttpClient"))
 | 
			
		||||
                .transform((builder, typeDescription, classLoader, module, protectionDomain) -> builder
 | 
			
		||||
                        .visit(Advice.to(HttpClientAdvice.class)
 | 
			
		||||
                                .on(ElementMatchers.named("openServer"))))
 | 
			
		||||
                                .on(ElementMatchers.named("openServer").and(ElementMatchers.takesArgument(0, String.class)))))
 | 
			
		||||
                .asTerminalTransformation()
 | 
			
		||||
 | 
			
		||||
                .type(ElementMatchers.named("java.lang.System"))
 | 
			
		||||
@@ -28,12 +31,6 @@ public class AgentMain {
 | 
			
		||||
                                .on(ElementMatchers.named("getProperty"))))
 | 
			
		||||
                .asTerminalTransformation()
 | 
			
		||||
 | 
			
		||||
                .type(ElementMatchers.named("java.net.Socket"))
 | 
			
		||||
                .transform((builder, typeDescription, classLoader, module, protectionDomain) -> builder
 | 
			
		||||
                        .visit(Advice.to(SocketAdvice.class)
 | 
			
		||||
                                .on(ElementMatchers.named("connect"))))
 | 
			
		||||
                .asTerminalTransformation()
 | 
			
		||||
 | 
			
		||||
                .installOn(inst);
 | 
			
		||||
 | 
			
		||||
        agentBuilder.installOn(inst);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package win.novice.li;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.Paths;
 | 
			
		||||
import java.security.cert.CertificateFactory;
 | 
			
		||||
import java.security.cert.TrustAnchor;
 | 
			
		||||
@@ -11,9 +11,9 @@ import java.security.cert.X509Certificate;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class TrustAnchorHolder {
 | 
			
		||||
public class ConfigHelper {
 | 
			
		||||
    public static Set<TrustAnchor> TRUST_ANCHORS;
 | 
			
		||||
 | 
			
		||||
    public static Set<String> BLOCK_URL_KEYWORDS;
 | 
			
		||||
 | 
			
		||||
    public static Set<TrustAnchor> loadTrustAnchors() throws Exception {
 | 
			
		||||
        if (TRUST_ANCHORS != null) {
 | 
			
		||||
@@ -22,8 +22,8 @@ public class TrustAnchorHolder {
 | 
			
		||||
        TRUST_ANCHORS = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
        String certDir;
 | 
			
		||||
        if (System.getenv("JB_HOME") != null) {
 | 
			
		||||
            certDir = System.getenv("JB_HOME");
 | 
			
		||||
        if (System.getenv("TRUST_CRT_DIR") != null) {
 | 
			
		||||
            certDir = System.getenv("TRUST_CRT_DIR");
 | 
			
		||||
        } else {
 | 
			
		||||
            URI jarURI = getJarURI();
 | 
			
		||||
            if (jarURI == null) {
 | 
			
		||||
@@ -39,23 +39,52 @@ public class TrustAnchorHolder {
 | 
			
		||||
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
 | 
			
		||||
                for (File item : files) {
 | 
			
		||||
                    if (item.getName().endsWith(".crt")) {
 | 
			
		||||
                        X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream(item));
 | 
			
		||||
                        X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(Files.newInputStream(item.toPath()));
 | 
			
		||||
                        TRUST_ANCHORS.add(new TrustAnchor(cert, null));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println("loaded "  + TRUST_ANCHORS.size() +  " crts");
 | 
			
		||||
        System.out.println("loaded " + TRUST_ANCHORS.size() + " crts");
 | 
			
		||||
        return TRUST_ANCHORS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Set<String> loadBlockUrlKeywords() throws Exception {
 | 
			
		||||
        if (BLOCK_URL_KEYWORDS != null) {
 | 
			
		||||
            return BLOCK_URL_KEYWORDS;
 | 
			
		||||
        }
 | 
			
		||||
        BLOCK_URL_KEYWORDS = new HashSet<>();
 | 
			
		||||
        String blockUrlKeywordFilePath;
 | 
			
		||||
        if (System.getenv("BLOCK_URL_KEYWORD_FILE_PATH") != null) {
 | 
			
		||||
            blockUrlKeywordFilePath = System.getenv("BLOCK_URL_KEYWORD_FILE_PATH");
 | 
			
		||||
        } else {
 | 
			
		||||
            URI jarURI = getJarURI();
 | 
			
		||||
            if (jarURI == null) {
 | 
			
		||||
                return BLOCK_URL_KEYWORDS;
 | 
			
		||||
            }
 | 
			
		||||
            blockUrlKeywordFilePath = Paths.get(jarURI).getParent().resolve("block_url_keywords").toString();
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println("load block url keywords from " + blockUrlKeywordFilePath);
 | 
			
		||||
        File file = new File(blockUrlKeywordFilePath);
 | 
			
		||||
        if (file.exists()) {
 | 
			
		||||
            for (String line : Files.readAllLines(file.toPath())) {
 | 
			
		||||
                if (!line.trim().isEmpty()) {
 | 
			
		||||
                    BLOCK_URL_KEYWORDS.add(line);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println("loaded " + BLOCK_URL_KEYWORDS.size() + " keywords");
 | 
			
		||||
        return BLOCK_URL_KEYWORDS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static URI getJarURI() throws Exception {
 | 
			
		||||
        URL url = TrustAnchorHolder.class.getProtectionDomain().getCodeSource().getLocation();
 | 
			
		||||
        URL url = ConfigHelper.class.getProtectionDomain().getCodeSource().getLocation();
 | 
			
		||||
        if (null != url) {
 | 
			
		||||
            return url.toURI();
 | 
			
		||||
        }
 | 
			
		||||
        String resourcePath = "/jarLocation.txt";
 | 
			
		||||
        url = TrustAnchorHolder.class.getResource(resourcePath);
 | 
			
		||||
        url = ConfigHelper.class.getResource(resourcePath);
 | 
			
		||||
        if (null == url) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -1,14 +1,26 @@
 | 
			
		||||
package win.novice.li;
 | 
			
		||||
 | 
			
		||||
import net.bytebuddy.asm.Advice;
 | 
			
		||||
import sun.net.www.http.HttpClient;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.net.SocketTimeoutException;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class HttpClientAdvice {
 | 
			
		||||
    @Advice.OnMethodExit
 | 
			
		||||
    public static void intercept(@Advice.This Object x) throws Exception {
 | 
			
		||||
        if (x.toString().contains("validateKey.action")){
 | 
			
		||||
            throw new SocketTimeoutException();
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public static void intercept(@Advice.This Object httpClient) throws Exception {
 | 
			
		||||
        Class<?> clazz = Class.forName("win.novice.li.ConfigHelper", true, ClassLoader.getSystemClassLoader());
 | 
			
		||||
        Method method = clazz.getDeclaredMethod("loadBlockUrlKeywords");
 | 
			
		||||
        Set<String> BLOCK_URL_KEYWORDS = (Set<String>) method.invoke(null);
 | 
			
		||||
        String clientString = httpClient.toString();
 | 
			
		||||
        for (String keyword : BLOCK_URL_KEYWORDS) {
 | 
			
		||||
            if (clientString.contains(keyword)) {
 | 
			
		||||
                throw new SocketTimeoutException();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ public class PKIXBuilderParametersAdvice {
 | 
			
		||||
    @Advice.OnMethodEnter
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public static void intercept(@Advice.Argument(value = 0, readOnly = false) Set<TrustAnchor> trustAnchors) throws Exception {
 | 
			
		||||
        Class<?> clazz = Class.forName("win.novice.li.TrustAnchorHolder", true, ClassLoader.getSystemClassLoader());
 | 
			
		||||
        Class<?> clazz = Class.forName("win.novice.li.ConfigHelper", true, ClassLoader.getSystemClassLoader());
 | 
			
		||||
        Method method = clazz.getDeclaredMethod("loadTrustAnchors");
 | 
			
		||||
        Set<TrustAnchor> loadedTrustAnchors = (Set<TrustAnchor>)method.invoke(null);
 | 
			
		||||
        HashSet<TrustAnchor> newTrustAnchors = new HashSet<>(trustAnchors);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
package win.novice.li;
 | 
			
		||||
 | 
			
		||||
import net.bytebuddy.asm.Advice;
 | 
			
		||||
 | 
			
		||||
import java.net.ConnectException;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.SocketAddress;
 | 
			
		||||
 | 
			
		||||
public class SocketAdvice {
 | 
			
		||||
    @Advice.OnMethodExit
 | 
			
		||||
    public static void intercept(@Advice.Argument(value = 0,readOnly = false) SocketAddress socketAddress) throws Exception {
 | 
			
		||||
        if (socketAddress instanceof InetSocketAddress){
 | 
			
		||||
            InetAddress address = ((InetSocketAddress) socketAddress).getAddress();
 | 
			
		||||
            if (address.getHostAddress().equals("116.62.33.138")){
 | 
			
		||||
                throw new ConnectException("拒绝连接");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,13 +2,15 @@ package win.novice.li;
 | 
			
		||||
 | 
			
		||||
import net.bytebuddy.asm.Advice;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class SystemAdvice {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //  System.getProperty
 | 
			
		||||
    @Advice.OnMethodExit
 | 
			
		||||
    public static void intercept(@Advice.Argument(0) Object x, @Advice.Return(readOnly = false) String r) throws Exception {
 | 
			
		||||
        if (x.toString().equals("jb.vmOptionsFile")) {
 | 
			
		||||
        if (Objects.equals(x, "jb.vmOptionsFile")) {
 | 
			
		||||
            RuntimeException exception = new RuntimeException();
 | 
			
		||||
            int nullCnt = 0;
 | 
			
		||||
            boolean hasReflect = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,28 +9,21 @@
 | 
			
		||||
    <fileSets>
 | 
			
		||||
        <fileSet>
 | 
			
		||||
            <directory>${project.parent.basedir}/script</directory>
 | 
			
		||||
            <outputDirectory>script</outputDirectory>
 | 
			
		||||
            <outputDirectory>jetbra/script</outputDirectory>
 | 
			
		||||
            <includes>
 | 
			
		||||
                <include>*</include>
 | 
			
		||||
            </includes>
 | 
			
		||||
        </fileSet>
 | 
			
		||||
        <fileSet>
 | 
			
		||||
            <directory>${project.parent.basedir}/vmoptions</directory>
 | 
			
		||||
            <outputDirectory>vmoptions</outputDirectory>
 | 
			
		||||
            <outputDirectory>jetbra/vmoptions</outputDirectory>
 | 
			
		||||
            <includes>
 | 
			
		||||
                <include>*</include>
 | 
			
		||||
            </includes>
 | 
			
		||||
        </fileSet>
 | 
			
		||||
        <fileSet>
 | 
			
		||||
            <directory>${project.parent.basedir}/trust-crt</directory>
 | 
			
		||||
            <outputDirectory>trust-crt</outputDirectory>
 | 
			
		||||
            <includes>
 | 
			
		||||
                <include>*</include>
 | 
			
		||||
            </includes>
 | 
			
		||||
        </fileSet>
 | 
			
		||||
        <fileSet>
 | 
			
		||||
            <directory>${project.parent.basedir}/trust-crt</directory>
 | 
			
		||||
            <outputDirectory>trust-crt</outputDirectory>
 | 
			
		||||
            <outputDirectory>jetbra/trust-crt</outputDirectory>
 | 
			
		||||
            <includes>
 | 
			
		||||
                <include>*</include>
 | 
			
		||||
            </includes>
 | 
			
		||||
@@ -39,7 +32,11 @@
 | 
			
		||||
    <files>
 | 
			
		||||
        <file>
 | 
			
		||||
            <source>${project.parent.basedir}/jetbra-agent/target/jetbra-agent.jar</source>
 | 
			
		||||
            <destName>jetbra-agent.jar</destName>
 | 
			
		||||
            <destName>jetbra/jetbra-agent.jar</destName>
 | 
			
		||||
        </file>
 | 
			
		||||
        <file>
 | 
			
		||||
            <source>${project.parent.basedir}/block_url_keywords</source>
 | 
			
		||||
            <destName>jetbra/block_url_keywords</destName>
 | 
			
		||||
        </file>
 | 
			
		||||
    </files>
 | 
			
		||||
</assembly>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,8 @@
 | 
			
		||||
    <artifactId>jetbra-dist</artifactId>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <maven.compiler.source>17</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>17</maven.compiler.target>
 | 
			
		||||
        <maven.compiler.source>1.8</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>1.8</maven.compiler.target>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
    </properties>
 | 
			
		||||
    <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,8 @@
 | 
			
		||||
    <artifactId>jetbra-server</artifactId>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <maven.compiler.source>17</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>17</maven.compiler.target>
 | 
			
		||||
        <maven.compiler.source>1.8</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>1.8</maven.compiler.target>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
    </properties>
 | 
			
		||||
 | 
			
		||||
@@ -40,12 +40,12 @@
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.bouncycastle</groupId>
 | 
			
		||||
            <artifactId>bcpkix-jdk18on</artifactId>
 | 
			
		||||
            <version>1.72</version>
 | 
			
		||||
            <version>1.77</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.bouncycastle</groupId>
 | 
			
		||||
            <artifactId>bcprov-jdk18on</artifactId>
 | 
			
		||||
            <version>1.72</version>
 | 
			
		||||
            <version>1.77</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.projectlombok</groupId>
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ import java.security.*;
 | 
			
		||||
import java.security.cert.CertificateFactory;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
import java.util.Base64;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@RestController
 | 
			
		||||
@@ -45,8 +46,7 @@ public class LicenseController {
 | 
			
		||||
        String sigResultsBase64 = Base64.getEncoder().encodeToString(signatureBytes);
 | 
			
		||||
 | 
			
		||||
        String result = licenseId + "-" + licensePartBase64 + "-" + sigResultsBase64 + "-" + Base64.getEncoder().encodeToString(CRT.getEncoded());
 | 
			
		||||
 | 
			
		||||
        return Map.of("license", result);
 | 
			
		||||
        return Collections.singletonMap("license", result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,13 @@
 | 
			
		||||
package win.novice.li.model;
 | 
			
		||||
 | 
			
		||||
import jakarta.validation.Valid;
 | 
			
		||||
import jakarta.validation.constraints.Min;
 | 
			
		||||
import jakarta.validation.constraints.NotBlank;
 | 
			
		||||
import jakarta.validation.constraints.NotEmpty;
 | 
			
		||||
import jakarta.validation.constraints.NotNull;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
import javax.validation.constraints.Min;
 | 
			
		||||
import javax.validation.constraints.NotBlank;
 | 
			
		||||
import javax.validation.constraints.NotEmpty;
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@
 | 
			
		||||
package win.novice.li.model;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import jakarta.validation.constraints.NotBlank;
 | 
			
		||||
import jakarta.validation.constraints.NotNull;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.NotBlank;
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class Product {
 | 
			
		||||
    @NotBlank
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										205
									
								
								jetbra.js
									
									
									
									
									
								
							
							
						
						
									
										205
									
								
								jetbra.js
									
									
									
									
									
								
							@@ -1,9 +1,9 @@
 | 
			
		||||
// ==UserScript==
 | 
			
		||||
// @name         JetBra
 | 
			
		||||
// @namespace    https://github.com/novice88/jetbra
 | 
			
		||||
// @version      1.1
 | 
			
		||||
// @version      2.0
 | 
			
		||||
// @license MIT
 | 
			
		||||
// @description  添加一个按钮,点击获取插件的激活码
 | 
			
		||||
// @description  Add a button on the plugin homepage and click to get the plugin activation code
 | 
			
		||||
// @author       novice.li
 | 
			
		||||
// @match        https://plugins.jetbrains.com/plugin/*
 | 
			
		||||
// @grant        GM_setClipboard
 | 
			
		||||
@@ -14,189 +14,19 @@
 | 
			
		||||
// @connect localhost
 | 
			
		||||
// ==/UserScript==
 | 
			
		||||
 | 
			
		||||
var elmGetter = function() {
 | 
			
		||||
    const win = window.unsafeWindow || document.defaultView || window;
 | 
			
		||||
    const doc = win.document;
 | 
			
		||||
    const listeners = new WeakMap();
 | 
			
		||||
    let mode = 'css';
 | 
			
		||||
    let $;
 | 
			
		||||
    const elProto = win.Element.prototype;
 | 
			
		||||
    const matches = elProto.matches ||
 | 
			
		||||
        elProto.matchesSelector ||
 | 
			
		||||
        elProto.webkitMatchesSelector ||
 | 
			
		||||
        elProto.mozMatchesSelector ||
 | 
			
		||||
        elProto.oMatchesSelector;
 | 
			
		||||
    const MutationObs = win.MutationObserver ||
 | 
			
		||||
        win.WebkitMutationObserver ||
 | 
			
		||||
        win.MozMutationObserver;
 | 
			
		||||
    function addObserver(target, callback) {
 | 
			
		||||
        const observer = new MutationObs(mutations => {
 | 
			
		||||
            for (const mutation of mutations) {
 | 
			
		||||
                if (mutation.type === 'attributes') {
 | 
			
		||||
                    callback(mutation.target);
 | 
			
		||||
                    if (observer.canceled) return;
 | 
			
		||||
                }
 | 
			
		||||
                for (const node of mutation.addedNodes) {
 | 
			
		||||
                    if (node instanceof Element) callback(node);
 | 
			
		||||
                    if (observer.canceled) return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        observer.canceled = false;
 | 
			
		||||
        observer.observe(target, {childList: true, subtree: true, attributes: true});
 | 
			
		||||
        return () => {
 | 
			
		||||
            observer.canceled = true;
 | 
			
		||||
            observer.disconnect();
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    function addFilter(target, filter) {
 | 
			
		||||
        let listener = listeners.get(target);
 | 
			
		||||
        if (!listener) {
 | 
			
		||||
            listener = {
 | 
			
		||||
                filters: new Set(),
 | 
			
		||||
                remove: addObserver(target, el => listener.filters.forEach(f => f(el)))
 | 
			
		||||
            };
 | 
			
		||||
            listeners.set(target, listener);
 | 
			
		||||
 | 
			
		||||
async function findElementWithRetry(cssSelector) {
 | 
			
		||||
    const maxAttempts = 50;
 | 
			
		||||
    for (let attempts = 0; attempts < maxAttempts; attempts++) {
 | 
			
		||||
        const element = document.querySelector(cssSelector);
 | 
			
		||||
        if (element) {
 | 
			
		||||
            return element;
 | 
			
		||||
        }
 | 
			
		||||
        listener.filters.add(filter);
 | 
			
		||||
        await new Promise(resolve => setTimeout(resolve, 100));
 | 
			
		||||
    }
 | 
			
		||||
    function removeFilter(target, filter) {
 | 
			
		||||
        const listener = listeners.get(target);
 | 
			
		||||
        if (!listener) return;
 | 
			
		||||
        listener.filters.delete(filter);
 | 
			
		||||
        if (!listener.filters.size) {
 | 
			
		||||
            listener.remove();
 | 
			
		||||
            listeners.delete(target);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    function query(all, selector, parent, includeParent, curMode) {
 | 
			
		||||
        switch (curMode) {
 | 
			
		||||
            case 'css':
 | 
			
		||||
                const checkParent = includeParent && matches.call(parent, selector);
 | 
			
		||||
                if (all) {
 | 
			
		||||
                    const queryAll = parent.querySelectorAll(selector);
 | 
			
		||||
                    return checkParent ? [parent, ...queryAll] : [...queryAll];
 | 
			
		||||
                }
 | 
			
		||||
                return checkParent ? parent : parent.querySelector(selector);
 | 
			
		||||
            case 'jquery':
 | 
			
		||||
                let jNodes = $(includeParent ? parent : []);
 | 
			
		||||
                jNodes = jNodes.add([...parent.querySelectorAll('*')]).filter(selector);
 | 
			
		||||
                if (all) return $.map(jNodes, el => $(el));
 | 
			
		||||
                return jNodes.length ? $(jNodes.get(0)) : null;
 | 
			
		||||
            case 'xpath':
 | 
			
		||||
                const ownerDoc = parent.ownerDocument || parent;
 | 
			
		||||
                selector += '/self::*';
 | 
			
		||||
                if (all) {
 | 
			
		||||
                    const xPathResult = ownerDoc.evaluate(selector, parent, null, 7, null);
 | 
			
		||||
                    const result = [];
 | 
			
		||||
                    for (let i = 0; i < xPathResult.snapshotLength; i++) {
 | 
			
		||||
                        result.push(xPathResult.snapshotItem(i));
 | 
			
		||||
                    }
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
                return ownerDoc.evaluate(selector, parent, null, 9, null).singleNodeValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    function isJquery(jq) {
 | 
			
		||||
        return jq && jq.fn && typeof jq.fn.jquery === 'string';
 | 
			
		||||
    }
 | 
			
		||||
    function getOne(selector, parent, timeout) {
 | 
			
		||||
        const curMode = mode;
 | 
			
		||||
        return new Promise(resolve => {
 | 
			
		||||
            const node = query(false, selector, parent, false, curMode);
 | 
			
		||||
            if (node) return resolve(node);
 | 
			
		||||
            let timer;
 | 
			
		||||
            const filter = el => {
 | 
			
		||||
                const node = query(false, selector, el, true, curMode);
 | 
			
		||||
                if (node) {
 | 
			
		||||
                    removeFilter(parent, filter);
 | 
			
		||||
                    timer && clearTimeout(timer);
 | 
			
		||||
                    resolve(node);
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            addFilter(parent, filter);
 | 
			
		||||
            if (timeout > 0) {
 | 
			
		||||
                timer = setTimeout(() => {
 | 
			
		||||
                    removeFilter(parent, filter);
 | 
			
		||||
                    resolve(null);
 | 
			
		||||
                }, timeout);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
        get currentSelector() {
 | 
			
		||||
            return mode;
 | 
			
		||||
        },
 | 
			
		||||
        get(selector, ...args) {
 | 
			
		||||
            let parent = typeof args[0] !== 'number' && args.shift() || doc;
 | 
			
		||||
            if (mode === 'jquery' && parent instanceof $) parent = parent.get(0);
 | 
			
		||||
            const timeout = args[0] || 0;
 | 
			
		||||
            if (Array.isArray(selector)) {
 | 
			
		||||
                return Promise.all(selector.map(s => getOne(s, parent, timeout)));
 | 
			
		||||
            }
 | 
			
		||||
            return getOne(selector, parent, timeout);
 | 
			
		||||
        },
 | 
			
		||||
        each(selector, ...args) {
 | 
			
		||||
            let parent = typeof args[0] !== 'function' && args.shift() || doc;
 | 
			
		||||
            if (mode === 'jquery' && parent instanceof $) parent = parent.get(0);
 | 
			
		||||
            const callback = args[0];
 | 
			
		||||
            const curMode = mode;
 | 
			
		||||
            const refs = new WeakSet();
 | 
			
		||||
            for (const node of query(true, selector, parent, false, curMode)) {
 | 
			
		||||
                refs.add(curMode === 'jquery' ? node.get(0) : node);
 | 
			
		||||
                if (callback(node, false) === false) return;
 | 
			
		||||
            }
 | 
			
		||||
            const filter = el => {
 | 
			
		||||
                for (const node of query(true, selector, el, true, curMode)) {
 | 
			
		||||
                    const _el = curMode === 'jquery' ? node.get(0) : node;
 | 
			
		||||
                    if (refs.has(_el)) break;
 | 
			
		||||
                    refs.add(_el);
 | 
			
		||||
                    if (callback(node, true) === false) {
 | 
			
		||||
                        return removeFilter(parent, filter);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            addFilter(parent, filter);
 | 
			
		||||
        },
 | 
			
		||||
        create(domString, ...args) {
 | 
			
		||||
            const returnList = typeof args[0] === 'boolean' && args.shift();
 | 
			
		||||
            const parent = args[0];
 | 
			
		||||
            const template = doc.createElement('template');
 | 
			
		||||
            template.innerHTML = domString;
 | 
			
		||||
            const node = template.content.firstElementChild;
 | 
			
		||||
            if (!node) return null;
 | 
			
		||||
            parent ? parent.appendChild(node) : node.remove();
 | 
			
		||||
            if (returnList) {
 | 
			
		||||
                const list = {};
 | 
			
		||||
                node.querySelectorAll('[id]').forEach(el => list[el.id] = el);
 | 
			
		||||
                list[0] = node;
 | 
			
		||||
                return list;
 | 
			
		||||
            }
 | 
			
		||||
            return node;
 | 
			
		||||
        },
 | 
			
		||||
        selector(desc) {
 | 
			
		||||
            switch (true) {
 | 
			
		||||
                case isJquery(desc):
 | 
			
		||||
                    $ = desc;
 | 
			
		||||
                    return mode = 'jquery';
 | 
			
		||||
                case !desc || typeof desc.toLowerCase !== 'function':
 | 
			
		||||
                    return mode = 'css';
 | 
			
		||||
                case desc.toLowerCase() === 'jquery':
 | 
			
		||||
                    for (const jq of [window.jQuery, window.$, win.jQuery, win.$]) {
 | 
			
		||||
                        if (isJquery(jq)) {
 | 
			
		||||
                            $ = jq;
 | 
			
		||||
                            break;
 | 
			
		||||
                        };
 | 
			
		||||
                    }
 | 
			
		||||
                    return mode = $ ? 'jquery' : 'css';
 | 
			
		||||
                case desc.toLowerCase() === 'xpath':
 | 
			
		||||
                    return mode = 'xpath';
 | 
			
		||||
                default:
 | 
			
		||||
                    return mode = 'css';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}();
 | 
			
		||||
    throw new Error(`Element with selector '${cssSelector}' not found after ${maxAttempts} attempts.`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(async function () {
 | 
			
		||||
    'use strict';
 | 
			
		||||
    GM_addStyle(`
 | 
			
		||||
@@ -227,17 +57,16 @@ var elmGetter = function() {
 | 
			
		||||
 | 
			
		||||
    let pluginDetail = await fetch('https://plugins.jetbrains.com/api/plugins/' + pluginId).then(r => r.json());
 | 
			
		||||
 | 
			
		||||
    const parentElement = await elmGetter.get('.plugin-header__controls-panel > div:first-child');
 | 
			
		||||
    const parentElement = await findElementWithRetry('.plugin-header__controls-panel > div:first-child');
 | 
			
		||||
 | 
			
		||||
    let newElement = document.createElement('div');
 | 
			
		||||
    newElement.classList.toggle('wt-col-inline');
 | 
			
		||||
    newElement.innerHTML = `<button class="jetbra-button" type="button">点击生成激活码</button>`;
 | 
			
		||||
    newElement.innerHTML = `<button class="jetbra-button" type="button">CLICK TO GENERATE ACTIVATION CODE</button>`;
 | 
			
		||||
    parentElement.appendChild(newElement)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    newElement.addEventListener('click', async () => {
 | 
			
		||||
        if (pluginDetail.purchaseInfo === undefined) {
 | 
			
		||||
            window.alert('此插件不是付费插件');
 | 
			
		||||
            window.alert('This plugin is not a paid plugin in the market');
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        let data = {
 | 
			
		||||
@@ -268,7 +97,7 @@ var elmGetter = function() {
 | 
			
		||||
            onload: function (response) {
 | 
			
		||||
                let license = JSON.parse(response.responseText).license
 | 
			
		||||
                GM_setClipboard(license, 'text');
 | 
			
		||||
                window.alert('激活码已复制到剪切版');
 | 
			
		||||
                window.alert('The activation code has been copied to your clipboard');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    })
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							@@ -5,7 +5,7 @@
 | 
			
		||||
	<parent>
 | 
			
		||||
		<groupId>org.springframework.boot</groupId>
 | 
			
		||||
		<artifactId>spring-boot-starter-parent</artifactId>
 | 
			
		||||
		<version>3.2.0</version>
 | 
			
		||||
		<version>2.7.14</version>
 | 
			
		||||
		<relativePath/>
 | 
			
		||||
	</parent>
 | 
			
		||||
	<groupId>win.novice</groupId>
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
		<module>jetbra-dist</module>
 | 
			
		||||
	</modules>
 | 
			
		||||
	<properties>
 | 
			
		||||
		<java.version>17</java.version>
 | 
			
		||||
		<java.version>1.8</java.version>
 | 
			
		||||
	</properties>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								readme.md
									
									
									
									
									
								
							@@ -1,12 +1,13 @@
 | 
			
		||||
# Jetbra
 | 
			
		||||
适用于jetbrains家族产品的一款工具,参照[热老的项目](https://jetbra.in/s)自己写了点代码 ,使用方式与之一致
 | 
			
		||||
在替换janetfilter前需要执行janetfilter的卸载脚本
 | 
			
		||||
An activation tool for jetbrains family products,including plugins
 | 
			
		||||
 | 
			
		||||
# Usage
 | 
			
		||||
 | 
			
		||||
1. Download jetbra-all.zip from the release page and unzip it
 | 
			
		||||
2. Execute installation script
 | 
			
		||||
   macOS or Linux: execute "scripts/install.sh"<br>
 | 
			
		||||
   Windows: double click to execute "scripts\install-current-user.vbs" (For current user),"scripts\install-all-users.vbs" (For all users)
 | 
			
		||||
3. Log in again to load environment variables
 | 
			
		||||
4. Go to the web page to get the activation code and activate the software
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
新增[油猴脚本](https://greasyfork.org/zh-CN/scripts/480799-jetbra), 使用这个脚本可以生成插件的激活码,需配合该工具使用
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
todo
 | 
			
		||||
 | 
			
		||||
- [ ] 禁止连接某些ip(restful-fast-request--api-buddy等插件不仅会在本地验证license还会将license发往他们自己的服务器进行验证)
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ Sub ProcessVmOptions(ByVal file)
 | 
			
		||||
    Loop
 | 
			
		||||
    oFile.Close
 | 
			
		||||
 | 
			
		||||
    sNewContent = sNewContent & "-javaagent:" & sJarFile & "=jetbrains"
 | 
			
		||||
    sNewContent = sNewContent & "-javaagent:" & sJarFile
 | 
			
		||||
    Set oFile = oFS.OpenTextFile(file, 2, 0)
 | 
			
		||||
    oFile.Write sNewContent
 | 
			
		||||
    oFile.Close
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ Sub ProcessVmOptions(ByVal file)
 | 
			
		||||
    Loop
 | 
			
		||||
    oFile.Close
 | 
			
		||||
 | 
			
		||||
    sNewContent = sNewContent & "-javaagent:" & sJarFile & "=jetbrains"
 | 
			
		||||
    sNewContent = sNewContent & "-javaagent:" & sJarFile
 | 
			
		||||
    Set oFile = oFS.OpenTextFile(file, 2, 0)
 | 
			
		||||
    oFile.Write sNewContent
 | 
			
		||||
    oFile.Close
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ for PRD in $JB_PRODUCTS; do
 | 
			
		||||
    sed -i '/^\-javaagent:.*[\/\\]jetbra\-agent\.jar.*/d' "${VM_FILE_PATH}"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  echo "-javaagent:${JAR_FILE_PATH}=jetbrains" >>"${VM_FILE_PATH}"
 | 
			
		||||
  echo "-javaagent:${JAR_FILE_PATH}" >>"${VM_FILE_PATH}"
 | 
			
		||||
 | 
			
		||||
  ENV_NAME=$(echo $PRD | tr '[a-z]' '[A-Z]')"_VM_OPTIONS"
 | 
			
		||||
  echo "export ${ENV_NAME}=\"${VM_FILE_PATH}\"" >>"${MY_VMOPTIONS_SHELL_FILE}"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms512m
 | 
			
		||||
-Xmx2g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx3992m
 | 
			
		||||
-Xms512m
 | 
			
		||||
-Xmx2g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms512m
 | 
			
		||||
-Xmx2g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx3992m
 | 
			
		||||
-Xms512m
 | 
			
		||||
-Xmx4g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-Xms128m
 | 
			
		||||
-Xmx1024m
 | 
			
		||||
-Xms256m
 | 
			
		||||
-Xmx1g
 | 
			
		||||
-XX:ReservedCodeCacheSize=512m
 | 
			
		||||
-XX:+IgnoreUnrecognizedVMOptions
 | 
			
		||||
-XX:+UseG1GC
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user