package main import ( "archive/zip" "fmt" "io" "net/http" "os" "path/filepath" "runtime" "strings" ) func GetHomeDir() string { homeDir, err := os.UserHomeDir() if err != nil { panic("get user home dir failed: " + err.Error()) } return homeDir } func GetWorkDir() string { homeDir := GetHomeDir() return filepath.Join(homeDir, ".ja") } func DefaultVmOptionDir() string { homeDir := GetHomeDir() if runtime.GOOS == "windows" { return filepath.Join(homeDir, "AppData/Roaming/JetBrains") } return filepath.Join(homeDir, ".config/JetBrains") } func DownloadJaNetfilter() { homeDir := GetWorkDir() filename := filepath.Join(homeDir, "ja-netfilter-2022.2.0.zip") if _, err := os.Stat(filename); os.IsNotExist(err) { url := "https://gitee.com/xuthus5/ja-netfilter/releases/download/v1.0.0/ja-netfilter.zip" err := downloadFile(url, filename) if err != nil { panic("download ja-netfilter failed: " + err.Error()) } } } func UnzipJaNetfilter() { homeDir := GetWorkDir() jaNetfilterDir := filepath.Join(homeDir, "ja-netfilter") if _, err := os.Stat(jaNetfilterDir); os.IsNotExist(err) { filename := filepath.Join(homeDir, "ja-netfilter-2022.2.0.zip") reader, err := zip.OpenReader(filename) if err != nil { panic("open zip failed: " + err.Error()) } defer reader.Close() for _, file := range reader.File { filePath := filepath.Join(homeDir, file.Name) if !strings.HasPrefix(filePath, filepath.Clean(homeDir)+string(os.PathSeparator)) { panic(fmt.Sprintf("illegal file path: %s", filePath)) } if file.FileInfo().IsDir() { if err := os.MkdirAll(filePath, os.ModePerm); err != nil { panic("create dir failed: " + err.Error()) } continue } if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { panic("create dir failed: " + err.Error()) } if err := unzipFile(file, filePath); err != nil { panic("unzip file failed: " + err.Error()) } } } } func unzipFile(f *zip.File, fpath string) error { rc, err := f.Open() if err != nil { return err } defer rc.Close() outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer outFile.Close() _, err = io.Copy(outFile, rc) if err != nil { return err } return nil } func downloadFile(url string, filepath string) error { // 创建HTTP请求 resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() // 创建文件 out, err := os.Create(filepath) if err != nil { return err } defer out.Close() // 将HTTP响应的内容写入文件 _, err = io.Copy(out, resp.Body) if err != nil { return err } return nil } func InjectVmOption(dirname, vmOptionFilename, vmOptionDir string) { if runtime.GOOS == "windows" { vmOptionFilename += ".exe.vmoptions" } else { vmOptionFilename += ".vmoptions" } logger.Printf("inject ide name: %s, vm option: %s", dirname, filepath.Join(vmOptionDir, dirname, vmOptionFilename)) var jaNetfilterFilename = "-javaagent:" + filepath.Join(GetWorkDir(), "ja-netfilter", "ja-netfilter.jar") vmFile := filepath.Join(vmOptionDir, dirname, vmOptionFilename) readFile, err := os.ReadFile(vmFile) if err != nil { panic("read vm file failed: " + err.Error()) } var vmString = string(readFile) if !strings.Contains(vmString, "--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED") { vmString += "\n--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED" } if !strings.Contains(vmString, "--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED") { vmString += "\n--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED" } if !strings.Contains(vmString, jaNetfilterFilename) { vmString += "\n" + jaNetfilterFilename } err = os.WriteFile(vmFile, []byte(vmString), 0644) if err != nil { panic("write vm file failed: " + err.Error()) } }