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 @@
- jetbra-agent.jar
+ jetbra/jetbra-agent.jar
+
+
+
+ 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