mirror of
				https://github.com/NotoChen/Jetbrains-Help.git
				synced 2025-10-31 08:58:31 +08:00 
			
		
		
		
	冲冲~
This commit is contained in:
		
							parent
							
								
									7b68f10cd7
								
							
						
					
					
						commit
						2ea9fcba13
					
				
							
								
								
									
										13
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | FROM java:21 | ||||||
|  | 
 | ||||||
|  | ADD target/Jetbrains-Help.jar /Jetbrains-Help.jar | ||||||
|  | 
 | ||||||
|  | RUN bash -c 'touch /Jetbrains-Help.jar' | ||||||
|  | 
 | ||||||
|  | ENV TZ=Asia/Shanghai | ||||||
|  | RUN ln -sf /usr/share/zoneinfo/{TZ} /etc/localtime && echo "{TZ}" > /etc/timezone | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | EXPOSE 10768 | ||||||
|  | 
 | ||||||
|  | ENTRYPOINT ["java", "-jar","/Jetbrains-Help.jar"] | ||||||
							
								
								
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							|  | @ -55,6 +55,7 @@ | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
|  |         <finalName>${artifactId}</finalName> | ||||||
|         <plugins> |         <plugins> | ||||||
|             <plugin> |             <plugin> | ||||||
|                 <groupId>org.springframework.boot</groupId> |                 <groupId>org.springframework.boot</groupId> | ||||||
|  |  | ||||||
|  | @ -1,8 +1,13 @@ | ||||||
| package com.jetbrains.help; | package com.jetbrains.help; | ||||||
| 
 | 
 | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
|  | import cn.hutool.core.net.Ipv4Util; | ||||||
|  | import cn.hutool.core.text.CharSequenceUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
| import com.jetbrains.help.context.*; | import com.jetbrains.help.context.*; | ||||||
|  | import lombok.SneakyThrows; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
| import org.springframework.boot.context.event.ApplicationReadyEvent; | import org.springframework.boot.context.event.ApplicationReadyEvent; | ||||||
|  | @ -11,9 +16,11 @@ import org.springframework.context.event.EventListener; | ||||||
| import org.springframework.scheduling.annotation.EnableScheduling; | import org.springframework.scheduling.annotation.EnableScheduling; | ||||||
| import org.springframework.scheduling.annotation.Scheduled; | import org.springframework.scheduling.annotation.Scheduled; | ||||||
| 
 | 
 | ||||||
|  | import java.net.InetAddress; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
|  | @Slf4j | ||||||
| @EnableScheduling | @EnableScheduling | ||||||
| @Import(SpringUtil.class) | @Import(SpringUtil.class) | ||||||
| @SpringBootApplication | @SpringBootApplication | ||||||
|  | @ -23,12 +30,21 @@ public class JetbrainsHelpApplication { | ||||||
|         SpringApplication.run(JetbrainsHelpApplication.class, args); |         SpringApplication.run(JetbrainsHelpApplication.class, args); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @SneakyThrows | ||||||
|     @EventListener(ApplicationReadyEvent.class) |     @EventListener(ApplicationReadyEvent.class) | ||||||
|     public void ready() { |     public void ready() { | ||||||
|         ProductsContextHolder.init(); |         ProductsContextHolder.init(); | ||||||
|         PluginsContextHolder.init(); |         PluginsContextHolder.init(); | ||||||
|         CertificateContextHolder.init(); |         CertificateContextHolder.init(); | ||||||
|         AgentContextHolder.init(); |         AgentContextHolder.init(); | ||||||
|  | 
 | ||||||
|  |         InetAddress localHost = InetAddress.getLocalHost(); | ||||||
|  |         String address = CharSequenceUtil.format("http://{}:{}", localHost.getHostAddress(), SpringUtil.getProperty("server.port")); | ||||||
|  |         String runSuccessWarn = "\n====================================================================================\n" + | ||||||
|  |                 "=                        Jetbrains-Help Run Success~                               =\n" + | ||||||
|  |                 "=                        address:" + address + "                            =\n" + | ||||||
|  |                 "====================================================================================\n"; | ||||||
|  |         log.info(runSuccessWarn); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Scheduled(cron = "0 0 12 * * ?") |     @Scheduled(cron = "0 0 12 * * ?") | ||||||
|  |  | ||||||
|  | @ -24,25 +24,33 @@ import java.util.concurrent.CompletableFuture; | ||||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||||
| public class AgentContextHolder { | public class AgentContextHolder { | ||||||
| 
 | 
 | ||||||
|     private static final String JA_NETFILTER_FILE_PATH = "static/agent/ja-netfilter"; |     private static final String JA_NETFILTER_FILE_PATH = "external/agent/ja-netfilter"; | ||||||
| //    private static final String JA_NETFILTER_FILE_PATH = "static/agent/ja"; |  | ||||||
| 
 | 
 | ||||||
|     private static final String POWER_CONF_FILE_NAME = JA_NETFILTER_FILE_PATH + "/config/power.conf"; |     private static final String POWER_CONF_FILE_NAME = JA_NETFILTER_FILE_PATH + "/config/power.conf"; | ||||||
| 
 | 
 | ||||||
|     private static File jaNetfilterFile; |     private static File jaNetfilterFile; | ||||||
| 
 | 
 | ||||||
|  |     private static File jaNetfilterZipFile; | ||||||
|  | 
 | ||||||
|     public static void init() { |     public static void init() { | ||||||
|         log.info("Agent context init loading..."); |         log.info("Agent context init loading..."); | ||||||
|         jaNetfilterFile = FileTools.getFileOrCreat(JA_NETFILTER_FILE_PATH); |         jaNetfilterZipFile = FileTools.getFileOrCreat(JA_NETFILTER_FILE_PATH + ".zip"); | ||||||
|         if (!powerConfHasInit()) { |         if (!FileTools.fileExists(JA_NETFILTER_FILE_PATH)) { | ||||||
|             log.info("Agent config init loading..."); |             unzipJaNetfilter(); | ||||||
|             loadPowerConf(); |             if (!powerConfHasInit()) { | ||||||
|             zipJaNetfilter(); |                 log.info("Agent config init loading..."); | ||||||
|             log.info("Agent config init success !"); |                 loadPowerConf(); | ||||||
|  |                 zipJaNetfilter(); | ||||||
|  |                 log.info("Agent config init success !"); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         log.info("Agent context init success !"); |         log.info("Agent context init success !"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static File jaNetfilterZipFile() { | ||||||
|  |         return AgentContextHolder.jaNetfilterZipFile; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private static boolean powerConfHasInit() { |     private static boolean powerConfHasInit() { | ||||||
|         File powerConfFile = FileTools.getFileOrCreat(POWER_CONF_FILE_NAME); |         File powerConfFile = FileTools.getFileOrCreat(POWER_CONF_FILE_NAME); | ||||||
|         String powerConfStr; |         String powerConfStr; | ||||||
|  | @ -90,7 +98,11 @@ public class AgentContextHolder { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private static void unzipJaNetfilter() { | ||||||
|  |         jaNetfilterFile = ZipUtil.unzip(jaNetfilterZipFile); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private static void zipJaNetfilter() { |     private static void zipJaNetfilter() { | ||||||
|         ZipUtil.zip(jaNetfilterFile); |         jaNetfilterZipFile = ZipUtil.zip(jaNetfilterFile); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -31,10 +31,10 @@ import java.security.cert.CertificateException; | ||||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||||
| public class CertificateContextHolder { | public class CertificateContextHolder { | ||||||
| 
 | 
 | ||||||
|     private static final String ROOT_KEY_FILE_NAME = "certificate/root.key"; |     private static final String ROOT_KEY_FILE_NAME = "external/certificate/root.key"; | ||||||
|     private static final String PRIVATE_KEY_FILE_NAME = "certificate/private.key"; |     private static final String PRIVATE_KEY_FILE_NAME = "external/certificate/private.key"; | ||||||
|     private static final String PUBLIC_KEY_FILE_NAME = "certificate/public.key"; |     private static final String PUBLIC_KEY_FILE_NAME = "external/certificate/public.key"; | ||||||
|     private static final String CET_FILE_NAME = "certificate/ca.crt"; |     private static final String CET_FILE_NAME = "external/certificate/ca.crt"; | ||||||
| 
 | 
 | ||||||
|     private static File rootKeyFile; |     private static File rootKeyFile; | ||||||
| 
 | 
 | ||||||
|  | @ -52,6 +52,7 @@ public class CertificateContextHolder { | ||||||
|                 || !FileTools.fileExists(CET_FILE_NAME)) { |                 || !FileTools.fileExists(CET_FILE_NAME)) { | ||||||
|             log.info("certificate context generate loading..."); |             log.info("certificate context generate loading..."); | ||||||
|             generateCertificate(); |             generateCertificate(); | ||||||
|  |             log.info("certificate context generate success!"); | ||||||
|         } else { |         } else { | ||||||
|             privateKeyFile = FileTools.getFileOrCreat(PRIVATE_KEY_FILE_NAME); |             privateKeyFile = FileTools.getFileOrCreat(PRIVATE_KEY_FILE_NAME); | ||||||
|             publicKeyFile = FileTools.getFileOrCreat(PUBLIC_KEY_FILE_NAME); |             publicKeyFile = FileTools.getFileOrCreat(PUBLIC_KEY_FILE_NAME); | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import lombok.NoArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | @ -28,7 +29,7 @@ public class PluginsContextHolder { | ||||||
| 
 | 
 | ||||||
|     private static final String PLUGIN_INFO_URL = PLUGIN_BASIC_URL + "/api/plugins/"; |     private static final String PLUGIN_INFO_URL = PLUGIN_BASIC_URL + "/api/plugins/"; | ||||||
| 
 | 
 | ||||||
|     private static final String PLUGIN_JSON_FILE_NAME = "plugin.json"; |     private static final String PLUGIN_JSON_FILE_NAME = "external/data/plugin.json"; | ||||||
| 
 | 
 | ||||||
|     private static List<PluginCache> pluginCacheList; |     private static List<PluginCache> pluginCacheList; | ||||||
| 
 | 
 | ||||||
|  | @ -84,11 +85,14 @@ public class PluginsContextHolder { | ||||||
|     public static PluginList pluginList() { |     public static PluginList pluginList() { | ||||||
|         return HttpUtil.createGet(PLUGIN_LIST_URL) |         return HttpUtil.createGet(PLUGIN_LIST_URL) | ||||||
|                 .thenFunction(response -> { |                 .thenFunction(response -> { | ||||||
|                     InputStream is = response.bodyStream(); |                     try (InputStream is = response.bodyStream()) { | ||||||
|                     if (!response.isOk()) { |                         if (!response.isOk()) { | ||||||
|                         throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_LIST_URL, response)); |                             throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_LIST_URL, response)); | ||||||
|  |                         } | ||||||
|  |                         return IoUtil.readObj(is, PluginList.class); | ||||||
|  |                     } catch (IOException e) { | ||||||
|  |                         throw new IllegalArgumentException(CharSequenceUtil.format("{} The request io read failed", PLUGIN_LIST_URL), e); | ||||||
|                     } |                     } | ||||||
|                     return IoUtil.readObj(is, PluginList.class); |  | ||||||
|                 }); |                 }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -119,11 +123,14 @@ public class PluginsContextHolder { | ||||||
|     public static PluginInfo pluginInfo(Long pluginId) { |     public static PluginInfo pluginInfo(Long pluginId) { | ||||||
|         return HttpUtil.createGet(PLUGIN_INFO_URL + pluginId) |         return HttpUtil.createGet(PLUGIN_INFO_URL + pluginId) | ||||||
|                 .thenFunction(response -> { |                 .thenFunction(response -> { | ||||||
|                     InputStream is = response.bodyStream(); |                     try (InputStream is = response.bodyStream()) { | ||||||
|                     if (!response.isOk()) { |                         if (!response.isOk()) { | ||||||
|                         throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_INFO_URL, response)); |                             throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_INFO_URL, response)); | ||||||
|  |                         } | ||||||
|  |                         return IoUtil.readObj(is, PluginInfo.class); | ||||||
|  |                     } catch (IOException e) { | ||||||
|  |                         throw new IllegalArgumentException(CharSequenceUtil.format("{} The request io read failed", PLUGIN_LIST_URL), e); | ||||||
|                     } |                     } | ||||||
|                     return IoUtil.readObj(is, PluginInfo.class); |  | ||||||
|                 }); |                 }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ import java.util.List; | ||||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||||
| public class ProductsContextHolder { | public class ProductsContextHolder { | ||||||
| 
 | 
 | ||||||
|     private static final String PRODUCT_JSON_FILE_NAME = "product.json"; |     private static final String PRODUCT_JSON_FILE_NAME = "external/data/product.json"; | ||||||
| 
 | 
 | ||||||
|     private static List<ProductCache> productCacheList; |     private static List<ProductCache> productCacheList; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,20 +1,32 @@ | ||||||
| package com.jetbrains.help.route; | package com.jetbrains.help.route; | ||||||
| 
 | 
 | ||||||
|  | import cn.hutool.core.io.FileUtil; | ||||||
|  | import cn.hutool.core.io.IoUtil; | ||||||
| import cn.hutool.core.text.CharSequenceUtil; | import cn.hutool.core.text.CharSequenceUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import com.jetbrains.help.JetbrainsHelpApplication; | import com.jetbrains.help.JetbrainsHelpApplication; | ||||||
|  | import com.jetbrains.help.context.AgentContextHolder; | ||||||
| import com.jetbrains.help.context.PluginsContextHolder; | import com.jetbrains.help.context.PluginsContextHolder; | ||||||
| import com.jetbrains.help.context.ProductsContextHolder; | import com.jetbrains.help.context.ProductsContextHolder; | ||||||
| import com.jetbrains.help.properties.JetbrainsHelpProperties; | import com.jetbrains.help.properties.JetbrainsHelpProperties; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
|  | import org.springframework.core.io.InputStreamResource; | ||||||
|  | import org.springframework.core.io.Resource; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
| import org.springframework.stereotype.Controller; | import org.springframework.stereotype.Controller; | ||||||
| import org.springframework.ui.Model; | import org.springframework.ui.Model; | ||||||
| import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||||
| import org.springframework.web.bind.annotation.RequestParam; | import org.springframework.web.bind.annotation.RequestParam; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
| 
 | 
 | ||||||
|  | import java.io.File; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
|  | import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; | ||||||
|  | import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; | ||||||
|  | 
 | ||||||
| @Controller | @Controller | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| public class IndexController { | public class IndexController { | ||||||
|  | @ -48,4 +60,14 @@ public class IndexController { | ||||||
|         model.addAttribute("defaults", jetbrainsHelpProperties); |         model.addAttribute("defaults", jetbrainsHelpProperties); | ||||||
|         return "index::product-list"; |         return "index::product-list"; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("ja-netfilter") | ||||||
|  |     @ResponseBody | ||||||
|  |     public ResponseEntity<Resource> downloadJaNetfilter() { | ||||||
|  |         File jaNetfilterZipFile = AgentContextHolder.jaNetfilterZipFile(); | ||||||
|  |         return ResponseEntity.ok() | ||||||
|  |                 .header(CONTENT_DISPOSITION, "attachment;filename=" + jaNetfilterZipFile.getName()) | ||||||
|  |                 .contentType(APPLICATION_OCTET_STREAM) | ||||||
|  |                 .body(new InputStreamResource(FileUtil.getInputStream(jaNetfilterZipFile))); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ package com.jetbrains.help.util; | ||||||
| 
 | 
 | ||||||
| import cn.hutool.core.io.FileUtil; | import cn.hutool.core.io.FileUtil; | ||||||
| import cn.hutool.core.text.CharSequenceUtil; | import cn.hutool.core.text.CharSequenceUtil; | ||||||
|  | import cn.hutool.core.util.ObjectUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import org.springframework.boot.system.ApplicationHome; | ||||||
| import org.springframework.core.io.ClassPathResource; | import org.springframework.core.io.ClassPathResource; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | @ -9,25 +12,35 @@ import java.io.IOException; | ||||||
| 
 | 
 | ||||||
| public interface FileTools { | public interface FileTools { | ||||||
| 
 | 
 | ||||||
|     static boolean fileExists(String pathOrFile) { |     ApplicationHome application = new ApplicationHome(); | ||||||
|         return FileUtil.file(new ClassPathResource(pathOrFile).getPath()).exists(); | 
 | ||||||
|  | 
 | ||||||
|  |     static boolean fileExists(String path) { | ||||||
|  |         return getFile(path).exists(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static File getFileOrCreat(String pathOrFile) { |     static File getFile(String path) { | ||||||
|         File file = FileUtil.file(new ClassPathResource(pathOrFile).getPath()); |         File homeDir = application.getDir(); | ||||||
|         if (!file.exists()) { |         File source = application.getSource(); | ||||||
|             try { |         ClassPathResource classPathResource = new ClassPathResource(path); | ||||||
|                 File parentFile = file.getParentFile(); |         return ObjectUtil.isNull(source) ? FileUtil.file(classPathResource.getPath()) : FileUtil.file(homeDir, path); | ||||||
|                 if (!parentFile.exists() && !parentFile.mkdir()) { |     } | ||||||
|                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File directory create Failed", pathOrFile)); | 
 | ||||||
|  |     static File getFileOrCreat(String path) { | ||||||
|  |         File file = getFile(path); | ||||||
|  |         if (ObjectUtil.isNotNull(application.getSource())) { | ||||||
|  |             ClassPathResource classPathResource = new ClassPathResource(path); | ||||||
|  |             File classPathFile = FileUtil.file(classPathResource.getPath()); | ||||||
|  |             if (classPathResource.exists() && !file.exists()) { | ||||||
|  |                 try { | ||||||
|  |                     FileUtil.writeFromStream(classPathResource.getInputStream(), classPathFile); | ||||||
|  |                 } catch (Exception e) { | ||||||
|  |                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File read failed", classPathFile.getPath()), e); | ||||||
|                 } |                 } | ||||||
|                 if (!file.createNewFile()) { |                 FileUtil.copy(classPathFile, file, true); | ||||||
|                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File create failed", pathOrFile)); |  | ||||||
|                 } |  | ||||||
|             } catch (IOException e) { |  | ||||||
|                 throw new IllegalArgumentException(CharSequenceUtil.format("{} File create failed", pathOrFile), e); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return file; |         return file; | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/main/resources/banner.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/main/resources/banner.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | 
 | ||||||
|  |      ██╗███████╗████████╗██████╗ ██████╗  █████╗ ██╗███╗   ██╗███████╗      ██╗  ██╗███████╗██╗     ██████╗ | ||||||
|  |      ██║██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗██║████╗  ██║██╔════╝      ██║  ██║██╔════╝██║     ██╔══██╗ | ||||||
|  |      ██║█████╗     ██║   ██████╔╝██████╔╝███████║██║██╔██╗ ██║███████╗█████╗███████║█████╗  ██║     ██████╔╝ | ||||||
|  | ██   ██║██╔══╝     ██║   ██╔══██╗██╔══██╗██╔══██║██║██║╚██╗██║╚════██║╚════╝██╔══██║██╔══╝  ██║     ██╔═══╝ | ||||||
|  | ╚█████╔╝███████╗   ██║   ██████╔╝██║  ██║██║  ██║██║██║ ╚████║███████║      ██║  ██║███████╗███████╗██║ | ||||||
|  |  ╚════╝ ╚══════╝   ╚═╝   ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝╚══════╝      ╚═╝  ╚═╝╚══════╝╚══════╝╚═╝ | ||||||
|  | 
 | ||||||
|  | ${AnsiColor.BRIGHT_YELLOW} Spring Boot Version: ${spring-boot.version} | ||||||
|  | 
 | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| [DNS] |  | ||||||
| ; put dns filter rules here |  | ||||||
| 
 |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| [Result] |  | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| [URL] |  | ||||||
| ; put url filter rules here |  | ||||||
| PREFIX,https://account.jetbrains.com/lservice/rpc/validateKey.action |  | ||||||
| 
 |  | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -11,7 +11,7 @@ | ||||||
| <body> | <body> | ||||||
| <header class="tip sticky flex items-center py-6"> | <header class="tip sticky flex items-center py-6"> | ||||||
|     <p> |     <p> | ||||||
|         🇨🇳 Download <a href="/agent/ja-netfilter.zip" title="Download jetbra first">ja-netfilter.zip</a> , and configure |         🇨🇳 Download <a href="ja-netfilter" title="Download jetbra first">ja-netfilter.zip</a> , and configure | ||||||
|         your JetBrains's <strong onclick="showVmoptins()">vmoptions!</strong> <br> |         your JetBrains's <strong onclick="showVmoptins()">vmoptions!</strong> <br> | ||||||
|         🇨🇳 Also you can <a onclick="showLicenseForm()">Refill license information</a> to customizer your license!</br> |         🇨🇳 Also you can <a onclick="showLicenseForm()">Refill license information</a> to customizer your license!</br> | ||||||
|         <strong>🇨🇳 Please note that this page is only developed and used by <span |         <strong>🇨🇳 Please note that this page is only developed and used by <span | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 藏柏
						藏柏