diff --git a/.task/checksum/build b/.task/checksum/build index 3ac0819..2c0b6e9 100644 --- a/.task/checksum/build +++ b/.task/checksum/build @@ -1 +1 @@ -4b0bf220c6b1a17111459c48c118e677 +18f2d39cff8b43ed829b9b6dac85391e diff --git a/FyneApp.toml b/FyneApp.toml index fb2b810..521a6b9 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -5,4 +5,4 @@ Website = "https://github.com/kociumba/Kinjector" Name = "Kinjector" ID = "org.kociumba.kinjector" Version = "1.0.0" - Build = 58 + Build = 60 diff --git a/Taskfile.yml b/Taskfile.yml index bb6601a..a1068d7 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -29,7 +29,7 @@ tasks: - task: deps:install - task: pre:build - go mod tidy - - fyne package -os windows -icon assets/icon.png -name Kinjector --tags 'ldflags=-s -w' -appVersion {{.VERSION}} + - fyne package -os windows -icon assets/icon.ico -name Kinjector --tags 'ldflags=-s -w' -appVersion {{.VERSION}} - task: find:and:move:bin # bugged couse fyne is a piece of shit and assumes every one has a cert to sign release version diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000..e5cbc78 Binary files /dev/null and b/assets/icon.ico differ diff --git a/injector.go b/injector.go index 4a42529..af961bc 100644 --- a/injector.go +++ b/injector.go @@ -1,7 +1,6 @@ package main import ( - "encoding/json" "flag" "fmt" "image/color" @@ -28,9 +27,13 @@ import ( var ( dbg = flag.Bool("dbg", false, "") - configDir string - configFile string - settingsFile string + configDir string + configFile string + settingsFile string + userSelection = &UserSelection{} + suppressSuggestions bool + procSelect *xwidget.CompletionEntry + selectDllButton *widget.Button ) func init() { @@ -58,87 +61,6 @@ type InjectionProfile struct { DllFile string `json:"dllFile"` } -type UserSelection struct { - SelectedProc string - SelectedDll string - DllFile string - processNames []string - Profiles []InjectionProfile - UnsafeUnload bool -} - -func (u *UserSelection) SaveProfile(name string) error { - profile := InjectionProfile{ - Name: name, - SelectedProc: u.SelectedProc, - SelectedDll: u.SelectedDll, - DllFile: u.DllFile, - } - - u.Profiles = append(u.Profiles, profile) - return u.saveProfilesToFile() -} - -func (u *UserSelection) LoadProfile(name string) error { - for _, profile := range u.Profiles { - if profile.Name == name { - u.SelectedProc = profile.SelectedProc - u.SelectedDll = profile.SelectedDll - u.DllFile = profile.DllFile - return nil - } - } - return fmt.Errorf("profile not found") -} - -func (u *UserSelection) saveProfilesToFile() error { - data, err := json.Marshal(u.Profiles) - if err != nil { - return err - } - - err = os.WriteFile(configFile, data, 0600) - if err != nil { - return err - } - - // err = u.loadProfilesFromFile() - // if err != nil { - // return err - // } - - return nil -} - -func (u *UserSelection) loadProfilesFromFile() error { - data, err := os.ReadFile(configFile) - if err != nil { - if os.IsNotExist(err) { - // File doesn't exist, which is fine for first run - return nil - } - return err - } - - err = json.Unmarshal(data, &u.Profiles) - if err != nil { - return err - } - - return nil -} - -func (u *UserSelection) DeleteProfile(name string) error { - for i, profile := range u.Profiles { - if profile.Name == name { - // Remove the profile from the slice - u.Profiles = append(u.Profiles[:i], u.Profiles[i+1:]...) - return u.saveProfilesToFile() - } - } - return fmt.Errorf("profile not found") -} - func trimFilePath(path string) string { clog.Info("Selected dll: " + path) @@ -176,7 +98,6 @@ func performUnload(userSelection *UserSelection, w fyne.Window) { func main() { flag.Parse() - userSelection := &UserSelection{} err := userSelection.loadProfilesFromFile() if err != nil { clog.Warn("Failed to load profiles:", err) @@ -275,8 +196,7 @@ func main() { userSelection.processNames = initialProcessNames // register the process selection input - procSelect := xwidget.NewCompletionEntry(userSelection.processNames) - var suppressSuggestions bool + procSelect = xwidget.NewCompletionEntry(userSelection.processNames) procSelect.OnChanged = func(s string) { if !suppressSuggestions { @@ -311,22 +231,15 @@ func main() { CreditsWindow(fyne.CurrentApp(), fyne.NewSize(800, 400)).Show() }) - // register text displays - dllDisplay := widget.NewLabelWithStyle("Dll selected: ", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) - // errorDisplay := widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) - injection := widget.NewActivity() - profileName := widget.NewEntry() - profileName.SetPlaceHolder("Profile Name") - // Create the unsafe unload checkbox unsafeUnloadCheck := widget.NewCheck("Unsafe Unload (Use with caution)", func(checked bool) { userSelection.UnsafeUnload = checked }) // Damn this shit stupid - selectDllButton := widget.NewButton("", func() {}) + selectDllButton = widget.NewButton("", func() {}) selectDllButton = widget.NewButton("Select DLL", func() { userSelection.SelectedDll, err = zenity.SelectFile(zenity.Filename(os.ExpandEnv("$HOME")), zenity.FileFilter{Patterns: []string{"*.dll"}}) @@ -434,83 +347,7 @@ func main() { nil, ) - // Create the profile management tab - profileName = widget.NewEntry() - profileName.SetPlaceHolder("Profile Name") - - loadProfileSelect := widget.NewSelect([]string{}, func(name string) { - err := userSelection.LoadProfile(name) - if err != nil { - dialog.ShowError(err, w) - } else { - suppressSuggestions = true - procSelect.SetText(userSelection.SelectedProc) - dllDisplay.SetText("Dll selected: " + userSelection.DllFile) - selectDllButton.SetText("DLL: " + userSelection.DllFile) - dialog.ShowInformation("Loaded profile", "Profile "+userSelection.SelectedProc+" loaded successfully", w) - } - }) - - updateProfileList := func() { - var names []string - for _, profile := range userSelection.Profiles { - names = append(names, profile.Name) - } - loadProfileSelect.Options = names - } - - profileForm := &widget.Form{ - Items: []*widget.FormItem{ - {Text: "Profile Name", Widget: profileName}, - {Text: "Load Profile", Widget: loadProfileSelect}, - }, - OnSubmit: func() { - if profileName.Text != "" { - err := userSelection.SaveProfile(profileName.Text) - if err != nil { - dialog.ShowError(err, w) - } else { - dialog.ShowInformation("Success", "Profile saved", w) - updateProfileList() - profileName.SetText("") // Clear the profile name entry after saving - } - } else { - dialog.ShowInformation("Error", "Please enter a profile name", w) - } - }, - OnCancel: func() { - if loadProfileSelect.Selected == "" { - dialog.ShowInformation("Error", "Please select a profile to delete", w) - return - } - dialog.NewConfirm( - "Delete Profile", - "Are you sure you want to delete the profile '"+loadProfileSelect.Selected+"'?", - func(confirm bool) { - if confirm { - err := userSelection.DeleteProfile(loadProfileSelect.Selected) - if err != nil { - dialog.ShowError(err, w) - } else { - dialog.ShowInformation("Success", "Profile deleted", w) - updateProfileList() - loadProfileSelect.SetSelected("") - } - } - }, - w, - ).Show() - }, - SubmitText: "Save Profile", - CancelText: "Delete Profile", - } - - updateProfileList() - - profileTab := container.NewVBox( - widget.NewLabelWithStyle("Profile Management", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), - profileForm, - ) + initProfiles(w) initSettings() diff --git a/profiles.go b/profiles.go new file mode 100644 index 0000000..0ef4dba --- /dev/null +++ b/profiles.go @@ -0,0 +1,184 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/widget" +) + +var ( + profileName = widget.NewEntry() + profileTab *fyne.Container + dllDisplay *widget.Label + loadProfileSelect *widget.Select + updateProfileList func() + profileForm *widget.Form +) + +func initProfiles(w fyne.Window) { + profileName.SetPlaceHolder("Profile Name") + + // register text displays + dllDisplay = widget.NewLabelWithStyle("Dll selected: ", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) + // errorDisplay := widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) + + loadProfileSelect = widget.NewSelect([]string{}, func(name string) { + err := userSelection.LoadProfile(name) + if err != nil { + dialog.ShowError(err, w) + } else { + suppressSuggestions = true + procSelect.SetText(userSelection.SelectedProc) + dllDisplay.SetText("Dll selected: " + userSelection.DllFile) + selectDllButton.SetText("DLL: " + userSelection.DllFile) + dialog.ShowInformation("Loaded profile", "Profile "+userSelection.SelectedProc+" loaded successfully", w) + } + }) + + updateProfileList = func() { + var names []string + for _, profile := range userSelection.Profiles { + names = append(names, profile.Name) + } + loadProfileSelect.Options = names + } + + profileForm = &widget.Form{ + Items: []*widget.FormItem{ + {Text: "Profile Name", Widget: profileName}, + {Text: "Load Profile", Widget: loadProfileSelect}, + }, + OnSubmit: func() { + if profileName.Text != "" { + err := userSelection.SaveProfile(profileName.Text) + if err != nil { + dialog.ShowError(err, w) + } else { + dialog.ShowInformation("Success", "Profile saved", w) + updateProfileList() + profileName.SetText("") // Clear the profile name entry after saving + } + } else { + dialog.ShowInformation("Error", "Please enter a profile name", w) + } + }, + OnCancel: func() { + if loadProfileSelect.Selected == "" { + dialog.ShowInformation("Error", "Please select a profile to delete", w) + return + } + dialog.NewConfirm( + "Delete Profile", + "Are you sure you want to delete the profile '"+loadProfileSelect.Selected+"'?", + func(confirm bool) { + if confirm { + err := userSelection.DeleteProfile(loadProfileSelect.Selected) + if err != nil { + dialog.ShowError(err, w) + } else { + dialog.ShowInformation("Success", "Profile deleted", w) + updateProfileList() + loadProfileSelect.SetSelected("") + } + } + }, + w, + ).Show() + }, + SubmitText: "Save Profile", + CancelText: "Delete Profile", + } + + updateProfileList() + + profileTab = container.NewVBox( + widget.NewLabelWithStyle("Profile Management", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), + profileForm, + ) +} + +type UserSelection struct { + SelectedProc string + SelectedDll string + DllFile string + processNames []string + Profiles []InjectionProfile + UnsafeUnload bool +} + +func (u *UserSelection) SaveProfile(name string) error { + profile := InjectionProfile{ + Name: name, + SelectedProc: u.SelectedProc, + SelectedDll: u.SelectedDll, + DllFile: u.DllFile, + } + + u.Profiles = append(u.Profiles, profile) + return u.saveProfilesToFile() +} + +func (u *UserSelection) LoadProfile(name string) error { + for _, profile := range u.Profiles { + if profile.Name == name { + u.SelectedProc = profile.SelectedProc + u.SelectedDll = profile.SelectedDll + u.DllFile = profile.DllFile + return nil + } + } + return fmt.Errorf("profile not found") +} + +func (u *UserSelection) saveProfilesToFile() error { + data, err := json.Marshal(u.Profiles) + if err != nil { + return err + } + + err = os.WriteFile(configFile, data, 0600) + if err != nil { + return err + } + + // err = u.loadProfilesFromFile() + // if err != nil { + // return err + // } + + return nil +} + +func (u *UserSelection) loadProfilesFromFile() error { + data, err := os.ReadFile(configFile) + if err != nil { + if os.IsNotExist(err) { + // File doesn't exist, which is fine for first run + return nil + } + return err + } + + err = json.Unmarshal(data, &u.Profiles) + if err != nil { + return err + } + + return nil +} + +func (u *UserSelection) DeleteProfile(name string) error { + for i, profile := range u.Profiles { + if profile.Name == name { + // Remove the profile from the slice + u.Profiles = append(u.Profiles[:i], u.Profiles[i+1:]...) + return u.saveProfilesToFile() + } + } + return fmt.Errorf("profile not found") +} diff --git a/todo.md b/todo.md index f594905..f47385e 100644 --- a/todo.md +++ b/todo.md @@ -3,7 +3,7 @@ - (E) make sys tray settings fucntional {cm:2024-10-09} - (E) make unload settings fucntional {cm:2024-10-09} -(F) improve build and gh actions +(F) improve build and gh actions {c} - (F) resolve issues with versioning +build +ghactions -(B) refactor profiles to into a seperate file like settings +profiles \ No newline at end of file +(B) refactor profiles to into a seperate file like settings +profiles {cm:2024-10-10} \ No newline at end of file