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> | ||||
| 
 | ||||
|     <build> | ||||
|         <finalName>${artifactId}</finalName> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|  |  | |||
|  | @ -1,8 +1,13 @@ | |||
| package com.jetbrains.help; | ||||
| 
 | ||||
| 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 com.jetbrains.help.context.*; | ||||
| import lombok.SneakyThrows; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 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.Scheduled; | ||||
| 
 | ||||
| import java.net.InetAddress; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Slf4j | ||||
| @EnableScheduling | ||||
| @Import(SpringUtil.class) | ||||
| @SpringBootApplication | ||||
|  | @ -23,12 +30,21 @@ public class JetbrainsHelpApplication { | |||
|         SpringApplication.run(JetbrainsHelpApplication.class, args); | ||||
|     } | ||||
| 
 | ||||
|     @SneakyThrows | ||||
|     @EventListener(ApplicationReadyEvent.class) | ||||
|     public void ready() { | ||||
|         ProductsContextHolder.init(); | ||||
|         PluginsContextHolder.init(); | ||||
|         CertificateContextHolder.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 * * ?") | ||||
|  |  | |||
|  | @ -24,25 +24,33 @@ import java.util.concurrent.CompletableFuture; | |||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class AgentContextHolder { | ||||
| 
 | ||||
|     private static final String JA_NETFILTER_FILE_PATH = "static/agent/ja-netfilter"; | ||||
| //    private static final String JA_NETFILTER_FILE_PATH = "static/agent/ja"; | ||||
|     private static final String JA_NETFILTER_FILE_PATH = "external/agent/ja-netfilter"; | ||||
| 
 | ||||
|     private static final String POWER_CONF_FILE_NAME = JA_NETFILTER_FILE_PATH + "/config/power.conf"; | ||||
| 
 | ||||
|     private static File jaNetfilterFile; | ||||
| 
 | ||||
|     private static File jaNetfilterZipFile; | ||||
| 
 | ||||
|     public static void init() { | ||||
|         log.info("Agent context init loading..."); | ||||
|         jaNetfilterFile = FileTools.getFileOrCreat(JA_NETFILTER_FILE_PATH); | ||||
|         jaNetfilterZipFile = FileTools.getFileOrCreat(JA_NETFILTER_FILE_PATH + ".zip"); | ||||
|         if (!FileTools.fileExists(JA_NETFILTER_FILE_PATH)) { | ||||
|             unzipJaNetfilter(); | ||||
|             if (!powerConfHasInit()) { | ||||
|                 log.info("Agent config init loading..."); | ||||
|                 loadPowerConf(); | ||||
|                 zipJaNetfilter(); | ||||
|                 log.info("Agent config init success !"); | ||||
|             } | ||||
|         } | ||||
|         log.info("Agent context init success !"); | ||||
|     } | ||||
| 
 | ||||
|     public static File jaNetfilterZipFile() { | ||||
|         return AgentContextHolder.jaNetfilterZipFile; | ||||
|     } | ||||
| 
 | ||||
|     private static boolean powerConfHasInit() { | ||||
|         File powerConfFile = FileTools.getFileOrCreat(POWER_CONF_FILE_NAME); | ||||
|         String powerConfStr; | ||||
|  | @ -90,7 +98,11 @@ public class AgentContextHolder { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static void unzipJaNetfilter() { | ||||
|         jaNetfilterFile = ZipUtil.unzip(jaNetfilterZipFile); | ||||
|     } | ||||
| 
 | ||||
|     private static void zipJaNetfilter() { | ||||
|         ZipUtil.zip(jaNetfilterFile); | ||||
|         jaNetfilterZipFile = ZipUtil.zip(jaNetfilterFile); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -31,10 +31,10 @@ import java.security.cert.CertificateException; | |||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class CertificateContextHolder { | ||||
| 
 | ||||
|     private static final String ROOT_KEY_FILE_NAME = "certificate/root.key"; | ||||
|     private static final String PRIVATE_KEY_FILE_NAME = "certificate/private.key"; | ||||
|     private static final String PUBLIC_KEY_FILE_NAME = "certificate/public.key"; | ||||
|     private static final String CET_FILE_NAME = "certificate/ca.crt"; | ||||
|     private static final String ROOT_KEY_FILE_NAME = "external/certificate/root.key"; | ||||
|     private static final String PRIVATE_KEY_FILE_NAME = "external/certificate/private.key"; | ||||
|     private static final String PUBLIC_KEY_FILE_NAME = "external/certificate/public.key"; | ||||
|     private static final String CET_FILE_NAME = "external/certificate/ca.crt"; | ||||
| 
 | ||||
|     private static File rootKeyFile; | ||||
| 
 | ||||
|  | @ -52,6 +52,7 @@ public class CertificateContextHolder { | |||
|                 || !FileTools.fileExists(CET_FILE_NAME)) { | ||||
|             log.info("certificate context generate loading..."); | ||||
|             generateCertificate(); | ||||
|             log.info("certificate context generate success!"); | ||||
|         } else { | ||||
|             privateKeyFile = FileTools.getFileOrCreat(PRIVATE_KEY_FILE_NAME); | ||||
|             publicKeyFile = FileTools.getFileOrCreat(PUBLIC_KEY_FILE_NAME); | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import lombok.NoArgsConstructor; | |||
| import lombok.extern.slf4j.Slf4j; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| 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_JSON_FILE_NAME = "plugin.json"; | ||||
|     private static final String PLUGIN_JSON_FILE_NAME = "external/data/plugin.json"; | ||||
| 
 | ||||
|     private static List<PluginCache> pluginCacheList; | ||||
| 
 | ||||
|  | @ -84,11 +85,14 @@ public class PluginsContextHolder { | |||
|     public static PluginList pluginList() { | ||||
|         return HttpUtil.createGet(PLUGIN_LIST_URL) | ||||
|                 .thenFunction(response -> { | ||||
|                     InputStream is = response.bodyStream(); | ||||
|                     try (InputStream is = response.bodyStream()) { | ||||
|                         if (!response.isOk()) { | ||||
|                             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); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
| 
 | ||||
|  | @ -119,11 +123,14 @@ public class PluginsContextHolder { | |||
|     public static PluginInfo pluginInfo(Long pluginId) { | ||||
|         return HttpUtil.createGet(PLUGIN_INFO_URL + pluginId) | ||||
|                 .thenFunction(response -> { | ||||
|                     InputStream is = response.bodyStream(); | ||||
|                     try (InputStream is = response.bodyStream()) { | ||||
|                         if (!response.isOk()) { | ||||
|                             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); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import java.util.List; | |||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| 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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,20 +1,32 @@ | |||
| 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.util.StrUtil; | ||||
| import com.jetbrains.help.JetbrainsHelpApplication; | ||||
| import com.jetbrains.help.context.AgentContextHolder; | ||||
| import com.jetbrains.help.context.PluginsContextHolder; | ||||
| import com.jetbrains.help.context.ProductsContextHolder; | ||||
| import com.jetbrains.help.properties.JetbrainsHelpProperties; | ||||
| import lombok.AllArgsConstructor; | ||||
| 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.ui.Model; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestParam; | ||||
| import org.springframework.web.bind.annotation.ResponseBody; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; | ||||
| import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; | ||||
| 
 | ||||
| @Controller | ||||
| @RequiredArgsConstructor | ||||
| public class IndexController { | ||||
|  | @ -48,4 +60,14 @@ public class IndexController { | |||
|         model.addAttribute("defaults", jetbrainsHelpProperties); | ||||
|         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.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 java.io.File; | ||||
|  | @ -9,25 +12,35 @@ import java.io.IOException; | |||
| 
 | ||||
| public interface FileTools { | ||||
| 
 | ||||
|     static boolean fileExists(String pathOrFile) { | ||||
|         return FileUtil.file(new ClassPathResource(pathOrFile).getPath()).exists(); | ||||
|     ApplicationHome application = new ApplicationHome(); | ||||
| 
 | ||||
| 
 | ||||
|     static boolean fileExists(String path) { | ||||
|         return getFile(path).exists(); | ||||
|     } | ||||
| 
 | ||||
|     static File getFileOrCreat(String pathOrFile) { | ||||
|         File file = FileUtil.file(new ClassPathResource(pathOrFile).getPath()); | ||||
|         if (!file.exists()) { | ||||
|     static File getFile(String path) { | ||||
|         File homeDir = application.getDir(); | ||||
|         File source = application.getSource(); | ||||
|         ClassPathResource classPathResource = new ClassPathResource(path); | ||||
|         return ObjectUtil.isNull(source) ? FileUtil.file(classPathResource.getPath()) : FileUtil.file(homeDir, path); | ||||
|     } | ||||
| 
 | ||||
|     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 { | ||||
|                 File parentFile = file.getParentFile(); | ||||
|                 if (!parentFile.exists() && !parentFile.mkdir()) { | ||||
|                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File directory create Failed", pathOrFile)); | ||||
|                     FileUtil.writeFromStream(classPathResource.getInputStream(), classPathFile); | ||||
|                 } catch (Exception e) { | ||||
|                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File read failed", classPathFile.getPath()), e); | ||||
|                 } | ||||
|                 if (!file.createNewFile()) { | ||||
|                     throw new IllegalArgumentException(CharSequenceUtil.format("{} File create failed", pathOrFile)); | ||||
|                 } | ||||
|             } catch (IOException e) { | ||||
|                 throw new IllegalArgumentException(CharSequenceUtil.format("{} File create failed", pathOrFile), e); | ||||
|                 FileUtil.copy(classPathFile, file, true); | ||||
|             } | ||||
|         } | ||||
|         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> | ||||
| <header class="tip sticky flex items-center py-6"> | ||||
|     <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> | ||||
|         🇨🇳 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 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 藏柏
						藏柏