Favorites and fixes.
Favorites functionality done, except editing favorite server. Note, that game profile defined for favorite server have higher priority on normal profile selected in combobox near "Launch!" button. Later WILL be ignored. Bunch of fixes is added.
This commit is contained in:
parent
d6765501a8
commit
063f6a622a
@ -16,11 +16,14 @@ updating information about them.
|
||||
* Extended Urban Terror launching capabilities (e.g. launching game
|
||||
in another X session).
|
||||
* Supporting of multiple profiles with multiple game versions.
|
||||
When you're launching Urban Terror URTrator will check profile you're
|
||||
trying to use and, if version incompatability found, will not launch
|
||||
the game.
|
||||
* Favorites servers.
|
||||
|
||||
Planning:
|
||||
|
||||
* Updating single server.
|
||||
* Favorites servers.
|
||||
* Showing information about servers (like in UrT Connector).
|
||||
* Friends searching.
|
||||
* RCON console.
|
||||
|
@ -65,12 +65,48 @@ func (d *Database) Migrate() {
|
||||
|
||||
func (d *Database) UpdateServers(data map[string]*datamodels.Server) {
|
||||
fmt.Println("Updating servers information in database...")
|
||||
// ToDo: real update :)
|
||||
d.Db.MustExec("DELETE FROM servers")
|
||||
raw_cached := []datamodels.Server{}
|
||||
d.Db.Select(&raw_cached, "SELECT * FROM servers")
|
||||
|
||||
// Create map[string]*datamodels.Server once, so we won't iterate
|
||||
// over slice of datamodels.Server everytime.
|
||||
cached_servers := make(map[string]*datamodels.Server)
|
||||
for s := range raw_cached {
|
||||
mapping_item_name := raw_cached[s].Ip + ":" + raw_cached[s].Port
|
||||
cached_servers[mapping_item_name] = &raw_cached[s]
|
||||
}
|
||||
|
||||
new_servers := make(map[string]*datamodels.Server)
|
||||
|
||||
// Update our cached mapping.
|
||||
for _, s := range data {
|
||||
mapping_item_name := s.Ip + ":" + s.Port
|
||||
_, ok := cached_servers[mapping_item_name]
|
||||
if !ok {
|
||||
fmt.Println(mapping_item_name + " not found!")
|
||||
new_servers[mapping_item_name] = s
|
||||
} else {
|
||||
cached_servers[mapping_item_name].Ip = s.Ip
|
||||
cached_servers[mapping_item_name].Port = s.Port
|
||||
cached_servers[mapping_item_name].Name = s.Name
|
||||
cached_servers[mapping_item_name].Players = s.Players
|
||||
cached_servers[mapping_item_name].Maxplayers = s.Maxplayers
|
||||
cached_servers[mapping_item_name].Ping = s.Ping
|
||||
cached_servers[mapping_item_name].Map = s.Map
|
||||
cached_servers[mapping_item_name].Gamemode = s.Gamemode
|
||||
}
|
||||
}
|
||||
|
||||
tx := d.Db.MustBegin()
|
||||
for _, srv := range data {
|
||||
fmt.Println("Adding new servers...")
|
||||
for _, srv := range new_servers {
|
||||
tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version)", srv)
|
||||
}
|
||||
fmt.Println("Updating cached servers...")
|
||||
for _, srv := range cached_servers {
|
||||
tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, version=:version WHERE ip=:ip AND port=:port", &srv)
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
fmt.Println("Done")
|
||||
}
|
||||
|
@ -55,6 +55,14 @@ func migrate_full(db *Database, version int) {
|
||||
three_to_four(db)
|
||||
version = 4
|
||||
}
|
||||
if version == 4 {
|
||||
four_to_five(db)
|
||||
version = 5
|
||||
}
|
||||
if version == 5 {
|
||||
five_to_six(db)
|
||||
version = 6
|
||||
}
|
||||
}
|
||||
|
||||
// Initial database structure.
|
||||
@ -84,4 +92,19 @@ func two_to_three(db *Database) {
|
||||
func three_to_four(db *Database) {
|
||||
fmt.Println("Upgrading database from 3 to 4...")
|
||||
db.Db.MustExec("UPDATE urt_profiles SET version='4.3.0' WHERE version='4.3.000'")
|
||||
db.Db.MustExec("UPDATE database SET version=4")
|
||||
}
|
||||
|
||||
// Server's passwords.
|
||||
func four_to_five(db *Database) {
|
||||
fmt.Println("Upgrading database from 4 to 5...")
|
||||
db.Db.MustExec("ALTER TABLE servers ADD password VARCHAR(64) DEFAULT ''")
|
||||
db.Db.MustExec("UPDATE database SET version=5")
|
||||
}
|
||||
|
||||
// Profile for server.
|
||||
func five_to_six(db *Database) {
|
||||
fmt.Println("Upgrading database from 5 to 6...")
|
||||
db.Db.MustExec("ALTER TABLE servers ADD profile_to_use VARCHAR(128) DEFAULT ''")
|
||||
db.Db.MustExec("UPDATE database SET version=6")
|
||||
}
|
||||
|
@ -30,4 +30,8 @@ type Server struct {
|
||||
Version string `db:"version"`
|
||||
// Is server was favorited?
|
||||
Favorite string `db:"favorite"`
|
||||
// Server's password.
|
||||
Password string `db:"password"`
|
||||
// Profile to use with server.
|
||||
ProfileToUse string `db:"profile_to_use"`
|
||||
}
|
||||
|
@ -144,6 +144,12 @@ func (r *Requester) UpdateAllServers(done_chan chan map[string]*datamodels.Serve
|
||||
done_chan <- servers
|
||||
}
|
||||
|
||||
func (r *Requester) UpdateFavoriteServers(servers [][]string, done_chan chan map[string]*datamodels.Server, error_chan chan bool) {
|
||||
fmt.Println("Updating favorites servers...")
|
||||
updated_servers := r.updateServerGoroutineDispatcher(servers)
|
||||
done_chan <- updated_servers
|
||||
}
|
||||
|
||||
func (r *Requester) updateServerGoroutineDispatcher(data [][]string) map[string]*datamodels.Server {
|
||||
var wait sync.WaitGroup
|
||||
var lock = sync.RWMutex{}
|
||||
|
223
ui/favorite.go
Normal file
223
ui/favorite.go
Normal file
@ -0,0 +1,223 @@
|
||||
// URTator - Urban Terror server browser and game launcher, written in
|
||||
// Go.
|
||||
//
|
||||
// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n)
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under Terms and Conditions of GNU General Public License
|
||||
// version 3 or any higher.
|
||||
// ToDo: put full text of license here.
|
||||
package ui
|
||||
|
||||
import (
|
||||
// stdlib
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
// Local
|
||||
"github.com/pztrn/urtrator/common"
|
||||
"github.com/pztrn/urtrator/datamodels"
|
||||
|
||||
// Other
|
||||
"github.com/mattn/go-gtk/gdkpixbuf"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
)
|
||||
|
||||
type FavoriteDialog struct {
|
||||
// Widgets.
|
||||
// Dialog's window.
|
||||
window *gtk.Window
|
||||
// Main vertical box.
|
||||
vbox *gtk.VBox
|
||||
// Server name.
|
||||
server_name *gtk.Entry
|
||||
// Server address.
|
||||
server_address *gtk.Entry
|
||||
// Server password
|
||||
server_password *gtk.Entry
|
||||
// Profile.
|
||||
profile *gtk.ComboBoxText
|
||||
|
||||
// Flags.
|
||||
// Is known server update performed?
|
||||
update bool
|
||||
|
||||
// Data.
|
||||
// If known server is used - here server's datamodel is.
|
||||
server *datamodels.Server
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) Close() {}
|
||||
|
||||
func (f *FavoriteDialog) closeByCancel() {
|
||||
f.window.Destroy()
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) fill() {
|
||||
f.server_name.SetText(f.server.Name)
|
||||
f.server_address.SetText(f.server.Ip + ":" + f.server.Port)
|
||||
f.server_password.SetText(f.server.Password)
|
||||
|
||||
// Profiles.
|
||||
profiles := []datamodels.Profile{}
|
||||
err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
for p := range profiles {
|
||||
if profiles[p].Version == f.server.Version {
|
||||
f.profile.AppendText(profiles[p].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) Initialize() {
|
||||
if f.update {
|
||||
fmt.Println("Updating favorite server...")
|
||||
} else {
|
||||
fmt.Println("New favorite server")
|
||||
}
|
||||
|
||||
f.initializeWindow()
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) InitializeNew() {
|
||||
f.update = false
|
||||
f.Initialize()
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) InitializeUpdate(server *datamodels.Server) {
|
||||
fmt.Println("Favorites updating...")
|
||||
f.update = true
|
||||
f.server = server
|
||||
f.Initialize()
|
||||
f.fill()
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) initializeWindow() {
|
||||
f.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
if f.update {
|
||||
f.window.SetTitle("URTrator - Updating favorite server")
|
||||
} else {
|
||||
f.window.SetTitle("URTrator - New favorite server")
|
||||
}
|
||||
f.window.Connect("destroy", f.Close)
|
||||
f.window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
f.window.SetModal(true)
|
||||
f.window.SetSizeRequest(400, 200)
|
||||
f.window.SetResizable(false)
|
||||
f.vbox = gtk.NewVBox(false, 0)
|
||||
|
||||
// Load program icon from base64.
|
||||
icon_bytes, _ := base64.StdEncoding.DecodeString(common.Logo)
|
||||
icon_pixbuf := gdkpixbuf.NewLoader()
|
||||
icon_pixbuf.Write(icon_bytes)
|
||||
logo = icon_pixbuf.GetPixbuf()
|
||||
f.window.SetIcon(logo)
|
||||
|
||||
// Server name.
|
||||
srv_name_hbox := gtk.NewHBox(false, 0)
|
||||
f.vbox.PackStart(srv_name_hbox, false, true, 5)
|
||||
srv_name_label := gtk.NewLabel("Server name:")
|
||||
srv_name_hbox.PackStart(srv_name_label, false, true, 5)
|
||||
srv_name_sep := gtk.NewHSeparator()
|
||||
srv_name_hbox.PackStart(srv_name_sep, true, true, 5)
|
||||
f.server_name = gtk.NewEntry()
|
||||
srv_name_hbox.PackStart(f.server_name, true, true, 5)
|
||||
|
||||
// Server address.
|
||||
srv_addr_hbox := gtk.NewHBox(false, 0)
|
||||
f.vbox.PackStart(srv_addr_hbox, false, true, 5)
|
||||
srv_addr_label := gtk.NewLabel("Server address:")
|
||||
srv_addr_hbox.PackStart(srv_addr_label, false, true, 5)
|
||||
srv_addr_sep := gtk.NewHSeparator()
|
||||
srv_addr_hbox.PackStart(srv_addr_sep, true, true, 5)
|
||||
f.server_address = gtk.NewEntry()
|
||||
srv_addr_hbox.PackStart(f.server_address, true, true, 5)
|
||||
if f.update {
|
||||
f.server_address.SetSensitive(false)
|
||||
}
|
||||
|
||||
// Server password.
|
||||
srv_pass_hbox := gtk.NewHBox(false, 0)
|
||||
f.vbox.PackStart(srv_pass_hbox, false, true, 5)
|
||||
srv_pass_label := gtk.NewLabel("Password:")
|
||||
srv_pass_hbox.PackStart(srv_pass_label, false, true, 5)
|
||||
srv_pass_sep := gtk.NewHSeparator()
|
||||
srv_pass_hbox.PackStart(srv_pass_sep, true, true, 5)
|
||||
f.server_password = gtk.NewEntry()
|
||||
srv_pass_hbox.PackStart(f.server_password, true, true, 5)
|
||||
|
||||
// Profile to use.
|
||||
profile_hbox := gtk.NewHBox(false, 0)
|
||||
f.vbox.PackStart(profile_hbox, false, true, 5)
|
||||
profile_label := gtk.NewLabel("Profile:")
|
||||
profile_hbox.PackStart(profile_label, false, true, 5)
|
||||
profile_sep := gtk.NewHSeparator()
|
||||
profile_hbox.PackStart(profile_sep, true, true, 5)
|
||||
f.profile = gtk.NewComboBoxText()
|
||||
profile_hbox.PackStart(f.profile, false, true, 5)
|
||||
|
||||
// Buttons hbox.
|
||||
buttons_hbox := gtk.NewHBox(false, 0)
|
||||
sep := gtk.NewHSeparator()
|
||||
buttons_hbox.PackStart(sep, true, true, 5)
|
||||
// OK-Cancel buttons.
|
||||
cancel_button := gtk.NewButtonWithLabel("Cancel")
|
||||
cancel_button.Clicked(f.closeByCancel)
|
||||
buttons_hbox.PackStart(cancel_button, false, true, 5)
|
||||
|
||||
ok_button := gtk.NewButtonWithLabel("OK")
|
||||
ok_button.Clicked(f.saveFavorite)
|
||||
buttons_hbox.PackStart(ok_button, false, true, 5)
|
||||
|
||||
f.vbox.PackStart(buttons_hbox, false, true, 5)
|
||||
|
||||
f.window.Add(f.vbox)
|
||||
f.window.ShowAll()
|
||||
}
|
||||
|
||||
func (f *FavoriteDialog) saveFavorite() error {
|
||||
if len(f.server_address.GetText()) == 0 {
|
||||
mbox_string := "Server address is empty.\n\nServers without address cannot be added."
|
||||
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||
m.Response(func() {
|
||||
m.Destroy()
|
||||
})
|
||||
m.Run()
|
||||
return errors.New("No server address specified")
|
||||
}
|
||||
|
||||
var port string = ""
|
||||
if strings.Contains(f.server_address.GetText(), ":") {
|
||||
port = strings.Split(f.server_address.GetText(), ":")[1]
|
||||
} else {
|
||||
port = "27960"
|
||||
}
|
||||
|
||||
fmt.Println("Saving favorite server...")
|
||||
|
||||
server := datamodels.Server{}
|
||||
server.Ip = strings.Split(f.server_address.GetText(), ":")[0]
|
||||
server.Port = port
|
||||
server.Name = f.server_name.GetText()
|
||||
server.Password = f.server_password.GetText()
|
||||
server.ProfileToUse = f.profile.GetActiveText()
|
||||
server.Favorite = "1"
|
||||
|
||||
if f.update {
|
||||
q := "UPDATE servers SET name=:name, ip=:ip, port=:port, password=:password, favorite=:favorite, profile_to_use=:profile_to_use WHERE ip='" + f.server.Ip + "' AND port='" + f.server.Port + "'"
|
||||
fmt.Println("Query: " + q)
|
||||
ctx.Database.Db.NamedExec(q, &server)
|
||||
} else {
|
||||
q := "INSERT INTO servers (name, ip, port, password, favorite, profile_to_use) VALUES (:name, :ip, :port, :password, \"1\", :profile_to_use)"
|
||||
fmt.Println(q)
|
||||
ctx.Database.Db.NamedExec(q, &server)
|
||||
}
|
||||
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
|
||||
return nil
|
||||
}
|
339
ui/mainwindow.go
339
ui/mainwindow.go
@ -15,6 +15,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
// Local
|
||||
"github.com/pztrn/urtrator/common"
|
||||
@ -61,6 +62,10 @@ type MainWindow struct {
|
||||
fav_servers_hide_offline *gtk.CheckButton
|
||||
// Game launch button.
|
||||
launch_button *gtk.Button
|
||||
// Quick connect: server address
|
||||
qc_server_address *gtk.Entry
|
||||
// Quick connect: password
|
||||
qc_password *gtk.Entry
|
||||
|
||||
// Storages.
|
||||
// All servers store.
|
||||
@ -72,6 +77,8 @@ type MainWindow struct {
|
||||
|
||||
// Dialogs.
|
||||
options_dialog *OptionsDialog
|
||||
// Favorite server editing.
|
||||
favorite_dialog *FavoriteDialog
|
||||
|
||||
// Other
|
||||
// Old profiles count.
|
||||
@ -80,12 +87,125 @@ type MainWindow struct {
|
||||
|
||||
func (m *MainWindow) addToFavorites() {
|
||||
fmt.Println("Adding server to favorites...")
|
||||
|
||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||
|
||||
// Getting server's address from list.
|
||||
sel := m.all_servers.GetSelection()
|
||||
model := m.all_servers.GetModel()
|
||||
if strings.Contains(current_tab, "Favorites") {
|
||||
// Getting server's address from list.
|
||||
sel = m.fav_servers.GetSelection()
|
||||
model = m.fav_servers.GetModel()
|
||||
}
|
||||
iter := new(gtk.TreeIter)
|
||||
_ = sel.GetSelected(iter)
|
||||
|
||||
// Getting server address.
|
||||
var srv_addr string
|
||||
srv_addr_gval := glib.ValueFromNative(srv_addr)
|
||||
model.GetValue(iter, 7, srv_addr_gval)
|
||||
server_address := srv_addr_gval.GetString()
|
||||
|
||||
// Getting server from database.
|
||||
m.favorite_dialog = &FavoriteDialog{}
|
||||
if len(server_address) > 0 {
|
||||
servers := []datamodels.Server{}
|
||||
address := strings.Split(server_address, ":")[0]
|
||||
port := strings.Split(server_address, ":")[1]
|
||||
err1 := ctx.Database.Db.Select(&servers, ctx.Database.Db.Rebind("SELECT * FROM servers WHERE ip=? AND port=?"), address, port)
|
||||
if err1 != nil {
|
||||
fmt.Println(err1.Error())
|
||||
}
|
||||
m.favorite_dialog.InitializeUpdate(&servers[0])
|
||||
} else {
|
||||
m.favorite_dialog.InitializeNew()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MainWindow) Close() {
|
||||
ctx.Close()
|
||||
}
|
||||
|
||||
func (m *MainWindow) deleteFromFavorites() {
|
||||
fmt.Println("Removing server from favorites...")
|
||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||
|
||||
// Assuming that deletion was called from "Servers" tab by default.
|
||||
sel := m.all_servers.GetSelection()
|
||||
model := m.all_servers.GetModel()
|
||||
if strings.Contains(current_tab, "Favorites") {
|
||||
// Getting server's address from list.
|
||||
sel = m.fav_servers.GetSelection()
|
||||
model = m.fav_servers.GetModel()
|
||||
}
|
||||
|
||||
iter := new(gtk.TreeIter)
|
||||
_ = sel.GetSelected(iter)
|
||||
|
||||
// Getting server address.
|
||||
var srv_addr string
|
||||
srv_addr_gval := glib.ValueFromNative(srv_addr)
|
||||
model.GetValue(iter, 7, srv_addr_gval)
|
||||
server_address := srv_addr_gval.GetString()
|
||||
|
||||
var not_favorited bool = false
|
||||
if len(server_address) > 0 {
|
||||
address := strings.Split(server_address, ":")[0]
|
||||
port := strings.Split(server_address, ":")[1]
|
||||
srv := []datamodels.Server{}
|
||||
err := ctx.Database.Db.Select(&srv, ctx.Database.Db.Rebind("SELECT * FROM servers WHERE ip=? AND port=?"), address, port)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
if srv[0].Favorite == "1" {
|
||||
ctx.Database.Db.MustExec(ctx.Database.Db.Rebind("UPDATE servers SET favorite='0' WHERE ip=? AND port=?"), address, port)
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
} else {
|
||||
not_favorited = true
|
||||
}
|
||||
} else {
|
||||
not_favorited = true
|
||||
}
|
||||
|
||||
if not_favorited {
|
||||
mbox_string := "Cannot delete server from favorites.\n\nServer isn't favorited."
|
||||
d := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, mbox_string)
|
||||
d.Response(func() {
|
||||
d.Destroy()
|
||||
})
|
||||
d.Run()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MainWindow) dropDatabasesData() {
|
||||
fmt.Println("Dropping database data...")
|
||||
var will_continue bool = false
|
||||
mbox_string := "You are about to drop whole database data.\n\nAfter clicking \"YES\" ALL data in database (servers, profiles, settings, etc.)\nwill be lost FOREVER. Are you sure?"
|
||||
d := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, mbox_string)
|
||||
d.Connect("response", func(resp *glib.CallbackContext) {
|
||||
if resp.Args(0) == 4294967287 {
|
||||
will_continue = false
|
||||
} else {
|
||||
will_continue = true
|
||||
}
|
||||
})
|
||||
d.Response(func() {
|
||||
d.Destroy()
|
||||
})
|
||||
d.Run()
|
||||
|
||||
if will_continue {
|
||||
ctx.Database.Db.MustExec("DELETE FROM servers")
|
||||
ctx.Database.Db.MustExec("DELETE FROM settings")
|
||||
ctx.Database.Db.MustExec("DELETE FROM urt_profiles")
|
||||
|
||||
ctx.Eventer.LaunchEvent("loadProfiles")
|
||||
ctx.Eventer.LaunchEvent("loadAllServers")
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MainWindow) hideOfflineAllServers() {
|
||||
fmt.Println("(Un)Hiding offline servers in 'Servers' tab...")
|
||||
ctx.Eventer.LaunchEvent("loadAllServers")
|
||||
@ -93,6 +213,7 @@ func (m *MainWindow) hideOfflineAllServers() {
|
||||
|
||||
func (m *MainWindow) hideOfflineFavoriteServers() {
|
||||
fmt.Println("(Un)Hiding offline servers in 'Favorite' tab...")
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
}
|
||||
|
||||
func (m *MainWindow) Initialize() {
|
||||
@ -137,7 +258,7 @@ func (m *MainWindow) Initialize() {
|
||||
// Temporary hack.
|
||||
var w, h int = 0, 0
|
||||
m.window.GetSize(&w, &h)
|
||||
m.hpane.SetPosition(w)
|
||||
m.hpane.SetPosition(w - 150)
|
||||
|
||||
// Game profiles and launch button.
|
||||
profile_and_launch_hbox := gtk.NewHBox(false, 0)
|
||||
@ -180,6 +301,7 @@ func (m *MainWindow) Initialize() {
|
||||
// Launch events.
|
||||
ctx.Eventer.LaunchEvent("loadProfiles")
|
||||
ctx.Eventer.LaunchEvent("loadAllServers")
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
|
||||
gtk.Main()
|
||||
}
|
||||
@ -199,6 +321,10 @@ func (m *MainWindow) InitializeMainMenu() {
|
||||
file_menu.Append(options_menu_item)
|
||||
options_menu_item.Connect("activate", m.options_dialog.ShowOptionsDialog)
|
||||
|
||||
// Separator.
|
||||
file_menu_sep1 := gtk.NewSeparatorMenuItem()
|
||||
file_menu.Append(file_menu_sep1)
|
||||
|
||||
// Exit.
|
||||
exit_menu_item := gtk.NewMenuItemWithMnemonic("E_xit")
|
||||
file_menu.Append(exit_menu_item)
|
||||
@ -214,11 +340,46 @@ func (m *MainWindow) InitializeMainMenu() {
|
||||
about_app_item := gtk.NewMenuItemWithMnemonic("About _URTrator...")
|
||||
about_menu.Append(about_app_item)
|
||||
about_app_item.Connect("activate", ShowAboutDialog)
|
||||
|
||||
// Separator.
|
||||
about_menu_sep1 := gtk.NewSeparatorMenuItem()
|
||||
about_menu.Append(about_menu_sep1)
|
||||
|
||||
// Drop databases thing.
|
||||
about_menu_drop_database_data_item := gtk.NewMenuItemWithMnemonic("Drop database data...")
|
||||
about_menu.Append(about_menu_drop_database_data_item)
|
||||
about_menu_drop_database_data_item.Connect("activate", m.dropDatabasesData)
|
||||
}
|
||||
|
||||
func (m *MainWindow) initializeSidebar() {
|
||||
sidebar_vbox := gtk.NewVBox(false, 0)
|
||||
|
||||
// Quick connect frame.
|
||||
quick_connect_frame := gtk.NewFrame("Quick connect")
|
||||
sidebar_vbox.PackStart(quick_connect_frame, true, true, 5)
|
||||
qc_vbox := gtk.NewVBox(false, 0)
|
||||
quick_connect_frame.Add(qc_vbox)
|
||||
|
||||
// Server address.
|
||||
srv_tooltip := "Server address we will connect to"
|
||||
srv_label := gtk.NewLabel("Server address:")
|
||||
srv_label.SetTooltipText(srv_tooltip)
|
||||
qc_vbox.PackStart(srv_label, false, true, 5)
|
||||
|
||||
m.qc_server_address = gtk.NewEntry()
|
||||
m.qc_server_address.SetTooltipText(srv_tooltip)
|
||||
qc_vbox.PackStart(m.qc_server_address, false, true, 5)
|
||||
|
||||
// Password.
|
||||
pass_tooltip := "Password we will use for server"
|
||||
pass_label := gtk.NewLabel("Password:")
|
||||
pass_label.SetTooltipText(pass_tooltip)
|
||||
qc_vbox.PackStart(pass_label, false, true, 5)
|
||||
|
||||
m.qc_password = gtk.NewEntry()
|
||||
m.qc_password.SetTooltipText(pass_tooltip)
|
||||
qc_vbox.PackStart(m.qc_password, false, true, 5)
|
||||
|
||||
m.hpane.Add2(sidebar_vbox)
|
||||
}
|
||||
|
||||
@ -331,13 +492,34 @@ func (m *MainWindow) InitializeTabs() {
|
||||
m.tab_widget.AppendPage(tab_fav_srv_hbox, gtk.NewLabel("Favorites"))
|
||||
m.fav_servers.SetModel(m.fav_servers_store)
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Status", gtk.NewCellRendererPixbuf(), "pixbuf", 0))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Name", gtk.NewCellRendererText(), "text", 1))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Mode", gtk.NewCellRendererText(), "text", 2))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Map", gtk.NewCellRendererText(), "text", 3))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Players", gtk.NewCellRendererText(), "text", 4))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Ping", gtk.NewCellRendererText(), "text", 5))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Version", gtk.NewCellRendererText(), "text", 6))
|
||||
m.fav_servers.AppendColumn(gtk.NewTreeViewColumnWithAttributes("IP", gtk.NewCellRendererText(), "text", 7))
|
||||
|
||||
fav_name_column := gtk.NewTreeViewColumnWithAttributes("Name", gtk.NewCellRendererText(), "text", 1)
|
||||
fav_name_column.SetSortColumnId(1)
|
||||
m.fav_servers.AppendColumn(fav_name_column)
|
||||
|
||||
fav_mode_column := gtk.NewTreeViewColumnWithAttributes("Mode", gtk.NewCellRendererText(), "text", 2)
|
||||
fav_mode_column.SetSortColumnId(2)
|
||||
m.fav_servers.AppendColumn(fav_mode_column)
|
||||
|
||||
fav_map_column := gtk.NewTreeViewColumnWithAttributes("Map", gtk.NewCellRendererText(), "text", 3)
|
||||
fav_map_column.SetSortColumnId(3)
|
||||
m.fav_servers.AppendColumn(fav_map_column)
|
||||
|
||||
fav_players_column := gtk.NewTreeViewColumnWithAttributes("Players", gtk.NewCellRendererText(), "text", 4)
|
||||
fav_players_column.SetSortColumnId(4)
|
||||
m.fav_servers.AppendColumn(fav_players_column)
|
||||
|
||||
fav_ping_column := gtk.NewTreeViewColumnWithAttributes("Ping", gtk.NewCellRendererText(), "text", 5)
|
||||
fav_ping_column.SetSortColumnId(5)
|
||||
m.fav_servers.AppendColumn(fav_ping_column)
|
||||
|
||||
fav_version_column := gtk.NewTreeViewColumnWithAttributes("Version", gtk.NewCellRendererText(), "text", 6)
|
||||
fav_version_column.SetSortColumnId(6)
|
||||
m.fav_servers.AppendColumn(fav_version_column)
|
||||
|
||||
fav_ip_column := gtk.NewTreeViewColumnWithAttributes("IP", gtk.NewCellRendererText(), "text", 7)
|
||||
fav_ip_column.SetSortColumnId(7)
|
||||
m.fav_servers.AppendColumn(fav_ip_column)
|
||||
|
||||
// VBox for some servers list controllers.
|
||||
tab_fav_srv_ctl_vbox := gtk.NewVBox(false, 0)
|
||||
@ -356,7 +538,8 @@ func (m *MainWindow) InitializeTabs() {
|
||||
// Add tab_widget widget to window.
|
||||
m.hpane.Add1(m.tab_widget)
|
||||
|
||||
ctx.Eventer.AddEventHandler("loadAllServers", m.loadServers)
|
||||
ctx.Eventer.AddEventHandler("loadAllServers", m.loadAllServers)
|
||||
ctx.Eventer.AddEventHandler("loadFavoriteServers", m.loadFavoriteServers)
|
||||
}
|
||||
|
||||
func (m *MainWindow) InitializeToolbar() {
|
||||
@ -380,17 +563,26 @@ func (m *MainWindow) InitializeToolbar() {
|
||||
fav_button.SetTooltipText("Add selected server to favorites")
|
||||
fav_button.OnClicked(m.addToFavorites)
|
||||
m.toolbar.Insert(fav_button, 2)
|
||||
|
||||
// Remove server from favorites button.
|
||||
fav_delete_button := gtk.NewToolButtonFromStock(gtk.STOCK_REMOVE)
|
||||
fav_delete_button.SetLabel("Remove from favorites")
|
||||
fav_delete_button.SetTooltipText("Remove selected server from favorites")
|
||||
fav_delete_button.OnClicked(m.deleteFromFavorites)
|
||||
m.toolbar.Insert(fav_delete_button, 3)
|
||||
}
|
||||
|
||||
func (m *MainWindow) launchGame() error {
|
||||
fmt.Println("Launching Urban Terror...")
|
||||
|
||||
//var launch_params string = ""
|
||||
|
||||
// Getting server's name from list.
|
||||
// ToDo: detect on what tab we are and use approriate list.
|
||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||
sel := m.all_servers.GetSelection()
|
||||
model := m.all_servers.GetModel()
|
||||
if strings.Contains(current_tab, "Favorites") {
|
||||
sel = m.fav_servers.GetSelection()
|
||||
model = m.fav_servers.GetModel()
|
||||
}
|
||||
iter := new(gtk.TreeIter)
|
||||
_ = sel.GetSelected(iter)
|
||||
|
||||
@ -412,7 +604,6 @@ func (m *MainWindow) launchGame() error {
|
||||
model.GetValue(iter, 6, srv_game_ver_gval)
|
||||
srv_game_ver := srv_game_ver_gval.GetString()
|
||||
|
||||
|
||||
// Check for proper server name. If length == 0: server is offline,
|
||||
// we should show notification to user.
|
||||
if len(server_name) == 0 {
|
||||
@ -437,7 +628,10 @@ func (m *MainWindow) launchGame() error {
|
||||
|
||||
// Getting selected profile's name.
|
||||
profile_name := m.profiles.GetActiveText()
|
||||
if strings.Contains(current_tab, "Servers") {
|
||||
// Checking profile name length. If 0 - then stop executing :)
|
||||
// This check only relevant to "Servers" tab, favorite servers
|
||||
// have profiles defined (see next).
|
||||
if len(profile_name) == 0 {
|
||||
mbox_string := "Invalid game profile selected.\n\nPlease, select profile and retry."
|
||||
m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||
@ -447,8 +641,19 @@ func (m *MainWindow) launchGame() error {
|
||||
m.Run()
|
||||
return errors.New("User didn't select valid profile.")
|
||||
}
|
||||
|
||||
fmt.Println("Connecting to " + server_name + " (" + srv_address + ") using profile " + profile_name + "...")
|
||||
} else if strings.Contains(current_tab, "Favorites") {
|
||||
// For favorite servers profile specified in favorite server
|
||||
// information have higher priority, so we just override it :)
|
||||
server := []datamodels.Server{}
|
||||
// All favorites servers should contain IP and Port :)
|
||||
ip := strings.Split(srv_address, ":")[0]
|
||||
port := strings.Split(srv_address, ":")[1]
|
||||
err := ctx.Database.Db.Select(&server, ctx.Database.Db.Rebind("SELECT * FROM servers WHERE ip=? AND port=?"), ip, port)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
profile_name = server[0].ProfileToUse
|
||||
}
|
||||
|
||||
// Getting profile data from database.
|
||||
// ToDo: cache profiles data in runtime.
|
||||
@ -478,28 +683,7 @@ func (m *MainWindow) launchGame() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MainWindow) loadProfiles() {
|
||||
fmt.Println("Loading profiles into combobox on MainWindow")
|
||||
for i := 0; i < m.old_profiles_count; i++ {
|
||||
// ComboBox indexes are shifting on element deletion, so we should
|
||||
// detele very first element every time.
|
||||
m.profiles.Remove(0)
|
||||
}
|
||||
|
||||
profiles := []datamodels.Profile{}
|
||||
err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
for p := range profiles {
|
||||
m.profiles.AppendText(profiles[p].Name)
|
||||
}
|
||||
|
||||
m.old_profiles_count = len(profiles)
|
||||
fmt.Println("Added " + strconv.Itoa(m.old_profiles_count) + " profiles")
|
||||
}
|
||||
|
||||
func (m *MainWindow) loadServers() {
|
||||
func (m *MainWindow) loadAllServers() {
|
||||
fmt.Println("Loading servers lists into widgets...")
|
||||
servers := []datamodels.Server{}
|
||||
err := ctx.Database.Db.Select(&servers, "SELECT * FROM servers")
|
||||
@ -529,28 +713,103 @@ func (m *MainWindow) loadServers() {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MainWindow) loadFavoriteServers() {
|
||||
fmt.Println("Loading favorite servers...")
|
||||
servers := []datamodels.Server{}
|
||||
err := ctx.Database.Db.Select(&servers, "SELECT * FROM servers WHERE favorite='1'")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
// ToDo: do it without clearing.
|
||||
m.fav_servers_store.Clear()
|
||||
for _, srv := range servers {
|
||||
if srv.Favorite != "1" {
|
||||
continue
|
||||
}
|
||||
if m.fav_servers_hide_offline.GetActive() && srv.Name == "" && srv.Players == "" {
|
||||
continue
|
||||
}
|
||||
var iter gtk.TreeIter
|
||||
m.fav_servers_store.Append(&iter)
|
||||
if srv.Name == "" && srv.Players == "" {
|
||||
m.fav_servers_store.Set(&iter, 0, gtk.NewImage().RenderIcon(gtk.STOCK_NO, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf)
|
||||
} else {
|
||||
m.fav_servers_store.Set(&iter, 0, gtk.NewImage().RenderIcon(gtk.STOCK_OK, gtk.ICON_SIZE_SMALL_TOOLBAR, "").GPixbuf)
|
||||
}
|
||||
m.fav_servers_store.Set(&iter, 1, srv.Name)
|
||||
m.fav_servers_store.Set(&iter, 2, m.gamemodes[srv.Gamemode])
|
||||
m.fav_servers_store.Set(&iter, 3, srv.Map)
|
||||
m.fav_servers_store.Set(&iter, 4, srv.Players + "/" + srv.Maxplayers)
|
||||
m.fav_servers_store.Set(&iter, 5, srv.Ping)
|
||||
m.fav_servers_store.Set(&iter, 6, srv.Version)
|
||||
m.fav_servers_store.Set(&iter, 7, srv.Ip + ":" + srv.Port)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MainWindow) loadProfiles() {
|
||||
fmt.Println("Loading profiles into combobox on MainWindow")
|
||||
for i := 0; i < m.old_profiles_count; i++ {
|
||||
// ComboBox indexes are shifting on element deletion, so we should
|
||||
// detele very first element every time.
|
||||
m.profiles.Remove(0)
|
||||
}
|
||||
|
||||
profiles := []datamodels.Profile{}
|
||||
err := ctx.Database.Db.Select(&profiles, "SELECT * FROM urt_profiles")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
for p := range profiles {
|
||||
m.profiles.AppendText(profiles[p].Name)
|
||||
}
|
||||
|
||||
m.old_profiles_count = len(profiles)
|
||||
fmt.Println("Added " + strconv.Itoa(m.old_profiles_count) + " profiles")
|
||||
}
|
||||
|
||||
func (m *MainWindow) unlockInterface() {
|
||||
m.launch_button.SetSensitive(true)
|
||||
m.statusbar.Push(m.statusbar_context_id, "URTrator is ready.")
|
||||
}
|
||||
|
||||
func (m *MainWindow) updateFavorites(done_chan chan map[string]*datamodels.Server, error_chan chan bool) {
|
||||
m.fav_servers_store.Clear()
|
||||
servers := []datamodels.Server{}
|
||||
err := ctx.Database.Db.Select(&servers, "SELECT * FROM servers WHERE favorite='1'")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
|
||||
var servers_from_db [][]string
|
||||
|
||||
for s := range servers {
|
||||
servers_from_db = append(servers_from_db, []string{servers[s].Ip, servers[s].Port})
|
||||
}
|
||||
|
||||
go ctx.Requester.UpdateFavoriteServers(servers_from_db, done_chan, error_chan)
|
||||
}
|
||||
|
||||
func (m *MainWindow) UpdateServers() {
|
||||
m.statusbar.Push(m.statusbar_context_id, "Updating servers...")
|
||||
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
|
||||
fmt.Println("Updating servers on tab '" + current_tab + "'...")
|
||||
done_chan := make(chan map[string]*datamodels.Server, 1)
|
||||
error_chan := make(chan bool, 1)
|
||||
if current_tab == "Servers" {
|
||||
if strings.Contains(current_tab, "Servers") {
|
||||
go ctx.Requester.UpdateAllServers(done_chan, error_chan)
|
||||
} else if current_tab == "Favorites" {
|
||||
fmt.Println("Favorites update stub")
|
||||
} else if strings.Contains(current_tab, "Favorites") {
|
||||
m.updateFavorites(done_chan, error_chan)
|
||||
}
|
||||
|
||||
select {
|
||||
case data := <- done_chan:
|
||||
fmt.Println("Information about servers successfully gathered")
|
||||
ctx.Database.UpdateServers(data)
|
||||
if current_tab == "Servers" {
|
||||
ctx.Eventer.LaunchEvent("loadAllServers")
|
||||
} else {
|
||||
ctx.Eventer.LaunchEvent("loadFavoriteServers")
|
||||
}
|
||||
case <- error_chan:
|
||||
fmt.Println("Error occured")
|
||||
}
|
||||
|
Reference in New Issue
Block a user