diff --git a/cache/cache_object.go b/cache/cache_object.go index 54c1bf9..451851d 100644 --- a/cache/cache_object.go +++ b/cache/cache_object.go @@ -15,140 +15,31 @@ import ( // local "github.com/pztrn/urtrator/cachemodels" - "github.com/pztrn/urtrator/datamodels" ) type Cache struct { + // Profiles cache. + Profiles map[string]*cachemodels.Profile // Servers cache. Servers map[string]*cachemodels.Server } -func (c *Cache) CreateServer(addr string) { - _, ok := c.Servers[addr] - if !ok { - c.Servers[addr] = &cachemodels.Server{} - c.Servers[addr].Server = &datamodels.Server{} - } else { - fmt.Println("Server " + addr + " already exist.") - } -} - -// Flush servers to database. -func (c *Cache) FlushServers() { - fmt.Println("Updating servers information in database...") - raw_cached := []datamodels.Server{} - Database.Db.Select(&raw_cached, "SELECT * FROM servers") - - // Create map[string]*datamodels.Server once, so we won't iterate - // over slice of datamodels.Server everytime. - cached_servers := make(map[string]*datamodels.Server) - for s := range raw_cached { - mapping_item_name := raw_cached[s].Ip + ":" + raw_cached[s].Port - cached_servers[mapping_item_name] = &raw_cached[s] - } - - new_servers := make(map[string]*datamodels.Server) - - // Update our cached mapping. - for _, s := range c.Servers { - mapping_item_name := s.Server.Ip + ":" + s.Server.Port - _, ok := cached_servers[mapping_item_name] - if !ok { - fmt.Println(mapping_item_name + " not found!") - new_servers[mapping_item_name] = &datamodels.Server{} - new_servers[mapping_item_name].Ip = s.Server.Ip - new_servers[mapping_item_name].Port = s.Server.Port - new_servers[mapping_item_name].Name = s.Server.Name - new_servers[mapping_item_name].Players = s.Server.Players - new_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers - new_servers[mapping_item_name].Ping = s.Server.Ping - new_servers[mapping_item_name].Map = s.Server.Map - new_servers[mapping_item_name].Gamemode = s.Server.Gamemode - new_servers[mapping_item_name].Version = s.Server.Version - new_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig - new_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo - new_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate - } else { - cached_servers[mapping_item_name].Ip = s.Server.Ip - cached_servers[mapping_item_name].Port = s.Server.Port - cached_servers[mapping_item_name].Name = s.Server.Name - cached_servers[mapping_item_name].Players = s.Server.Players - cached_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers - cached_servers[mapping_item_name].Ping = s.Server.Ping - cached_servers[mapping_item_name].Map = s.Server.Map - cached_servers[mapping_item_name].Gamemode = s.Server.Gamemode - cached_servers[mapping_item_name].Version = s.Server.Version - cached_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig - cached_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo - cached_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate - } - } - - Database.Unlock() - tx := Database.Db.MustBegin() - fmt.Println("Adding new servers...") - if len(new_servers) > 0 { - for _, srv := range new_servers { - tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version, extended_config, players_info, is_private) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private)", srv) - } - } - fmt.Println("Updating cached servers...") - for _, srv := range cached_servers { - _, err := tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, ping=:ping, version=:version, extended_config=:extended_config, players_info=:players_info, is_private=:is_private WHERE ip=:ip AND port=:port", &srv) - if err != nil { - fmt.Println(err.Error()) - } - } - - tx.Commit() - Database.Lock() - fmt.Println("Done") -} - func (c *Cache) Initialize() { fmt.Println("Initializing cache...") c.initializeStorages() - c.LoadServers() + c.LoadServers(map[string]string{}) + + Eventer.AddEventHandler("deleteProfile", c.deleteProfile) + Eventer.AddEventHandler("flushProfiles", c.FlushProfiles) + Eventer.AddEventHandler("loadProfiles", c.LoadProfiles) Eventer.AddEventHandler("flushServers", c.FlushServers) Eventer.AddEventHandler("loadServersIntoCache", c.LoadServers) } func (c *Cache) initializeStorages() { + // Profiles cache. + c.Profiles = make(map[string]*cachemodels.Profile) // Servers cache. c.Servers = make(map[string]*cachemodels.Server) } - -func (c *Cache) LoadServers() { - fmt.Println("Loading servers into cache...") - c.Servers = make(map[string]*cachemodels.Server) - // Getting servers from database. - raw_servers := []datamodels.Server{} - err := Database.Db.Select(&raw_servers, "SELECT * FROM servers") - if err != nil { - fmt.Println(err.Error()) - } - - // Due to nature of pointers and goroutines thing (?) this should - // be done in this way. - for _, server := range raw_servers { - key := server.Ip + ":" + server.Port - c.CreateServer(key) - c.Servers[key].Server.Name = server.Name - c.Servers[key].Server.Ip = server.Ip - c.Servers[key].Server.Port = server.Port - c.Servers[key].Server.Players = server.Players - c.Servers[key].Server.Maxplayers = server.Maxplayers - c.Servers[key].Server.Ping = server.Ping - c.Servers[key].Server.Gamemode = server.Gamemode - c.Servers[key].Server.Map = server.Map - c.Servers[key].Server.Version = server.Version - c.Servers[key].Server.Favorite = server.Favorite - c.Servers[key].Server.Password = server.Password - c.Servers[key].Server.ProfileToUse = server.ProfileToUse - c.Servers[key].Server.ExtendedConfig = server.ExtendedConfig - c.Servers[key].Server.PlayersInfo = server.PlayersInfo - c.Servers[key].Server.IsPrivate = server.IsPrivate - } - fmt.Println("Load completed.") -} diff --git a/cache/cache_profiles.go b/cache/cache_profiles.go new file mode 100644 index 0000000..e227779 --- /dev/null +++ b/cache/cache_profiles.go @@ -0,0 +1,115 @@ +// URTator - Urban Terror server browser and game launcher, written in +// Go. +// +// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n) +// All rights reserved. +// +// Licensed under Terms and Conditions of GNU General Public License +// version 3 or any higher. +// ToDo: put full text of license here. +package cache + +import ( + // stdlib + "fmt" + "strconv" + + // local + "github.com/pztrn/urtrator/cachemodels" + "github.com/pztrn/urtrator/datamodels" +) + +func (c *Cache) CreateProfile(name string) { + fmt.Println("Creating profile " + name) + _, ok := c.Profiles[name] + + if !ok { + c.Profiles[name] = &cachemodels.Profile{} + c.Profiles[name].Profile = &datamodels.Profile{} + } +} + +func (c *Cache) deleteProfile(data map[string]string) { + fmt.Println("Deleting profile " + data["profile_name"]) + + _, ok := c.Profiles[data["profile_name"]] + if ok { + delete(c.Profiles, data["profile_name"]) + } + + _, ok1 := c.Profiles[data["profile_name"]] + if !ok1 { + fmt.Println("Profile deleted") + Database.Unlock() + Database.Db.MustExec(Database.Db.Rebind("DELETE FROM urt_profiles WHERE name=?"), data["profile_name"]) + Database.Lock() + } else { + fmt.Println("Something goes wrong! Profile is still here!") + } +} + +func (c *Cache) FlushProfiles(data map[string]string) { + fmt.Println("Flushing profiles to database...") + + raw_profiles := []datamodels.Profile{} + err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles") + if err != nil { + fmt.Println(err.Error()) + } + + cached_profiles := make(map[string]*datamodels.Profile) + for i := range raw_profiles { + cached_profiles[raw_profiles[i].Name] = &raw_profiles[i] + } + + new_profiles := make(map[string]*datamodels.Profile) + + for _, profile := range c.Profiles { + _, ok := cached_profiles[profile.Profile.Name] + if !ok { + fmt.Println("Flushing new profile " + profile.Profile.Name) + new_profiles[profile.Profile.Name] = &datamodels.Profile{} + new_profiles[profile.Profile.Name].Name = profile.Profile.Name + new_profiles[profile.Profile.Name].Version = profile.Profile.Version + new_profiles[profile.Profile.Name].Binary = profile.Profile.Binary + new_profiles[profile.Profile.Name].Second_x_session = profile.Profile.Second_x_session + new_profiles[profile.Profile.Name].Additional_params = profile.Profile.Additional_params + } + } + + Database.Unlock() + tx := Database.Db.MustBegin() + fmt.Println("Adding new profiles...") + for _, profile := range new_profiles { + tx.NamedExec("INSERT INTO urt_profiles (name, version, binary, second_x_session, additional_parameters) VALUES (:name, :version, :binary, :second_x_session, :additional_parameters)", &profile) + } + fmt.Println("Updating existing profiles...") + for _, profile := range cached_profiles { + tx.NamedExec("UPDATE urt_profiles SET name=:name, version=:version, binary=:binary, second_x_session=:second_x_session, additional_parameters=:additional_parameters WHERE name=:name", &profile) + } + tx.Commit() + Database.Lock() + fmt.Println("Done") +} + +func (c *Cache) LoadProfiles(data map[string]string) { + fmt.Println("Loading profiles to cache...") + + raw_profiles := []datamodels.Profile{} + err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles") + if err != nil { + fmt.Println(err.Error()) + } + + for _, profile := range raw_profiles { + c.Profiles[profile.Name] = &cachemodels.Profile{} + c.Profiles[profile.Name].Profile = &datamodels.Profile{} + c.Profiles[profile.Name].Profile.Name = profile.Name + c.Profiles[profile.Name].Profile.Version = profile.Version + c.Profiles[profile.Name].Profile.Binary = profile.Binary + c.Profiles[profile.Name].Profile.Second_x_session = profile.Second_x_session + c.Profiles[profile.Name].Profile.Additional_params = profile.Additional_params + } + + fmt.Println("Load completed. Loaded " + strconv.Itoa(len(c.Profiles)) + " profiles.") +} diff --git a/cache/cache_servers.go b/cache/cache_servers.go new file mode 100644 index 0000000..ca18e47 --- /dev/null +++ b/cache/cache_servers.go @@ -0,0 +1,135 @@ +// URTator - Urban Terror server browser and game launcher, written in +// Go. +// +// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n) +// All rights reserved. +// +// Licensed under Terms and Conditions of GNU General Public License +// version 3 or any higher. +// ToDo: put full text of license here. +package cache + +import ( + // stdlib + "fmt" + + // local + "github.com/pztrn/urtrator/cachemodels" + "github.com/pztrn/urtrator/datamodels" +) + +func (c *Cache) CreateServer(addr string) { + _, ok := c.Servers[addr] + if !ok { + c.Servers[addr] = &cachemodels.Server{} + c.Servers[addr].Server = &datamodels.Server{} + } else { + fmt.Println("Server " + addr + " already exist.") + } +} + +// Flush servers to database. +func (c *Cache) FlushServers(data map[string]string) { + fmt.Println("Updating servers information in database...") + raw_cached := []datamodels.Server{} + Database.Db.Select(&raw_cached, "SELECT * FROM servers") + + // Create map[string]*datamodels.Server once, so we won't iterate + // over slice of datamodels.Server everytime. + cached_servers := make(map[string]*datamodels.Server) + for s := range raw_cached { + mapping_item_name := raw_cached[s].Ip + ":" + raw_cached[s].Port + cached_servers[mapping_item_name] = &raw_cached[s] + } + + new_servers := make(map[string]*datamodels.Server) + + // Update our cached mapping. + for _, s := range c.Servers { + mapping_item_name := s.Server.Ip + ":" + s.Server.Port + _, ok := cached_servers[mapping_item_name] + if !ok { + fmt.Println(mapping_item_name + " not found!") + new_servers[mapping_item_name] = &datamodels.Server{} + new_servers[mapping_item_name].Ip = s.Server.Ip + new_servers[mapping_item_name].Port = s.Server.Port + new_servers[mapping_item_name].Name = s.Server.Name + new_servers[mapping_item_name].Players = s.Server.Players + new_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers + new_servers[mapping_item_name].Ping = s.Server.Ping + new_servers[mapping_item_name].Map = s.Server.Map + new_servers[mapping_item_name].Gamemode = s.Server.Gamemode + new_servers[mapping_item_name].Version = s.Server.Version + new_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig + new_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo + new_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate + } else { + cached_servers[mapping_item_name].Ip = s.Server.Ip + cached_servers[mapping_item_name].Port = s.Server.Port + cached_servers[mapping_item_name].Name = s.Server.Name + cached_servers[mapping_item_name].Players = s.Server.Players + cached_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers + cached_servers[mapping_item_name].Ping = s.Server.Ping + cached_servers[mapping_item_name].Map = s.Server.Map + cached_servers[mapping_item_name].Gamemode = s.Server.Gamemode + cached_servers[mapping_item_name].Version = s.Server.Version + cached_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig + cached_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo + cached_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate + } + } + + Database.Unlock() + tx := Database.Db.MustBegin() + fmt.Println("Adding new servers...") + if len(new_servers) > 0 { + for _, srv := range new_servers { + tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version, extended_config, players_info, is_private) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private)", srv) + } + } + fmt.Println("Updating cached servers...") + for _, srv := range cached_servers { + _, err := tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, ping=:ping, version=:version, extended_config=:extended_config, players_info=:players_info, is_private=:is_private WHERE ip=:ip AND port=:port", &srv) + if err != nil { + fmt.Println(err.Error()) + } + } + + tx.Commit() + Database.Lock() + fmt.Println("Done") +} + +func (c *Cache) LoadServers(data map[string]string) { + fmt.Println("Loading servers into cache...") + c.Servers = make(map[string]*cachemodels.Server) + // Getting servers from database. + raw_servers := []datamodels.Server{} + err := Database.Db.Select(&raw_servers, "SELECT * FROM servers") + if err != nil { + fmt.Println(err.Error()) + } + + // Due to nature of pointers and goroutines thing (?) this should + // be done in this way. + for _, server := range raw_servers { + key := server.Ip + ":" + server.Port + c.CreateServer(key) + c.Servers[key].Server.Name = server.Name + c.Servers[key].Server.Ip = server.Ip + c.Servers[key].Server.Port = server.Port + c.Servers[key].Server.Players = server.Players + c.Servers[key].Server.Maxplayers = server.Maxplayers + c.Servers[key].Server.Ping = server.Ping + c.Servers[key].Server.Gamemode = server.Gamemode + c.Servers[key].Server.Map = server.Map + c.Servers[key].Server.Version = server.Version + c.Servers[key].Server.Favorite = server.Favorite + c.Servers[key].Server.Password = server.Password + c.Servers[key].Server.ProfileToUse = server.ProfileToUse + c.Servers[key].Server.ExtendedConfig = server.ExtendedConfig + c.Servers[key].Server.PlayersInfo = server.PlayersInfo + c.Servers[key].Server.IsPrivate = server.IsPrivate + } + fmt.Println("Load completed.") +} diff --git a/cachemodels/profile.go b/cachemodels/profile.go new file mode 100644 index 0000000..ac03288 --- /dev/null +++ b/cachemodels/profile.go @@ -0,0 +1,19 @@ +// URTator - Urban Terror server browser and game launcher, written in +// Go. +// +// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n) +// All rights reserved. +// +// Licensed under Terms and Conditions of GNU General Public License +// version 3 or any higher. +// ToDo: put full text of license here. +package cachemodels + +import ( + // local + "github.com/pztrn/urtrator/datamodels" +) + +type Profile struct { + Profile *datamodels.Profile +} diff --git a/context/context_object.go b/context/context_object.go index a74577f..c3930ad 100644 --- a/context/context_object.go +++ b/context/context_object.go @@ -51,7 +51,8 @@ func (ctx *Context) Close() error { if launched != nil { return errors.New("Urban Terror is launched!") } - ctx.Cache.FlushServers() + ctx.Cache.FlushProfiles(map[string]string{}) + ctx.Cache.FlushServers(map[string]string{}) ctx.Database.Close() // At last, close main window. diff --git a/eventer/eventer_object.go b/eventer/eventer_object.go index 7542605..f5160bf 100644 --- a/eventer/eventer_object.go +++ b/eventer/eventer_object.go @@ -17,13 +17,13 @@ import ( type Eventer struct { // Events - events map[string]map[string]func() + events map[string]map[string]func(data map[string]string) } -func (e *Eventer) AddEventHandler(event string, handler func()) { +func (e *Eventer) AddEventHandler(event string, handler func(data map[string]string)) { _, ok := e.events[event] if !ok { - e.events[event] = make(map[string]func()) + e.events[event] = make(map[string]func(data map[string]string)) } event_id_raw := make([]byte, 16) crand.Read(event_id_raw) @@ -36,10 +36,10 @@ func (e *Eventer) Initialize() { } func (e *Eventer) initializeStorage() { - e.events = make(map[string]map[string]func()) + e.events = make(map[string]map[string]func(data map[string]string)) } -func (e *Eventer) LaunchEvent(event string) error { +func (e *Eventer) LaunchEvent(event string, data map[string]string) error { _, ok := e.events[event] if !ok { return errors.New("Event " + event + " not found!") @@ -47,7 +47,7 @@ func (e *Eventer) LaunchEvent(event string) error { fmt.Println("Launching event " + event) for _, val := range e.events[event] { - val() + val(data) } return nil diff --git a/launcher/launcher_object.go b/launcher/launcher_object.go index b050739..f9db1af 100644 --- a/launcher/launcher_object.go +++ b/launcher/launcher_object.go @@ -56,7 +56,7 @@ func (l *Launcher) Initialize() { fmt.Println("Initializing game launcher...") } -func (l *Launcher) Launch(profile *datamodels.Profile, server string, password string, callback func()) { +func (l *Launcher) Launch(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, additional_parameters []string, callback func()) { // ToDo: only one instance of Urban Terror should be launched, so button // should be disabled. fmt.Println("Launching Urban Terror...") @@ -65,23 +65,30 @@ func (l *Launcher) Launch(profile *datamodels.Profile, server string, password s // Create launch string. var launch_bin string = "" - launch_bin, err := exec.LookPath(profile.Binary) + launch_bin, err := exec.LookPath(user_profile.Binary) if err != nil { fmt.Println(err.Error()) } + server_address := server_profile.Ip + ":" + server_profile.Port + var launch_params []string - if len(server) > 0 { - launch_params = append(launch_params, "+connect", server) + if len(server_address) > 0 { + launch_params = append(launch_params, "+connect", server_address) } if len(password) > 0 { launch_params = append(launch_params, "+password", password) } - if len(profile.Additional_params) > 0 { - additional_params := strings.Split(profile.Additional_params, " ") + if len(user_profile.Additional_params) > 0 { + additional_params := strings.Split(user_profile.Additional_params, " ") launch_params = append(launch_params, additional_params...) } - if profile.Second_x_session == "1" { + if len(additional_parameters) > 0 { + for i := range additional_parameters { + launch_params = append(launch_params, additional_parameters[i]) + } + } + if user_profile.Second_x_session == "1" { fmt.Println(launch_params) launch_params = append([]string{launch_bin}, launch_params...) display := l.findFreeDisplay() diff --git a/requester/pooler.go b/requester/pooler.go index 832fdc4..bbc7640 100644 --- a/requester/pooler.go +++ b/requester/pooler.go @@ -131,11 +131,11 @@ func (p *Pooler) UpdateOneServer(server_address string) { }(server) wait.Wait() p.PingOneServer(server_address) - Eventer.LaunchEvent("flushServers") + Eventer.LaunchEvent("flushServers", map[string]string{}) - Eventer.LaunchEvent("loadAllServers") - Eventer.LaunchEvent("loadFavoriteServers") - Eventer.LaunchEvent("serversUpdateCompleted") + Eventer.LaunchEvent("loadAllServers", map[string]string{}) + Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) + Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{}) } func (p *Pooler) UpdateServers(servers_type string) { @@ -153,11 +153,11 @@ func (p *Pooler) UpdateServers(servers_type string) { } wait.Wait() p.PingServers(servers_type) - Eventer.LaunchEvent("flushServers") + Eventer.LaunchEvent("flushServers", map[string]string{}) - Eventer.LaunchEvent("loadAllServers") - Eventer.LaunchEvent("loadFavoriteServers") - Eventer.LaunchEvent("serversUpdateCompleted") + Eventer.LaunchEvent("loadAllServers", map[string]string{}) + Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) + Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{}) } // Updates information about specific server. diff --git a/ui/favorite.go b/ui/favorite.go index ec5fd5a..320250d 100644 --- a/ui/favorite.go +++ b/ui/favorite.go @@ -245,7 +245,7 @@ func (f *FavoriteDialog) saveFavorite() error { ctx.Cache.Servers[key].Server.ExtendedConfig = f.server.ExtendedConfig ctx.Cache.Servers[key].Server.PlayersInfo = f.server.PlayersInfo - ctx.Eventer.LaunchEvent("loadFavoriteServers") + ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) f.window.Destroy() return nil diff --git a/ui/mainwindow.go b/ui/mainwindow.go index 6fee46b..027be19 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -11,7 +11,6 @@ package ui import ( // stdlib - "errors" "fmt" "strconv" "strings" @@ -67,6 +66,8 @@ type MainWindow struct { qc_server_address *gtk.Entry // Quick connect: password qc_password *gtk.Entry + // Quick connect: nickname + qc_nickname *gtk.Entry // Tray icon. tray_icon *gtk.StatusIcon // Tray menu. @@ -219,7 +220,7 @@ func (m *MainWindow) deleteFromFavorites() { d.Run() } - ctx.Eventer.LaunchEvent("loadFavoriteServers") + ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) } // Drop database data. @@ -246,9 +247,9 @@ func (m *MainWindow) dropDatabasesData() { ctx.Database.Db.MustExec("DELETE FROM settings") ctx.Database.Db.MustExec("DELETE FROM urt_profiles") - ctx.Eventer.LaunchEvent("loadProfiles") - ctx.Eventer.LaunchEvent("loadAllServers") - ctx.Eventer.LaunchEvent("loadFavoriteServers") + ctx.Eventer.LaunchEvent("loadProfiles", map[string]string{}) + ctx.Eventer.LaunchEvent("loadAllServers", map[string]string{}) + ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) } } @@ -273,7 +274,7 @@ func (m *MainWindow) hideOfflineAllServers() { } else { ctx.Cfg.Cfg["/serverslist/all_servers/hide_offline"] = "0" } - ctx.Eventer.LaunchEvent("loadAllServers") + ctx.Eventer.LaunchEvent("loadAllServers", map[string]string{}) } // Executes when "Hide offline servers" checkbox changed it's state on @@ -285,138 +286,10 @@ func (m *MainWindow) hideOfflineFavoriteServers() { } else { ctx.Cfg.Cfg["/serverslist/favorite/hide_offline"] = "0" } - ctx.Eventer.LaunchEvent("loadFavoriteServers") + ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) } -func (m *MainWindow) launchGame() error { - fmt.Println("Launching Urban Terror...") - - // Getting server's name from list. - current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage())) - sel := m.all_servers.GetSelection() - model := m.all_servers.GetModel() - if strings.Contains(current_tab, "Favorites") { - sel = m.fav_servers.GetSelection() - model = m.fav_servers.GetModel() - } - iter := new(gtk.TreeIter) - _ = sel.GetSelected(iter) - - // Getting server name. - var srv_name string - srv_name_gval := glib.ValueFromNative(srv_name) - if strings.Contains(current_tab, "Servers") { - model.GetValue(iter, m.column_pos["Servers"]["Name"], srv_name_gval) - } else if strings.Contains(current_tab, "Favorites") { - model.GetValue(iter, m.column_pos["Favorites"]["Name"], srv_name_gval) - } - server_name := srv_name_gval.GetString() - - // Getting server address. - var srv_addr string - srv_address_gval := glib.ValueFromNative(srv_addr) - if strings.Contains(current_tab, "Servers") { - model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_address_gval) - } else if strings.Contains(current_tab, "Favorites") { - model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_address_gval) - } - srv_address := srv_address_gval.GetString() - - // Getting server's game version. - var srv_game_ver_raw string - srv_game_ver_gval := glib.ValueFromNative(srv_game_ver_raw) - if strings.Contains(current_tab, "Servers") { - model.GetValue(iter, m.column_pos["Servers"]["Version"], srv_game_ver_gval) - } else if strings.Contains(current_tab, "Favorites") { - model.GetValue(iter, m.column_pos["Favorites"]["Version"], srv_game_ver_gval) - } - srv_game_ver := srv_game_ver_gval.GetString() - - // Check for proper server name. If length == 0: server is offline, - // we should show notification to user. - if len(server_name) == 0 { - var will_continue bool = false - mbox_string := "Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server." - m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string) - m.Connect("response", func(resp *glib.CallbackContext) { - if resp.Args(0) == 4294967287 { - will_continue = false - } else { - will_continue = true - } - }) - m.Response(func() { - m.Destroy() - }) - m.Run() - if !will_continue { - return errors.New("User declined to connect to offline server") - } - } - - // Getting selected profile's name. - profile_name := m.profiles.GetActiveText() - if strings.Contains(current_tab, "Servers") { - // Checking profile name length. If 0 - then stop executing :) - // This check only relevant to "Servers" tab, favorite servers - // have profiles defined (see next). - if len(profile_name) == 0 { - mbox_string := "Invalid game profile selected.\n\nPlease, select profile and retry." - m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) - m.Response(func() { - m.Destroy() - }) - m.Run() - return errors.New("User didn't select valid profile.") - } - } else if strings.Contains(current_tab, "Favorites") { - // For favorite servers profile specified in favorite server - // information have higher priority, so we just override it :) - server := []datamodels.Server{} - // All favorites servers should contain IP and Port :) - ip := strings.Split(srv_address, ":")[0] - port := strings.Split(srv_address, ":")[1] - err := ctx.Database.Db.Select(&server, ctx.Database.Db.Rebind("SELECT * FROM servers WHERE ip=? AND port=?"), ip, port) - if err != nil { - fmt.Println(err.Error()) - } - profile_name = server[0].ProfileToUse - } - - // Getting profile data from database. - // ToDo: cache profiles data in runtime. - profile := []datamodels.Profile{} - err := ctx.Database.Db.Select(&profile, ctx.Database.Db.Rebind("SELECT * FROM urt_profiles WHERE name=?"), profile_name) - if err != nil { - fmt.Println(err.Error()) - } - - // Check if profile version is valid for selected game server. - if profile[0].Version != srv_game_ver { - mbox_string := "Invalid game profile selected.\n\nSelected profile have different game version than server.\nPlease, select valid profile and retry." - m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) - m.Response(func() { - m.Destroy() - }) - m.Run() - return errors.New("User didn't select valid profile, mismatch with server's version.") - } - - // Hey, we're ok here! :) Launch Urban Terror! - // Crear server name from "" things. - srv_name_for_label := string([]byte(server_name)[8:len(server_name)-9]) - fmt.Println(srv_name_for_label) - // Show great coloured label. - m.statusbar.Push(m.statusbar_context_id, "Launching Urban Terror...") - m.toolbar_label.SetMarkup("Urban Terror is launched with profile " + profile[0].Name + " and connected to " + srv_name_for_label + "") - m.launch_button.SetSensitive(false) - // ToDo: handling server passwords. - ctx.Launcher.Launch(&profile[0], srv_address, "", m.unlockInterface) - - return nil -} - -func (m *MainWindow) loadAllServers() { +func (m *MainWindow) loadAllServers(data map[string]string) { fmt.Println("Loading all servers...") // ToDo: do it without clearing. for _, server := range ctx.Cache.Servers { @@ -469,7 +342,7 @@ func (m *MainWindow) loadAllServers() { } } -func (m *MainWindow) loadFavoriteServers() { +func (m *MainWindow) loadFavoriteServers(data map[string]string) { fmt.Println("Loading favorite servers...") for _, server := range ctx.Cache.Servers { iter := new(gtk.TreeIter) @@ -534,7 +407,7 @@ func (m *MainWindow) loadFavoriteServers() { } } -func (m *MainWindow) loadProfiles() { +func (m *MainWindow) loadProfiles(data map[string]string) { fmt.Println("Loading profiles into combobox on MainWindow") for i := 0; i < m.old_profiles_count; i++ { // ComboBox indexes are shifting on element deletion, so we should @@ -542,22 +415,25 @@ func (m *MainWindow) loadProfiles() { m.profiles.Remove(0) } - profiles := []datamodels.Profile{} - err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles") - if err != nil { - fmt.Println(err.Error()) - } - for p := range profiles { - m.profiles.AppendText(profiles[p].Name) + for _, profile := range ctx.Cache.Profiles { + m.profiles.AppendText(profile.Profile.Name) } - m.old_profiles_count = len(profiles) + m.old_profiles_count = len(ctx.Cache.Profiles) fmt.Println("Added " + strconv.Itoa(m.old_profiles_count) + " profiles") } -func (m *MainWindow) serversUpdateCompleted() { - m.statusbar.Push(m.statusbar_context_id, "Servers updated.") - m.toolbar_label.SetLabel("Servers updated.") +func (m *MainWindow) serversUpdateCompleted(data map[string]string) { + ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "Servers updated."}) +} + +func (m *MainWindow) setToolbarLabelText(data map[string]string) { + fmt.Println("Setting toolbar's label text...") + if strings.Contains(data["text"], "") { + m.toolbar_label.SetMarkup(data["text"]) + } else { + m.toolbar_label.SetLabel(data["text"]) + } } func (m *MainWindow) showHide() { @@ -687,8 +563,7 @@ func (m *MainWindow) showTrayMenu(cbx *glib.CallbackContext) { // Unlocking interface after game shut down. func (m *MainWindow) unlockInterface() { m.launch_button.SetSensitive(true) - m.statusbar.Push(m.statusbar_context_id, "URTrator is ready.") - m.toolbar_label.SetLabel("URTrator is ready.") + ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "URTrator is ready."}) } func (m *MainWindow) updateOneServer() { @@ -702,8 +577,7 @@ func (m *MainWindow) updateOneServer() { // Triggered when "Update all servers" button is clicked. func (m *MainWindow) UpdateServers() { - m.statusbar.Push(m.statusbar_context_id, "Updating servers...") - m.toolbar_label.SetMarkup("Updating servers...") + ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "Updating servers..."}) current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage())) fmt.Println("Updating servers on tab '" + current_tab + "'...") diff --git a/ui/mainwindow_init.go b/ui/mainwindow_init.go index 9b93f69..7cf9276 100644 --- a/ui/mainwindow_init.go +++ b/ui/mainwindow_init.go @@ -139,21 +139,16 @@ func (m *MainWindow) Initialize() { m.launch_button.SetImage(launch_button_image) profile_and_launch_hbox.PackStart(m.launch_button, false, true, 5) - // Statusbar. - m.statusbar = gtk.NewStatusbar() - m.vbox.PackStart(m.statusbar, false, true, 0) - - m.statusbar_context_id = m.statusbar.GetContextId("Status Bar") - m.statusbar.Push(m.statusbar_context_id, "URTrator is ready") - m.window.Add(m.vbox) m.window.ShowAll() // Launch events. - ctx.Eventer.LaunchEvent("loadProfiles") - ctx.Eventer.LaunchEvent("loadServersIntoCache") - ctx.Eventer.LaunchEvent("loadAllServers") - ctx.Eventer.LaunchEvent("loadFavoriteServers") + ctx.Eventer.LaunchEvent("loadProfiles", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{}) + ctx.Eventer.LaunchEvent("loadServersIntoCache", map[string]string{}) + ctx.Eventer.LaunchEvent("loadAllServers", map[string]string{}) + ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{}) + ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "URTrator is ready."}) gtk.Main() } @@ -163,8 +158,9 @@ func (m *MainWindow) initializeEvents() { fmt.Println("Initializing events...") ctx.Eventer.AddEventHandler("loadAllServers", m.loadAllServers) ctx.Eventer.AddEventHandler("loadFavoriteServers", m.loadFavoriteServers) - ctx.Eventer.AddEventHandler("loadProfiles", m.loadProfiles) + ctx.Eventer.AddEventHandler("loadProfilesIntoMainWindow", m.loadProfiles) ctx.Eventer.AddEventHandler("serversUpdateCompleted", m.serversUpdateCompleted) + ctx.Eventer.AddEventHandler("setToolbarLabelText", m.setToolbarLabelText) } // Main menu initialization. @@ -269,6 +265,16 @@ func (m *MainWindow) initializeSidebar() { m.qc_password.SetTooltipText(pass_tooltip) qc_vbox.PackStart(m.qc_password, false, true, 5) + // Nickname + nick_tooltip := "Nickname we will use" + nick_label := gtk.NewLabel("Nickname:") + nick_label.SetTooltipText(nick_tooltip) + qc_vbox.PackStart(nick_label, false, true, 5) + + m.qc_nickname = gtk.NewEntry() + m.qc_nickname.SetTooltipText(nick_tooltip) + qc_vbox.PackStart(m.qc_nickname, false, true, 5) + m.hpane.Add2(sidebar_vbox) } diff --git a/ui/mainwindow_launch.go b/ui/mainwindow_launch.go new file mode 100644 index 0000000..7ed3d1b --- /dev/null +++ b/ui/mainwindow_launch.go @@ -0,0 +1,192 @@ +package ui + +import ( + // stdlib + "errors" + "fmt" + "strings" + + // Local + "github.com/pztrn/urtrator/datamodels" + + // other + "github.com/mattn/go-gtk/glib" + "github.com/mattn/go-gtk/gtk" +) + +func (m *MainWindow) launchGame() error { + fmt.Println("Launching Urban Terror...") + if len(m.qc_server_address.GetText()) != 0 { + m.launchWithQuickConnect() + } else { + m.launchAsUsual() + } + + return nil +} + +// Triggers if we clicked "Launch" button without any text in quick connect +// widget. +func (m *MainWindow) launchAsUsual() error { + fmt.Println("Connecting to selected server...") + var srv_address string = "" + + // Getting server's name from list. + current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage())) + sel := m.all_servers.GetSelection() + model := m.all_servers.GetModel() + if strings.Contains(current_tab, "Favorites") { + sel = m.fav_servers.GetSelection() + model = m.fav_servers.GetModel() + } + iter := new(gtk.TreeIter) + _ = sel.GetSelected(iter) + + // Getting server address. + var srv_addr string + srv_address_gval := glib.ValueFromNative(srv_addr) + if strings.Contains(current_tab, "Servers") { + model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_address_gval) + } else if strings.Contains(current_tab, "Favorites") { + model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_address_gval) + } + srv_address = srv_address_gval.GetString() + server_profile := ctx.Cache.Servers[srv_address].Server + + // Check for proper server name. If length == 0: server is offline, + // we should show notification to user. + if len(server_profile.Name) == 0 { + var will_continue bool = false + mbox_string := "Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server." + m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string) + m.Connect("response", func(resp *glib.CallbackContext) { + if resp.Args(0) == 4294967287 { + will_continue = false + } else { + will_continue = true + } + }) + m.Response(func() { + m.Destroy() + }) + m.Run() + if !will_continue { + return errors.New("User declined to connect to offline server") + } + } + + // Getting selected profile's name. + profile_name := m.profiles.GetActiveText() + user_profile := &datamodels.Profile{} + if strings.Contains(current_tab, "Servers") { + // Checking profile name length. If 0 - then stop executing :) + // This check only relevant to "Servers" tab, favorite servers + // have profiles defined (see next). + if len(profile_name) == 0 { + mbox_string := "Invalid game profile selected.\n\nPlease, select profile and retry." + m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) + m.Response(func() { + m.Destroy() + }) + m.Run() + return errors.New("User didn't select valid profile.") + } + user_profile = ctx.Cache.Profiles[profile_name].Profile + } else if strings.Contains(current_tab, "Favorites") { + // For favorite servers profile specified in favorite server + // information have higher priority, so we just override it :) + user_profile = ctx.Cache.Profiles[server_profile.ProfileToUse].Profile + } + + m.launchActually(server_profile, user_profile, "", "") + return nil +} + +// Triggers when Launch button was clicked with some text in quick connect +// widget. +func (m *MainWindow) launchWithQuickConnect() error { + fmt.Println("Launching game with data from quick connect...") + + srv_address := m.qc_server_address.GetText() + srv_password := m.qc_password.GetText() + srv_nickname := m.qc_nickname.GetText() + current_profile_name := m.profiles.GetActiveText() + + // As we're launching without any profile defined - we should + // check server version and globally selected profile. + // Checking if we have server defined in cache. + var ip string = "" + var port string = "" + if strings.Contains(srv_address, ":") { + ip = strings.Split(srv_address, ":")[0] + port = strings.Split(srv_address, ":")[1] + } else { + ip = strings.Split(srv_address, ":")[0] + port = "27960" + } + + key := ip + ":" + port + + _, ok := ctx.Cache.Servers[key] + if !ok { + ctx.Cache.CreateServer(key) + fmt.Println("Server not found in cache, requesting information...") + ctx.Requester.UpdateOneServer(key) + } + + server_profile := ctx.Cache.Servers[key] + user_profile := ctx.Cache.Profiles[current_profile_name] + + m.launchActually(server_profile.Server, user_profile.Profile, srv_password, srv_nickname) + return nil +} + +func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, nickname_to_use string) error { + if server_profile.Name == "" { + var will_continue bool = false + mbox_string := "Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server." + m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string) + m.Connect("response", func(resp *glib.CallbackContext) { + if resp.Args(0) == 4294967287 { + will_continue = false + } else { + will_continue = true + } + }) + m.Response(func() { + m.Destroy() + }) + m.Run() + if !will_continue { + return errors.New("User declined to connect to offline server") + } + } + + // Check if server is applicable for selected profile. + if server_profile.Version != user_profile.Version { + mbox_string := "Invalid game profile selected.\n\nSelected profile have different game version than server.\nPlease, select valid profile and retry." + m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) + m.Response(func() { + m.Destroy() + }) + m.Run() + return errors.New("User didn't select valid profile, mismatch with server's version.") + } + + server_password := password + if len(server_password) == 0 { + server_password = server_profile.Password + } + + // Hey, we're ok here! :) Launch Urban Terror! + // Crear server name from "" things. + srv_name_for_label := string([]byte(server_profile.Name)[8:len(server_profile.Name)-9]) + fmt.Println(srv_name_for_label) + // Show great coloured label. + ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "Urban Terror is launched with profile " + user_profile.Name + " and connected to " + srv_name_for_label + ""}) + m.launch_button.SetSensitive(false) + // ToDo: handling server passwords. + ctx.Launcher.Launch(server_profile, user_profile, server_password, []string{"+name", nickname_to_use}, m.unlockInterface) + + return nil +} diff --git a/ui/options.go b/ui/options.go index c1592db..a7bd318 100644 --- a/ui/options.go +++ b/ui/options.go @@ -48,8 +48,10 @@ func (o *OptionsDialog) addProfile() { fmt.Println("Adding profile...") op := OptionsProfile{} - op.Initialize(false, o.loadProfiles) - ctx.Eventer.LaunchEvent("loadProfiles") + op.Initialize(false) + ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{}) } func (o *OptionsDialog) closeOptionsDialogByCancel() { @@ -71,8 +73,6 @@ func (o *OptionsDialog) closeOptionsDialogWithSaving() { }) m.Run() - ctx.Eventer.LaunchEvent("loadProfiles") - o.window.Destroy() } @@ -92,8 +92,10 @@ func (o *OptionsDialog) deleteProfile() { profile := datamodels.Profile{} profile.Name = profile_name - ctx.Database.Db.NamedExec("DELETE FROM urt_profiles WHERE name=:name", &profile) - ctx.Eventer.LaunchEvent("loadProfiles") + ctx.Eventer.LaunchEvent("deleteProfile", map[string]string{"profile_name": profile_name}) + ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) } } @@ -110,8 +112,10 @@ func (o *OptionsDialog) editProfile() { if len(profile_name) > 0 { op := OptionsProfile{} - op.InitializeUpdate(profile_name, o.loadProfiles) - ctx.Eventer.LaunchEvent("loadProfiles") + op.InitializeUpdate(profile_name) + ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) } } @@ -169,6 +173,8 @@ func (o *OptionsDialog) initializeTabs() { o.vbox.PackStart(o.tab_widget, true, true, 5) o.vbox.PackStart(buttons_hbox, false, true, 5) + + ctx.Eventer.AddEventHandler("loadProfilesIntoOptionsWindow", o.loadProfiles) } func (o *OptionsDialog) initializeUrtTab() { @@ -213,26 +219,18 @@ func (o *OptionsDialog) initializeUrtTab() { o.tab_widget.AppendPage(urt_hbox, gtk.NewLabel("Urban Terror")) // Load Profiles. - o.loadProfiles() + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) } -func (o *OptionsDialog) loadProfiles() { +func (o *OptionsDialog) loadProfiles(data map[string]string) { fmt.Println("Loading profiles...") o.profiles_list_store.Clear() - // Get profiles from database. - profiles := []datamodels.Profile{} - err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles") - if err != nil { - fmt.Println(err.Error()) - } - for p := range profiles { + for _, p := range ctx.Cache.Profiles { var iter gtk.TreeIter o.profiles_list_store.Append(&iter) - o.profiles_list_store.Set(&iter, 0, profiles[p].Name) - o.profiles_list_store.Set(&iter, 1, profiles[p].Version) - //state, _ := strconv.ParseBool(profiles[p].Second_x_session) - //o.profiles_list_store.Set(&iter, 2, state) + o.profiles_list_store.Set(&iter, 0, p.Profile.Name) + o.profiles_list_store.Set(&iter, 1, p.Profile.Version) } } @@ -267,5 +265,8 @@ func (o *OptionsDialog) ShowOptionsDialog() { o.fill() o.window.Add(o.vbox) + + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) + o.window.ShowAll() } diff --git a/ui/options_profile.go b/ui/options_profile.go index 91983c1..0a9548c 100644 --- a/ui/options_profile.go +++ b/ui/options_profile.go @@ -47,10 +47,6 @@ type OptionsProfile struct { // This is profile update? update bool - // Callbacks. - // This will be triggered after we change profile. - loadProfiles func() - // Others. // Old profile, needed for proper update. old_profile *datamodels.Profile @@ -105,13 +101,11 @@ func (op *OptionsProfile) closeByCancel() { func (op *OptionsProfile) closeWithDiscard() { } -func (op *OptionsProfile) Initialize(update bool, lp func()) { +func (op *OptionsProfile) Initialize(update bool) { if update { op.update = true } - op.loadProfiles = lp - op.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL) if update { op.window.SetTitle("URTrator - Update Urban Terror profile") @@ -233,9 +227,9 @@ func (op *OptionsProfile) Initialize(update bool, lp func()) { op.window.ShowAll() } -func (op *OptionsProfile) InitializeUpdate(profile_name string, lp func()) { +func (op *OptionsProfile) InitializeUpdate(profile_name string) { fmt.Println("Updating profile '" + profile_name + "'") - op.Initialize(true, lp) + op.Initialize(true) // Get profile data. profile := []datamodels.Profile{} @@ -284,7 +278,7 @@ func (op *OptionsProfile) saveProfile() { m.Run() } // ...and must be executable! :) - filestat, err := os.Stat(op.binary_path.GetText()) + _, err := os.Stat(op.binary_path.GetText()) if err != nil { mbox_string := "Invalid path to binary!\n\nError was:\n" + err.Error() + "\n\nCheck binary path and try again." m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) @@ -294,37 +288,11 @@ func (op *OptionsProfile) saveProfile() { m.Run() } else { // ToDo: executable flag checking. - fmt.Println(filestat.Mode()) + //fmt.Println(filestat.Mode()) + profile_name := op.profile_name.GetText() - // If we here - we can try to save game profile :). - profile := datamodels.Profile{ - Name: op.profile_name.GetText(), - Version: op.urt_version_combo.GetActiveText(), - Binary: op.binary_path.GetText(), - Additional_params: op.additional_parameters.GetText(), - } - - if op.another_x_session.GetActive() { - profile.Second_x_session = "1" - } else { - profile.Second_x_session = "0" - } - - // Check if we already have profile with such name. - profiles := []datamodels.Profile{} - err1 := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles") - if err1 != nil { - fmt.Println(err1.Error()) - } - - var found bool = false - for p := range profiles { - if profiles[p].Name == profile.Name { - found = true - } - } - - if found && profile.Version == op.old_profile.Version && profile.Binary == op.old_profile.Binary && profile.Name == op.old_profile.Name && profile.Second_x_session == op.old_profile.Second_x_session { + _, ok := ctx.Cache.Profiles[profile_name] + if ok && !op.update { mbox_string := "Game profile with same name already exist.\nRename profile for saving." m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string) m.Response(func() { @@ -332,13 +300,20 @@ func (op *OptionsProfile) saveProfile() { }) m.Run() } else { - if op.update { - ctx.Database.Db.NamedExec("UPDATE urt_profiles SET name=:name, version=:version, binary=:binary, second_x_session=:second_x_session, additional_parameters=:additional_parameters WHERE name='" + op.old_profile.Name + "'", &profile) + ctx.Cache.CreateProfile(profile_name) + ctx.Cache.Profiles[profile_name].Profile.Name = profile_name + ctx.Cache.Profiles[profile_name].Profile.Version = op.urt_version_combo.GetActiveText() + ctx.Cache.Profiles[profile_name].Profile.Binary = op.binary_path.GetText() + ctx.Cache.Profiles[profile_name].Profile.Additional_params = op.additional_parameters.GetText() + + if op.another_x_session.GetActive() { + ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "1" } else { - ctx.Database.Db.NamedExec("INSERT INTO urt_profiles (name, version, binary, second_x_session, additional_parameters) VALUES (:name, :version, :binary, :second_x_session, :additional_parameters)", &profile) + ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "0" } } } - op.loadProfiles() + ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{}) + ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{}) op.window.Destroy() }