diff --git a/.gitignore b/.gitignore index 395dde9..c3dc894 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.iml .idea/ -target/ \ No newline at end of file +target/ +.fastRequest \ No newline at end of file diff --git a/block_url_keywords b/block_url_keywords new file mode 100644 index 0000000..c1df1b1 --- /dev/null +++ b/block_url_keywords @@ -0,0 +1,2 @@ +https://account.jetbrains.com/lservice/rpc/validateKey.action +116.62.33.138 \ No newline at end of file diff --git a/crt_and_key_gen.py b/crt_and_key_gen.py deleted file mode 100644 index 0dce6b4..0000000 --- a/crt_and_key_gen.py +++ /dev/null @@ -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) diff --git a/jetbra-agent/pom.xml b/jetbra-agent/pom.xml index 1e35d70..40d8ccd 100644 --- a/jetbra-agent/pom.xml +++ b/jetbra-agent/pom.xml @@ -13,8 +13,8 @@ jetbra-agent - 17 - 17 + 1.8 + 1.8 UTF-8 @@ -29,6 +29,13 @@ byte-buddy-agent 1.14.8 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + provided + diff --git a/jetbra-agent/src/main/java/win/novice/li/AgentMain.java b/jetbra-agent/src/main/java/win/novice/li/AgentMain.java index b6c42fb..facb929 100644 --- a/jetbra-agent/src/main/java/win/novice/li/AgentMain.java +++ b/jetbra-agent/src/main/java/win/novice/li/AgentMain.java @@ -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); diff --git a/jetbra-agent/src/main/java/win/novice/li/TrustAnchorHolder.java b/jetbra-agent/src/main/java/win/novice/li/ConfigHelper.java similarity index 52% rename from jetbra-agent/src/main/java/win/novice/li/TrustAnchorHolder.java rename to jetbra-agent/src/main/java/win/novice/li/ConfigHelper.java index a354c40..e55b021 100644 --- a/jetbra-agent/src/main/java/win/novice/li/TrustAnchorHolder.java +++ b/jetbra-agent/src/main/java/win/novice/li/ConfigHelper.java @@ -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 TRUST_ANCHORS; - + public static Set BLOCK_URL_KEYWORDS; public static Set 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 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; } diff --git a/jetbra-agent/src/main/java/win/novice/li/HttpClientAdvice.java b/jetbra-agent/src/main/java/win/novice/li/HttpClientAdvice.java index d6263bd..4e721b5 100644 --- a/jetbra-agent/src/main/java/win/novice/li/HttpClientAdvice.java +++ b/jetbra-agent/src/main/java/win/novice/li/HttpClientAdvice.java @@ -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 BLOCK_URL_KEYWORDS = (Set) method.invoke(null); + String clientString = httpClient.toString(); + for (String keyword : BLOCK_URL_KEYWORDS) { + if (clientString.contains(keyword)) { + throw new SocketTimeoutException(); + } } } } diff --git a/jetbra-agent/src/main/java/win/novice/li/PKIXBuilderParametersAdvice.java b/jetbra-agent/src/main/java/win/novice/li/PKIXBuilderParametersAdvice.java index 9123702..e3c3d0e 100644 --- a/jetbra-agent/src/main/java/win/novice/li/PKIXBuilderParametersAdvice.java +++ b/jetbra-agent/src/main/java/win/novice/li/PKIXBuilderParametersAdvice.java @@ -13,7 +13,7 @@ public class PKIXBuilderParametersAdvice { @Advice.OnMethodEnter @SuppressWarnings("unchecked") public static void intercept(@Advice.Argument(value = 0, readOnly = false) Set 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 loadedTrustAnchors = (Set)method.invoke(null); HashSet newTrustAnchors = new HashSet<>(trustAnchors); diff --git a/jetbra-agent/src/main/java/win/novice/li/SocketAdvice.java b/jetbra-agent/src/main/java/win/novice/li/SocketAdvice.java deleted file mode 100644 index ba12ef6..0000000 --- a/jetbra-agent/src/main/java/win/novice/li/SocketAdvice.java +++ /dev/null @@ -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("拒绝连接"); - } - } - } -} diff --git a/jetbra-agent/src/main/java/win/novice/li/SystemAdvice.java b/jetbra-agent/src/main/java/win/novice/li/SystemAdvice.java index 912a6db..bb490b5 100644 --- a/jetbra-agent/src/main/java/win/novice/li/SystemAdvice.java +++ b/jetbra-agent/src/main/java/win/novice/li/SystemAdvice.java @@ -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; diff --git a/jetbra-dist/package.xml b/jetbra-dist/package.xml index 00cf610..4e30cb8 100644 --- a/jetbra-dist/package.xml +++ b/jetbra-dist/package.xml @@ -9,28 +9,21 @@ ${project.parent.basedir}/script - script + jetbra/script * ${project.parent.basedir}/vmoptions - vmoptions + jetbra/vmoptions * ${project.parent.basedir}/trust-crt - trust-crt - - * - - - - ${project.parent.basedir}/trust-crt - trust-crt + jetbra/trust-crt * @@ -39,7 +32,11 @@ ${project.parent.basedir}/jetbra-agent/target/jetbra-agent.jar - jetbra-agent.jar + jetbra/jetbra-agent.jar + + + ${project.parent.basedir}/block_url_keywords + jetbra/block_url_keywords diff --git a/jetbra-dist/pom.xml b/jetbra-dist/pom.xml index f58cd9a..e4f35bc 100644 --- a/jetbra-dist/pom.xml +++ b/jetbra-dist/pom.xml @@ -13,8 +13,8 @@ jetbra-dist - 17 - 17 + 1.8 + 1.8 UTF-8 diff --git a/jetbra-server/pom.xml b/jetbra-server/pom.xml index dd2f83d..c9a5047 100644 --- a/jetbra-server/pom.xml +++ b/jetbra-server/pom.xml @@ -13,8 +13,8 @@ jetbra-server - 17 - 17 + 1.8 + 1.8 UTF-8 @@ -40,12 +40,12 @@ org.bouncycastle bcpkix-jdk18on - 1.72 + 1.77 org.bouncycastle bcprov-jdk18on - 1.72 + 1.77 org.projectlombok diff --git a/jetbra-server/src/main/java/win/novice/li/controller/LicenseController.java b/jetbra-server/src/main/java/win/novice/li/controller/LicenseController.java index af874d9..bc23522 100644 --- a/jetbra-server/src/main/java/win/novice/li/controller/LicenseController.java +++ b/jetbra-server/src/main/java/win/novice/li/controller/LicenseController.java @@ -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); } diff --git a/jetbra-server/src/main/java/win/novice/li/model/License.java b/jetbra-server/src/main/java/win/novice/li/model/License.java index 5cf6224..ab542db 100644 --- a/jetbra-server/src/main/java/win/novice/li/model/License.java +++ b/jetbra-server/src/main/java/win/novice/li/model/License.java @@ -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 diff --git a/jetbra-server/src/main/java/win/novice/li/model/Product.java b/jetbra-server/src/main/java/win/novice/li/model/Product.java index 417cdc8..8c4bf2d 100644 --- a/jetbra-server/src/main/java/win/novice/li/model/Product.java +++ b/jetbra-server/src/main/java/win/novice/li/model/Product.java @@ -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 diff --git a/jetbra.js b/jetbra.js index a1bca40..e29be5c 100644 --- a/jetbra.js +++ b/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 = ``; + newElement.innerHTML = ``; 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'); } }); }) diff --git a/pom.xml b/pom.xml index f923b43..86d362f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.0 + 2.7.14 win.novice @@ -20,7 +20,7 @@ jetbra-dist - 17 + 1.8 diff --git a/readme.md b/readme.md index 302f84a..ca97c16 100644 --- a/readme.md +++ b/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"
+ 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发往他们自己的服务器进行验证) diff --git a/script/install-all-users.vbs b/script/install-all-users.vbs index cc5512d..3ea5e4f 100644 --- a/script/install-all-users.vbs +++ b/script/install-all-users.vbs @@ -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 diff --git a/script/install-current-user.vbs b/script/install-current-user.vbs index c991525..a984aa2 100644 --- a/script/install-current-user.vbs +++ b/script/install-current-user.vbs @@ -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 diff --git a/script/install.sh b/script/install.sh index b158c60..7c3944d 100755 --- a/script/install.sh +++ b/script/install.sh @@ -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}" diff --git a/vmoptions/appcode.vmoptions b/vmoptions/appcode.vmoptions index 32beca5..8b86880 100644 --- a/vmoptions/appcode.vmoptions +++ b/vmoptions/appcode.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms512m +-Xmx2g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/clion.vmoptions b/vmoptions/clion.vmoptions index d089c2a..8b86880 100644 --- a/vmoptions/clion.vmoptions +++ b/vmoptions/clion.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx3992m +-Xms512m +-Xmx2g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/datagrip.vmoptions b/vmoptions/datagrip.vmoptions index 4f8d00e..b1c8584 100644 --- a/vmoptions/datagrip.vmoptions +++ b/vmoptions/datagrip.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/dataspell.vmoptions b/vmoptions/dataspell.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/dataspell.vmoptions +++ b/vmoptions/dataspell.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/devecostudio.vmoptions b/vmoptions/devecostudio.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/devecostudio.vmoptions +++ b/vmoptions/devecostudio.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/gateway.vmoptions b/vmoptions/gateway.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/gateway.vmoptions +++ b/vmoptions/gateway.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/goland.vmoptions b/vmoptions/goland.vmoptions index 32beca5..8b86880 100644 --- a/vmoptions/goland.vmoptions +++ b/vmoptions/goland.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms512m +-Xmx2g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/idea.vmoptions b/vmoptions/idea.vmoptions index d089c2a..cae84f5 100644 --- a/vmoptions/idea.vmoptions +++ b/vmoptions/idea.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx3992m +-Xms512m +-Xmx4g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/jetbrains_client.vmoptions b/vmoptions/jetbrains_client.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/jetbrains_client.vmoptions +++ b/vmoptions/jetbrains_client.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/jetbrainsclient.vmoptions b/vmoptions/jetbrainsclient.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/jetbrainsclient.vmoptions +++ b/vmoptions/jetbrainsclient.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/phpstorm.vmoptions b/vmoptions/phpstorm.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/phpstorm.vmoptions +++ b/vmoptions/phpstorm.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/pycharm.vmoptions b/vmoptions/pycharm.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/pycharm.vmoptions +++ b/vmoptions/pycharm.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/rider.vmoptions b/vmoptions/rider.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/rider.vmoptions +++ b/vmoptions/rider.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/rubymine.vmoptions b/vmoptions/rubymine.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/rubymine.vmoptions +++ b/vmoptions/rubymine.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/studio.vmoptions b/vmoptions/studio.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/studio.vmoptions +++ b/vmoptions/studio.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/webide.vmoptions b/vmoptions/webide.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/webide.vmoptions +++ b/vmoptions/webide.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC diff --git a/vmoptions/webstorm.vmoptions b/vmoptions/webstorm.vmoptions index 32beca5..db21289 100644 --- a/vmoptions/webstorm.vmoptions +++ b/vmoptions/webstorm.vmoptions @@ -1,5 +1,5 @@ --Xms128m --Xmx1024m +-Xms256m +-Xmx1g -XX:ReservedCodeCacheSize=512m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseG1GC