package main import ( "crypto/rand" "fmt" "log" "math/big" "net/http" "os" "os/exec" "regexp" "strconv" "strings" "syscall" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/driver/desktop" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/elazarl/goproxy" ) var ( AoiApp fyne.App AoiJan fyne.Window VSCode bool CodeBlocks bool Python bool Home string ) type TextGridWriter struct { TextGridWidget *widget.TextGrid } func (tw *TextGridWriter) Write(p []byte) (n int, err error) { logMsg := string(p) tw.TextGridWidget.SetText(tw.TextGridWidget.Text() + logMsg) return len(p), nil } func proxy() { proxy := goproxy.NewProxyHttpServer() proxy.Verbose = true proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("boca.facom.*:443$"))).HandleConnect(goproxy.FuncHttpsHandler(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) { return goproxy.OkConnect, host })) proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(".*:443$"))).HandleConnect(goproxy.AlwaysReject) randport, _ := rand.Int(rand.Reader, (big.NewInt(65535 - 40000 + 1))) portaAleatoria := fmt.Sprintf("%v", randport) strPorta, _ := strconv.Atoi(portaAleatoria) strPorta += 40000 fmt.Printf("%v", strPorta) log.Fatal(http.ListenAndServe(":8080", proxy)) } func main() { Home, _ = os.UserHomeDir() aoi := app.NewWithID("br.ufu.facom.boca.aoi") AoiApp = aoi aoiJanela := aoi.NewWindow("AOI - Apenas Outro Instalador") AoiJan = aoiJanela aoiJanela.CenterOnScreen() aoiJanela.SetMaster() aoiJanela.RequestFocus() aoiJanela.Resize(fyne.Size{Height: 644, Width: 866}) aoiJanela.SetIcon(resourceIconPng) AoiApp.SetIcon(resourceIconPng) aoiJanela.SetCloseIntercept(func() { aoiJanela.Hide() }) tituloPaginaPrincipal := widget.NewRichTextFromMarkdown(textoPaginaPrincipal) //tituloPaginaPrincipal.Wrapping = fyne.TextWrapWord btnProximoPaginaPrincipal := widget.NewButtonWithIcon("Iniciar", theme.NavigateNextIcon(), func() { mudarPagina(1) }) btnProximoPaginaPrincipal.IconPlacement = widget.ButtonIconTrailingText btnProximoPaginaPrincipal.Importance = widget.SuccessImportance if desk, ok := AoiApp.(desktop.App); ok { m := fyne.NewMenu("AOI", fyne.NewMenuItem("Mostrar", func() { AoiJan.Show() }), fyne.NewMenuItemSeparator(), fyne.NewMenuItem("Quit", func() { AoiJan.Show() sairSenha := dialog.NewEntryDialog("Opa, chama o seu professor!", "Digite a senha de acesso.", func(s string) { if s == "facom" { scriptMatarProxy, _ := os.CreateTemp("", "AOI_PROXY_REMOVE_*.cmd") scriptMatarProxy.WriteString(scriptRemoverProxy) scriptMatarProxy.Sync() scriptMatarProxy.Close() removerProxy := exec.Command("cmd", "/c", scriptMatarProxy.Name()) removerProxy.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} removerProxy.Run() AoiApp.Quit() } }, AoiJan) sairSenha.Show() })) desk.SetSystemTrayMenu(m) } aoiJanela.SetContent(container.NewCenter(container.NewVBox(tituloPaginaPrincipal, btnProximoPaginaPrincipal))) aoiJanela.ShowAndRun() } func mudarPagina(x int) { switch x { case 1: //Começa a instalar o scoop labelStatus := widget.NewLabel("Criando script de instalação...") actv := widget.NewProgressBarInfinite() actv.Start() barraStatus := container.NewStack(labelStatus, actv) registroStdout := widget.NewTextGrid() AoiJan.SetContent(container.NewBorder(barraStatus, nil, nil, nil, container.NewScroll(registroStdout))) textGridWidgetWriter := &TextGridWriter{TextGridWidget: registroStdout} log.SetPrefix("") log.SetOutput(textGridWidgetWriter) command := exec.Command("powershell", "-c", "Set-ExecutionPolicy", "-ExecutionPolicy", "Unrestricted", "-Scope", "CurrentUser") command.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} command.Stdin = strings.NewReader("s\n") command.Run() log.Print("[Debug] ExecutionPolicy: ") command = exec.Command("powershell", "-c", "Get-ExecutionPolicy") command.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} out, _ := command.CombinedOutput() log.Printf("%s", out) command.Run() log.Println("Instalando scoop, isso pode demorar um pouco...") git7zip, _ := os.CreateTemp("", "AOI_*.ps1") git7zip.WriteString(scriptInstalação) git7zip.Sync() git7zip.Close() git7zipInstall := exec.Command("powershell", "-c", git7zip.Name()) git7zipInstall.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} out, _ = git7zipInstall.CombinedOutput() log.Printf("%s", out) git7zipInstall.Run() log.Println("==== INSTALAÇÃO PRONTA =====") barraStatus.RemoveAll() barraStatus.Add(widget.NewButtonWithIcon("Continuar", theme.NavigateNextIcon(), func() { mudarPagina(2) })) case 2: labelTituloSelecionarIde := widget.NewLabel("\tSelecione qual IDE você quer utilizar.") labelTituloSelecionarIde.TextStyle = fyne.TextStyle{Bold: true} btnSelecionarIdeVsc := widget.NewButtonWithIcon("Visual Studio Code", resourceVscodePng, func() { VSCode = true; mudarPagina(3) }) btnSelecionarIdeVsc.Importance = widget.HighImportance btnSelecionarIdeCb := widget.NewButtonWithIcon("Code::Blocks", resourceCodeblocksPng, func() { CodeBlocks = true; mudarPagina(3) }) btnSelecionarIdeCb.Importance = widget.HighImportance conteudoPagina := container.NewCenter(container.NewBorder(labelTituloSelecionarIde, nil, nil, nil, container.NewGridWithColumns(2, btnSelecionarIdeVsc, btnSelecionarIdeCb))) AoiJan.SetContent(conteudoPagina) case 3: labelTituloSelecionarLang := widget.NewLabel("\tEscolha qual linguagem irá utilizar.") labelTituloSelecionarLang.TextStyle = fyne.TextStyle{Bold: true} chkSelecionarCpp := &widget.Check{Text: "C/C++"} imgSelecionarCpp := canvas.NewImageFromResource(resourceCppPng) imgSelecionarCpp.FillMode = canvas.ImageFillOriginal imgAndChkSelecionarCpp := container.NewBorder(nil, nil, imgSelecionarCpp, nil, chkSelecionarCpp) chkSelecionarPython := &widget.Check{Text: "Python 3.10"} imgSelecionarPython := canvas.NewImageFromResource(resourcePythonPng) imgSelecionarPython.FillMode = canvas.ImageFillOriginal imgAndChkSelecionarPython := container.NewBorder(nil, nil, imgSelecionarPython, nil, chkSelecionarPython) if CodeBlocks { chkSelecionarPython.Disable() chkSelecionarCpp.SetChecked(true) } btnProximaPagina := widget.NewButtonWithIcon("Instalar IDE e linguagem(s)", theme.NavigateNextIcon(), func() { if !chkSelecionarCpp.Checked && !chkSelecionarPython.Checked { dialog.ShowInformation("Escolha uma linguagem", "Escolha pelo menos uma linguagem para prosseguir.", AoiJan) return } mudarPagina(4) }) btnProximaPagina.IconPlacement = widget.ButtonIconTrailingText btnProximaPagina.Importance = widget.HighImportance AoiJan.SetContent(container.NewCenter(container.NewBorder(labelTituloSelecionarLang, btnProximaPagina, nil, nil, container.NewGridWithRows(2, imgAndChkSelecionarCpp, imgAndChkSelecionarPython)))) case 4: labelStatus := widget.NewLabel("Instalando linguagens e ide...") barraProgresso := widget.NewProgressBarInfinite() barraProgresso.Start() barraStatus := container.NewStack(labelStatus, barraProgresso) registroStdout := widget.NewTextGrid() escrivãoRegistro := &TextGridWriter{TextGridWidget: registroStdout} log.SetOutput(escrivãoRegistro) AoiJan.SetContent(container.NewBorder(barraStatus, nil, nil, nil, container.NewScroll(registroStdout))) switch { case CodeBlocks: log.Println("[Info] Instalando Code::Blocks com GCC...") instalarVSCode := exec.Command("cmd", "/c", "scoop", "install", "extras/codeblocks-mingw") instalarVSCode.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} instalarVSCode.Dir = Home + "\\scoop\\shims" out, _ := instalarVSCode.CombinedOutput() log.Printf("%s", out) instalarVSCode.Run() case VSCode: log.Println("[Info] Instalando Visual Studio Code...") instalarVSCode := exec.Command("scoop", "install", "extras/vscode") instalarVSCode.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} instalarVSCode.Dir = Home + "\\scoop\\shims" out, _ := instalarVSCode.CombinedOutput() log.Printf("%s", out) instalarVSCode.Run() case Python: log.Println("[Info] Instalando Python 3.10...") instalarPython := exec.Command("scoop", "install", "versions/python310") instalarPython.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} instalarPython.Dir = Home + "\\scoop\\shims" out, _ := instalarPython.CombinedOutput() log.Printf("%s", out) instalarPython.Run() log.Println("[Info] [Python] Mesclando entrada no registro....") mesclarRegistro := exec.Command("reg", "merge", fmt.Sprintf("%s\\scoop\\apps\\python310\\current\\install-pep-514.reg", Home)) mesclarRegistro.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} mesclarRegistro.Run() case VSCode && !Python: log.Println("[Info] Instalando GCC...") instalarGcc := exec.Command("scoop", "install", "versions/tdm-gcc") instalarGcc.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} instalarGcc.Dir = Home + "\\scoop\\shims" out, _ := instalarGcc.CombinedOutput() log.Printf("%s", out) instalarGcc.Run() } barraStatus.RemoveAll() barraStatus.Add(widget.NewButtonWithIcon("Continuar", theme.NavigateNextIcon(), func() { mudarPagina(5) })) case 5: labelFim := widget.NewRichTextFromMarkdown(`# Tudo pronto! Agora você já pode começar sua prova!`) btnIniciarProxy := widget.NewButtonWithIcon("Fechar o app", theme.WindowCloseIcon(), func() { proxyScript, _ := os.CreateTemp("", "AOI_PROXY_*.cmd") proxyScript.WriteString(scriptProxy) proxyScript.Sync() proxyScript.Close() ativarProxy := exec.Command("cmd", "/c", proxyScript.Name()) ativarProxy.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} ativarProxy.Start() go func() { proxy() }() AoiJan.Hide() }) btnIniciarProxy.Importance = widget.DangerImportance AoiJan.SetContent(container.NewVBox(labelFim, btnIniciarProxy)) } }