Updated to latest GTK2 bindings API and moved to Gitlab.
This commit is contained in:
parent
070aa50762
commit
127e1b8ab9
50
cache/cache_object.go
vendored
50
cache/cache_object.go
vendored
@ -10,41 +10,41 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cachemodels"
|
"gitlab.com/pztrn/urtrator/cachemodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
// Profiles cache.
|
// Profiles cache.
|
||||||
Profiles map[string]*cachemodels.Profile
|
Profiles map[string]*cachemodels.Profile
|
||||||
// Profiles cache mutex.
|
// Profiles cache mutex.
|
||||||
ProfilesMutex sync.Mutex
|
ProfilesMutex sync.Mutex
|
||||||
// Servers cache.
|
// Servers cache.
|
||||||
Servers map[string]*cachemodels.Server
|
Servers map[string]*cachemodels.Server
|
||||||
// Servers cache mutex.
|
// Servers cache mutex.
|
||||||
ServersMutex sync.Mutex
|
ServersMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) Initialize() {
|
func (c *Cache) Initialize() {
|
||||||
fmt.Println("Initializing cache...")
|
fmt.Println("Initializing cache...")
|
||||||
c.initializeStorages()
|
c.initializeStorages()
|
||||||
c.LoadServers(map[string]string{})
|
c.LoadServers(map[string]string{})
|
||||||
|
|
||||||
Eventer.AddEventHandler("deleteProfile", c.deleteProfile)
|
Eventer.AddEventHandler("deleteProfile", c.deleteProfile)
|
||||||
Eventer.AddEventHandler("flushProfiles", c.FlushProfiles)
|
Eventer.AddEventHandler("flushProfiles", c.FlushProfiles)
|
||||||
Eventer.AddEventHandler("loadProfiles", c.LoadProfiles)
|
Eventer.AddEventHandler("loadProfiles", c.LoadProfiles)
|
||||||
|
|
||||||
Eventer.AddEventHandler("flushServers", c.FlushServers)
|
Eventer.AddEventHandler("flushServers", c.FlushServers)
|
||||||
Eventer.AddEventHandler("loadServersIntoCache", c.LoadServers)
|
Eventer.AddEventHandler("loadServersIntoCache", c.LoadServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) initializeStorages() {
|
func (c *Cache) initializeStorages() {
|
||||||
// Profiles cache.
|
// Profiles cache.
|
||||||
c.Profiles = make(map[string]*cachemodels.Profile)
|
c.Profiles = make(map[string]*cachemodels.Profile)
|
||||||
// Servers cache.
|
// Servers cache.
|
||||||
c.Servers = make(map[string]*cachemodels.Server)
|
c.Servers = make(map[string]*cachemodels.Server)
|
||||||
}
|
}
|
||||||
|
154
cache/cache_profiles.go
vendored
154
cache/cache_profiles.go
vendored
@ -10,105 +10,105 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cachemodels"
|
"gitlab.com/pztrn/urtrator/cachemodels"
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Cache) CreateProfile(name string) {
|
func (c *Cache) CreateProfile(name string) {
|
||||||
fmt.Println("Creating profile " + name)
|
fmt.Println("Creating profile " + name)
|
||||||
_, ok := c.Profiles[name]
|
_, ok := c.Profiles[name]
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
c.Profiles[name] = &cachemodels.Profile{}
|
c.Profiles[name] = &cachemodels.Profile{}
|
||||||
c.Profiles[name].Profile = &datamodels.Profile{}
|
c.Profiles[name].Profile = &datamodels.Profile{}
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) deleteProfile(data map[string]string) {
|
func (c *Cache) deleteProfile(data map[string]string) {
|
||||||
fmt.Println("Deleting profile " + data["profile_name"])
|
fmt.Println("Deleting profile " + data["profile_name"])
|
||||||
|
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
_, ok := c.Profiles[data["profile_name"]]
|
_, ok := c.Profiles[data["profile_name"]]
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
delete(c.Profiles, data["profile_name"])
|
delete(c.Profiles, data["profile_name"])
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
_, ok1 := c.Profiles[data["profile_name"]]
|
_, ok1 := c.Profiles[data["profile_name"]]
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
if !ok1 {
|
if !ok1 {
|
||||||
Database.Db.MustExec(Database.Db.Rebind("DELETE FROM urt_profiles WHERE name=?"), data["profile_name"])
|
Database.Db.MustExec(Database.Db.Rebind("DELETE FROM urt_profiles WHERE name=?"), data["profile_name"])
|
||||||
fmt.Println("Profile deleted")
|
fmt.Println("Profile deleted")
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Something goes wrong! Profile is still here!")
|
fmt.Println("Something goes wrong! Profile is still here!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) FlushProfiles(data map[string]string) {
|
func (c *Cache) FlushProfiles(data map[string]string) {
|
||||||
fmt.Println("Flushing profiles to database...")
|
fmt.Println("Flushing profiles to database...")
|
||||||
|
|
||||||
raw_profiles := []datamodels.Profile{}
|
raw_profiles := []datamodels.Profile{}
|
||||||
err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles")
|
err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_profiles := make(map[string]*datamodels.Profile)
|
cached_profiles := make(map[string]*datamodels.Profile)
|
||||||
for i := range raw_profiles {
|
for i := range raw_profiles {
|
||||||
cached_profiles[raw_profiles[i].Name] = c.Profiles[raw_profiles[i].Name].Profile
|
cached_profiles[raw_profiles[i].Name] = c.Profiles[raw_profiles[i].Name].Profile
|
||||||
}
|
}
|
||||||
|
|
||||||
new_profiles := make(map[string]*datamodels.Profile)
|
new_profiles := make(map[string]*datamodels.Profile)
|
||||||
|
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
for _, profile := range c.Profiles {
|
for _, profile := range c.Profiles {
|
||||||
_, ok := cached_profiles[profile.Profile.Name]
|
_, ok := cached_profiles[profile.Profile.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Println("Flushing new profile " + profile.Profile.Name)
|
fmt.Println("Flushing new profile " + profile.Profile.Name)
|
||||||
new_profiles[profile.Profile.Name] = profile.Profile
|
new_profiles[profile.Profile.Name] = profile.Profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
|
|
||||||
tx := Database.Db.MustBegin()
|
tx := Database.Db.MustBegin()
|
||||||
fmt.Println("Adding new profiles...")
|
fmt.Println("Adding new profiles...")
|
||||||
for _, profile := range new_profiles {
|
for _, profile := range new_profiles {
|
||||||
tx.NamedExec("INSERT INTO urt_profiles (name, version, binary, second_x_session, additional_parameters, profile_path) VALUES (:name, :version, :binary, :second_x_session, :additional_parameters, :profile_path)", &profile)
|
tx.NamedExec("INSERT INTO urt_profiles (name, version, binary, second_x_session, additional_parameters, profile_path) VALUES (:name, :version, :binary, :second_x_session, :additional_parameters, :profile_path)", &profile)
|
||||||
}
|
}
|
||||||
fmt.Println("Updating existing profiles...")
|
fmt.Println("Updating existing profiles...")
|
||||||
for _, profile := range cached_profiles {
|
for _, profile := range cached_profiles {
|
||||||
fmt.Println(fmt.Sprintf("%+v", profile))
|
fmt.Println(fmt.Sprintf("%+v", profile))
|
||||||
tx.NamedExec("UPDATE urt_profiles SET name=:name, version=:version, binary=:binary, second_x_session=:second_x_session, additional_parameters=:additional_parameters, profile_path=:profile_path WHERE name=:name", &profile)
|
tx.NamedExec("UPDATE urt_profiles SET name=:name, version=:version, binary=:binary, second_x_session=:second_x_session, additional_parameters=:additional_parameters, profile_path=:profile_path WHERE name=:name", &profile)
|
||||||
}
|
}
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) LoadProfiles(data map[string]string) {
|
func (c *Cache) LoadProfiles(data map[string]string) {
|
||||||
fmt.Println("Loading profiles to cache...")
|
fmt.Println("Loading profiles to cache...")
|
||||||
|
|
||||||
raw_profiles := []datamodels.Profile{}
|
raw_profiles := []datamodels.Profile{}
|
||||||
err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles")
|
err := Database.Db.Select(&raw_profiles, "SELECT * FROM urt_profiles")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ProfilesMutex.Lock()
|
c.ProfilesMutex.Lock()
|
||||||
for _, profile := range raw_profiles {
|
for _, profile := range raw_profiles {
|
||||||
c.Profiles[profile.Name] = &cachemodels.Profile{}
|
c.Profiles[profile.Name] = &cachemodels.Profile{}
|
||||||
c.Profiles[profile.Name].Profile = &profile
|
c.Profiles[profile.Name].Profile = &profile
|
||||||
}
|
}
|
||||||
c.ProfilesMutex.Unlock()
|
c.ProfilesMutex.Unlock()
|
||||||
|
|
||||||
fmt.Println("Load completed. Loaded " + strconv.Itoa(len(c.Profiles)) + " profiles.")
|
fmt.Println("Load completed. Loaded " + strconv.Itoa(len(c.Profiles)) + " profiles.")
|
||||||
}
|
}
|
||||||
|
228
cache/cache_servers.go
vendored
228
cache/cache_servers.go
vendored
@ -10,135 +10,135 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cachemodels"
|
"gitlab.com/pztrn/urtrator/cachemodels"
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Cache) CreateServer(addr string) {
|
func (c *Cache) CreateServer(addr string) {
|
||||||
_, ok := c.Servers[addr]
|
_, ok := c.Servers[addr]
|
||||||
if !ok {
|
if !ok {
|
||||||
c.ServersMutex.Lock()
|
c.ServersMutex.Lock()
|
||||||
c.Servers[addr] = &cachemodels.Server{}
|
c.Servers[addr] = &cachemodels.Server{}
|
||||||
c.Servers[addr].Server = &datamodels.Server{}
|
c.Servers[addr].Server = &datamodels.Server{}
|
||||||
c.ServersMutex.Unlock()
|
c.ServersMutex.Unlock()
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Server " + addr + " already exist.")
|
fmt.Println("Server " + addr + " already exist.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush servers to database.
|
// Flush servers to database.
|
||||||
func (c *Cache) FlushServers(data map[string]string) {
|
func (c *Cache) FlushServers(data map[string]string) {
|
||||||
fmt.Println("Updating servers information in database...")
|
fmt.Println("Updating servers information in database...")
|
||||||
raw_cached := []datamodels.Server{}
|
raw_cached := []datamodels.Server{}
|
||||||
Database.Db.Select(&raw_cached, "SELECT * FROM servers")
|
Database.Db.Select(&raw_cached, "SELECT * FROM servers")
|
||||||
|
|
||||||
// Create map[string]*datamodels.Server once, so we won't iterate
|
// Create map[string]*datamodels.Server once, so we won't iterate
|
||||||
// over slice of datamodels.Server everytime.
|
// over slice of datamodels.Server everytime.
|
||||||
cached_servers := make(map[string]*datamodels.Server)
|
cached_servers := make(map[string]*datamodels.Server)
|
||||||
for s := range raw_cached {
|
for s := range raw_cached {
|
||||||
mapping_item_name := raw_cached[s].Ip + ":" + raw_cached[s].Port
|
mapping_item_name := raw_cached[s].Ip + ":" + raw_cached[s].Port
|
||||||
cached_servers[mapping_item_name] = &raw_cached[s]
|
cached_servers[mapping_item_name] = &raw_cached[s]
|
||||||
}
|
}
|
||||||
|
|
||||||
new_servers := make(map[string]*datamodels.Server)
|
new_servers := make(map[string]*datamodels.Server)
|
||||||
|
|
||||||
// Update our cached mapping.
|
// Update our cached mapping.
|
||||||
for _, s := range c.Servers {
|
for _, s := range c.Servers {
|
||||||
mapping_item_name := s.Server.Ip + ":" + s.Server.Port
|
mapping_item_name := s.Server.Ip + ":" + s.Server.Port
|
||||||
_, ok := cached_servers[mapping_item_name]
|
_, ok := cached_servers[mapping_item_name]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Println(mapping_item_name + " not found!")
|
fmt.Println(mapping_item_name + " not found!")
|
||||||
new_servers[mapping_item_name] = &datamodels.Server{}
|
new_servers[mapping_item_name] = &datamodels.Server{}
|
||||||
new_servers[mapping_item_name].Ip = s.Server.Ip
|
new_servers[mapping_item_name].Ip = s.Server.Ip
|
||||||
new_servers[mapping_item_name].Port = s.Server.Port
|
new_servers[mapping_item_name].Port = s.Server.Port
|
||||||
new_servers[mapping_item_name].Name = s.Server.Name
|
new_servers[mapping_item_name].Name = s.Server.Name
|
||||||
new_servers[mapping_item_name].Players = s.Server.Players
|
new_servers[mapping_item_name].Players = s.Server.Players
|
||||||
new_servers[mapping_item_name].Bots = s.Server.Bots
|
new_servers[mapping_item_name].Bots = s.Server.Bots
|
||||||
new_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers
|
new_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers
|
||||||
new_servers[mapping_item_name].Ping = s.Server.Ping
|
new_servers[mapping_item_name].Ping = s.Server.Ping
|
||||||
new_servers[mapping_item_name].Map = s.Server.Map
|
new_servers[mapping_item_name].Map = s.Server.Map
|
||||||
new_servers[mapping_item_name].Gamemode = s.Server.Gamemode
|
new_servers[mapping_item_name].Gamemode = s.Server.Gamemode
|
||||||
new_servers[mapping_item_name].Version = s.Server.Version
|
new_servers[mapping_item_name].Version = s.Server.Version
|
||||||
new_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
|
new_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
|
||||||
new_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
|
new_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
|
||||||
new_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
|
new_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
|
||||||
new_servers[mapping_item_name].Favorite = s.Server.Favorite
|
new_servers[mapping_item_name].Favorite = s.Server.Favorite
|
||||||
new_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
|
new_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
|
||||||
new_servers[mapping_item_name].Password = s.Server.Password
|
new_servers[mapping_item_name].Password = s.Server.Password
|
||||||
} else {
|
} else {
|
||||||
cached_servers[mapping_item_name].Ip = s.Server.Ip
|
cached_servers[mapping_item_name].Ip = s.Server.Ip
|
||||||
cached_servers[mapping_item_name].Port = s.Server.Port
|
cached_servers[mapping_item_name].Port = s.Server.Port
|
||||||
cached_servers[mapping_item_name].Name = s.Server.Name
|
cached_servers[mapping_item_name].Name = s.Server.Name
|
||||||
cached_servers[mapping_item_name].Players = s.Server.Players
|
cached_servers[mapping_item_name].Players = s.Server.Players
|
||||||
cached_servers[mapping_item_name].Bots = s.Server.Bots
|
cached_servers[mapping_item_name].Bots = s.Server.Bots
|
||||||
cached_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers
|
cached_servers[mapping_item_name].Maxplayers = s.Server.Maxplayers
|
||||||
cached_servers[mapping_item_name].Ping = s.Server.Ping
|
cached_servers[mapping_item_name].Ping = s.Server.Ping
|
||||||
cached_servers[mapping_item_name].Map = s.Server.Map
|
cached_servers[mapping_item_name].Map = s.Server.Map
|
||||||
cached_servers[mapping_item_name].Gamemode = s.Server.Gamemode
|
cached_servers[mapping_item_name].Gamemode = s.Server.Gamemode
|
||||||
cached_servers[mapping_item_name].Version = s.Server.Version
|
cached_servers[mapping_item_name].Version = s.Server.Version
|
||||||
cached_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
|
cached_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
|
||||||
cached_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
|
cached_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
|
||||||
cached_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
|
cached_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
|
||||||
cached_servers[mapping_item_name].Favorite = s.Server.Favorite
|
cached_servers[mapping_item_name].Favorite = s.Server.Favorite
|
||||||
cached_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
|
cached_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
|
||||||
cached_servers[mapping_item_name].Password = s.Server.Password
|
cached_servers[mapping_item_name].Password = s.Server.Password
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := Database.Db.MustBegin()
|
tx := Database.Db.MustBegin()
|
||||||
fmt.Println("Adding new servers...")
|
fmt.Println("Adding new servers...")
|
||||||
if len(new_servers) > 0 {
|
if len(new_servers) > 0 {
|
||||||
for _, srv := range new_servers {
|
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, favorite, profile_to_use, bots) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private, :favorite, :profile_to_use, :bots)", srv)
|
tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version, extended_config, players_info, is_private, favorite, profile_to_use, bots) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private, :favorite, :profile_to_use, :bots)", srv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Updating cached servers...")
|
fmt.Println("Updating cached servers...")
|
||||||
for _, srv := range 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, favorite=:favorite, password=:password, players_info=:players_info, is_private=:is_private, profile_to_use=:profile_to_use, bots=:bots WHERE ip=:ip AND port=:port", &srv)
|
_, err := tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, ping=:ping, version=:version, extended_config=:extended_config, favorite=:favorite, password=:password, players_info=:players_info, is_private=:is_private, profile_to_use=:profile_to_use, bots=:bots WHERE ip=:ip AND port=:port", &srv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) LoadServers(data map[string]string) {
|
func (c *Cache) LoadServers(data map[string]string) {
|
||||||
fmt.Println("Loading servers into cache...")
|
fmt.Println("Loading servers into cache...")
|
||||||
c.Servers = make(map[string]*cachemodels.Server)
|
c.Servers = make(map[string]*cachemodels.Server)
|
||||||
// Getting servers from database.
|
// Getting servers from database.
|
||||||
raw_servers := []datamodels.Server{}
|
raw_servers := []datamodels.Server{}
|
||||||
err := Database.Db.Select(&raw_servers, "SELECT * FROM servers")
|
err := Database.Db.Select(&raw_servers, "SELECT * FROM servers")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to nature of pointers and goroutines thing (?) this should
|
// Due to nature of pointers and goroutines thing (?) this should
|
||||||
// be done in this way.
|
// be done in this way.
|
||||||
for _, server := range raw_servers {
|
for _, server := range raw_servers {
|
||||||
key := server.Ip + ":" + server.Port
|
key := server.Ip + ":" + server.Port
|
||||||
c.CreateServer(key)
|
c.CreateServer(key)
|
||||||
c.Servers[key].Server.Name = server.Name
|
c.Servers[key].Server.Name = server.Name
|
||||||
c.Servers[key].Server.Ip = server.Ip
|
c.Servers[key].Server.Ip = server.Ip
|
||||||
c.Servers[key].Server.Port = server.Port
|
c.Servers[key].Server.Port = server.Port
|
||||||
c.Servers[key].Server.Players = server.Players
|
c.Servers[key].Server.Players = server.Players
|
||||||
c.Servers[key].Server.Bots = server.Bots
|
c.Servers[key].Server.Bots = server.Bots
|
||||||
c.Servers[key].Server.Maxplayers = server.Maxplayers
|
c.Servers[key].Server.Maxplayers = server.Maxplayers
|
||||||
c.Servers[key].Server.Ping = server.Ping
|
c.Servers[key].Server.Ping = server.Ping
|
||||||
c.Servers[key].Server.Gamemode = server.Gamemode
|
c.Servers[key].Server.Gamemode = server.Gamemode
|
||||||
c.Servers[key].Server.Map = server.Map
|
c.Servers[key].Server.Map = server.Map
|
||||||
c.Servers[key].Server.Version = server.Version
|
c.Servers[key].Server.Version = server.Version
|
||||||
c.Servers[key].Server.Favorite = server.Favorite
|
c.Servers[key].Server.Favorite = server.Favorite
|
||||||
c.Servers[key].Server.Password = server.Password
|
c.Servers[key].Server.Password = server.Password
|
||||||
c.Servers[key].Server.ProfileToUse = server.ProfileToUse
|
c.Servers[key].Server.ProfileToUse = server.ProfileToUse
|
||||||
c.Servers[key].Server.ExtendedConfig = server.ExtendedConfig
|
c.Servers[key].Server.ExtendedConfig = server.ExtendedConfig
|
||||||
c.Servers[key].Server.PlayersInfo = server.PlayersInfo
|
c.Servers[key].Server.PlayersInfo = server.PlayersInfo
|
||||||
c.Servers[key].Server.IsPrivate = server.IsPrivate
|
c.Servers[key].Server.IsPrivate = server.IsPrivate
|
||||||
}
|
}
|
||||||
fmt.Println("Load completed.")
|
fmt.Println("Load completed.")
|
||||||
}
|
}
|
||||||
|
18
cache/exported.go
vendored
18
cache/exported.go
vendored
@ -10,19 +10,19 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
event "github.com/pztrn/urtrator/eventer"
|
"gitlab.com/pztrn/urtrator/database"
|
||||||
"github.com/pztrn/urtrator/database"
|
event "gitlab.com/pztrn/urtrator/eventer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Database *database.Database
|
Database *database.Database
|
||||||
Eventer *event.Eventer
|
Eventer *event.Eventer
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(d *database.Database, e *event.Eventer) *Cache {
|
func New(d *database.Database, e *event.Eventer) *Cache {
|
||||||
Database = d
|
Database = d
|
||||||
Eventer = e
|
Eventer = e
|
||||||
c := Cache{}
|
c := Cache{}
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
package cachemodels
|
package cachemodels
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Profile struct {
|
type Profile struct {
|
||||||
Profile *datamodels.Profile
|
Profile *datamodels.Profile
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,20 @@
|
|||||||
package cachemodels
|
package cachemodels
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Server *datamodels.Server
|
Server *datamodels.Server
|
||||||
AllServersIter *gtk.TreeIter
|
AllServersIter *gtk.TreeIter
|
||||||
AllServersIterSet bool
|
AllServersIterSet bool
|
||||||
AllServersIterInList bool
|
AllServersIterInList bool
|
||||||
|
|
||||||
FavServersIter *gtk.TreeIter
|
FavServersIter *gtk.TreeIter
|
||||||
FavServersIterSet bool
|
FavServersIterSet bool
|
||||||
FavServersIterInList bool
|
FavServersIterInList bool
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,20 @@
|
|||||||
// ToDo: put full text of license here.
|
// ToDo: put full text of license here.
|
||||||
package clipboardwatcher
|
package clipboardwatcher
|
||||||
|
|
||||||
import(
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cache"
|
"gitlab.com/pztrn/urtrator/cache"
|
||||||
"github.com/pztrn/urtrator/eventer"
|
"gitlab.com/pztrn/urtrator/eventer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
Eventer *eventer.Eventer
|
Eventer *eventer.Eventer
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(c *cache.Cache, e *eventer.Eventer) *ClipboardWatcher {
|
func New(c *cache.Cache, e *eventer.Eventer) *ClipboardWatcher {
|
||||||
Cache = c
|
Cache = c
|
||||||
Eventer = e
|
Eventer = e
|
||||||
cw := ClipboardWatcher{}
|
cw := ClipboardWatcher{}
|
||||||
return &cw
|
return &cw
|
||||||
}
|
}
|
||||||
|
@ -10,125 +10,125 @@
|
|||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cache"
|
"gitlab.com/pztrn/urtrator/cache"
|
||||||
"github.com/pztrn/urtrator/clipboardwatcher"
|
"gitlab.com/pztrn/urtrator/clipboardwatcher"
|
||||||
"github.com/pztrn/urtrator/colorizer"
|
"gitlab.com/pztrn/urtrator/colorizer"
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
"github.com/pztrn/urtrator/database"
|
"gitlab.com/pztrn/urtrator/database"
|
||||||
"github.com/pztrn/urtrator/eventer"
|
"gitlab.com/pztrn/urtrator/eventer"
|
||||||
"github.com/pztrn/urtrator/launcher"
|
"gitlab.com/pztrn/urtrator/launcher"
|
||||||
"github.com/pztrn/urtrator/requester"
|
"gitlab.com/pztrn/urtrator/requester"
|
||||||
"github.com/pztrn/urtrator/timer"
|
"gitlab.com/pztrn/urtrator/timer"
|
||||||
"github.com/pztrn/urtrator/translator"
|
"gitlab.com/pztrn/urtrator/translator"
|
||||||
|
|
||||||
// Github
|
// Github
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
// Caching.
|
// Caching.
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
// Clipboard watcher.
|
// Clipboard watcher.
|
||||||
Clipboard *clipboardwatcher.ClipboardWatcher
|
Clipboard *clipboardwatcher.ClipboardWatcher
|
||||||
// Colors parser and prettifier.
|
// Colors parser and prettifier.
|
||||||
Colorizer *colorizer.Colorizer
|
Colorizer *colorizer.Colorizer
|
||||||
// Configuration.
|
// Configuration.
|
||||||
Cfg *configuration.Config
|
Cfg *configuration.Config
|
||||||
// Database.
|
// Database.
|
||||||
Database *database.Database
|
Database *database.Database
|
||||||
// Eventer.
|
// Eventer.
|
||||||
Eventer *eventer.Eventer
|
Eventer *eventer.Eventer
|
||||||
// Game launcher.
|
// Game launcher.
|
||||||
Launcher *launcher.Launcher
|
Launcher *launcher.Launcher
|
||||||
// Requester, which requests server's information.
|
// Requester, which requests server's information.
|
||||||
Requester *requester.Requester
|
Requester *requester.Requester
|
||||||
// Timer.
|
// Timer.
|
||||||
Timer *timer.Timer
|
Timer *timer.Timer
|
||||||
// Translator.
|
// Translator.
|
||||||
Translator *translator.Translator
|
Translator *translator.Translator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) Close() error {
|
func (ctx *Context) Close() error {
|
||||||
fmt.Println("Closing URTrator...")
|
fmt.Println("Closing URTrator...")
|
||||||
|
|
||||||
launched := ctx.Launcher.CheckForLaunchedUrbanTerror()
|
launched := ctx.Launcher.CheckForLaunchedUrbanTerror()
|
||||||
if launched != nil {
|
if launched != nil {
|
||||||
return errors.New("Urban Terror is launched!")
|
return errors.New("Urban Terror is launched!")
|
||||||
}
|
}
|
||||||
ctx.Cache.FlushProfiles(map[string]string{})
|
ctx.Cache.FlushProfiles(map[string]string{})
|
||||||
ctx.Cache.FlushServers(map[string]string{})
|
ctx.Cache.FlushServers(map[string]string{})
|
||||||
ctx.Database.Close()
|
ctx.Database.Close()
|
||||||
|
|
||||||
// At last, close main window.
|
// At last, close main window.
|
||||||
gtk.MainQuit()
|
gtk.MainQuit()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeCache() {
|
func (ctx *Context) initializeCache() {
|
||||||
ctx.Cache = cache.New(ctx.Database, ctx.Eventer)
|
ctx.Cache = cache.New(ctx.Database, ctx.Eventer)
|
||||||
ctx.Cache.Initialize()
|
ctx.Cache.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) InitializeClipboardWatcher() {
|
func (ctx *Context) InitializeClipboardWatcher() {
|
||||||
ctx.Clipboard = clipboardwatcher.New(ctx.Cache, ctx.Eventer)
|
ctx.Clipboard = clipboardwatcher.New(ctx.Cache, ctx.Eventer)
|
||||||
ctx.Clipboard.Initialize()
|
ctx.Clipboard.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeColorizer() {
|
func (ctx *Context) initializeColorizer() {
|
||||||
ctx.Colorizer = colorizer.New()
|
ctx.Colorizer = colorizer.New()
|
||||||
ctx.Colorizer.Initialize()
|
ctx.Colorizer.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeConfig() {
|
func (ctx *Context) initializeConfig() {
|
||||||
ctx.Cfg = configuration.New()
|
ctx.Cfg = configuration.New()
|
||||||
ctx.Cfg.Initialize()
|
ctx.Cfg.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeDatabase() {
|
func (ctx *Context) initializeDatabase() {
|
||||||
ctx.Database = database.New(ctx.Cfg)
|
ctx.Database = database.New(ctx.Cfg)
|
||||||
ctx.Database.Initialize(ctx.Cfg)
|
ctx.Database.Initialize(ctx.Cfg)
|
||||||
ctx.Database.Migrate()
|
ctx.Database.Migrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeEventer() {
|
func (ctx *Context) initializeEventer() {
|
||||||
ctx.Eventer = eventer.New()
|
ctx.Eventer = eventer.New()
|
||||||
ctx.Eventer.Initialize()
|
ctx.Eventer.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeLauncher() {
|
func (ctx *Context) initializeLauncher() {
|
||||||
ctx.Launcher = launcher.New()
|
ctx.Launcher = launcher.New()
|
||||||
ctx.Launcher.Initialize()
|
ctx.Launcher.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeRequester() {
|
func (ctx *Context) initializeRequester() {
|
||||||
ctx.Requester = requester.New(ctx.Cache, ctx.Eventer, ctx.Cfg, ctx.Timer)
|
ctx.Requester = requester.New(ctx.Cache, ctx.Eventer, ctx.Cfg, ctx.Timer)
|
||||||
ctx.Requester.Initialize()
|
ctx.Requester.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeTimer() {
|
func (ctx *Context) initializeTimer() {
|
||||||
ctx.Timer = timer.New(ctx.Eventer, ctx.Cfg)
|
ctx.Timer = timer.New(ctx.Eventer, ctx.Cfg)
|
||||||
ctx.Timer.Initialize()
|
ctx.Timer.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initializeTranslator() {
|
func (ctx *Context) initializeTranslator() {
|
||||||
ctx.Translator = translator.New(ctx.Cfg)
|
ctx.Translator = translator.New(ctx.Cfg)
|
||||||
ctx.Translator.Initialize()
|
ctx.Translator.Initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) Initialize() {
|
func (ctx *Context) Initialize() {
|
||||||
fmt.Println("Initializing application context...")
|
fmt.Println("Initializing application context...")
|
||||||
ctx.initializeColorizer()
|
ctx.initializeColorizer()
|
||||||
ctx.initializeConfig()
|
ctx.initializeConfig()
|
||||||
ctx.initializeDatabase()
|
ctx.initializeDatabase()
|
||||||
ctx.initializeTranslator()
|
ctx.initializeTranslator()
|
||||||
ctx.initializeEventer()
|
ctx.initializeEventer()
|
||||||
ctx.initializeCache()
|
ctx.initializeCache()
|
||||||
ctx.initializeLauncher()
|
ctx.initializeLauncher()
|
||||||
ctx.initializeTimer()
|
ctx.initializeTimer()
|
||||||
ctx.initializeRequester()
|
ctx.initializeRequester()
|
||||||
}
|
}
|
||||||
|
@ -10,85 +10,84 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
//"database/sql"
|
//"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
// Configuration.
|
// Configuration.
|
||||||
cfg *configuration.Config
|
cfg *configuration.Config
|
||||||
// Pointer to initialized database connection.
|
// Pointer to initialized database connection.
|
||||||
Db *sqlx.DB
|
Db *sqlx.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) Close() {
|
func (d *Database) Close() {
|
||||||
fmt.Println("Closing database...")
|
fmt.Println("Closing database...")
|
||||||
|
|
||||||
// Save configuration.
|
// Save configuration.
|
||||||
// Delete previous configuration.
|
// Delete previous configuration.
|
||||||
d.Db.MustExec("DELETE FROM configuration")
|
d.Db.MustExec("DELETE FROM configuration")
|
||||||
tx := d.Db.MustBegin()
|
tx := d.Db.MustBegin()
|
||||||
for k, v := range cfg.Cfg {
|
for k, v := range cfg.Cfg {
|
||||||
cfg_item := datamodels.Configuration{}
|
cfg_item := datamodels.Configuration{}
|
||||||
cfg_item.Key = k
|
cfg_item.Key = k
|
||||||
cfg_item.Value = v
|
cfg_item.Value = v
|
||||||
tx.NamedExec("INSERT INTO configuration (key, value) VALUES (:key, :value)", &cfg_item)
|
tx.NamedExec("INSERT INTO configuration (key, value) VALUES (:key, :value)", &cfg_item)
|
||||||
}
|
}
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
|
||||||
d.Db.Close()
|
d.Db.Close()
|
||||||
|
|
||||||
runtime.UnlockOSThread()
|
runtime.UnlockOSThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) Initialize(cfg *configuration.Config) {
|
func (d *Database) Initialize(cfg *configuration.Config) {
|
||||||
fmt.Println("Initializing database...")
|
fmt.Println("Initializing database...")
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
// Connect to database.
|
// Connect to database.
|
||||||
db_path := path.Join(cfg.TEMP["DATA"], "database.sqlite3")
|
db_path := path.Join(cfg.TEMP["DATA"], "database.sqlite3")
|
||||||
fmt.Println("Database path: " + db_path)
|
fmt.Println("Database path: " + db_path)
|
||||||
db, err := sqlx.Connect("sqlite3", db_path)
|
db, err := sqlx.Connect("sqlite3", db_path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
d.Db = db
|
d.Db = db
|
||||||
|
|
||||||
// Load configuration.
|
// Load configuration.
|
||||||
cfgs := []datamodels.Configuration{}
|
cfgs := []datamodels.Configuration{}
|
||||||
d.Db.Select(&cfgs, "SELECT * FROM configuration")
|
d.Db.Select(&cfgs, "SELECT * FROM configuration")
|
||||||
if len(cfgs) > 0 {
|
if len(cfgs) > 0 {
|
||||||
for i := range cfgs {
|
for i := range cfgs {
|
||||||
cfg.Cfg[cfgs[i].Key] = cfgs[i].Value
|
cfg.Cfg[cfgs[i].Key] = cfgs[i].Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) Migrate() {
|
func (d *Database) Migrate() {
|
||||||
// Getting current database version.
|
// Getting current database version.
|
||||||
dbver := 0
|
dbver := 0
|
||||||
database := []datamodels.Database{}
|
database := []datamodels.Database{}
|
||||||
d.Db.Select(&database, "SELECT * FROM database")
|
d.Db.Select(&database, "SELECT * FROM database")
|
||||||
if len(database) > 0 {
|
if len(database) > 0 {
|
||||||
fmt.Println("Current database version: " + database[0].Version)
|
fmt.Println("Current database version: " + database[0].Version)
|
||||||
dbver, _ = strconv.Atoi(database[0].Version)
|
dbver, _ = strconv.Atoi(database[0].Version)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("No database found, will create new one")
|
fmt.Println("No database found, will create new one")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
migrate_full(d, dbver)
|
||||||
migrate_full(d, dbver)
|
|
||||||
}
|
}
|
||||||
|
@ -10,16 +10,16 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfg *configuration.Config
|
cfg *configuration.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(c *configuration.Config) *Database {
|
func New(c *configuration.Config) *Database {
|
||||||
cfg = c
|
cfg = c
|
||||||
d := Database{}
|
d := Database{}
|
||||||
return &d
|
return &d
|
||||||
}
|
}
|
||||||
|
@ -51,14 +51,14 @@ fi
|
|||||||
|
|
||||||
# Okay, let's compile.
|
# Okay, let's compile.
|
||||||
echo "Getting URTrator (and dependencies) sources"
|
echo "Getting URTrator (and dependencies) sources"
|
||||||
go get -u -v -d github.com/pztrn/urtrator
|
go get -u -v -d gitlab.com/pztrn/urtrator
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Failed to get URTrator sources"
|
echo "Failed to get URTrator sources"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Building URTrator..."
|
echo "Building URTrator..."
|
||||||
go install -v github.com/pztrn/urtrator
|
go install -v gitlab.com/pztrn/urtrator
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Failed to build URTrator! Please, create a new bug report at https://github.com/pztrn/urtrator and attach FULL console output!"
|
echo "Failed to build URTrator! Please, create a new bug report at https://github.com/pztrn/urtrator and attach FULL console output!"
|
||||||
exit 1
|
exit 1
|
||||||
@ -69,7 +69,7 @@ mkdir -p URTrator.app/Contents/{MacOS,Framework,Resources}
|
|||||||
# Copying URTrator binary
|
# Copying URTrator binary
|
||||||
cp $GOPATH/bin/urtrator URTrator.app/Contents/MacOS/
|
cp $GOPATH/bin/urtrator URTrator.app/Contents/MacOS/
|
||||||
# Copying main resources.
|
# Copying main resources.
|
||||||
cp $GOPATH/src/github.com/pztrn/urtrator/artwork/urtrator.icns ./URTrator.app/Contents/Resources/
|
cp $GOPATH/src/gitlab.com/pztrn/urtrator/artwork/urtrator.icns ./URTrator.app/Contents/Resources/
|
||||||
cp -R ./Resources/themes ./URTrator.app/Contents/Resources/
|
cp -R ./Resources/themes ./URTrator.app/Contents/Resources/
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
@ -90,7 +90,7 @@ INFOPLIST='<?xml version="1.0" encoding="UTF-8"?>
|
|||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>urtrator.icns</string>
|
<string>urtrator.icns</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.1.0</string>
|
<string>0.2.0</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
|
@ -10,128 +10,128 @@
|
|||||||
package launcher
|
package launcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Github
|
// Github
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Launcher struct {
|
type Launcher struct {
|
||||||
// Flags.
|
// Flags.
|
||||||
// Is Urban Terror launched ATM?
|
// Is Urban Terror launched ATM?
|
||||||
launched bool
|
launched bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Launcher) CheckForLaunchedUrbanTerror() error {
|
func (l *Launcher) CheckForLaunchedUrbanTerror() error {
|
||||||
if l.launched {
|
if l.launched {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := "Game is launched.\n\nCannot quit, because game is launched.\nQuit Urban Terror to exit URTrator!"
|
mbox_string := "Game is launched.\n\nCannot quit, because game is launched.\nQuit Urban Terror to exit URTrator!"
|
||||||
m := gtk.NewMessageDialog(nil, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(nil, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
return errors.New("User didn't select valid profile, mismatch with server's version.")
|
return errors.New("User didn't select valid profile, mismatch with server's version.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Launcher) findFreeDisplay() string {
|
func (l *Launcher) findFreeDisplay() string {
|
||||||
current_display_raw := os.Getenv("DISPLAY")
|
current_display_raw := os.Getenv("DISPLAY")
|
||||||
current_display, _ := strconv.Atoi(strings.Split(current_display_raw, ":")[1])
|
current_display, _ := strconv.Atoi(strings.Split(current_display_raw, ":")[1])
|
||||||
current_display += 1
|
current_display += 1
|
||||||
return strconv.Itoa(current_display)
|
return strconv.Itoa(current_display)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Launcher) Initialize() {
|
func (l *Launcher) Initialize() {
|
||||||
fmt.Println("Initializing game launcher...")
|
fmt.Println("Initializing game launcher...")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Launcher) Launch(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, additional_parameters []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
|
// ToDo: only one instance of Urban Terror should be launched, so button
|
||||||
// should be disabled.
|
// should be disabled.
|
||||||
fmt.Println("Launching Urban Terror...")
|
fmt.Println("Launching Urban Terror...")
|
||||||
|
|
||||||
done := make(chan bool, 1)
|
done := make(chan bool, 1)
|
||||||
|
|
||||||
// Create launch string.
|
// Create launch string.
|
||||||
var launch_bin string = ""
|
var launch_bin string = ""
|
||||||
launch_bin, err := exec.LookPath(user_profile.Binary)
|
launch_bin, err := exec.LookPath(user_profile.Binary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
server_address := server_profile.Ip + ":" + server_profile.Port
|
server_address := server_profile.Ip + ":" + server_profile.Port
|
||||||
|
|
||||||
var launch_params []string
|
var launch_params []string
|
||||||
if len(server_address) > 0 {
|
if len(server_address) > 0 {
|
||||||
launch_params = append(launch_params, "+connect", server_address)
|
launch_params = append(launch_params, "+connect", server_address)
|
||||||
}
|
}
|
||||||
if len(password) > 0 {
|
if len(password) > 0 {
|
||||||
launch_params = append(launch_params, "+password", password)
|
launch_params = append(launch_params, "+password", password)
|
||||||
}
|
}
|
||||||
if len(user_profile.Additional_params) > 0 {
|
if len(user_profile.Additional_params) > 0 {
|
||||||
additional_params := strings.Split(user_profile.Additional_params, " ")
|
additional_params := strings.Split(user_profile.Additional_params, " ")
|
||||||
launch_params = append(launch_params, additional_params...)
|
launch_params = append(launch_params, additional_params...)
|
||||||
}
|
}
|
||||||
if len(additional_parameters) > 0 {
|
if len(additional_parameters) > 0 {
|
||||||
for i := range additional_parameters {
|
for i := range additional_parameters {
|
||||||
launch_params = append(launch_params, additional_parameters[i])
|
launch_params = append(launch_params, additional_parameters[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "linux" && user_profile.Second_x_session == "1" {
|
if runtime.GOOS == "linux" && user_profile.Second_x_session == "1" {
|
||||||
launch_params = append([]string{launch_bin}, launch_params...)
|
launch_params = append([]string{launch_bin}, launch_params...)
|
||||||
display := l.findFreeDisplay()
|
display := l.findFreeDisplay()
|
||||||
launch_bin, err = exec.LookPath("xinit")
|
launch_bin, err = exec.LookPath("xinit")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
launch_params = append(launch_params, "--", ":" + display)
|
launch_params = append(launch_params, "--", ":"+display)
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
// On macOS we should not start binary, but application bundle.
|
// On macOS we should not start binary, but application bundle.
|
||||||
// So we will obtain app bundle path.
|
// So we will obtain app bundle path.
|
||||||
bundle_path := strings.Split(launch_bin, "/Contents")[0]
|
bundle_path := strings.Split(launch_bin, "/Contents")[0]
|
||||||
// and create special launch string, which involves open.
|
// and create special launch string, which involves open.
|
||||||
launch_bin = "/usr/bin/open"
|
launch_bin = "/usr/bin/open"
|
||||||
launch_params = append([]string{launch_bin, "-W", "-a", bundle_path, "--args"}, launch_params...)
|
launch_params = append([]string{launch_bin, "-W", "-a", bundle_path, "--args"}, launch_params...)
|
||||||
}
|
}
|
||||||
fmt.Println(launch_bin, launch_params)
|
fmt.Println(launch_bin, launch_params)
|
||||||
go func() {
|
go func() {
|
||||||
go func() {
|
go func() {
|
||||||
cmd := exec.Command(launch_bin, launch_params...)
|
cmd := exec.Command(launch_bin, launch_params...)
|
||||||
// This workaround is required on Windows, otherwise ioq3
|
// This workaround is required on Windows, otherwise ioq3
|
||||||
// will not find game data.
|
// will not find game data.
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
dir := filepath.Dir(launch_bin)
|
dir := filepath.Dir(launch_bin)
|
||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
}
|
}
|
||||||
out, err1 := cmd.Output()
|
out, err1 := cmd.Output()
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
fmt.Println("Launch error: " + err1.Error())
|
fmt.Println("Launch error: " + err1.Error())
|
||||||
}
|
}
|
||||||
fmt.Println(string(out))
|
fmt.Println(string(out))
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <- done:
|
case <-done:
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -10,29 +10,29 @@
|
|||||||
package requester
|
package requester
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/cache"
|
"gitlab.com/pztrn/urtrator/cache"
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
"github.com/pztrn/urtrator/eventer"
|
"gitlab.com/pztrn/urtrator/eventer"
|
||||||
"github.com/pztrn/urtrator/timer"
|
"gitlab.com/pztrn/urtrator/timer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
Cfg *configuration.Config
|
Cfg *configuration.Config
|
||||||
Eventer *eventer.Eventer
|
Eventer *eventer.Eventer
|
||||||
Timer *timer.Timer
|
Timer *timer.Timer
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(c *cache.Cache, e *eventer.Eventer, cc *configuration.Config, t *timer.Timer) *Requester {
|
func New(c *cache.Cache, e *eventer.Eventer, cc *configuration.Config, t *timer.Timer) *Requester {
|
||||||
Cache = c
|
Cache = c
|
||||||
Cfg = cc
|
Cfg = cc
|
||||||
Eventer = e
|
Eventer = e
|
||||||
Timer = t
|
Timer = t
|
||||||
fmt.Println("Creating Requester object...")
|
fmt.Println("Creating Requester object...")
|
||||||
r := Requester{}
|
r := Requester{}
|
||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
@ -10,281 +10,281 @@
|
|||||||
package requester
|
package requester
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pooler struct {
|
type Pooler struct {
|
||||||
// Maximum number of simultaneous requests running.
|
// Maximum number of simultaneous requests running.
|
||||||
maxrequests int
|
maxrequests int
|
||||||
// Packet prefix.
|
// Packet prefix.
|
||||||
pp string
|
pp string
|
||||||
// Current requests counter mutex.
|
// Current requests counter mutex.
|
||||||
cur_requests_mutex sync.Mutex
|
cur_requests_mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pooler) Initialize() {
|
func (p *Pooler) Initialize() {
|
||||||
fmt.Println("Initializing requester goroutine pooler...")
|
fmt.Println("Initializing requester goroutine pooler...")
|
||||||
// ToDo: figure out how to make this work nice.
|
// ToDo: figure out how to make this work nice.
|
||||||
p.maxrequests = 150
|
p.maxrequests = 150
|
||||||
_ = runtime.GOMAXPROCS(runtime.NumCPU() * 4)
|
_ = runtime.GOMAXPROCS(runtime.NumCPU() * 4)
|
||||||
p.pp = "\377\377\377\377"
|
p.pp = "\377\377\377\377"
|
||||||
fmt.Println("Pooler initialized")
|
fmt.Println("Pooler initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pooler) PingOneServer(server_address string) {
|
func (p *Pooler) PingOneServer(server_address string) {
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
|
|
||||||
Cache.ServersMutex.Lock()
|
Cache.ServersMutex.Lock()
|
||||||
server := Cache.Servers[server_address].Server
|
server := Cache.Servers[server_address].Server
|
||||||
Cache.ServersMutex.Unlock()
|
Cache.ServersMutex.Unlock()
|
||||||
|
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
go func(srv *datamodels.Server) {
|
go func(srv *datamodels.Server) {
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
p.pingServersExecutor(srv)
|
p.pingServersExecutor(srv)
|
||||||
}(server)
|
}(server)
|
||||||
wait.Wait()
|
wait.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Servers pinging pooler. Should be started as goroutine to prevent
|
// Servers pinging pooler. Should be started as goroutine to prevent
|
||||||
// UI blocking.
|
// UI blocking.
|
||||||
func (p *Pooler) PingServers(servers_type string) {
|
func (p *Pooler) PingServers(servers_type string) {
|
||||||
fmt.Println("About to ping " + servers_type + " servers...")
|
fmt.Println("About to ping " + servers_type + " servers...")
|
||||||
|
|
||||||
cur_requests := 0
|
cur_requests := 0
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
|
|
||||||
Cache.ServersMutex.Lock()
|
Cache.ServersMutex.Lock()
|
||||||
for _, server_to_ping := range Cache.Servers {
|
for _, server_to_ping := range Cache.Servers {
|
||||||
if servers_type == "favorites" && server_to_ping.Server.Favorite != "1" {
|
if servers_type == "favorites" && server_to_ping.Server.Favorite != "1" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
p.cur_requests_mutex.Lock()
|
p.cur_requests_mutex.Lock()
|
||||||
if cur_requests == p.maxrequests {
|
if cur_requests == p.maxrequests {
|
||||||
p.cur_requests_mutex.Unlock()
|
p.cur_requests_mutex.Unlock()
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
} else {
|
} else {
|
||||||
p.cur_requests_mutex.Unlock()
|
p.cur_requests_mutex.Unlock()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
p.cur_requests_mutex.Lock()
|
p.cur_requests_mutex.Lock()
|
||||||
cur_requests += 1
|
cur_requests += 1
|
||||||
p.cur_requests_mutex.Unlock()
|
p.cur_requests_mutex.Unlock()
|
||||||
go func(srv *datamodels.Server) {
|
go func(srv *datamodels.Server) {
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
p.pingServersExecutor(srv)
|
p.pingServersExecutor(srv)
|
||||||
p.cur_requests_mutex.Lock()
|
p.cur_requests_mutex.Lock()
|
||||||
cur_requests -= 1
|
cur_requests -= 1
|
||||||
p.cur_requests_mutex.Unlock()
|
p.cur_requests_mutex.Unlock()
|
||||||
}(server_to_ping.Server)
|
}(server_to_ping.Server)
|
||||||
}
|
}
|
||||||
wait.Wait()
|
wait.Wait()
|
||||||
Cache.ServersMutex.Unlock()
|
Cache.ServersMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pooler) pingServersExecutor(server *datamodels.Server) error {
|
func (p *Pooler) pingServersExecutor(server *datamodels.Server) error {
|
||||||
srv := server.Ip + ":" + server.Port
|
srv := server.Ip + ":" + server.Port
|
||||||
fmt.Println("Pinging " + srv)
|
fmt.Println("Pinging " + srv)
|
||||||
// Dial to server.
|
// Dial to server.
|
||||||
start_p := time.Now()
|
start_p := time.Now()
|
||||||
conn_ping, err2 := net.Dial("udp", srv)
|
conn_ping, err2 := net.Dial("udp", srv)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
fmt.Println("Error dialing to server " + srv + "!")
|
fmt.Println("Error dialing to server " + srv + "!")
|
||||||
return errors.New("Error dialing to server " + srv + "!")
|
return errors.New("Error dialing to server " + srv + "!")
|
||||||
}
|
}
|
||||||
// Set deadline, so we won't wait forever.
|
// Set deadline, so we won't wait forever.
|
||||||
ddl_ping := time.Now()
|
ddl_ping := time.Now()
|
||||||
// This should be enough. Maybe, you should'n run URTrator on modem
|
// This should be enough. Maybe, you should'n run URTrator on modem
|
||||||
// connections? :)
|
// connections? :)
|
||||||
ddl_ping = ddl_ping.Add(time.Second * 10)
|
ddl_ping = ddl_ping.Add(time.Second * 10)
|
||||||
conn_ping.SetDeadline(ddl_ping)
|
conn_ping.SetDeadline(ddl_ping)
|
||||||
|
|
||||||
msg_ping := []byte(p.pp + "getinfo")
|
msg_ping := []byte(p.pp + "getinfo")
|
||||||
conn_ping.Write(msg_ping)
|
conn_ping.Write(msg_ping)
|
||||||
|
|
||||||
// UDP Buffer.
|
// UDP Buffer.
|
||||||
var received_buf_ping []byte = make([]byte, 128)
|
var received_buf_ping []byte = make([]byte, 128)
|
||||||
// Received buffer.
|
// Received buffer.
|
||||||
var raw_received_ping []byte
|
var raw_received_ping []byte
|
||||||
_, err := conn_ping.Read(received_buf_ping)
|
_, err := conn_ping.Read(received_buf_ping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("PING ERROR")
|
fmt.Println("PING ERROR")
|
||||||
}
|
}
|
||||||
raw_received_ping = append(raw_received_ping, received_buf_ping...)
|
raw_received_ping = append(raw_received_ping, received_buf_ping...)
|
||||||
conn_ping.Close()
|
conn_ping.Close()
|
||||||
|
|
||||||
delta := strconv.Itoa(int(time.Since(start_p).Nanoseconds()) / 1000000)
|
delta := strconv.Itoa(int(time.Since(start_p).Nanoseconds()) / 1000000)
|
||||||
server.Ping = delta
|
server.Ping = delta
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pooler) UpdateOneServer(server_address string) {
|
func (p *Pooler) UpdateOneServer(server_address string) {
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
|
|
||||||
Cache.ServersMutex.Lock()
|
Cache.ServersMutex.Lock()
|
||||||
server := Cache.Servers[server_address].Server
|
server := Cache.Servers[server_address].Server
|
||||||
Cache.ServersMutex.Unlock()
|
Cache.ServersMutex.Unlock()
|
||||||
|
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
go func(server *datamodels.Server) {
|
go func(server *datamodels.Server) {
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
p.UpdateSpecificServer(server)
|
p.UpdateSpecificServer(server)
|
||||||
}(server)
|
}(server)
|
||||||
wait.Wait()
|
wait.Wait()
|
||||||
p.PingOneServer(server_address)
|
p.PingOneServer(server_address)
|
||||||
Eventer.LaunchEvent("flushServers", map[string]string{})
|
Eventer.LaunchEvent("flushServers", map[string]string{})
|
||||||
|
|
||||||
Eventer.LaunchEvent("loadAllServers", map[string]string{})
|
Eventer.LaunchEvent("loadAllServers", map[string]string{})
|
||||||
Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
||||||
Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{})
|
Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pooler) UpdateServers(servers_type string) {
|
func (p *Pooler) UpdateServers(servers_type string) {
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
|
|
||||||
Cache.ServersMutex.Lock()
|
Cache.ServersMutex.Lock()
|
||||||
for _, server := range Cache.Servers {
|
for _, server := range Cache.Servers {
|
||||||
if servers_type == "favorites" && server.Server.Favorite != "1" {
|
if servers_type == "favorites" && server.Server.Favorite != "1" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
go func(server *datamodels.Server) {
|
go func(server *datamodels.Server) {
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
p.UpdateSpecificServer(server)
|
p.UpdateSpecificServer(server)
|
||||||
}(server.Server)
|
}(server.Server)
|
||||||
}
|
}
|
||||||
wait.Wait()
|
wait.Wait()
|
||||||
Cache.ServersMutex.Unlock()
|
Cache.ServersMutex.Unlock()
|
||||||
p.PingServers(servers_type)
|
p.PingServers(servers_type)
|
||||||
Eventer.LaunchEvent("flushServers", map[string]string{})
|
Eventer.LaunchEvent("flushServers", map[string]string{})
|
||||||
|
|
||||||
Eventer.LaunchEvent("loadAllServers", map[string]string{})
|
Eventer.LaunchEvent("loadAllServers", map[string]string{})
|
||||||
Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
||||||
Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{})
|
Eventer.LaunchEvent("serversUpdateCompleted", map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates information about specific server.
|
// Updates information about specific server.
|
||||||
func (p *Pooler) UpdateSpecificServer(server *datamodels.Server) error {
|
func (p *Pooler) UpdateSpecificServer(server *datamodels.Server) error {
|
||||||
server_addr := server.Ip + ":" + server.Port
|
server_addr := server.Ip + ":" + server.Port
|
||||||
fmt.Println("Updating server: " + server_addr)
|
fmt.Println("Updating server: " + server_addr)
|
||||||
|
|
||||||
// Dial to server.
|
// Dial to server.
|
||||||
conn, err1 := net.Dial("udp", server_addr)
|
conn, err1 := net.Dial("udp", server_addr)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
fmt.Println("Error dialing to server " + server_addr + "!")
|
fmt.Println("Error dialing to server " + server_addr + "!")
|
||||||
return errors.New("Error dialing to server " + server_addr + "!")
|
return errors.New("Error dialing to server " + server_addr + "!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set deadline, so we won't wait forever.
|
// Set deadline, so we won't wait forever.
|
||||||
ddl := time.Now()
|
ddl := time.Now()
|
||||||
// This should be enough. Maybe, you should'n run URTrator on modem
|
// This should be enough. Maybe, you should'n run URTrator on modem
|
||||||
// connections? :)
|
// connections? :)
|
||||||
ddl = ddl.Add(time.Second * 2)
|
ddl = ddl.Add(time.Second * 2)
|
||||||
conn.SetDeadline(ddl)
|
conn.SetDeadline(ddl)
|
||||||
|
|
||||||
msg := []byte(p.pp + "getstatus")
|
msg := []byte(p.pp + "getstatus")
|
||||||
conn.Write(msg)
|
conn.Write(msg)
|
||||||
|
|
||||||
// UDP Buffer.
|
// UDP Buffer.
|
||||||
var received_buf []byte = make([]byte, 4096)
|
var received_buf []byte = make([]byte, 4096)
|
||||||
// Received buffer.
|
// Received buffer.
|
||||||
var raw_received []byte
|
var raw_received []byte
|
||||||
for {
|
for {
|
||||||
_, err := conn.Read(received_buf)
|
_, err := conn.Read(received_buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
raw_received = append(raw_received, received_buf...)
|
raw_received = append(raw_received, received_buf...)
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
|
|
||||||
// First line is "infoResponse" string, which we should skip by
|
// First line is "infoResponse" string, which we should skip by
|
||||||
// splitting response by "\n".
|
// splitting response by "\n".
|
||||||
received_lines := strings.Split(string(raw_received), "\n")
|
received_lines := strings.Split(string(raw_received), "\n")
|
||||||
// We have server's data!
|
// We have server's data!
|
||||||
if len(received_lines) > 1 {
|
if len(received_lines) > 1 {
|
||||||
srv_config := strings.Split(received_lines[1], "\\")
|
srv_config := strings.Split(received_lines[1], "\\")
|
||||||
// Parse server configuration into passed server's datamodel.
|
// Parse server configuration into passed server's datamodel.
|
||||||
for i := 0; i < len(srv_config); i = i + 1 {
|
for i := 0; i < len(srv_config); i = i + 1 {
|
||||||
if srv_config[i] == "g_modversion" {
|
if srv_config[i] == "g_modversion" {
|
||||||
server.Version = srv_config[i + 1]
|
server.Version = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "g_gametype" {
|
if srv_config[i] == "g_gametype" {
|
||||||
server.Gamemode = srv_config[i + 1]
|
server.Gamemode = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "sv_maxclients" {
|
if srv_config[i] == "sv_maxclients" {
|
||||||
server.Maxplayers = srv_config[i + 1]
|
server.Maxplayers = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "clients" {
|
if srv_config[i] == "clients" {
|
||||||
server.Players = srv_config[i + 1]
|
server.Players = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "mapname" {
|
if srv_config[i] == "mapname" {
|
||||||
server.Map = srv_config[i + 1]
|
server.Map = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "sv_hostname" {
|
if srv_config[i] == "sv_hostname" {
|
||||||
server.Name = srv_config[i + 1]
|
server.Name = srv_config[i+1]
|
||||||
}
|
}
|
||||||
if srv_config[i] == "g_needpass" {
|
if srv_config[i] == "g_needpass" {
|
||||||
if srv_config[i + 1] == "0" {
|
if srv_config[i+1] == "0" {
|
||||||
server.IsPrivate = "0"
|
server.IsPrivate = "0"
|
||||||
} else {
|
} else {
|
||||||
server.IsPrivate = "1"
|
server.IsPrivate = "1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.ExtendedConfig = received_lines[1]
|
server.ExtendedConfig = received_lines[1]
|
||||||
}
|
}
|
||||||
if len(received_lines) >= 2 {
|
if len(received_lines) >= 2 {
|
||||||
// Here we go, players information.
|
// Here we go, players information.
|
||||||
players := received_lines[2:]
|
players := received_lines[2:]
|
||||||
var real_players int = 0
|
var real_players int = 0
|
||||||
var bots int = 0
|
var bots int = 0
|
||||||
// Calculate players!
|
// Calculate players!
|
||||||
if len(players) == 1 && len(players[0]) > 255 {
|
if len(players) == 1 && len(players[0]) > 255 {
|
||||||
server.Players = "0"
|
server.Players = "0"
|
||||||
server.Bots = "0"
|
server.Bots = "0"
|
||||||
} else {
|
} else {
|
||||||
// Looks like we have last element to be empty, due to
|
// Looks like we have last element to be empty, due to
|
||||||
// strings.Split() call before.
|
// strings.Split() call before.
|
||||||
for i := range players {
|
for i := range players {
|
||||||
// Get slice with data for bots-humans parsing.
|
// Get slice with data for bots-humans parsing.
|
||||||
player_data := strings.Split(string(players[i]), " ")
|
player_data := strings.Split(string(players[i]), " ")
|
||||||
// If slice length isn't equal 3 - this is not what
|
// If slice length isn't equal 3 - this is not what
|
||||||
// we want.
|
// we want.
|
||||||
if len(player_data) != 3 {
|
if len(player_data) != 3 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if player_data[1] == "0" {
|
if player_data[1] == "0" {
|
||||||
bots++
|
bots++
|
||||||
} else {
|
} else {
|
||||||
real_players++
|
real_players++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//server.Players = strconv.Itoa(len(players) - 1)
|
//server.Players = strconv.Itoa(len(players) - 1)
|
||||||
server.Players = strconv.Itoa(real_players)
|
server.Players = strconv.Itoa(real_players)
|
||||||
server.Bots = strconv.Itoa(bots)
|
server.Bots = strconv.Itoa(bots)
|
||||||
fmt.Println(server.Players, server.Bots)
|
fmt.Println(server.Players, server.Bots)
|
||||||
}
|
}
|
||||||
server.PlayersInfo = strings.Join(received_lines[2:], "\\")
|
server.PlayersInfo = strings.Join(received_lines[2:], "\\")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: Calculate ping. 0 for now.
|
// ToDo: Calculate ping. 0 for now.
|
||||||
server.Ping = "0"
|
server.Ping = "0"
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -10,23 +10,23 @@
|
|||||||
package timer
|
package timer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
"github.com/pztrn/urtrator/eventer"
|
"gitlab.com/pztrn/urtrator/eventer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Cfg *configuration.Config
|
Cfg *configuration.Config
|
||||||
Eventer *eventer.Eventer
|
Eventer *eventer.Eventer
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(e *eventer.Eventer, cc *configuration.Config) *Timer {
|
func New(e *eventer.Eventer, cc *configuration.Config) *Timer {
|
||||||
Cfg = cc
|
Cfg = cc
|
||||||
Eventer = e
|
Eventer = e
|
||||||
fmt.Println("Creating Timer object...")
|
fmt.Println("Creating Timer object...")
|
||||||
t := Timer{}
|
t := Timer{}
|
||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@
|
|||||||
package translator
|
package translator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/configuration"
|
"gitlab.com/pztrn/urtrator/configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Configuration.
|
// Configuration.
|
||||||
cfg *configuration.Config
|
cfg *configuration.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(c *configuration.Config) *Translator {
|
func New(c *configuration.Config) *Translator {
|
||||||
cfg = c
|
cfg = c
|
||||||
t := Translator{}
|
t := Translator{}
|
||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
@ -10,40 +10,40 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/common"
|
"gitlab.com/pztrn/urtrator/common"
|
||||||
|
|
||||||
// other
|
// other
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ShowAboutDialog() {
|
func ShowAboutDialog() {
|
||||||
ad := gtk.NewAboutDialog()
|
ad := gtk.NewAboutDialog()
|
||||||
|
|
||||||
ad.SetProgramName("URTrator")
|
ad.SetProgramName("URTrator")
|
||||||
ad.SetComments(ctx.Translator.Translate("Urban Terror servers browser and game launcher", nil))
|
ad.SetComments(ctx.Translator.Translate("Urban Terror servers browser and game launcher", nil))
|
||||||
ad.SetVersion(common.URTRATOR_VERSION)
|
ad.SetVersion(common.URTRATOR_VERSION)
|
||||||
ad.SetWebsite("http://urtrator.pztrn.name")
|
ad.SetWebsite("https://gitlab.com/pztrn/urtrator")
|
||||||
ad.SetLogo(logo)
|
ad.SetLogo(logo)
|
||||||
|
|
||||||
// ToDo: put it in plain text files.
|
// ToDo: put it in plain text files.
|
||||||
var authors []string
|
var authors []string
|
||||||
authors = append(authors, "Stanislav N. aka pztrn - project creator, main developer.")
|
authors = append(authors, "Stanislav N. aka pztrn - project creator, main developer.")
|
||||||
ad.SetAuthors(authors)
|
ad.SetAuthors(authors)
|
||||||
|
|
||||||
var artists []string
|
var artists []string
|
||||||
artists = append(artists, "UrTConnector team, for great icons and allowing to use them.")
|
artists = append(artists, "UrTConnector team, for great icons and allowing to use them.")
|
||||||
ad.SetArtists(artists)
|
ad.SetArtists(artists)
|
||||||
|
|
||||||
var documenters []string
|
var documenters []string
|
||||||
documenters = append(documenters, "No one at this moment")
|
documenters = append(documenters, "No one at this moment")
|
||||||
ad.SetDocumenters(documenters)
|
ad.SetDocumenters(documenters)
|
||||||
|
|
||||||
ad.SetCopyright("Stanislav N. aka pztrn")
|
ad.SetCopyright("Stanislav N. aka pztrn")
|
||||||
ad.SetLicense(GPL_LICENSE)
|
ad.SetLicense(GPL_LICENSE)
|
||||||
|
|
||||||
ad.Run()
|
ad.Run()
|
||||||
ad.Destroy()
|
ad.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
var GPL_LICENSE = `
|
var GPL_LICENSE = `
|
||||||
|
@ -10,21 +10,21 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/context"
|
"gitlab.com/pztrn/urtrator/context"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ctx *context.Context
|
ctx *context.Context
|
||||||
|
|
||||||
logo *gdkpixbuf.Pixbuf
|
logo *gdkpixbuf.Pixbuf
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewMainWindow(c *context.Context) *MainWindow {
|
func NewMainWindow(c *context.Context) *MainWindow {
|
||||||
ctx = c
|
ctx = c
|
||||||
m := MainWindow{}
|
m := MainWindow{}
|
||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
|
@ -10,283 +10,283 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/cachemodels"
|
"gitlab.com/pztrn/urtrator/cachemodels"
|
||||||
"github.com/pztrn/urtrator/common"
|
"gitlab.com/pztrn/urtrator/common"
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FavoriteDialog struct {
|
type FavoriteDialog struct {
|
||||||
// Widgets.
|
// Widgets.
|
||||||
// Dialog's window.
|
// Dialog's window.
|
||||||
window *gtk.Window
|
window *gtk.Window
|
||||||
// Main vertical box.
|
// Main vertical box.
|
||||||
vbox *gtk.VBox
|
vbox *gtk.VBox
|
||||||
// Server name.
|
// Server name.
|
||||||
server_name *gtk.Entry
|
server_name *gtk.Entry
|
||||||
// Server address.
|
// Server address.
|
||||||
server_address *gtk.Entry
|
server_address *gtk.Entry
|
||||||
// Server password
|
// Server password
|
||||||
server_password *gtk.Entry
|
server_password *gtk.Entry
|
||||||
// Profile.
|
// Profile.
|
||||||
profile *gtk.ComboBoxText
|
profile *gtk.ComboBoxText
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
// Is known server update performed?
|
// Is known server update performed?
|
||||||
update bool
|
update bool
|
||||||
|
|
||||||
// Data.
|
// Data.
|
||||||
// Server's we're working with.
|
// Server's we're working with.
|
||||||
server *datamodels.Server
|
server *datamodels.Server
|
||||||
// Profiles count that was added to profiles combobox.
|
// Profiles count that was added to profiles combobox.
|
||||||
profiles int
|
profiles int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) Close() {}
|
func (f *FavoriteDialog) Close() {}
|
||||||
|
|
||||||
func (f *FavoriteDialog) closeByCancel() {
|
func (f *FavoriteDialog) closeByCancel() {
|
||||||
f.window.Destroy()
|
f.window.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) fill() {
|
func (f *FavoriteDialog) fill() {
|
||||||
f.server_name.SetText(f.server.Name)
|
f.server_name.SetText(f.server.Name)
|
||||||
f.server_address.SetText(f.server.Ip + ":" + f.server.Port)
|
f.server_address.SetText(f.server.Ip + ":" + f.server.Port)
|
||||||
f.server_password.SetText(f.server.Password)
|
f.server_password.SetText(f.server.Password)
|
||||||
|
|
||||||
// Profiles.
|
// Profiles.
|
||||||
// Remove old profiles.
|
// Remove old profiles.
|
||||||
if f.profiles > 0 {
|
if f.profiles > 0 {
|
||||||
for i := 0; i <= f.profiles; i++ {
|
for i := 0; i <= f.profiles; i++ {
|
||||||
f.profile.RemoveText(0)
|
f.profile.RemoveText(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profiles := []datamodels.Profile{}
|
profiles := []datamodels.Profile{}
|
||||||
err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles")
|
err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
var idx_in_combobox int = 0
|
var idx_in_combobox int = 0
|
||||||
var idx_should_be_active int = 0
|
var idx_should_be_active int = 0
|
||||||
for p := range profiles {
|
for p := range profiles {
|
||||||
if profiles[p].Version == f.server.Version {
|
if profiles[p].Version == f.server.Version {
|
||||||
f.profile.AppendText(profiles[p].Name)
|
f.profile.AppendText(profiles[p].Name)
|
||||||
idx_should_be_active = idx_in_combobox
|
idx_should_be_active = idx_in_combobox
|
||||||
idx_in_combobox += 1
|
idx_in_combobox += 1
|
||||||
f.profiles += 1
|
f.profiles += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.profile.SetActive(idx_should_be_active)
|
f.profile.SetActive(idx_should_be_active)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) InitializeNew() {
|
func (f *FavoriteDialog) InitializeNew() {
|
||||||
f.update = false
|
f.update = false
|
||||||
f.server = &datamodels.Server{}
|
f.server = &datamodels.Server{}
|
||||||
f.profiles = 0
|
f.profiles = 0
|
||||||
f.initializeWindow()
|
f.initializeWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) InitializeUpdate(server *datamodels.Server) {
|
func (f *FavoriteDialog) InitializeUpdate(server *datamodels.Server) {
|
||||||
fmt.Println("Favorites updating...")
|
fmt.Println("Favorites updating...")
|
||||||
f.update = true
|
f.update = true
|
||||||
f.server = server
|
f.server = server
|
||||||
f.profiles = 0
|
f.profiles = 0
|
||||||
f.initializeWindow()
|
f.initializeWindow()
|
||||||
f.fill()
|
f.fill()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) initializeWindow() {
|
func (f *FavoriteDialog) initializeWindow() {
|
||||||
f.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
f.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||||
if f.update {
|
if f.update {
|
||||||
f.window.SetTitle(ctx.Translator.Translate("URTrator - {{ action }} favorite server", map[string]string{"action": "Update"}))
|
f.window.SetTitle(ctx.Translator.Translate("URTrator - {{ action }} favorite server", map[string]string{"action": "Update"}))
|
||||||
} else {
|
} else {
|
||||||
f.window.SetTitle(ctx.Translator.Translate("URTrator - {{ action }} favorite server", map[string]string{"action": "Add"}))
|
f.window.SetTitle(ctx.Translator.Translate("URTrator - {{ action }} favorite server", map[string]string{"action": "Add"}))
|
||||||
}
|
}
|
||||||
f.window.Connect("destroy", f.Close)
|
f.window.Connect("destroy", f.Close)
|
||||||
f.window.SetPosition(gtk.WIN_POS_CENTER)
|
f.window.SetPosition(gtk.WIN_POS_CENTER)
|
||||||
f.window.SetModal(true)
|
f.window.SetModal(true)
|
||||||
f.window.SetSizeRequest(400, 200)
|
f.window.SetSizeRequest(400, 200)
|
||||||
f.window.SetResizable(false)
|
f.window.SetResizable(false)
|
||||||
|
|
||||||
// Load program icon from base64.
|
// Load program icon from base64.
|
||||||
icon_bytes, _ := base64.StdEncoding.DecodeString(common.Logo)
|
icon_bytes, _ := base64.StdEncoding.DecodeString(common.Logo)
|
||||||
icon_pixbuf := gdkpixbuf.NewLoader()
|
icon_pixbuf := gdkpixbuf.NewLoader()
|
||||||
icon_pixbuf.Write(icon_bytes)
|
icon_pixbuf.Write(icon_bytes)
|
||||||
logo = icon_pixbuf.GetPixbuf()
|
logo = icon_pixbuf.GetPixbuf()
|
||||||
f.window.SetIcon(logo)
|
f.window.SetIcon(logo)
|
||||||
|
|
||||||
// Set some GTK options for this window.
|
// Set some GTK options for this window.
|
||||||
gtk_opts_raw := gtk.SettingsGetDefault()
|
gtk_opts_raw := gtk.SettingsGetDefault()
|
||||||
gtk_opts := gtk_opts_raw.ToGObject()
|
gtk_opts := gtk_opts_raw.ToGObject()
|
||||||
gtk_opts.Set("gtk-button-images", true)
|
gtk_opts.Set("gtk-button-images", true)
|
||||||
|
|
||||||
f.vbox = gtk.NewVBox(false, 0)
|
f.vbox = gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
table := gtk.NewTable(5, 2, false)
|
table := gtk.NewTable(5, 2, false)
|
||||||
f.vbox.PackStart(table, true, true, 5)
|
f.vbox.PackStart(table, true, true, 5)
|
||||||
|
|
||||||
// Server name.
|
// Server name.
|
||||||
srv_name_label := gtk.NewLabel(ctx.Translator.Translate("Server name:", nil))
|
srv_name_label := gtk.NewLabel(ctx.Translator.Translate("Server name:", nil))
|
||||||
srv_name_label.SetAlignment(0, 0)
|
srv_name_label.SetAlignment(0, 0)
|
||||||
table.Attach(srv_name_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
table.Attach(srv_name_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
f.server_name = gtk.NewEntry()
|
f.server_name = gtk.NewEntry()
|
||||||
table.Attach(f.server_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
table.Attach(f.server_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Server address.
|
// Server address.
|
||||||
srv_addr_label := gtk.NewLabel(ctx.Translator.Translate("Server address:", nil))
|
srv_addr_label := gtk.NewLabel(ctx.Translator.Translate("Server address:", nil))
|
||||||
srv_addr_label.SetAlignment(0, 0)
|
srv_addr_label.SetAlignment(0, 0)
|
||||||
table.Attach(srv_addr_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
table.Attach(srv_addr_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
srv_addr_hbox := gtk.NewHBox(false, 0)
|
srv_addr_hbox := gtk.NewHBox(false, 0)
|
||||||
f.server_address = gtk.NewEntry()
|
f.server_address = gtk.NewEntry()
|
||||||
srv_addr_hbox.PackStart(f.server_address, true, true, 0)
|
srv_addr_hbox.PackStart(f.server_address, true, true, 0)
|
||||||
srv_addr_update_btn := gtk.NewButton()
|
srv_addr_update_btn := gtk.NewButton()
|
||||||
srv_addr_update_btn.SetTooltipText(ctx.Translator.Translate("Update server information", nil))
|
srv_addr_update_btn.SetTooltipText(ctx.Translator.Translate("Update server information", nil))
|
||||||
srv_addr_update_btn_image := gtk.NewImageFromStock(gtk.STOCK_REDO, gtk.ICON_SIZE_SMALL_TOOLBAR)
|
srv_addr_update_btn_image := gtk.NewImageFromStock(gtk.STOCK_REDO, gtk.ICON_SIZE_SMALL_TOOLBAR)
|
||||||
srv_addr_update_btn.SetImage(srv_addr_update_btn_image)
|
srv_addr_update_btn.SetImage(srv_addr_update_btn_image)
|
||||||
srv_addr_update_btn.Clicked(f.updateServerInfo)
|
srv_addr_update_btn.Clicked(f.updateServerInfo)
|
||||||
srv_addr_hbox.PackStart(srv_addr_update_btn, false, true, 5)
|
srv_addr_hbox.PackStart(srv_addr_update_btn, false, true, 5)
|
||||||
if f.update {
|
if f.update {
|
||||||
f.server_address.SetSensitive(false)
|
f.server_address.SetSensitive(false)
|
||||||
}
|
}
|
||||||
table.Attach(srv_addr_hbox, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
|
table.Attach(srv_addr_hbox, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Server password.
|
// Server password.
|
||||||
srv_pass_label := gtk.NewLabel(ctx.Translator.Translate("Password:", nil))
|
srv_pass_label := gtk.NewLabel(ctx.Translator.Translate("Password:", nil))
|
||||||
srv_pass_label.SetAlignment(0, 0)
|
srv_pass_label.SetAlignment(0, 0)
|
||||||
table.Attach(srv_pass_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
table.Attach(srv_pass_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
f.server_password = gtk.NewEntry()
|
f.server_password = gtk.NewEntry()
|
||||||
table.Attach(f.server_password, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
|
table.Attach(f.server_password, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Profile to use.
|
// Profile to use.
|
||||||
profile_label := gtk.NewLabel(ctx.Translator.Translate("Profile:", nil))
|
profile_label := gtk.NewLabel(ctx.Translator.Translate("Profile:", nil))
|
||||||
profile_label.SetAlignment(0, 0)
|
profile_label.SetAlignment(0, 0)
|
||||||
table.Attach(profile_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
|
table.Attach(profile_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
f.profile = gtk.NewComboBoxText()
|
f.profile = gtk.NewComboBoxText()
|
||||||
table.Attach(f.profile , 1, 2, 3, 4, gtk.FILL, gtk.FILL, 5, 5)
|
table.Attach(f.profile, 1, 2, 3, 4, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Invisible thing.
|
// Invisible thing.
|
||||||
inv_label1 := gtk.NewLabel("")
|
inv_label1 := gtk.NewLabel("")
|
||||||
table.Attach(inv_label1, 0, 1, 4, 5, gtk.EXPAND, gtk.FILL, 5, 5)
|
table.Attach(inv_label1, 0, 1, 4, 5, gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
inv_label2 := gtk.NewLabel("")
|
inv_label2 := gtk.NewLabel("")
|
||||||
table.Attach(inv_label2, 1, 2, 4, 5, gtk.EXPAND, gtk.FILL, 5, 5)
|
table.Attach(inv_label2, 1, 2, 4, 5, gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Buttons hbox.
|
// Buttons hbox.
|
||||||
buttons_hbox := gtk.NewHBox(false, 0)
|
buttons_hbox := gtk.NewHBox(false, 0)
|
||||||
sep := gtk.NewHSeparator()
|
sep := gtk.NewHSeparator()
|
||||||
buttons_hbox.PackStart(sep, true, true, 5)
|
buttons_hbox.PackStart(sep, true, true, 5)
|
||||||
// OK-Cancel buttons.
|
// OK-Cancel buttons.
|
||||||
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
||||||
cancel_button.Clicked(f.closeByCancel)
|
cancel_button.Clicked(f.closeByCancel)
|
||||||
buttons_hbox.PackStart(cancel_button, false, true, 5)
|
buttons_hbox.PackStart(cancel_button, false, true, 5)
|
||||||
|
|
||||||
ok_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("OK", nil))
|
ok_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("OK", nil))
|
||||||
ok_button.Clicked(f.saveFavorite)
|
ok_button.Clicked(f.saveFavorite)
|
||||||
buttons_hbox.PackStart(ok_button, false, true, 5)
|
buttons_hbox.PackStart(ok_button, false, true, 5)
|
||||||
|
|
||||||
f.vbox.PackStart(buttons_hbox, false, true, 5)
|
f.vbox.PackStart(buttons_hbox, false, true, 5)
|
||||||
|
|
||||||
f.window.Add(f.vbox)
|
f.window.Add(f.vbox)
|
||||||
f.window.ShowAll()
|
f.window.ShowAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) saveFavorite() error {
|
func (f *FavoriteDialog) saveFavorite() error {
|
||||||
// Update server's information.
|
// Update server's information.
|
||||||
f.server.Name = f.server_name.GetText()
|
f.server.Name = f.server_name.GetText()
|
||||||
//ctx.Requester.Pooler.UpdateSpecificServer(f.server)
|
//ctx.Requester.Pooler.UpdateSpecificServer(f.server)
|
||||||
|
|
||||||
if len(f.server_address.GetText()) == 0 {
|
if len(f.server_address.GetText()) == 0 {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Server address is empty.\n\nServers without address cannot be added.", nil)
|
mbox_string := ctx.Translator.Translate("Server address is empty.\n\nServers without address cannot be added.", nil)
|
||||||
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
return errors.New("No server address specified")
|
return errors.New("No server address specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
var port string = ""
|
var port string = ""
|
||||||
if strings.Contains(f.server_address.GetText(), ":") {
|
if strings.Contains(f.server_address.GetText(), ":") {
|
||||||
port = strings.Split(f.server_address.GetText(), ":")[1]
|
port = strings.Split(f.server_address.GetText(), ":")[1]
|
||||||
} else {
|
} else {
|
||||||
port = "27960"
|
port = "27960"
|
||||||
}
|
}
|
||||||
f.server.Ip = strings.Split(f.server_address.GetText(), ":")[0]
|
f.server.Ip = strings.Split(f.server_address.GetText(), ":")[0]
|
||||||
f.server.Port = port
|
f.server.Port = port
|
||||||
|
|
||||||
if len(f.profile.GetActiveText()) == 0 {
|
if len(f.profile.GetActiveText()) == 0 {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Profile wasn't selected.\n\nPlease, select valid profile for this server.\nIf you haven't add profiles yet - you can do it\nin options on \"Urban Terror\" tab.", nil)
|
mbox_string := ctx.Translator.Translate("Profile wasn't selected.\n\nPlease, select valid profile for this server.\nIf you haven't add profiles yet - you can do it\nin options on \"Urban Terror\" tab.", nil)
|
||||||
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
return errors.New("No game profile specified")
|
return errors.New("No game profile specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Saving favorite server...")
|
fmt.Println("Saving favorite server...")
|
||||||
fmt.Println(fmt.Sprintf("%+v", f.server))
|
fmt.Println(fmt.Sprintf("%+v", f.server))
|
||||||
|
|
||||||
key := strings.Split(f.server_address.GetText(), ":")[0] + ":" + port
|
key := strings.Split(f.server_address.GetText(), ":")[0] + ":" + port
|
||||||
|
|
||||||
// Check if server already in cache. This would replace data about it.
|
// Check if server already in cache. This would replace data about it.
|
||||||
_, ok := ctx.Cache.Servers[key]
|
_, ok := ctx.Cache.Servers[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Cache.Servers[key] = &cachemodels.Server{}
|
ctx.Cache.Servers[key] = &cachemodels.Server{}
|
||||||
ctx.Cache.Servers[key].Server = &datamodels.Server{}
|
ctx.Cache.Servers[key].Server = &datamodels.Server{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Cache.Servers[key].Server.Ip = f.server.Ip
|
ctx.Cache.Servers[key].Server.Ip = f.server.Ip
|
||||||
ctx.Cache.Servers[key].Server.Port = f.server.Port
|
ctx.Cache.Servers[key].Server.Port = f.server.Port
|
||||||
ctx.Cache.Servers[key].Server.Name = f.server.Name
|
ctx.Cache.Servers[key].Server.Name = f.server.Name
|
||||||
ctx.Cache.Servers[key].Server.Password = f.server_password.GetText()
|
ctx.Cache.Servers[key].Server.Password = f.server_password.GetText()
|
||||||
ctx.Cache.Servers[key].Server.ProfileToUse = f.profile.GetActiveText()
|
ctx.Cache.Servers[key].Server.ProfileToUse = f.profile.GetActiveText()
|
||||||
ctx.Cache.Servers[key].Server.Favorite = "1"
|
ctx.Cache.Servers[key].Server.Favorite = "1"
|
||||||
ctx.Cache.Servers[key].Server.ExtendedConfig = f.server.ExtendedConfig
|
ctx.Cache.Servers[key].Server.ExtendedConfig = f.server.ExtendedConfig
|
||||||
ctx.Cache.Servers[key].Server.PlayersInfo = f.server.PlayersInfo
|
ctx.Cache.Servers[key].Server.PlayersInfo = f.server.PlayersInfo
|
||||||
|
|
||||||
ctx.Eventer.LaunchEvent("flushServers", map[string]string{})
|
ctx.Eventer.LaunchEvent("flushServers", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
|
||||||
f.window.Destroy()
|
f.window.Destroy()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FavoriteDialog) updateServerInfo() {
|
func (f *FavoriteDialog) updateServerInfo() {
|
||||||
fmt.Println("Updating server information...")
|
fmt.Println("Updating server information...")
|
||||||
var port string = ""
|
var port string = ""
|
||||||
if strings.Contains(f.server_address.GetText(), ":") {
|
if strings.Contains(f.server_address.GetText(), ":") {
|
||||||
port = strings.Split(f.server_address.GetText(), ":")[1]
|
port = strings.Split(f.server_address.GetText(), ":")[1]
|
||||||
} else {
|
} else {
|
||||||
port = "27960"
|
port = "27960"
|
||||||
}
|
}
|
||||||
f.server.Ip = strings.Split(f.server_address.GetText(), ":")[0]
|
f.server.Ip = strings.Split(f.server_address.GetText(), ":")[0]
|
||||||
f.server.Port = port
|
f.server.Port = port
|
||||||
|
|
||||||
ctx.Requester.Pooler.UpdateSpecificServer(f.server)
|
ctx.Requester.Pooler.UpdateSpecificServer(f.server)
|
||||||
|
|
||||||
f.fill()
|
f.fill()
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,253 +1,253 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// other
|
// other
|
||||||
"github.com/mattn/go-gtk/glib"
|
"github.com/mattn/go-gtk/glib"
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *MainWindow) launchGame() error {
|
func (m *MainWindow) launchGame() error {
|
||||||
fmt.Println("Launching Urban Terror...")
|
fmt.Println("Launching Urban Terror...")
|
||||||
if len(m.qc_server_address.GetText()) != 0 {
|
if len(m.qc_server_address.GetText()) != 0 {
|
||||||
m.launchWithQuickConnect()
|
m.launchWithQuickConnect()
|
||||||
} else {
|
} else {
|
||||||
m.launchAsUsual()
|
m.launchAsUsual()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triggers if we clicked "Launch" button without any text in quick connect
|
// Triggers if we clicked "Launch" button without any text in quick connect
|
||||||
// widget.
|
// widget.
|
||||||
func (m *MainWindow) launchAsUsual() error {
|
func (m *MainWindow) launchAsUsual() error {
|
||||||
fmt.Println("Connecting to selected server...")
|
fmt.Println("Connecting to selected server...")
|
||||||
var srv_address string = ""
|
var srv_address string = ""
|
||||||
|
|
||||||
// Getting server's name from list.
|
// Getting server's name from list.
|
||||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||||
sel := m.all_servers.GetSelection()
|
sel := m.all_servers.GetSelection()
|
||||||
model := m.all_servers.GetModel()
|
model := m.all_servers.GetModel()
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
sel = m.fav_servers.GetSelection()
|
sel = m.fav_servers.GetSelection()
|
||||||
model = m.fav_servers.GetModel()
|
model = m.fav_servers.GetModel()
|
||||||
}
|
}
|
||||||
iter := new(gtk.TreeIter)
|
iter := new(gtk.TreeIter)
|
||||||
_ = sel.GetSelected(iter)
|
_ = sel.GetSelected(iter)
|
||||||
|
|
||||||
// Getting server address.
|
// Getting server address.
|
||||||
var srv_addr string
|
var srv_addr string
|
||||||
srv_address_gval := glib.ValueFromNative(srv_addr)
|
srv_address_gval := glib.ValueFromNative(srv_addr)
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
||||||
model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_address_gval)
|
model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_address_gval)
|
||||||
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_address_gval)
|
model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_address_gval)
|
||||||
}
|
}
|
||||||
srv_address = srv_address_gval.GetString()
|
srv_address = srv_address_gval.GetString()
|
||||||
if len(srv_address) == 0 {
|
if len(srv_address) == 0 {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("No server selected.\n\nPlease, select a server to continue connecting.", nil)
|
mbox_string := ctx.Translator.Translate("No server selected.\n\nPlease, select a server to continue connecting.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
messagebox.Response(func() {
|
messagebox.Response(func() {
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Select a server we will connect to!", nil) + "</span></markup>"})
|
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Select a server we will connect to!", nil) + "</span></markup>"})
|
||||||
}
|
}
|
||||||
return errors.New(ctx.Translator.Translate("No server selected.", nil))
|
return errors.New(ctx.Translator.Translate("No server selected.", nil))
|
||||||
}
|
}
|
||||||
server_profile := ctx.Cache.Servers[srv_address].Server
|
server_profile := ctx.Cache.Servers[srv_address].Server
|
||||||
|
|
||||||
// Check for proper server name. If length == 0: server is offline,
|
// Check for proper server name. If length == 0: server is offline,
|
||||||
// we should show notification to user.
|
// we should show notification to user.
|
||||||
if len(server_profile.Name) == 0 {
|
if len(server_profile.Name) == 0 {
|
||||||
var will_continue bool = false
|
var will_continue bool = false
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server.", nil)
|
mbox_string := ctx.Translator.Translate("Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
|
||||||
messagebox.Connect("response", func(resp *glib.CallbackContext) {
|
messagebox.Connect("response", func(resp *glib.CallbackContext) {
|
||||||
if resp.Args(0) == 4294967287 {
|
if resp.Args(0) == 4294967287 {
|
||||||
will_continue = false
|
will_continue = false
|
||||||
} else {
|
} else {
|
||||||
will_continue = true
|
will_continue = true
|
||||||
}
|
}
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
// We're okay to connect to empty server, temporary.
|
// We're okay to connect to empty server, temporary.
|
||||||
will_continue = true
|
will_continue = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !will_continue {
|
if !will_continue {
|
||||||
return errors.New(ctx.Translator.Translate("User declined to connect to offline server", nil))
|
return errors.New(ctx.Translator.Translate("User declined to connect to offline server", nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting selected profile's name.
|
// Getting selected profile's name.
|
||||||
profile_name := m.profiles.GetActiveText()
|
profile_name := m.profiles.GetActiveText()
|
||||||
user_profile := &datamodels.Profile{}
|
user_profile := &datamodels.Profile{}
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
||||||
// Checking profile name length. If 0 - then stop executing :)
|
// Checking profile name length. If 0 - then stop executing :)
|
||||||
// This check only relevant to "Servers" tab, favorite servers
|
// This check only relevant to "Servers" tab, favorite servers
|
||||||
// have profiles defined (see next).
|
// have profiles defined (see next).
|
||||||
if len(profile_name) == 0 {
|
if len(profile_name) == 0 {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid game profile selected.\n\nPlease, select profile and retry.", nil)
|
mbox_string := ctx.Translator.Translate("Invalid game profile selected.\n\nPlease, select profile and retry.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
messagebox.Response(func() {
|
messagebox.Response(func() {
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile selected.", nil) + "</span></markup>"})
|
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile selected.", nil) + "</span></markup>"})
|
||||||
}
|
}
|
||||||
return errors.New(ctx.Translator.Translate("User didn't select valid profile.", nil))
|
return errors.New(ctx.Translator.Translate("User didn't select valid profile.", nil))
|
||||||
}
|
}
|
||||||
user_profile = ctx.Cache.Profiles[profile_name].Profile
|
user_profile = ctx.Cache.Profiles[profile_name].Profile
|
||||||
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
// For favorite servers profile specified in favorite server
|
// For favorite servers profile specified in favorite server
|
||||||
// information have higher priority, so we just override it :)
|
// information have higher priority, so we just override it :)
|
||||||
user_profile_cached, ok := ctx.Cache.Profiles[server_profile.ProfileToUse]
|
user_profile_cached, ok := ctx.Cache.Profiles[server_profile.ProfileToUse]
|
||||||
if !ok {
|
if !ok {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid game profile specified for favorite server.\n\nPlease, edit your favorite server, select valid profile and retry.", nil)
|
mbox_string := ctx.Translator.Translate("Invalid game profile specified for favorite server.\n\nPlease, edit your favorite server, select valid profile and retry.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
messagebox.Response(func() {
|
messagebox.Response(func() {
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile specified in favorite entry.", nil) + "</span></markup>"})
|
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile specified in favorite entry.", nil) + "</span></markup>"})
|
||||||
}
|
}
|
||||||
return errors.New(ctx.Translator.Translate("User didn't select valid profile.", nil))
|
return errors.New(ctx.Translator.Translate("User didn't select valid profile.", nil))
|
||||||
}
|
}
|
||||||
user_profile = user_profile_cached.Profile
|
user_profile = user_profile_cached.Profile
|
||||||
}
|
}
|
||||||
|
|
||||||
m.launchActually(server_profile, user_profile, "", "")
|
m.launchActually(server_profile, user_profile, "", "")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triggers when Launch button was clicked with some text in quick connect
|
// Triggers when Launch button was clicked with some text in quick connect
|
||||||
// widget.
|
// widget.
|
||||||
func (m *MainWindow) launchWithQuickConnect() error {
|
func (m *MainWindow) launchWithQuickConnect() error {
|
||||||
fmt.Println("Launching game with data from quick connect...")
|
fmt.Println("Launching game with data from quick connect...")
|
||||||
|
|
||||||
srv_address := m.qc_server_address.GetText()
|
srv_address := m.qc_server_address.GetText()
|
||||||
srv_password := m.qc_password.GetText()
|
srv_password := m.qc_password.GetText()
|
||||||
srv_nickname := m.qc_nickname.GetText()
|
srv_nickname := m.qc_nickname.GetText()
|
||||||
current_profile_name := m.profiles.GetActiveText()
|
current_profile_name := m.profiles.GetActiveText()
|
||||||
|
|
||||||
// As we're launching without any profile defined - we should
|
// As we're launching without any profile defined - we should
|
||||||
// check server version and globally selected profile.
|
// check server version and globally selected profile.
|
||||||
// Checking if we have server defined in cache.
|
// Checking if we have server defined in cache.
|
||||||
var ip string = ""
|
var ip string = ""
|
||||||
var port string = ""
|
var port string = ""
|
||||||
if strings.Contains(srv_address, ":") {
|
if strings.Contains(srv_address, ":") {
|
||||||
ip = strings.Split(srv_address, ":")[0]
|
ip = strings.Split(srv_address, ":")[0]
|
||||||
port = strings.Split(srv_address, ":")[1]
|
port = strings.Split(srv_address, ":")[1]
|
||||||
} else {
|
} else {
|
||||||
ip = strings.Split(srv_address, ":")[0]
|
ip = strings.Split(srv_address, ":")[0]
|
||||||
port = "27960"
|
port = "27960"
|
||||||
}
|
}
|
||||||
|
|
||||||
key := ip + ":" + port
|
key := ip + ":" + port
|
||||||
|
|
||||||
_, ok := ctx.Cache.Servers[key]
|
_, ok := ctx.Cache.Servers[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Cache.CreateServer(key)
|
ctx.Cache.CreateServer(key)
|
||||||
fmt.Println("Server not found in cache, requesting information...")
|
fmt.Println("Server not found in cache, requesting information...")
|
||||||
ctx.Requester.UpdateOneServer(key)
|
ctx.Requester.UpdateOneServer(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
server_profile := ctx.Cache.Servers[key]
|
server_profile := ctx.Cache.Servers[key]
|
||||||
user_profile := ctx.Cache.Profiles[current_profile_name]
|
user_profile := ctx.Cache.Profiles[current_profile_name]
|
||||||
|
|
||||||
m.launchActually(server_profile.Server, user_profile.Profile, srv_password, srv_nickname)
|
m.launchActually(server_profile.Server, user_profile.Profile, srv_password, srv_nickname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, nickname_to_use string) error {
|
func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, nickname_to_use string) error {
|
||||||
if server_profile.Name == "" {
|
if server_profile.Name == "" {
|
||||||
var will_continue bool = false
|
var will_continue bool = false
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server.", nil)
|
mbox_string := ctx.Translator.Translate("Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
|
||||||
messagebox.Connect("response", func(resp *glib.CallbackContext) {
|
messagebox.Connect("response", func(resp *glib.CallbackContext) {
|
||||||
if resp.Args(0) == 4294967287 {
|
if resp.Args(0) == 4294967287 {
|
||||||
will_continue = false
|
will_continue = false
|
||||||
} else {
|
} else {
|
||||||
will_continue = true
|
will_continue = true
|
||||||
}
|
}
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
// We're ok here, temporary.
|
// We're ok here, temporary.
|
||||||
will_continue = true
|
will_continue = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !will_continue {
|
if !will_continue {
|
||||||
return errors.New(ctx.Translator.Translate("User declined to connect to offline server", nil))
|
return errors.New(ctx.Translator.Translate("User declined to connect to offline server", nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if server is applicable for selected profile.
|
// Check if server is applicable for selected profile.
|
||||||
if server_profile.Version != user_profile.Version {
|
if server_profile.Version != user_profile.Version {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid game profile selected.\n\nSelected profile have different game version than server.\nPlease, select valid profile and retry.", nil)
|
mbox_string := ctx.Translator.Translate("Invalid game profile selected.\n\nSelected profile have different game version than server.\nPlease, select valid profile and retry.", nil)
|
||||||
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
messagebox.Response(func() {
|
messagebox.Response(func() {
|
||||||
messagebox.Destroy()
|
messagebox.Destroy()
|
||||||
})
|
})
|
||||||
messagebox.Run()
|
messagebox.Run()
|
||||||
} else {
|
} else {
|
||||||
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile selected.", nil) + "</span></markup>"})
|
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Invalid game profile selected.", nil) + "</span></markup>"})
|
||||||
}
|
}
|
||||||
return errors.New(ctx.Translator.Translate("User didn't select valid profile, mismatch with server's version.", nil))
|
return errors.New(ctx.Translator.Translate("User didn't select valid profile, mismatch with server's version.", nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
server_password := password
|
server_password := password
|
||||||
if len(server_password) == 0 {
|
if len(server_password) == 0 {
|
||||||
server_password = server_profile.Password
|
server_password = server_profile.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hey, we're ok here! :) Launch Urban Terror!
|
// Hey, we're ok here! :) Launch Urban Terror!
|
||||||
// Clear server name from "<markup></markup>" things.
|
// Clear server name from "<markup></markup>" things.
|
||||||
srv_name_for_label := server_profile.Name
|
srv_name_for_label := server_profile.Name
|
||||||
if strings.Contains(server_profile.Name, "markup") {
|
if strings.Contains(server_profile.Name, "markup") {
|
||||||
srv_name_for_label = string([]byte(server_profile.Name)[8:len(server_profile.Name)-9])
|
srv_name_for_label = string([]byte(server_profile.Name)[8 : len(server_profile.Name)-9])
|
||||||
} else {
|
} else {
|
||||||
srv_name := ctx.Colorizer.Fix(server_profile.Name)
|
srv_name := ctx.Colorizer.Fix(server_profile.Name)
|
||||||
srv_name_for_label = string([]byte(srv_name)[8:len(srv_name)-9])
|
srv_name_for_label = string([]byte(srv_name)[8 : len(srv_name)-9])
|
||||||
}
|
}
|
||||||
// Show great coloured label.
|
// Show great coloured label.
|
||||||
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Urban Terror is launched with profile", nil) + " </span><span foreground=\"blue\">" + user_profile.Name + "</span> <span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("and connected to", nil) + " </span><span foreground=\"orange\" font_weight=\"bold\">" + srv_name_for_label + "</span></markup>"})
|
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("Urban Terror is launched with profile", nil) + " </span><span foreground=\"blue\">" + user_profile.Name + "</span> <span foreground=\"red\" font_weight=\"bold\">" + ctx.Translator.Translate("and connected to", nil) + " </span><span foreground=\"orange\" font_weight=\"bold\">" + srv_name_for_label + "</span></markup>"})
|
||||||
m.launch_button.SetSensitive(false)
|
m.launch_button.SetSensitive(false)
|
||||||
// ToDo: handling server passwords.
|
// ToDo: handling server passwords.
|
||||||
ctx.Launcher.Launch(server_profile, user_profile, server_password, []string{"+name", nickname_to_use}, m.unlockInterface)
|
ctx.Launcher.Launch(server_profile, user_profile, server_password, []string{"+name", nickname_to_use}, m.unlockInterface)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,96 +1,96 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// other
|
// other
|
||||||
"github.com/mattn/go-gtk/glib"
|
"github.com/mattn/go-gtk/glib"
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *MainWindow) sortServersByName(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
|
func (m *MainWindow) sortServersByName(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter, userData interface{}) int {
|
||||||
var name1_raw glib.GValue
|
var name1_raw glib.GValue
|
||||||
var name2_raw glib.GValue
|
var name2_raw glib.GValue
|
||||||
|
|
||||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Name", nil)], &name1_raw)
|
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Name", nil)], &name1_raw)
|
||||||
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Name", nil)], &name2_raw)
|
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Name", nil)], &name2_raw)
|
||||||
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Name", nil)], &name1_raw)
|
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Name", nil)], &name1_raw)
|
||||||
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Name", nil)], &name2_raw)
|
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Name", nil)], &name2_raw)
|
||||||
} else {
|
} else {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
name1 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name1_raw.GetString()))
|
name1 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name1_raw.GetString()))
|
||||||
name2 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name2_raw.GetString()))
|
name2 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name2_raw.GetString()))
|
||||||
|
|
||||||
if name1 < name2 {
|
if name1 < name2 {
|
||||||
return -1
|
return -1
|
||||||
} else {
|
} else {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MainWindow) sortServersByPlayers(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
|
func (m *MainWindow) sortServersByPlayers(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter, userData interface{}) int {
|
||||||
var players1_raw glib.GValue
|
var players1_raw glib.GValue
|
||||||
var players2_raw glib.GValue
|
var players2_raw glib.GValue
|
||||||
|
|
||||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Players", nil)], &players1_raw)
|
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Players", nil)], &players1_raw)
|
||||||
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Players", nil)], &players2_raw)
|
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Players", nil)], &players2_raw)
|
||||||
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Players", nil)], &players1_raw)
|
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Players", nil)], &players1_raw)
|
||||||
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Players", nil)], &players2_raw)
|
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Players", nil)], &players2_raw)
|
||||||
} else {
|
} else {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
players1_online := strings.Split(players1_raw.GetString(), "/")[0]
|
players1_online := strings.Split(players1_raw.GetString(), "/")[0]
|
||||||
players2_online := strings.Split(players2_raw.GetString(), "/")[0]
|
players2_online := strings.Split(players2_raw.GetString(), "/")[0]
|
||||||
|
|
||||||
if len(players1_online) > 0 && len(players2_online) > 0 {
|
if len(players1_online) > 0 && len(players2_online) > 0 {
|
||||||
players1, _ := strconv.Atoi(players1_online)
|
players1, _ := strconv.Atoi(players1_online)
|
||||||
players2, _ := strconv.Atoi(players2_online)
|
players2, _ := strconv.Atoi(players2_online)
|
||||||
if players1 > players2 {
|
if players1 > players2 {
|
||||||
return -1
|
return -1
|
||||||
} else {
|
} else {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MainWindow) sortServersByPing(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
|
func (m *MainWindow) sortServersByPing(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter, userData interface{}) int {
|
||||||
var ping1_raw glib.GValue
|
var ping1_raw glib.GValue
|
||||||
var ping2_raw glib.GValue
|
var ping2_raw glib.GValue
|
||||||
|
|
||||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||||
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Ping", nil)], &ping1_raw)
|
model.GetValue(a, m.column_pos["Servers"][ctx.Translator.Translate("Ping", nil)], &ping1_raw)
|
||||||
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Ping", nil)], &ping2_raw)
|
model.GetValue(b, m.column_pos["Servers"][ctx.Translator.Translate("Ping", nil)], &ping2_raw)
|
||||||
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
|
||||||
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Ping", nil)], &ping1_raw)
|
model.GetValue(a, m.column_pos["Favorites"][ctx.Translator.Translate("Ping", nil)], &ping1_raw)
|
||||||
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Ping", nil)], &ping2_raw)
|
model.GetValue(b, m.column_pos["Favorites"][ctx.Translator.Translate("Ping", nil)], &ping2_raw)
|
||||||
} else {
|
} else {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
ping1, _ := strconv.Atoi(ping1_raw.GetString())
|
ping1, _ := strconv.Atoi(ping1_raw.GetString())
|
||||||
ping2, _ := strconv.Atoi(ping2_raw.GetString())
|
ping2, _ := strconv.Atoi(ping2_raw.GetString())
|
||||||
|
|
||||||
if ping1 < ping2 {
|
if ping1 < ping2 {
|
||||||
return 1
|
return 1
|
||||||
} else {
|
} else {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
@ -10,427 +10,427 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/glib"
|
||||||
"github.com/mattn/go-gtk/glib"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OptionsDialog struct {
|
type OptionsDialog struct {
|
||||||
// Window.
|
// Window.
|
||||||
window *gtk.Window
|
window *gtk.Window
|
||||||
// Options main VBox.
|
// Options main VBox.
|
||||||
vbox *gtk.VBox
|
vbox *gtk.VBox
|
||||||
// Tabs widget.
|
// Tabs widget.
|
||||||
tab_widget *gtk.Notebook
|
tab_widget *gtk.Notebook
|
||||||
|
|
||||||
// Widgets.
|
// Widgets.
|
||||||
// General tab.
|
// General tab.
|
||||||
// Show tray icon checkbutton.
|
// Show tray icon checkbutton.
|
||||||
show_tray_icon *gtk.CheckButton
|
show_tray_icon *gtk.CheckButton
|
||||||
// Enable autoupdate checkbutton.
|
// Enable autoupdate checkbutton.
|
||||||
autoupdate *gtk.CheckButton
|
autoupdate *gtk.CheckButton
|
||||||
// Appearance tab.
|
// Appearance tab.
|
||||||
// Language to use.
|
// Language to use.
|
||||||
language_combo *gtk.ComboBoxText
|
language_combo *gtk.ComboBoxText
|
||||||
// Urban Terror tab.
|
// Urban Terror tab.
|
||||||
// Profiles list.
|
// Profiles list.
|
||||||
profiles_list *gtk.TreeView
|
profiles_list *gtk.TreeView
|
||||||
// Servers updating tab.
|
// Servers updating tab.
|
||||||
// Master server address.
|
// Master server address.
|
||||||
master_server_addr *gtk.Entry
|
master_server_addr *gtk.Entry
|
||||||
// Servers autoupdate.
|
// Servers autoupdate.
|
||||||
servers_autoupdate *gtk.CheckButton
|
servers_autoupdate *gtk.CheckButton
|
||||||
// Timeout for servers autoupdating.
|
// Timeout for servers autoupdating.
|
||||||
servers_autoupdate_timeout *gtk.Entry
|
servers_autoupdate_timeout *gtk.Entry
|
||||||
|
|
||||||
// Data stores.
|
// Data stores.
|
||||||
// Urban Terror profiles list.
|
// Urban Terror profiles list.
|
||||||
profiles_list_store *gtk.ListStore
|
profiles_list_store *gtk.ListStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) addProfile() {
|
func (o *OptionsDialog) addProfile() {
|
||||||
fmt.Println("Adding profile...")
|
fmt.Println("Adding profile...")
|
||||||
|
|
||||||
op := OptionsProfile{}
|
op := OptionsProfile{}
|
||||||
op.Initialize(false)
|
op.Initialize(false)
|
||||||
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) closeOptionsDialogByCancel() {
|
func (o *OptionsDialog) closeOptionsDialogByCancel() {
|
||||||
o.window.Destroy()
|
o.window.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) closeOptionsDialogWithDiscard() {
|
func (o *OptionsDialog) closeOptionsDialogWithDiscard() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) closeOptionsDialogWithSaving() {
|
func (o *OptionsDialog) closeOptionsDialogWithSaving() {
|
||||||
fmt.Println("Saving changes to options...")
|
fmt.Println("Saving changes to options...")
|
||||||
|
|
||||||
o.saveGeneral()
|
o.saveGeneral()
|
||||||
o.saveAppearance()
|
o.saveAppearance()
|
||||||
|
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Some options require application restart to be applied.", nil)
|
mbox_string := ctx.Translator.Translate("Some options require application restart to be applied.", nil)
|
||||||
m := gtk.NewMessageDialog(o.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(o.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
o.window.Destroy()
|
o.window.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) deleteProfile() {
|
func (o *OptionsDialog) deleteProfile() {
|
||||||
// Oh... dat... GTK...
|
// Oh... dat... GTK...
|
||||||
sel := o.profiles_list.GetSelection()
|
sel := o.profiles_list.GetSelection()
|
||||||
model := o.profiles_list.GetModel()
|
model := o.profiles_list.GetModel()
|
||||||
iter := new(gtk.TreeIter)
|
iter := new(gtk.TreeIter)
|
||||||
_ = sel.GetSelected(iter)
|
_ = sel.GetSelected(iter)
|
||||||
var p string
|
var p string
|
||||||
gval := glib.ValueFromNative(p)
|
gval := glib.ValueFromNative(p)
|
||||||
model.GetValue(iter, 0, gval)
|
model.GetValue(iter, 0, gval)
|
||||||
profile_name := gval.GetString()
|
profile_name := gval.GetString()
|
||||||
|
|
||||||
if len(profile_name) > 0 {
|
if len(profile_name) > 0 {
|
||||||
fmt.Println("Deleting profile '" + profile_name + "'")
|
fmt.Println("Deleting profile '" + profile_name + "'")
|
||||||
|
|
||||||
profile := datamodels.Profile{}
|
profile := datamodels.Profile{}
|
||||||
profile.Name = profile_name
|
profile.Name = profile_name
|
||||||
ctx.Eventer.LaunchEvent("deleteProfile", map[string]string{"profile_name": profile_name})
|
ctx.Eventer.LaunchEvent("deleteProfile", map[string]string{"profile_name": profile_name})
|
||||||
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) editProfile() {
|
func (o *OptionsDialog) editProfile() {
|
||||||
// Oh... dat... GTK...
|
// Oh... dat... GTK...
|
||||||
sel := o.profiles_list.GetSelection()
|
sel := o.profiles_list.GetSelection()
|
||||||
model := o.profiles_list.GetModel()
|
model := o.profiles_list.GetModel()
|
||||||
iter := new(gtk.TreeIter)
|
iter := new(gtk.TreeIter)
|
||||||
_ = sel.GetSelected(iter)
|
_ = sel.GetSelected(iter)
|
||||||
var p string
|
var p string
|
||||||
gval := glib.ValueFromNative(p)
|
gval := glib.ValueFromNative(p)
|
||||||
model.GetValue(iter, 0, gval)
|
model.GetValue(iter, 0, gval)
|
||||||
profile_name := gval.GetString()
|
profile_name := gval.GetString()
|
||||||
|
|
||||||
if len(profile_name) > 0 {
|
if len(profile_name) > 0 {
|
||||||
op := OptionsProfile{}
|
op := OptionsProfile{}
|
||||||
op.InitializeUpdate(profile_name)
|
op.InitializeUpdate(profile_name)
|
||||||
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
ctx.Eventer.LaunchEvent("flushProfiles", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) fill() {
|
func (o *OptionsDialog) fill() {
|
||||||
if ctx.Cfg.Cfg["/general/show_tray_icon"] == "1" {
|
if ctx.Cfg.Cfg["/general/show_tray_icon"] == "1" {
|
||||||
o.show_tray_icon.SetActive(true)
|
o.show_tray_icon.SetActive(true)
|
||||||
}
|
}
|
||||||
if ctx.Cfg.Cfg["/general/urtrator_autoupdate"] == "1" {
|
if ctx.Cfg.Cfg["/general/urtrator_autoupdate"] == "1" {
|
||||||
o.autoupdate.SetActive(true)
|
o.autoupdate.SetActive(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Servers updating tab.
|
// Servers updating tab.
|
||||||
master_server_addr, ok := ctx.Cfg.Cfg["/servers_updating/master_server"]
|
master_server_addr, ok := ctx.Cfg.Cfg["/servers_updating/master_server"]
|
||||||
if !ok {
|
if !ok {
|
||||||
o.master_server_addr.SetText("master.urbanterror.info:27900")
|
o.master_server_addr.SetText("master.urbanterror.info:27900")
|
||||||
} else {
|
} else {
|
||||||
o.master_server_addr.SetText(master_server_addr)
|
o.master_server_addr.SetText(master_server_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
servers_autoupdate, ok1 := ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"]
|
servers_autoupdate, ok1 := ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"]
|
||||||
if ok1 {
|
if ok1 {
|
||||||
if servers_autoupdate == "1" {
|
if servers_autoupdate == "1" {
|
||||||
o.servers_autoupdate.SetActive(true)
|
o.servers_autoupdate.SetActive(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
servers_update_timeout, ok2 := ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"]
|
servers_update_timeout, ok2 := ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"]
|
||||||
if !ok2 {
|
if !ok2 {
|
||||||
o.servers_autoupdate_timeout.SetText("10")
|
o.servers_autoupdate_timeout.SetText("10")
|
||||||
} else {
|
} else {
|
||||||
o.servers_autoupdate_timeout.SetText(servers_update_timeout)
|
o.servers_autoupdate_timeout.SetText(servers_update_timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appearance tab initialization.
|
// Appearance tab initialization.
|
||||||
func (o *OptionsDialog) initializeAppearanceTab() {
|
func (o *OptionsDialog) initializeAppearanceTab() {
|
||||||
appearance_vbox := gtk.NewVBox(false, 0)
|
appearance_vbox := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
appearance_table := gtk.NewTable(1, 2, false)
|
appearance_table := gtk.NewTable(1, 2, false)
|
||||||
|
|
||||||
language_selection_tooltip := ctx.Translator.Translate("Language which URTrator will use.\n\nChanging this requires URTrator restart!", nil)
|
language_selection_tooltip := ctx.Translator.Translate("Language which URTrator will use.\n\nChanging this requires URTrator restart!", nil)
|
||||||
|
|
||||||
language_selection_label := gtk.NewLabel(ctx.Translator.Translate("Language:", nil))
|
language_selection_label := gtk.NewLabel(ctx.Translator.Translate("Language:", nil))
|
||||||
language_selection_label.SetAlignment(0, 0)
|
language_selection_label.SetAlignment(0, 0)
|
||||||
language_selection_label.SetTooltipText(language_selection_tooltip)
|
language_selection_label.SetTooltipText(language_selection_tooltip)
|
||||||
appearance_table.Attach(language_selection_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
appearance_table.Attach(language_selection_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.language_combo = gtk.NewComboBoxText()
|
o.language_combo = gtk.NewComboBoxText()
|
||||||
o.language_combo.SetTooltipText(language_selection_tooltip)
|
o.language_combo.SetTooltipText(language_selection_tooltip)
|
||||||
// Get all available languages and fill combobox.
|
// Get all available languages and fill combobox.
|
||||||
lang_idx := 0
|
lang_idx := 0
|
||||||
var lang_active int = 0
|
var lang_active int = 0
|
||||||
for lang, _ := range ctx.Translator.AcceptedLanguages {
|
for lang, _ := range ctx.Translator.AcceptedLanguages {
|
||||||
o.language_combo.AppendText(lang)
|
o.language_combo.AppendText(lang)
|
||||||
if ctx.Translator.AcceptedLanguages[lang] == ctx.Cfg.Cfg["/general/language"] {
|
if ctx.Translator.AcceptedLanguages[lang] == ctx.Cfg.Cfg["/general/language"] {
|
||||||
lang_active = lang_idx
|
lang_active = lang_idx
|
||||||
}
|
}
|
||||||
lang_idx += 1
|
lang_idx += 1
|
||||||
}
|
}
|
||||||
o.language_combo.SetActive(lang_active)
|
o.language_combo.SetActive(lang_active)
|
||||||
|
|
||||||
appearance_table.Attach(o.language_combo, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5)
|
appearance_table.Attach(o.language_combo, 1, 2, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
appearance_vbox.PackStart(appearance_table, false, true, 0)
|
appearance_vbox.PackStart(appearance_table, false, true, 0)
|
||||||
o.tab_widget.AppendPage(appearance_vbox, gtk.NewLabel(ctx.Translator.Translate("Appearance", nil)))
|
o.tab_widget.AppendPage(appearance_vbox, gtk.NewLabel(ctx.Translator.Translate("Appearance", nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) initializeGeneralTab() {
|
func (o *OptionsDialog) initializeGeneralTab() {
|
||||||
general_vbox := gtk.NewVBox(false, 0)
|
general_vbox := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
general_table := gtk.NewTable(2, 2, false)
|
general_table := gtk.NewTable(2, 2, false)
|
||||||
|
|
||||||
// Tray icon checkbox.
|
// Tray icon checkbox.
|
||||||
show_tray_icon_label := gtk.NewLabel(ctx.Translator.Translate("Show icon in tray", nil))
|
show_tray_icon_label := gtk.NewLabel(ctx.Translator.Translate("Show icon in tray", nil))
|
||||||
show_tray_icon_label.SetAlignment(0, 0)
|
show_tray_icon_label.SetAlignment(0, 0)
|
||||||
general_table.Attach(show_tray_icon_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
general_table.Attach(show_tray_icon_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.show_tray_icon = gtk.NewCheckButtonWithLabel("")
|
o.show_tray_icon = gtk.NewCheckButtonWithLabel("")
|
||||||
o.show_tray_icon.SetTooltipText(ctx.Translator.Translate("Show icon in tray", nil))
|
o.show_tray_icon.SetTooltipText(ctx.Translator.Translate("Show icon in tray", nil))
|
||||||
general_table.Attach(o.show_tray_icon, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5)
|
general_table.Attach(o.show_tray_icon, 1, 2, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Autoupdate checkbox.
|
// Autoupdate checkbox.
|
||||||
autoupdate_tooltip := ctx.Translator.Translate("Should URTrator check for updates and update itself? Not working now.", nil)
|
autoupdate_tooltip := ctx.Translator.Translate("Should URTrator check for updates and update itself? Not working now.", nil)
|
||||||
autoupdate_label := gtk.NewLabel(ctx.Translator.Translate("Automatically update URTrator?", nil))
|
autoupdate_label := gtk.NewLabel(ctx.Translator.Translate("Automatically update URTrator?", nil))
|
||||||
autoupdate_label.SetTooltipText(autoupdate_tooltip)
|
autoupdate_label.SetTooltipText(autoupdate_tooltip)
|
||||||
autoupdate_label.SetAlignment(0, 0)
|
autoupdate_label.SetAlignment(0, 0)
|
||||||
general_table.Attach(autoupdate_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
general_table.Attach(autoupdate_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.autoupdate = gtk.NewCheckButtonWithLabel("")
|
o.autoupdate = gtk.NewCheckButtonWithLabel("")
|
||||||
o.autoupdate.SetTooltipText(autoupdate_tooltip)
|
o.autoupdate.SetTooltipText(autoupdate_tooltip)
|
||||||
general_table.Attach(o.autoupdate, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5)
|
general_table.Attach(o.autoupdate, 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Vertical separator.
|
// Vertical separator.
|
||||||
sep := gtk.NewVBox(false, 0)
|
sep := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
general_vbox.PackStart(general_table, false, true, 0)
|
general_vbox.PackStart(general_table, false, true, 0)
|
||||||
general_vbox.PackStart(sep, false, true, 0)
|
general_vbox.PackStart(sep, false, true, 0)
|
||||||
|
|
||||||
o.tab_widget.AppendPage(general_vbox, gtk.NewLabel(ctx.Translator.Translate("General", nil)))
|
o.tab_widget.AppendPage(general_vbox, gtk.NewLabel(ctx.Translator.Translate("General", nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) initializeServersOptionsTab() {
|
func (o *OptionsDialog) initializeServersOptionsTab() {
|
||||||
servers_options_vbox := gtk.NewVBox(false, 0)
|
servers_options_vbox := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
servers_updating_table := gtk.NewTable(3, 2, false)
|
servers_updating_table := gtk.NewTable(3, 2, false)
|
||||||
servers_updating_table.SetRowSpacings(2)
|
servers_updating_table.SetRowSpacings(2)
|
||||||
|
|
||||||
// Master server address.
|
// Master server address.
|
||||||
master_server_addr_tooltip := ctx.Translator.Translate("Address of master server. Specify in form: addr:port.", nil)
|
master_server_addr_tooltip := ctx.Translator.Translate("Address of master server. Specify in form: addr:port.", nil)
|
||||||
master_server_addr_label := gtk.NewLabel(ctx.Translator.Translate("Master server address", nil))
|
master_server_addr_label := gtk.NewLabel(ctx.Translator.Translate("Master server address", nil))
|
||||||
master_server_addr_label.SetTooltipText(master_server_addr_tooltip)
|
master_server_addr_label.SetTooltipText(master_server_addr_tooltip)
|
||||||
master_server_addr_label.SetAlignment(0, 0)
|
master_server_addr_label.SetAlignment(0, 0)
|
||||||
servers_updating_table.Attach(master_server_addr_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
servers_updating_table.Attach(master_server_addr_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.master_server_addr = gtk.NewEntry()
|
o.master_server_addr = gtk.NewEntry()
|
||||||
o.master_server_addr.SetTooltipText(master_server_addr_tooltip)
|
o.master_server_addr.SetTooltipText(master_server_addr_tooltip)
|
||||||
servers_updating_table.Attach(o.master_server_addr, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
servers_updating_table.Attach(o.master_server_addr, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Servers autoupdate checkbox.
|
// Servers autoupdate checkbox.
|
||||||
servers_autoupdate_cb_tooptip := ctx.Translator.Translate("Should servers be automatically updated?", nil)
|
servers_autoupdate_cb_tooptip := ctx.Translator.Translate("Should servers be automatically updated?", nil)
|
||||||
servers_autoupdate_cb_label := gtk.NewLabel(ctx.Translator.Translate("Servers autoupdate", nil))
|
servers_autoupdate_cb_label := gtk.NewLabel(ctx.Translator.Translate("Servers autoupdate", nil))
|
||||||
servers_autoupdate_cb_label.SetTooltipText(servers_autoupdate_cb_tooptip)
|
servers_autoupdate_cb_label.SetTooltipText(servers_autoupdate_cb_tooptip)
|
||||||
servers_autoupdate_cb_label.SetAlignment(0, 0)
|
servers_autoupdate_cb_label.SetAlignment(0, 0)
|
||||||
servers_updating_table.Attach(servers_autoupdate_cb_label, 0, 1 ,1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
servers_updating_table.Attach(servers_autoupdate_cb_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.servers_autoupdate = gtk.NewCheckButtonWithLabel("")
|
o.servers_autoupdate = gtk.NewCheckButtonWithLabel("")
|
||||||
o.servers_autoupdate.SetTooltipText(servers_autoupdate_cb_tooptip)
|
o.servers_autoupdate.SetTooltipText(servers_autoupdate_cb_tooptip)
|
||||||
servers_updating_table.Attach(o.servers_autoupdate, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL, 5, 5)
|
servers_updating_table.Attach(o.servers_autoupdate, 1, 2, 1, 2, gtk.EXPAND|gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Servers update timeout.
|
// Servers update timeout.
|
||||||
servers_autoupdate_timeout_tooltip := ctx.Translator.Translate("Timeout which will trigger servers information update, in minutes.", nil)
|
servers_autoupdate_timeout_tooltip := ctx.Translator.Translate("Timeout which will trigger servers information update, in minutes.", nil)
|
||||||
servers_autoupdate_label := gtk.NewLabel(ctx.Translator.Translate("Servers update timeout (minutes)", nil))
|
servers_autoupdate_label := gtk.NewLabel(ctx.Translator.Translate("Servers update timeout (minutes)", nil))
|
||||||
servers_autoupdate_label.SetTooltipText(servers_autoupdate_timeout_tooltip)
|
servers_autoupdate_label.SetTooltipText(servers_autoupdate_timeout_tooltip)
|
||||||
servers_autoupdate_label.SetAlignment(0, 0)
|
servers_autoupdate_label.SetAlignment(0, 0)
|
||||||
servers_updating_table.Attach(servers_autoupdate_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
servers_updating_table.Attach(servers_autoupdate_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
o.servers_autoupdate_timeout = gtk.NewEntry()
|
o.servers_autoupdate_timeout = gtk.NewEntry()
|
||||||
o.servers_autoupdate_timeout.SetTooltipText(servers_autoupdate_timeout_tooltip)
|
o.servers_autoupdate_timeout.SetTooltipText(servers_autoupdate_timeout_tooltip)
|
||||||
servers_updating_table.Attach(o.servers_autoupdate_timeout, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
|
servers_updating_table.Attach(o.servers_autoupdate_timeout, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Vertical separator.
|
// Vertical separator.
|
||||||
sep := gtk.NewVBox(false, 0)
|
sep := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
servers_options_vbox.PackStart(servers_updating_table, false, true, 0)
|
servers_options_vbox.PackStart(servers_updating_table, false, true, 0)
|
||||||
servers_options_vbox.PackStart(sep, true, true, 0)
|
servers_options_vbox.PackStart(sep, true, true, 0)
|
||||||
|
|
||||||
o.tab_widget.AppendPage(servers_options_vbox, gtk.NewLabel(ctx.Translator.Translate("Servers updating", nil)))
|
o.tab_widget.AppendPage(servers_options_vbox, gtk.NewLabel(ctx.Translator.Translate("Servers updating", nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) initializeStorages() {
|
func (o *OptionsDialog) initializeStorages() {
|
||||||
// Structure:
|
// Structure:
|
||||||
// Name|Version|Second X session
|
// Name|Version|Second X session
|
||||||
o.profiles_list_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING, glib.G_TYPE_BOOL)
|
o.profiles_list_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING, glib.G_TYPE_BOOL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) initializeTabs() {
|
func (o *OptionsDialog) initializeTabs() {
|
||||||
o.initializeStorages()
|
o.initializeStorages()
|
||||||
o.tab_widget = gtk.NewNotebook()
|
o.tab_widget = gtk.NewNotebook()
|
||||||
o.tab_widget.SetTabPos(gtk.POS_LEFT)
|
o.tab_widget.SetTabPos(gtk.POS_LEFT)
|
||||||
|
|
||||||
o.initializeGeneralTab()
|
o.initializeGeneralTab()
|
||||||
o.initializeAppearanceTab()
|
o.initializeAppearanceTab()
|
||||||
o.initializeUrtTab()
|
o.initializeUrtTab()
|
||||||
o.initializeServersOptionsTab()
|
o.initializeServersOptionsTab()
|
||||||
|
|
||||||
// Buttons for saving and discarding changes.
|
// Buttons for saving and discarding changes.
|
||||||
buttons_hbox := gtk.NewHBox(false, 0)
|
buttons_hbox := gtk.NewHBox(false, 0)
|
||||||
sep := gtk.NewHBox(false, 0)
|
sep := gtk.NewHBox(false, 0)
|
||||||
|
|
||||||
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
||||||
cancel_button.Clicked(o.closeOptionsDialogByCancel)
|
cancel_button.Clicked(o.closeOptionsDialogByCancel)
|
||||||
|
|
||||||
ok_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("OK", nil))
|
ok_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("OK", nil))
|
||||||
ok_button.Clicked(o.closeOptionsDialogWithSaving)
|
ok_button.Clicked(o.closeOptionsDialogWithSaving)
|
||||||
|
|
||||||
buttons_hbox.PackStart(sep, true, true, 5)
|
buttons_hbox.PackStart(sep, true, true, 5)
|
||||||
buttons_hbox.PackStart(cancel_button, false, true, 5)
|
buttons_hbox.PackStart(cancel_button, false, true, 5)
|
||||||
buttons_hbox.PackStart(ok_button, false, true, 5)
|
buttons_hbox.PackStart(ok_button, false, true, 5)
|
||||||
|
|
||||||
o.vbox.PackStart(o.tab_widget, true, true, 5)
|
o.vbox.PackStart(o.tab_widget, true, true, 5)
|
||||||
o.vbox.PackStart(buttons_hbox, false, true, 5)
|
o.vbox.PackStart(buttons_hbox, false, true, 5)
|
||||||
|
|
||||||
ctx.Eventer.AddEventHandler("loadProfilesIntoOptionsWindow", o.loadProfiles)
|
ctx.Eventer.AddEventHandler("loadProfilesIntoOptionsWindow", o.loadProfiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) initializeUrtTab() {
|
func (o *OptionsDialog) initializeUrtTab() {
|
||||||
urt_hbox := gtk.NewHBox(false, 5)
|
urt_hbox := gtk.NewHBox(false, 5)
|
||||||
|
|
||||||
// Profiles list.
|
// Profiles list.
|
||||||
o.profiles_list = gtk.NewTreeView()
|
o.profiles_list = gtk.NewTreeView()
|
||||||
o.profiles_list.SetTooltipText(ctx.Translator.Translate("All available profiles", nil))
|
o.profiles_list.SetTooltipText(ctx.Translator.Translate("All available profiles", nil))
|
||||||
urt_hbox.Add(o.profiles_list)
|
urt_hbox.Add(o.profiles_list)
|
||||||
o.profiles_list.SetModel(o.profiles_list_store)
|
o.profiles_list.SetModel(o.profiles_list_store)
|
||||||
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Profile name", nil), gtk.NewCellRendererText(), "text", 0))
|
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Profile name", nil), gtk.NewCellRendererText(), "text", 0))
|
||||||
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Urban Terror version", nil), gtk.NewCellRendererText(), "text", 1))
|
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Urban Terror version", nil), gtk.NewCellRendererText(), "text", 1))
|
||||||
|
|
||||||
// Profiles list buttons.
|
// Profiles list buttons.
|
||||||
urt_profiles_buttons_vbox := gtk.NewVBox(false, 0)
|
urt_profiles_buttons_vbox := gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
button_add := gtk.NewButtonWithLabel(ctx.Translator.Translate("Add", nil))
|
button_add := gtk.NewButtonWithLabel(ctx.Translator.Translate("Add", nil))
|
||||||
button_add.SetTooltipText(ctx.Translator.Translate("Add new profile", nil))
|
button_add.SetTooltipText(ctx.Translator.Translate("Add new profile", nil))
|
||||||
button_add.Clicked(o.addProfile)
|
button_add.Clicked(o.addProfile)
|
||||||
urt_profiles_buttons_vbox.PackStart(button_add, false, true, 0)
|
urt_profiles_buttons_vbox.PackStart(button_add, false, true, 0)
|
||||||
|
|
||||||
button_edit := gtk.NewButtonWithLabel(ctx.Translator.Translate("Edit", nil))
|
button_edit := gtk.NewButtonWithLabel(ctx.Translator.Translate("Edit", nil))
|
||||||
button_edit.SetTooltipText(ctx.Translator.Translate("Edit selected profile. Do nothing if no profile was selected.", nil))
|
button_edit.SetTooltipText(ctx.Translator.Translate("Edit selected profile. Do nothing if no profile was selected.", nil))
|
||||||
button_edit.Clicked(o.editProfile)
|
button_edit.Clicked(o.editProfile)
|
||||||
urt_profiles_buttons_vbox.PackStart(button_edit, false, true, 5)
|
urt_profiles_buttons_vbox.PackStart(button_edit, false, true, 5)
|
||||||
|
|
||||||
// Spacer for profiles list buttons.
|
// Spacer for profiles list buttons.
|
||||||
sep := gtk.NewVBox(false, 0)
|
sep := gtk.NewVBox(false, 0)
|
||||||
urt_profiles_buttons_vbox.PackStart(sep, true, true, 5)
|
urt_profiles_buttons_vbox.PackStart(sep, true, true, 5)
|
||||||
|
|
||||||
button_delete := gtk.NewButtonWithLabel(ctx.Translator.Translate("Delete", nil))
|
button_delete := gtk.NewButtonWithLabel(ctx.Translator.Translate("Delete", nil))
|
||||||
button_delete.SetTooltipText(ctx.Translator.Translate("Delete selected profile. Do nothing if no profile was selected.", nil))
|
button_delete.SetTooltipText(ctx.Translator.Translate("Delete selected profile. Do nothing if no profile was selected.", nil))
|
||||||
button_delete.Clicked(o.deleteProfile)
|
button_delete.Clicked(o.deleteProfile)
|
||||||
urt_profiles_buttons_vbox.PackStart(button_delete, false, true, 0)
|
urt_profiles_buttons_vbox.PackStart(button_delete, false, true, 0)
|
||||||
|
|
||||||
urt_hbox.Add(urt_profiles_buttons_vbox)
|
urt_hbox.Add(urt_profiles_buttons_vbox)
|
||||||
|
|
||||||
o.tab_widget.AppendPage(urt_hbox, gtk.NewLabel(ctx.Translator.Translate("Urban Terror", nil)))
|
o.tab_widget.AppendPage(urt_hbox, gtk.NewLabel(ctx.Translator.Translate("Urban Terror", nil)))
|
||||||
|
|
||||||
// Load Profiles.
|
// Load Profiles.
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) loadProfiles(data map[string]string) {
|
func (o *OptionsDialog) loadProfiles(data map[string]string) {
|
||||||
fmt.Println("Loading profiles...")
|
fmt.Println("Loading profiles...")
|
||||||
o.profiles_list_store.Clear()
|
o.profiles_list_store.Clear()
|
||||||
|
|
||||||
ctx.Cache.ProfilesMutex.Lock()
|
ctx.Cache.ProfilesMutex.Lock()
|
||||||
for _, p := range ctx.Cache.Profiles {
|
for _, p := range ctx.Cache.Profiles {
|
||||||
var iter gtk.TreeIter
|
var iter gtk.TreeIter
|
||||||
o.profiles_list_store.Append(&iter)
|
o.profiles_list_store.Append(&iter)
|
||||||
o.profiles_list_store.Set(&iter, 0, p.Profile.Name)
|
o.profiles_list_store.Set(&iter, 0, p.Profile.Name)
|
||||||
o.profiles_list_store.Set(&iter, 1, p.Profile.Version)
|
o.profiles_list_store.Set(&iter, 1, p.Profile.Version)
|
||||||
}
|
}
|
||||||
ctx.Cache.ProfilesMutex.Unlock()
|
ctx.Cache.ProfilesMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) saveAppearance() {
|
func (o *OptionsDialog) saveAppearance() {
|
||||||
ctx.Cfg.Cfg["/general/language"] = ctx.Translator.AcceptedLanguages[o.language_combo.GetActiveText()]
|
ctx.Cfg.Cfg["/general/language"] = ctx.Translator.AcceptedLanguages[o.language_combo.GetActiveText()]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) saveGeneral() {
|
func (o *OptionsDialog) saveGeneral() {
|
||||||
if o.show_tray_icon.GetActive() {
|
if o.show_tray_icon.GetActive() {
|
||||||
ctx.Cfg.Cfg["/general/show_tray_icon"] = "1"
|
ctx.Cfg.Cfg["/general/show_tray_icon"] = "1"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cfg.Cfg["/general/show_tray_icon"] = "0"
|
ctx.Cfg.Cfg["/general/show_tray_icon"] = "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.autoupdate.GetActive() {
|
if o.autoupdate.GetActive() {
|
||||||
ctx.Cfg.Cfg["/general/urtrator_autoupdate"] = "1"
|
ctx.Cfg.Cfg["/general/urtrator_autoupdate"] = "1"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cfg.Cfg["/general/urtrator_autoupdate"] = "0"
|
ctx.Cfg.Cfg["/general/urtrator_autoupdate"] = "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Servers updating tab.
|
// Servers updating tab.
|
||||||
master_server_addr := o.master_server_addr.GetText()
|
master_server_addr := o.master_server_addr.GetText()
|
||||||
if len(master_server_addr) < 1 {
|
if len(master_server_addr) < 1 {
|
||||||
ctx.Cfg.Cfg["/servers_updating/master_server"] = "master.urbanterror.info:27900"
|
ctx.Cfg.Cfg["/servers_updating/master_server"] = "master.urbanterror.info:27900"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cfg.Cfg["/servers_updating/master_server"] = master_server_addr
|
ctx.Cfg.Cfg["/servers_updating/master_server"] = master_server_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.servers_autoupdate.GetActive() {
|
if o.servers_autoupdate.GetActive() {
|
||||||
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"] = "1"
|
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"] = "1"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"] = "0"
|
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate"] = "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
update_timeout := o.servers_autoupdate_timeout.GetText()
|
update_timeout := o.servers_autoupdate_timeout.GetText()
|
||||||
if len(update_timeout) < 1 {
|
if len(update_timeout) < 1 {
|
||||||
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"] = "10"
|
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"] = "10"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"] = update_timeout
|
ctx.Cfg.Cfg["/servers_updating/servers_autoupdate_timeout"] = update_timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Eventer.LaunchEvent("initializeTasksForMainWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("initializeTasksForMainWindow", map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OptionsDialog) ShowOptionsDialog() {
|
func (o *OptionsDialog) ShowOptionsDialog() {
|
||||||
o.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
o.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||||
o.window.SetTitle(ctx.Translator.Translate("URTrator - Options", nil))
|
o.window.SetTitle(ctx.Translator.Translate("URTrator - Options", nil))
|
||||||
o.window.Connect("destroy", o.closeOptionsDialogWithDiscard)
|
o.window.Connect("destroy", o.closeOptionsDialogWithDiscard)
|
||||||
o.window.SetModal(true)
|
o.window.SetModal(true)
|
||||||
o.window.SetSizeRequest(750, 600)
|
o.window.SetSizeRequest(750, 600)
|
||||||
o.window.SetPosition(gtk.WIN_POS_CENTER)
|
o.window.SetPosition(gtk.WIN_POS_CENTER)
|
||||||
o.window.SetIcon(logo)
|
o.window.SetIcon(logo)
|
||||||
|
|
||||||
o.vbox = gtk.NewVBox(false, 0)
|
o.vbox = gtk.NewVBox(false, 0)
|
||||||
|
|
||||||
o.initializeTabs()
|
o.initializeTabs()
|
||||||
o.fill()
|
o.fill()
|
||||||
|
|
||||||
o.window.Add(o.vbox)
|
o.window.Add(o.vbox)
|
||||||
|
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
|
|
||||||
o.window.ShowAll()
|
o.window.ShowAll()
|
||||||
}
|
}
|
||||||
|
@ -10,391 +10,390 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/datamodels"
|
"gitlab.com/pztrn/urtrator/datamodels"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
//"github.com/mattn/go-gtk/glib"
|
//"github.com/mattn/go-gtk/glib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OptionsProfile struct {
|
type OptionsProfile struct {
|
||||||
// Window.
|
// Window.
|
||||||
window *gtk.Window
|
window *gtk.Window
|
||||||
// Main table.
|
// Main table.
|
||||||
table *gtk.Table
|
table *gtk.Table
|
||||||
// Profile name.
|
// Profile name.
|
||||||
profile_name *gtk.Entry
|
profile_name *gtk.Entry
|
||||||
// Binary path.
|
// Binary path.
|
||||||
binary_path *gtk.Entry
|
binary_path *gtk.Entry
|
||||||
// Profile directory path.
|
// Profile directory path.
|
||||||
profile_path *gtk.Entry
|
profile_path *gtk.Entry
|
||||||
// Urban Terror versions combobox
|
// Urban Terror versions combobox
|
||||||
urt_version_combo *gtk.ComboBoxText
|
urt_version_combo *gtk.ComboBoxText
|
||||||
// Another X session?
|
// Another X session?
|
||||||
another_x_session *gtk.CheckButton
|
another_x_session *gtk.CheckButton
|
||||||
// Additional parameters for game launching.
|
// Additional parameters for game launching.
|
||||||
additional_parameters *gtk.Entry
|
additional_parameters *gtk.Entry
|
||||||
|
|
||||||
// File chooser dialog for selecting binary.
|
// File chooser dialog for selecting binary.
|
||||||
f *gtk.FileChooserDialog
|
f *gtk.FileChooserDialog
|
||||||
// Profile directory chooser dialog.
|
// Profile directory chooser dialog.
|
||||||
p *gtk.FileChooserDialog
|
p *gtk.FileChooserDialog
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
// This is profile update?
|
// This is profile update?
|
||||||
update bool
|
update bool
|
||||||
|
|
||||||
// Others.
|
// Others.
|
||||||
// Old profile, needed for proper update.
|
// Old profile, needed for proper update.
|
||||||
old_profile *datamodels.Profile
|
old_profile *datamodels.Profile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) browseForBinary() {
|
func (op *OptionsProfile) browseForBinary() {
|
||||||
op.f = gtk.NewFileChooserDialog(ctx.Translator.Translate("URTrator - Select Urban Terror binary", nil), op.window, gtk.FILE_CHOOSER_ACTION_OPEN, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
|
op.f = gtk.NewFileChooserDialog(ctx.Translator.Translate("URTrator - Select Urban Terror binary", nil), op.window, gtk.FILE_CHOOSER_ACTION_OPEN, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
|
||||||
op.f.Response(op.browseForBinaryHelper)
|
op.f.Response(op.browseForBinaryHelper)
|
||||||
op.f.Run()
|
op.f.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) browseForProfile() {
|
func (op *OptionsProfile) browseForProfile() {
|
||||||
op.p = gtk.NewFileChooserDialog(ctx.Translator.Translate("URTrator - Select Urban Terror profile path", nil), op.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
|
op.p = gtk.NewFileChooserDialog(ctx.Translator.Translate("URTrator - Select Urban Terror profile path", nil), op.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
|
||||||
op.p.Response(op.browseForProfileHelper)
|
op.p.Response(op.browseForProfileHelper)
|
||||||
if op.profile_path.GetText() != "" {
|
if op.profile_path.GetText() != "" {
|
||||||
op.p.SetCurrentFolder(op.profile_path.GetText())
|
op.p.SetCurrentFolder(op.profile_path.GetText())
|
||||||
}
|
}
|
||||||
op.p.Run()
|
op.p.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) browseForBinaryHelper() {
|
func (op *OptionsProfile) browseForBinaryHelper() {
|
||||||
filename := op.f.GetFilename()
|
filename := op.f.GetFilename()
|
||||||
op.binary_path.SetText(filename)
|
op.binary_path.SetText(filename)
|
||||||
op.f.Destroy()
|
op.f.Destroy()
|
||||||
fmt.Println(filename)
|
fmt.Println(filename)
|
||||||
|
|
||||||
// Check for valid filename.
|
// Check for valid filename.
|
||||||
// ToDo: add more OSes.
|
// ToDo: add more OSes.
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
// Filename should end with approriate arch.
|
// Filename should end with approriate arch.
|
||||||
if runtime.GOARCH == "amd64" {
|
if runtime.GOARCH == "amd64" {
|
||||||
if len(filename) > 0 && strings.Split(filename, ".")[1] != "x86_64" && strings.Split(filename, ".")[0] != "Quake3-UrT" {
|
if len(filename) > 0 && strings.Split(filename, ".")[1] != "x86_64" && strings.Split(filename, ".")[0] != "Quake3-UrT" {
|
||||||
fmt.Println("Invalid binary selected!")
|
fmt.Println("Invalid binary selected!")
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.x86_64."
|
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.x86_64."
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
op.binary_path.SetText("")
|
op.binary_path.SetText("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if runtime.GOOS == "darwin" {
|
} else if runtime.GOOS == "darwin" {
|
||||||
// Official application: Quake3-UrT.app. Split by it and get second
|
// Official application: Quake3-UrT.app. Split by it and get second
|
||||||
// part of string.
|
// part of string.
|
||||||
if strings.Contains(filename, "Quake3-UrT.app") {
|
if strings.Contains(filename, "Quake3-UrT.app") {
|
||||||
filename = strings.Split(filename, "Quake3-UrT.app")[1]
|
filename = strings.Split(filename, "Quake3-UrT.app")[1]
|
||||||
if len(filename) > 0 && !strings.Contains(strings.Split(filename, ".")[1], "x86_64") && !strings.Contains(strings.Split(filename, ".")[0], "Quake3-UrT") {
|
if len(filename) > 0 && !strings.Contains(strings.Split(filename, ".")[1], "x86_64") && !strings.Contains(strings.Split(filename, ".")[0], "Quake3-UrT") {
|
||||||
fmt.Println("Invalid binary selected!")
|
fmt.Println("Invalid binary selected!")
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64."
|
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64."
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
op.binary_path.SetText("")
|
op.binary_path.SetText("")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Temporary disable all these modals on Linux.
|
// Temporary disable all these modals on Linux.
|
||||||
// See https://github.com/mattn/go-gtk/issues/289.
|
// See https://github.com/mattn/go-gtk/issues/289.
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64.\n\n" + ctx.Translator.Translate("Note, that currently URTrator supports only official binary.", nil)
|
mbox_string := ctx.Translator.Translate("Invalid binary selected!\nAccording to your OS, it should be", nil) + " Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64.\n\n" + ctx.Translator.Translate("Note, that currently URTrator supports only official binary.", nil)
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if op.profile_path.GetText() == "" {
|
if op.profile_path.GetText() == "" {
|
||||||
op.profile_path.SetText(ctx.Cfg.TEMP["DEFAULT_PROFILE_PATH"])
|
op.profile_path.SetText(ctx.Cfg.TEMP["DEFAULT_PROFILE_PATH"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) browseForProfileHelper() {
|
func (op *OptionsProfile) browseForProfileHelper() {
|
||||||
directory := op.p.GetFilename()
|
directory := op.p.GetFilename()
|
||||||
op.profile_path.SetText(directory)
|
op.profile_path.SetText(directory)
|
||||||
op.p.Destroy()
|
op.p.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) closeByCancel() {
|
func (op *OptionsProfile) closeByCancel() {
|
||||||
op.window.Destroy()
|
op.window.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) closeWithDiscard() {
|
func (op *OptionsProfile) closeWithDiscard() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) Initialize(update bool) {
|
func (op *OptionsProfile) Initialize(update bool) {
|
||||||
if update {
|
if update {
|
||||||
op.update = true
|
op.update = true
|
||||||
}
|
}
|
||||||
|
|
||||||
op.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
op.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||||
if update {
|
if update {
|
||||||
op.window.SetTitle(ctx.Translator.Translate("URTrator - Update Urban Terror profile", nil))
|
op.window.SetTitle(ctx.Translator.Translate("URTrator - Update Urban Terror profile", nil))
|
||||||
} else {
|
} else {
|
||||||
op.window.SetTitle(ctx.Translator.Translate("URTrator - Add Urban Terror profile", nil))
|
op.window.SetTitle(ctx.Translator.Translate("URTrator - Add Urban Terror profile", nil))
|
||||||
}
|
}
|
||||||
op.window.Connect("destroy", op.closeWithDiscard)
|
op.window.Connect("destroy", op.closeWithDiscard)
|
||||||
op.window.SetModal(true)
|
op.window.SetModal(true)
|
||||||
op.window.SetSizeRequest(550, 400)
|
op.window.SetSizeRequest(550, 400)
|
||||||
op.window.SetPosition(gtk.WIN_POS_CENTER)
|
op.window.SetPosition(gtk.WIN_POS_CENTER)
|
||||||
op.window.SetIcon(logo)
|
op.window.SetIcon(logo)
|
||||||
|
|
||||||
op.table = gtk.NewTable(7, 2, false)
|
op.table = gtk.NewTable(7, 2, false)
|
||||||
op.table.SetRowSpacings(2)
|
op.table.SetRowSpacings(2)
|
||||||
|
|
||||||
// Profile name.
|
// Profile name.
|
||||||
profile_name_tooltip := ctx.Translator.Translate("This how you will see profile on profiles lists.", nil)
|
profile_name_tooltip := ctx.Translator.Translate("This how you will see profile on profiles lists.", nil)
|
||||||
pn_label := gtk.NewLabel(ctx.Translator.Translate("Profile name:", nil))
|
pn_label := gtk.NewLabel(ctx.Translator.Translate("Profile name:", nil))
|
||||||
pn_label.SetTooltipText(profile_name_tooltip)
|
pn_label.SetTooltipText(profile_name_tooltip)
|
||||||
pn_label.SetAlignment(0, 0)
|
pn_label.SetAlignment(0, 0)
|
||||||
op.table.Attach(pn_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
op.table.Attach(pn_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
op.profile_name = gtk.NewEntry()
|
op.profile_name = gtk.NewEntry()
|
||||||
op.profile_name.SetTooltipText(profile_name_tooltip)
|
op.profile_name.SetTooltipText(profile_name_tooltip)
|
||||||
op.table.Attach(op.profile_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
op.table.Attach(op.profile_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
|
// Urban Terror version.
|
||||||
|
urt_version_tooltip := ctx.Translator.Translate("Urban Terror version for which this profile applies.", nil)
|
||||||
|
urt_version_label := gtk.NewLabel(ctx.Translator.Translate("Urban Terror version:", nil))
|
||||||
|
urt_version_label.SetTooltipText(urt_version_tooltip)
|
||||||
|
urt_version_label.SetAlignment(0, 0)
|
||||||
|
op.table.Attach(urt_version_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
// Urban Terror version.
|
op.urt_version_combo = gtk.NewComboBoxText()
|
||||||
urt_version_tooltip := ctx.Translator.Translate("Urban Terror version for which this profile applies.", nil)
|
op.urt_version_combo.SetTooltipText(urt_version_tooltip)
|
||||||
urt_version_label := gtk.NewLabel(ctx.Translator.Translate("Urban Terror version:", nil))
|
op.urt_version_combo.AppendText("4.2.023")
|
||||||
urt_version_label.SetTooltipText(urt_version_tooltip)
|
op.urt_version_combo.AppendText("4.3.1")
|
||||||
urt_version_label.SetAlignment(0, 0)
|
op.urt_version_combo.AppendText("4.3.2")
|
||||||
op.table.Attach(urt_version_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
|
op.urt_version_combo.SetActive(2)
|
||||||
|
op.table.Attach(op.urt_version_combo, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
op.urt_version_combo = gtk.NewComboBoxText()
|
// Urban Terror binary path.
|
||||||
op.urt_version_combo.SetTooltipText(urt_version_tooltip)
|
select_binary_tooltip := ctx.Translator.Translate("Urban Terror binary. Some checks will be executed, so make sure you have selected right binary:\n\nQuake3-UrT.i386 for linux-x86\nQuake3-UrT.x86_64 for linux-amd64\nQuake3-UrT.app for macOS", nil)
|
||||||
op.urt_version_combo.AppendText("4.2.023")
|
binpath_hbox := gtk.NewHBox(false, 0)
|
||||||
op.urt_version_combo.AppendText("4.3.1")
|
binpath_label := gtk.NewLabel(ctx.Translator.Translate("Urban Terror binary:", nil))
|
||||||
op.urt_version_combo.AppendText("4.3.2")
|
binpath_label.SetTooltipText(select_binary_tooltip)
|
||||||
op.urt_version_combo.SetActive(2)
|
binpath_label.SetAlignment(0, 0)
|
||||||
op.table.Attach(op.urt_version_combo, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
|
op.table.Attach(binpath_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
// Urban Terror binary path.
|
op.binary_path = gtk.NewEntry()
|
||||||
select_binary_tooltip := ctx.Translator.Translate("Urban Terror binary. Some checks will be executed, so make sure you have selected right binary:\n\nQuake3-UrT.i386 for linux-x86\nQuake3-UrT.x86_64 for linux-amd64\nQuake3-UrT.app for macOS", nil)
|
op.binary_path.SetTooltipText(select_binary_tooltip)
|
||||||
binpath_hbox := gtk.NewHBox(false, 0)
|
button_select_binary := gtk.NewButtonWithLabel(ctx.Translator.Translate("Browse", nil))
|
||||||
binpath_label := gtk.NewLabel(ctx.Translator.Translate("Urban Terror binary:", nil))
|
button_select_binary.SetTooltipText(select_binary_tooltip)
|
||||||
binpath_label.SetTooltipText(select_binary_tooltip)
|
button_select_binary.Clicked(op.browseForBinary)
|
||||||
binpath_label.SetAlignment(0, 0)
|
binpath_hbox.PackStart(op.binary_path, true, true, 5)
|
||||||
op.table.Attach(binpath_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
|
binpath_hbox.PackStart(button_select_binary, false, true, 5)
|
||||||
|
op.table.Attach(binpath_hbox, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0)
|
||||||
|
|
||||||
op.binary_path = gtk.NewEntry()
|
// Path to Urban Terror's profile directory.
|
||||||
op.binary_path.SetTooltipText(select_binary_tooltip)
|
// Should be in user's home directory automatically, but can be
|
||||||
button_select_binary := gtk.NewButtonWithLabel(ctx.Translator.Translate("Browse", nil))
|
// changed :).
|
||||||
button_select_binary.SetTooltipText(select_binary_tooltip)
|
select_profile_path_tooltip := ctx.Translator.Translate("Urban Terror profile path.\n\nSpecify directory where configs, demos\nand downloaded maps are located.\n\nDefault: $HOME/.q3ut4", nil)
|
||||||
button_select_binary.Clicked(op.browseForBinary)
|
profile_path_hbox := gtk.NewHBox(false, 0)
|
||||||
binpath_hbox.PackStart(op.binary_path, true, true, 5)
|
profile_path_label := gtk.NewLabel(ctx.Translator.Translate("Profile path:", nil))
|
||||||
binpath_hbox.PackStart(button_select_binary, false, true, 5)
|
profile_path_label.SetTooltipText(select_profile_path_tooltip)
|
||||||
op.table.Attach(binpath_hbox, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0)
|
profile_path_label.SetAlignment(0, 0)
|
||||||
|
op.table.Attach(profile_path_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
|
|
||||||
// Path to Urban Terror's profile directory.
|
op.profile_path = gtk.NewEntry()
|
||||||
// Should be in user's home directory automatically, but can be
|
op.profile_path.SetTooltipText(select_profile_path_tooltip)
|
||||||
// changed :).
|
button_select_path := gtk.NewButtonWithLabel(ctx.Translator.Translate("Browse", nil))
|
||||||
select_profile_path_tooltip := ctx.Translator.Translate("Urban Terror profile path.\n\nSpecify directory where configs, demos\nand downloaded maps are located.\n\nDefault: $HOME/.q3ut4", nil)
|
button_select_path.SetTooltipText(select_profile_path_tooltip)
|
||||||
profile_path_hbox := gtk.NewHBox(false, 0)
|
button_select_path.Clicked(op.browseForProfile)
|
||||||
profile_path_label := gtk.NewLabel(ctx.Translator.Translate("Profile path:", nil))
|
profile_path_hbox.PackStart(op.profile_path, true, true, 5)
|
||||||
profile_path_label.SetTooltipText(select_profile_path_tooltip)
|
profile_path_hbox.PackStart(button_select_path, false, true, 5)
|
||||||
profile_path_label.SetAlignment(0, 0)
|
op.table.Attach(profile_path_hbox, 1, 2, 3, 4, gtk.FILL, gtk.FILL, 0, 0)
|
||||||
op.table.Attach(profile_path_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
|
|
||||||
|
|
||||||
op.profile_path = gtk.NewEntry()
|
// Should we use additional X session?
|
||||||
op.profile_path.SetTooltipText(select_profile_path_tooltip)
|
another_x_tooltip := ctx.Translator.Translate("If this is checked, Urban Terror will be launched in another X session.\n\nThis could help if you're experiencing visual lag, glitches and FPS drops under compositing WMs, like Mutter and KWin.", nil)
|
||||||
button_select_path := gtk.NewButtonWithLabel(ctx.Translator.Translate("Browse", nil))
|
another_x_label := gtk.NewLabel(ctx.Translator.Translate("Start Urban Terror in another X session?", nil))
|
||||||
button_select_path.SetTooltipText(select_profile_path_tooltip)
|
another_x_label.SetTooltipText(another_x_tooltip)
|
||||||
button_select_path.Clicked(op.browseForProfile)
|
another_x_label.SetAlignment(0, 0)
|
||||||
profile_path_hbox.PackStart(op.profile_path, true, true, 5)
|
op.table.Attach(another_x_label, 0, 1, 4, 5, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
profile_path_hbox.PackStart(button_select_path, false, true, 5)
|
op.another_x_session = gtk.NewCheckButtonWithLabel("")
|
||||||
op.table.Attach(profile_path_hbox, 1, 2, 3, 4, gtk.FILL, gtk.FILL, 0, 0)
|
op.another_x_session.SetTooltipText(another_x_tooltip)
|
||||||
|
// macOS and Windows can't do that :).
|
||||||
|
if runtime.GOOS != "linux" {
|
||||||
|
op.another_x_session.SetSensitive(false)
|
||||||
|
}
|
||||||
|
op.table.Attach(op.another_x_session, 1, 2, 4, 5, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Should we use additional X session?
|
// Additional game parameters.
|
||||||
another_x_tooltip := ctx.Translator.Translate("If this is checked, Urban Terror will be launched in another X session.\n\nThis could help if you're experiencing visual lag, glitches and FPS drops under compositing WMs, like Mutter and KWin.", nil)
|
params_tooltip := ctx.Translator.Translate("Additional parameters that will be passed to Urban Terror executable.", nil)
|
||||||
another_x_label := gtk.NewLabel(ctx.Translator.Translate("Start Urban Terror in another X session?", nil))
|
params_label := gtk.NewLabel(ctx.Translator.Translate("Additional parameters:", nil))
|
||||||
another_x_label.SetTooltipText(another_x_tooltip)
|
params_label.SetTooltipText(params_tooltip)
|
||||||
another_x_label.SetAlignment(0, 0)
|
params_label.SetAlignment(0, 0)
|
||||||
op.table.Attach(another_x_label, 0, 1, 4, 5, gtk.FILL, gtk.SHRINK, 5, 5)
|
op.table.Attach(params_label, 0, 1, 5, 6, gtk.FILL, gtk.SHRINK, 5, 5)
|
||||||
op.another_x_session = gtk.NewCheckButtonWithLabel("")
|
|
||||||
op.another_x_session.SetTooltipText(another_x_tooltip)
|
|
||||||
// macOS and Windows can't do that :).
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
op.another_x_session.SetSensitive(false)
|
|
||||||
}
|
|
||||||
op.table.Attach(op.another_x_session, 1, 2, 4, 5, gtk.FILL, gtk.FILL, 5, 5)
|
|
||||||
|
|
||||||
// Additional game parameters.
|
op.additional_parameters = gtk.NewEntry()
|
||||||
params_tooltip := ctx.Translator.Translate("Additional parameters that will be passed to Urban Terror executable.", nil)
|
op.additional_parameters.SetTooltipText(params_tooltip)
|
||||||
params_label := gtk.NewLabel(ctx.Translator.Translate("Additional parameters:", nil))
|
op.table.Attach(op.additional_parameters, 1, 2, 5, 6, gtk.FILL, gtk.FILL, 5, 5)
|
||||||
params_label.SetTooltipText(params_tooltip)
|
|
||||||
params_label.SetAlignment(0, 0)
|
|
||||||
op.table.Attach(params_label, 0, 1, 5, 6, gtk.FILL, gtk.SHRINK, 5, 5)
|
|
||||||
|
|
||||||
op.additional_parameters = gtk.NewEntry()
|
// Invisible thing.
|
||||||
op.additional_parameters.SetTooltipText(params_tooltip)
|
inv_label := gtk.NewLabel("")
|
||||||
op.table.Attach(op.additional_parameters, 1, 2, 5, 6, gtk.FILL, gtk.FILL, 5, 5)
|
op.table.Attach(inv_label, 1, 2, 6, 7, gtk.EXPAND, gtk.FILL, 5, 5)
|
||||||
|
|
||||||
// Invisible thing.
|
// The buttons.
|
||||||
inv_label := gtk.NewLabel("")
|
buttons_box := gtk.NewHBox(false, 0)
|
||||||
op.table.Attach(inv_label, 1, 2, 6, 7, gtk.EXPAND, gtk.FILL, 5, 5)
|
buttons_sep := gtk.NewHBox(false, 0)
|
||||||
|
|
||||||
// The buttons.
|
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
||||||
buttons_box := gtk.NewHBox(false, 0)
|
cancel_button.SetTooltipText(ctx.Translator.Translate("Close without saving", nil))
|
||||||
buttons_sep := gtk.NewHBox(false, 0)
|
cancel_button.Clicked(op.closeByCancel)
|
||||||
|
buttons_box.PackStart(cancel_button, false, true, 5)
|
||||||
|
|
||||||
cancel_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Cancel", nil))
|
buttons_box.PackStart(buttons_sep, true, true, 5)
|
||||||
cancel_button.SetTooltipText(ctx.Translator.Translate("Close without saving", nil))
|
|
||||||
cancel_button.Clicked(op.closeByCancel)
|
|
||||||
buttons_box.PackStart(cancel_button, false, true, 5)
|
|
||||||
|
|
||||||
buttons_box.PackStart(buttons_sep, true, true, 5)
|
add_button := gtk.NewButton()
|
||||||
|
if op.update {
|
||||||
|
add_button.SetLabel(ctx.Translator.Translate("Update", nil))
|
||||||
|
add_button.SetTooltipText(ctx.Translator.Translate("Update profile", nil))
|
||||||
|
} else {
|
||||||
|
add_button.SetLabel(ctx.Translator.Translate("Add", nil))
|
||||||
|
add_button.SetTooltipText(ctx.Translator.Translate("Add profile", nil))
|
||||||
|
}
|
||||||
|
add_button.Clicked(op.saveProfile)
|
||||||
|
buttons_box.PackStart(add_button, false, true, 5)
|
||||||
|
|
||||||
add_button := gtk.NewButton()
|
vert_sep_box := gtk.NewVBox(false, 0)
|
||||||
if op.update {
|
|
||||||
add_button.SetLabel(ctx.Translator.Translate("Update", nil))
|
|
||||||
add_button.SetTooltipText(ctx.Translator.Translate("Update profile", nil))
|
|
||||||
} else {
|
|
||||||
add_button.SetLabel(ctx.Translator.Translate("Add", nil))
|
|
||||||
add_button.SetTooltipText(ctx.Translator.Translate("Add profile", nil))
|
|
||||||
}
|
|
||||||
add_button.Clicked(op.saveProfile)
|
|
||||||
buttons_box.PackStart(add_button, false, true, 5)
|
|
||||||
|
|
||||||
vert_sep_box := gtk.NewVBox(false, 0)
|
vbox := gtk.NewVBox(false, 0)
|
||||||
|
vbox.PackStart(op.table, false, true, 5)
|
||||||
|
vbox.PackStart(vert_sep_box, true, true, 5)
|
||||||
|
vbox.PackStart(buttons_box, false, true, 5)
|
||||||
|
|
||||||
vbox := gtk.NewVBox(false, 0)
|
op.window.Add(vbox)
|
||||||
vbox.PackStart(op.table, false, true, 5)
|
op.window.ShowAll()
|
||||||
vbox.PackStart(vert_sep_box, true, true, 5)
|
|
||||||
vbox.PackStart(buttons_box, false, true, 5)
|
|
||||||
|
|
||||||
op.window.Add(vbox)
|
|
||||||
op.window.ShowAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) InitializeUpdate(profile_name string) {
|
func (op *OptionsProfile) InitializeUpdate(profile_name string) {
|
||||||
fmt.Println("Updating profile '" + profile_name + "'")
|
fmt.Println("Updating profile '" + profile_name + "'")
|
||||||
op.Initialize(true)
|
op.Initialize(true)
|
||||||
|
|
||||||
// Get profile data.
|
// Get profile data.
|
||||||
profile := ctx.Cache.Profiles[profile_name].Profile
|
profile := ctx.Cache.Profiles[profile_name].Profile
|
||||||
op.profile_name.SetText(profile.Name)
|
op.profile_name.SetText(profile.Name)
|
||||||
op.binary_path.SetText(profile.Binary)
|
op.binary_path.SetText(profile.Binary)
|
||||||
op.additional_parameters.SetText(profile.Additional_params)
|
op.additional_parameters.SetText(profile.Additional_params)
|
||||||
if profile.Profile_path == "" {
|
if profile.Profile_path == "" {
|
||||||
op.profile_path.SetText(ctx.Cfg.TEMP["DEFAULT_PROFILE_PATH"])
|
op.profile_path.SetText(ctx.Cfg.TEMP["DEFAULT_PROFILE_PATH"])
|
||||||
} else {
|
} else {
|
||||||
op.profile_path.SetText(profile.Profile_path)
|
op.profile_path.SetText(profile.Profile_path)
|
||||||
}
|
}
|
||||||
if profile.Second_x_session == "1" {
|
if profile.Second_x_session == "1" {
|
||||||
op.another_x_session.SetActive(true)
|
op.another_x_session.SetActive(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if profile.Version == "4.3.1" {
|
if profile.Version == "4.3.1" {
|
||||||
op.urt_version_combo.SetActive(1)
|
op.urt_version_combo.SetActive(1)
|
||||||
} else if profile.Version == "4.3.2" {
|
} else if profile.Version == "4.3.2" {
|
||||||
op.urt_version_combo.SetActive(2)
|
op.urt_version_combo.SetActive(2)
|
||||||
} else {
|
} else {
|
||||||
op.urt_version_combo.SetActive(0)
|
op.urt_version_combo.SetActive(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
op.old_profile = profile
|
op.old_profile = profile
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *OptionsProfile) saveProfile() {
|
func (op *OptionsProfile) saveProfile() {
|
||||||
fmt.Println("Saving profile...")
|
fmt.Println("Saving profile...")
|
||||||
|
|
||||||
// Validating fields.
|
// Validating fields.
|
||||||
// Profile name must not be empty.
|
// Profile name must not be empty.
|
||||||
if len(op.profile_name.GetText()) < 1 {
|
if len(op.profile_name.GetText()) < 1 {
|
||||||
mbox_string := ctx.Translator.Translate("Empty profile name!\nProfile must be named somehow.", nil)
|
mbox_string := ctx.Translator.Translate("Empty profile name!\nProfile must be named somehow.", nil)
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
// Binary path must also be filled.
|
// Binary path must also be filled.
|
||||||
if len(op.binary_path.GetText()) < 1 {
|
if len(op.binary_path.GetText()) < 1 {
|
||||||
mbox_string := ctx.Translator.Translate("Empty path to binary!\nThis profile will be unusable if you\nwill not provide path to binary!", nil)
|
mbox_string := ctx.Translator.Translate("Empty path to binary!\nThis profile will be unusable if you\nwill not provide path to binary!", nil)
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
// ...and must be executable! :)
|
// ...and must be executable! :)
|
||||||
_, err := os.Stat(op.binary_path.GetText())
|
_, err := os.Stat(op.binary_path.GetText())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mbox_string := ctx.Translator.Translate("Invalid path to binary!\n\nError was:\n", nil) + err.Error() + ctx.Translator.Translate("\n\nCheck binary path and try again.", nil)
|
mbox_string := ctx.Translator.Translate("Invalid path to binary!\n\nError was:\n", nil) + err.Error() + ctx.Translator.Translate("\n\nCheck binary path and try again.", nil)
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
} else {
|
} else {
|
||||||
// ToDo: executable flag checking.
|
// ToDo: executable flag checking.
|
||||||
//fmt.Println(filestat.Mode())
|
//fmt.Println(filestat.Mode())
|
||||||
profile_name := op.profile_name.GetText()
|
profile_name := op.profile_name.GetText()
|
||||||
|
|
||||||
_, ok := ctx.Cache.Profiles[profile_name]
|
_, ok := ctx.Cache.Profiles[profile_name]
|
||||||
if ok && !op.update {
|
if ok && !op.update {
|
||||||
mbox_string := ctx.Translator.Translate("Game profile with same name already exist.\nRename profile for saving.", nil)
|
mbox_string := ctx.Translator.Translate("Game profile with same name already exist.\nRename profile for saving.", nil)
|
||||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||||
m.Response(func() {
|
m.Response(func() {
|
||||||
m.Destroy()
|
m.Destroy()
|
||||||
})
|
})
|
||||||
m.Run()
|
m.Run()
|
||||||
} else {
|
} else {
|
||||||
ctx.Cache.CreateProfile(profile_name)
|
ctx.Cache.CreateProfile(profile_name)
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Name = 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.Version = op.urt_version_combo.GetActiveText()
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Binary = op.binary_path.GetText()
|
ctx.Cache.Profiles[profile_name].Profile.Binary = op.binary_path.GetText()
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Additional_params = op.additional_parameters.GetText()
|
ctx.Cache.Profiles[profile_name].Profile.Additional_params = op.additional_parameters.GetText()
|
||||||
|
|
||||||
if op.profile_path.GetText() == "" {
|
if op.profile_path.GetText() == "" {
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Profile_path = "~/.q3ut4"
|
ctx.Cache.Profiles[profile_name].Profile.Profile_path = "~/.q3ut4"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Profile_path = op.profile_path.GetText()
|
ctx.Cache.Profiles[profile_name].Profile.Profile_path = op.profile_path.GetText()
|
||||||
}
|
}
|
||||||
|
|
||||||
if op.another_x_session.GetActive() {
|
if op.another_x_session.GetActive() {
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "1"
|
ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "1"
|
||||||
} else {
|
} else {
|
||||||
ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "0"
|
ctx.Cache.Profiles[profile_name].Profile.Second_x_session = "0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Eventer.LaunchEvent("flushProfiles", nil)
|
ctx.Eventer.LaunchEvent("flushProfiles", nil)
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoOptionsWindow", map[string]string{})
|
||||||
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
ctx.Eventer.LaunchEvent("loadProfilesIntoMainWindow", map[string]string{})
|
||||||
op.window.Destroy()
|
op.window.Destroy()
|
||||||
}
|
}
|
||||||
|
@ -10,95 +10,95 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
"github.com/pztrn/urtrator/ioq3dataparser"
|
"gitlab.com/pztrn/urtrator/ioq3dataparser"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
"github.com/mattn/go-gtk/gtk"
|
"github.com/mattn/go-gtk/glib"
|
||||||
"github.com/mattn/go-gtk/glib"
|
"github.com/mattn/go-gtk/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerCVarsDialog struct {
|
type ServerCVarsDialog struct {
|
||||||
// Window.
|
// Window.
|
||||||
window *gtk.Window
|
window *gtk.Window
|
||||||
// Main Vertical Box.
|
// Main Vertical Box.
|
||||||
vbox *gtk.VBox
|
vbox *gtk.VBox
|
||||||
// Treeview for CVars.
|
// Treeview for CVars.
|
||||||
treeview *gtk.TreeView
|
treeview *gtk.TreeView
|
||||||
// Store for treeview.
|
// Store for treeview.
|
||||||
treeview_store *gtk.ListStore
|
treeview_store *gtk.ListStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scd *ServerCVarsDialog) Close() {
|
func (scd *ServerCVarsDialog) Close() {
|
||||||
scd.window.Destroy()
|
scd.window.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scd *ServerCVarsDialog) fill(srv_address string) {
|
func (scd *ServerCVarsDialog) fill(srv_address string) {
|
||||||
server_info := ctx.Cache.Servers[srv_address].Server
|
server_info := ctx.Cache.Servers[srv_address].Server
|
||||||
parsed_general_data := ioq3dataparser.ParseInfoToMap(server_info.ExtendedConfig)
|
parsed_general_data := ioq3dataparser.ParseInfoToMap(server_info.ExtendedConfig)
|
||||||
|
|
||||||
// Sort it!
|
// Sort it!
|
||||||
general_data_keys := make([]string, 0, len(parsed_general_data))
|
general_data_keys := make([]string, 0, len(parsed_general_data))
|
||||||
for k := range parsed_general_data {
|
for k := range parsed_general_data {
|
||||||
general_data_keys = append(general_data_keys, k)
|
general_data_keys = append(general_data_keys, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(general_data_keys)
|
sort.Strings(general_data_keys)
|
||||||
|
|
||||||
for k := range general_data_keys {
|
for k := range general_data_keys {
|
||||||
iter := new(gtk.TreeIter)
|
iter := new(gtk.TreeIter)
|
||||||
scd.treeview_store.Append(iter)
|
scd.treeview_store.Append(iter)
|
||||||
scd.treeview_store.SetValue(iter, 0, general_data_keys[k])
|
scd.treeview_store.SetValue(iter, 0, general_data_keys[k])
|
||||||
scd.treeview_store.SetValue(iter, 1, parsed_general_data[general_data_keys[k]])
|
scd.treeview_store.SetValue(iter, 1, parsed_general_data[general_data_keys[k]])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scd *ServerCVarsDialog) Initialize(w *gtk.Window, srv_address string) {
|
func (scd *ServerCVarsDialog) Initialize(w *gtk.Window, srv_address string) {
|
||||||
fmt.Println("Showing server's CVars...")
|
fmt.Println("Showing server's CVars...")
|
||||||
|
|
||||||
scd.initializeStorages()
|
scd.initializeStorages()
|
||||||
|
|
||||||
scd.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
scd.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||||
scd.window.SetTitle(ctx.Translator.Translate("URTrator - Server CVars", nil))
|
scd.window.SetTitle(ctx.Translator.Translate("URTrator - Server CVars", nil))
|
||||||
scd.window.Connect("destroy", scd.Close)
|
scd.window.Connect("destroy", scd.Close)
|
||||||
scd.window.SetTransientFor(w)
|
scd.window.SetTransientFor(w)
|
||||||
scd.window.SetDefaultSize(300, 400)
|
scd.window.SetDefaultSize(300, 400)
|
||||||
|
|
||||||
scd.vbox = gtk.NewVBox(false, 0)
|
scd.vbox = gtk.NewVBox(false, 0)
|
||||||
scd.window.Add(scd.vbox)
|
scd.window.Add(scd.vbox)
|
||||||
|
|
||||||
// CVars scrolls.
|
// CVars scrolls.
|
||||||
si := gtk.NewScrolledWindow(nil, nil)
|
si := gtk.NewScrolledWindow(nil, nil)
|
||||||
scd.vbox.PackStart(si, true, true, 5)
|
scd.vbox.PackStart(si, true, true, 5)
|
||||||
|
|
||||||
// CVars list.
|
// CVars list.
|
||||||
scd.treeview = gtk.NewTreeView()
|
scd.treeview = gtk.NewTreeView()
|
||||||
scd.treeview.SetModel(scd.treeview_store)
|
scd.treeview.SetModel(scd.treeview_store)
|
||||||
si.Add(scd.treeview)
|
si.Add(scd.treeview)
|
||||||
|
|
||||||
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Key", nil), gtk.NewCellRendererText(), "markup", 0))
|
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Key", nil), gtk.NewCellRendererText(), "markup", 0))
|
||||||
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Value", nil), gtk.NewCellRendererText(), "markup", 1))
|
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes(ctx.Translator.Translate("Value", nil), gtk.NewCellRendererText(), "markup", 1))
|
||||||
|
|
||||||
// Close button.
|
// Close button.
|
||||||
hbox := gtk.NewHBox(false, 0)
|
hbox := gtk.NewHBox(false, 0)
|
||||||
scd.vbox.PackStart(hbox, false, true, 5)
|
scd.vbox.PackStart(hbox, false, true, 5)
|
||||||
|
|
||||||
sep := gtk.NewHBox(false, 0)
|
sep := gtk.NewHBox(false, 0)
|
||||||
hbox.PackStart(sep, true, true, 5)
|
hbox.PackStart(sep, true, true, 5)
|
||||||
|
|
||||||
close_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Close", nil))
|
close_button := gtk.NewButtonWithLabel(ctx.Translator.Translate("Close", nil))
|
||||||
close_button.Clicked(scd.Close)
|
close_button.Clicked(scd.Close)
|
||||||
hbox.PackStart(close_button, false, true, 5)
|
hbox.PackStart(close_button, false, true, 5)
|
||||||
|
|
||||||
scd.fill(srv_address)
|
scd.fill(srv_address)
|
||||||
|
|
||||||
scd.window.ShowAll()
|
scd.window.ShowAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scd *ServerCVarsDialog) initializeStorages() {
|
func (scd *ServerCVarsDialog) initializeStorages() {
|
||||||
scd.treeview_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING)
|
scd.treeview_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING)
|
||||||
}
|
}
|
||||||
|
30
urtrator.go
30
urtrator.go
@ -10,26 +10,26 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"github.com/pztrn/urtrator/common"
|
"gitlab.com/pztrn/urtrator/common"
|
||||||
"github.com/pztrn/urtrator/context"
|
"gitlab.com/pztrn/urtrator/context"
|
||||||
"github.com/pztrn/urtrator/ui/gtk2"
|
"gitlab.com/pztrn/urtrator/ui/gtk2"
|
||||||
//"github.com/pztrn/urtrator/ui/qt5"
|
//"github.com/pztrn/urtrator/ui/qt5"
|
||||||
|
|
||||||
// stdlib
|
// stdlib
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("This is URTrator, version " + common.URTRATOR_VERSION)
|
fmt.Println("This is URTrator, version " + common.URTRATOR_VERSION)
|
||||||
|
|
||||||
numCPUs := runtime.NumCPU()
|
numCPUs := runtime.NumCPU()
|
||||||
runtime.GOMAXPROCS(numCPUs)
|
runtime.GOMAXPROCS(numCPUs)
|
||||||
|
|
||||||
ctx := context.New()
|
ctx := context.New()
|
||||||
ctx.Initialize()
|
ctx.Initialize()
|
||||||
|
|
||||||
ui := ui.NewMainWindow(ctx)
|
ui := ui.NewMainWindow(ctx)
|
||||||
ui.Initialize()
|
ui.Initialize()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user