11 Commits

Author SHA1 Message Date
e66875ffbe Version bump. 2016-11-26 19:32:37 +05:00
979de8d858 Filtering by game mode implemented. 2016-11-26 16:20:57 +05:00
f0ddda1af5 "All versions" instead of "All" in version select comboboxes. 2016-11-26 16:06:33 +05:00
bd344fee2e Filter by server version and forgotten server's CVars window.
Implemented filtering servers by server's version, related to #27.
This combobox is saved-restored across restarts.

Added forgotten bd04870 server_cvars.go, which is responsible for
showing server's CVars window.
2016-11-26 16:00:17 +05:00
7950ab5a1f macOS might have no GTK configuration, so forcing "only icons" for toolbar. 2016-11-26 09:35:59 +05:00
3b3aae16b0 Accidently attached wrong widget. 2016-11-26 09:27:46 +05:00
a57c878dad Prettified favorites add/edit dialog. Fixes #33. 2016-11-26 09:24:36 +05:00
474821ba7b Ooops :) 2016-11-26 09:11:51 +05:00
f32cf4d1f6 "GENERAL INFO" list item isn't needed anymore. 2016-11-26 09:10:57 +05:00
bd04870aa3 Splitted sidebar's list into two and separate CVars window.
Splitted sidebar's list into two separate lists - one for
general server's info (hostname, players, etc.) and one for
players list.

Also, moved CVars list to separate window which can be shown by
clicking approriate button under player's list.
2016-11-26 09:05:48 +05:00
280c65f116 Distinguish bots from humans.
Players column now have three integers - first is real humans
count, second - bots count, and third - maximum players allowed
on this server. Also, sidebar will show bots count as well.
2016-11-26 07:38:26 +05:00
12 changed files with 406 additions and 85 deletions

View File

@@ -55,6 +55,7 @@ func (c *Cache) FlushServers(data map[string]string) {
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].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
@@ -71,6 +72,7 @@ func (c *Cache) FlushServers(data map[string]string) {
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].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
@@ -90,12 +92,12 @@ func (c *Cache) FlushServers(data map[string]string) {
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) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private, :favorite, :profile_to_use)", 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 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())
} }
@@ -125,6 +127,7 @@ func (c *Cache) LoadServers(data map[string]string) {
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.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

View File

@@ -10,5 +10,11 @@
package common package common
const ( const (
URTRATOR_VERSION = "0.1.0" URTRATOR_VERSION = "0.1.1"
) )
// Self-named.
var SUPPORTED_URT_VERSIONS []string = []string{
"4.2.023",
"4.3.1",
}

View File

@@ -48,6 +48,7 @@ func migrate_full(db *Database, version int) {
if version == 6 {six_to_seven(db); version = 7} if version == 6 {six_to_seven(db); version = 7}
if version == 7 {seven_to_eight(db); version = 8} if version == 7 {seven_to_eight(db); version = 8}
if version == 8 {eight_to_nine(db); version = 9} if version == 8 {eight_to_nine(db); version = 9}
if version == 9 {nine_to_ten(db); version = 10}
} }
// Initial database structure. // Initial database structure.
@@ -115,3 +116,10 @@ func eight_to_nine(db *Database) {
db.Db.MustExec("ALTER TABLE servers ADD is_private VARCHAR(1) NOT NULL DEFAULT '0'") db.Db.MustExec("ALTER TABLE servers ADD is_private VARCHAR(1) NOT NULL DEFAULT '0'")
db.Db.MustExec("UPDATE database SET version=9") db.Db.MustExec("UPDATE database SET version=9")
} }
// Bots count.
func nine_to_ten(db *Database) {
fmt.Println("Upgrading database from 9 to 10...")
db.Db.MustExec("ALTER TABLE servers ADD bots VARCHAR(2) NOT NULL DEFAULT '0'")
db.Db.MustExec("UPDATE database SET version=10")
}

View File

@@ -18,6 +18,8 @@ type Server struct {
Name string `db:"name"` Name string `db:"name"`
// Current players count // Current players count
Players string `db:"players"` Players string `db:"players"`
// Bots count
Bots string `db:"bots"`
// Maximum players // Maximum players
Maxplayers string `db:"maxplayers"` Maxplayers string `db:"maxplayers"`
// Ping // Ping

View File

@@ -150,6 +150,9 @@ ln -s ../../../Framework .
cd ../../../MacOS cd ../../../MacOS
GDK_PIXBUF_MODULE_FILE="../lib/gdk-pixbuf-2.0/loaders.cache" GDK_PIXBUF_MODULEDIR="../lib/gdk-pixbuf-2.0/2.10.0/loaders/" GTK_EXE_PREFIX="../lib" GTK_PATH="../Framework" ./gdk-pixbuf-query-loaders > ../lib/gdk-pixbuf-2.0/2.10.0/loaders.cache GDK_PIXBUF_MODULE_FILE="../lib/gdk-pixbuf-2.0/loaders.cache" GDK_PIXBUF_MODULEDIR="../lib/gdk-pixbuf-2.0/2.10.0/loaders/" GTK_EXE_PREFIX="../lib" GTK_PATH="../Framework" ./gdk-pixbuf-query-loaders > ../lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
echo "Copying icon theme..."
echo "Finishing..." echo "Finishing..."
echo "URTrator is ready! Copy URTrator.app bundle to Applications and launch it!" echo "URTrator is ready! Copy URTrator.app bundle to Applications and launch it!"

View File

@@ -234,13 +234,34 @@ func (p *Pooler) UpdateSpecificServer(server *datamodels.Server) error {
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 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"
} 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.
server.Players = strconv.Itoa(len(players) - 1) for i := range players {
// Get slice with data for bots-humans parsing.
player_data := strings.Split(string(players[i]), " ")
// If slice length isn't equal 3 - this is not what
// we want.
if len(player_data) != 3 {
continue
}
if player_data[1] == "0" {
bots++
} else {
real_players++
}
}
//server.Players = strconv.Itoa(len(players) - 1)
server.Players = strconv.Itoa(real_players)
server.Bots = strconv.Itoa(bots)
fmt.Println(server.Players, server.Bots)
} }
server.PlayersInfo = strings.Join(received_lines[2:], "\\") server.PlayersInfo = strings.Join(received_lines[2:], "\\")
} }

View File

@@ -118,7 +118,6 @@ func (f *FavoriteDialog) initializeWindow() {
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)
f.vbox = gtk.NewVBox(false, 0)
// Load program icon from base64. // Load program icon from base64.
icon_bytes, _ := base64.StdEncoding.DecodeString(common.Logo) icon_bytes, _ := base64.StdEncoding.DecodeString(common.Logo)
@@ -132,25 +131,27 @@ func (f *FavoriteDialog) initializeWindow() {
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)
table := gtk.NewTable(5, 2, false)
f.vbox.PackStart(table, true, true, 5)
// Server name. // 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_label := gtk.NewLabel("Server name:")
srv_name_hbox.PackStart(srv_name_label, false, true, 5) srv_name_label.SetAlignment(0, 0)
srv_name_sep := gtk.NewHSeparator() table.Attach(srv_name_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
srv_name_hbox.PackStart(srv_name_sep, true, true, 5)
f.server_name = gtk.NewEntry() f.server_name = gtk.NewEntry()
srv_name_hbox.PackStart(f.server_name, true, true, 5) table.Attach(f.server_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
// Server address. // 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_label := gtk.NewLabel("Server address:")
srv_addr_hbox.PackStart(srv_addr_label, false, true, 5) srv_addr_label.SetAlignment(0, 0)
srv_addr_sep := gtk.NewHSeparator() table.Attach(srv_addr_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
srv_addr_hbox.PackStart(srv_addr_sep, true, true, 5)
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, 5) 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("Update server information") srv_addr_update_btn.SetTooltipText("Update server information")
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)
@@ -160,26 +161,29 @@ func (f *FavoriteDialog) initializeWindow() {
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)
// Server password. // 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_label := gtk.NewLabel("Password:")
srv_pass_hbox.PackStart(srv_pass_label, false, true, 5) srv_pass_label.SetAlignment(0, 0)
srv_pass_sep := gtk.NewHSeparator() table.Attach(srv_pass_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
srv_pass_hbox.PackStart(srv_pass_sep, true, true, 5)
f.server_password = gtk.NewEntry() f.server_password = gtk.NewEntry()
srv_pass_hbox.PackStart(f.server_password, true, true, 5) table.Attach(f.server_password, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
// Profile to use. // Profile to use.
profile_hbox := gtk.NewHBox(false, 0)
f.vbox.PackStart(profile_hbox, false, true, 5)
profile_label := gtk.NewLabel("Profile:") profile_label := gtk.NewLabel("Profile:")
profile_hbox.PackStart(profile_label, false, true, 5) profile_label.SetAlignment(0, 0)
profile_sep := gtk.NewHSeparator() table.Attach(profile_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
profile_hbox.PackStart(profile_sep, true, true, 5)
f.profile = gtk.NewComboBoxText() f.profile = gtk.NewComboBoxText()
profile_hbox.PackStart(f.profile, false, true, 5) table.Attach(f.profile , 1, 2, 3, 4, gtk.FILL, gtk.FILL, 5, 5)
// Invisible thing.
inv_label1 := gtk.NewLabel("")
table.Attach(inv_label1, 0, 1, 4, 5, gtk.EXPAND, gtk.FILL, 5, 5)
inv_label2 := gtk.NewLabel("")
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)

View File

@@ -62,14 +62,24 @@ type MainWindow struct {
all_servers_hide_offline *gtk.CheckButton all_servers_hide_offline *gtk.CheckButton
// Checkbox for hiding/showing passworded servers in 'Servers' tab list. // Checkbox for hiding/showing passworded servers in 'Servers' tab list.
all_servers_hide_private *gtk.CheckButton all_servers_hide_private *gtk.CheckButton
// Combobox for filtering server's versions.
all_servers_version *gtk.ComboBoxText
// Combobox for filtering by gamemode.
all_servers_gamemode *gtk.ComboBoxText
// Checkbox for hiding/showing offline servers in 'Favorites' tab list. // Checkbox for hiding/showing offline servers in 'Favorites' tab list.
fav_servers_hide_offline *gtk.CheckButton fav_servers_hide_offline *gtk.CheckButton
// Checkbox for hiding/showing passworded servers in 'Favorites' tab list. // Checkbox for hiding/showing passworded servers in 'Favorites' tab list.
fav_servers_hide_private *gtk.CheckButton fav_servers_hide_private *gtk.CheckButton
// Combobox for filtering server's versions.
fav_servers_version *gtk.ComboBoxText
// Combobox for filtering by gamemode.
fav_servers_gamemode *gtk.ComboBoxText
// Game launch button. // Game launch button.
launch_button *gtk.Button launch_button *gtk.Button
// Server's information. // Server's main information.
server_info *gtk.TreeView server_info *gtk.TreeView
// Players information.
players_info *gtk.TreeView
// Quick connect: server address // Quick connect: server address
qc_server_address *gtk.Entry qc_server_address *gtk.Entry
// Quick connect: password // Quick connect: password
@@ -92,9 +102,12 @@ type MainWindow struct {
fav_servers_store *gtk.ListStore fav_servers_store *gtk.ListStore
// Server's information store. // Server's information store.
server_info_store *gtk.ListStore server_info_store *gtk.ListStore
// Players information store.
players_info_store *gtk.ListStore
// Dialogs. // Dialogs.
options_dialog *OptionsDialog options_dialog *OptionsDialog
server_cvars_dialog *ServerCVarsDialog
// Other // Other
// Old profiles count. // Old profiles count.
@@ -168,6 +181,16 @@ func (m *MainWindow) addToFavorites() {
} }
} }
func (m *MainWindow) allServersGamemodeFilterChanged() {
ctx.Cfg.Cfg["/serverslist/all_servers/gamemode"] = strconv.Itoa(m.all_servers_gamemode.GetActive())
ctx.Eventer.LaunchEvent("loadAllServers", nil)
}
func (m *MainWindow) allServersVersionFilterChanged() {
ctx.Cfg.Cfg["/serverslist/all_servers/version"] = strconv.Itoa(m.all_servers_version.GetActive())
ctx.Eventer.LaunchEvent("loadAllServers", nil)
}
// Executes when delimiter for two panes is moved, to calculate VALID // Executes when delimiter for two panes is moved, to calculate VALID
// position. // position.
func (m *MainWindow) checkMainPanePosition() { func (m *MainWindow) checkMainPanePosition() {
@@ -309,6 +332,16 @@ func (m *MainWindow) editFavorite() {
} }
} }
func (m *MainWindow) favServersGamemodeFilterChanged() {
ctx.Cfg.Cfg["/serverslist/favorite/gamemode"] = strconv.Itoa(m.fav_servers_gamemode.GetActive())
ctx.Eventer.LaunchEvent("loadFavoriteServers", nil)
}
func (m *MainWindow) favServersVersionFilterChanged() {
ctx.Cfg.Cfg["/serverslist/favorite/version"] = strconv.Itoa(m.fav_servers_version.GetActive())
ctx.Eventer.LaunchEvent("loadFavoriteServers", nil)
}
// Executes when "Hide offline servers" checkbox changed it's state on // Executes when "Hide offline servers" checkbox changed it's state on
// "Servers" tab. // "Servers" tab.
func (m *MainWindow) hideOfflineAllServers() { func (m *MainWindow) hideOfflineAllServers() {
@@ -370,6 +403,7 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
iter = server.AllServersIter iter = server.AllServersIter
} }
// Hide offline servers?
if m.all_servers_hide_offline.GetActive() && (server.Server.Players == "" && server.Server.Maxplayers == "" || ping > 9000) { if m.all_servers_hide_offline.GetActive() && (server.Server.Players == "" && server.Server.Maxplayers == "" || ping > 9000) {
if server.AllServersIterInList && server.AllServersIterSet { if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter) m.all_servers_store.Remove(iter)
@@ -378,6 +412,7 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
continue continue
} }
// Hide private servers?
if m.all_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" { if m.all_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" {
if server.AllServersIterInList && server.AllServersIterSet { if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter) m.all_servers_store.Remove(iter)
@@ -386,6 +421,27 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
continue continue
} }
// Hide servers that using different version than selected in
// filter?
if m.all_servers_version.GetActiveText() != "All versions" && m.all_servers_version.GetActiveText() != server.Server.Version {
if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter)
server.AllServersIterInList = false
}
continue
}
// Hide servers that using different gamemode than selected in
// filter?
gm_int_as_str := strconv.Itoa(m.all_servers_gamemode.GetActive())
if m.all_servers_gamemode.GetActiveText() != "All gamemodes" && gm_int_as_str != server.Server.Gamemode {
if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter)
server.AllServersIterInList = false
}
continue
}
if !server.AllServersIterInList && server.AllServersIterSet { if !server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Append(iter) m.all_servers_store.Append(iter)
server.AllServersIterInList = true server.AllServersIterInList = true
@@ -409,7 +465,7 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Name"], server_name) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Name"], server_name)
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Mode"], m.getGameModeName(server.Server.Gamemode)) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Mode"], m.getGameModeName(server.Server.Gamemode))
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Map"], server.Server.Map) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Map"], server.Server.Map)
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Players"], server.Server.Players + "/" + server.Server.Maxplayers) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Players"], server.Server.Players + "/" + server.Server.Bots + "/" + server.Server.Maxplayers)
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Ping"], server.Server.Ping) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Ping"], server.Server.Ping)
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Version"], server.Server.Version) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["Version"], server.Server.Version)
m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["IP"], server.Server.Ip + ":" + server.Server.Port) m.all_servers_store.SetValue(iter, m.column_pos["Servers"]["IP"], server.Server.Ip + ":" + server.Server.Port)
@@ -430,6 +486,7 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
iter = server.FavServersIter iter = server.FavServersIter
} }
// Hide offline servers?
if m.fav_servers_hide_offline.GetActive() && (server.Server.Players == "" && server.Server.Maxplayers == "" || ping > 9000) { if m.fav_servers_hide_offline.GetActive() && (server.Server.Players == "" && server.Server.Maxplayers == "" || ping > 9000) {
if server.FavServersIterInList { if server.FavServersIterInList {
m.fav_servers_store.Remove(iter) m.fav_servers_store.Remove(iter)
@@ -438,6 +495,7 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
continue continue
} }
// Hide private servers?
if m.fav_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" { if m.fav_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" {
if server.FavServersIterInList && server.FavServersIterSet { if server.FavServersIterInList && server.FavServersIterSet {
m.fav_servers_store.Remove(iter) m.fav_servers_store.Remove(iter)
@@ -446,6 +504,27 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
continue continue
} }
// Hide servers that using different version than selected in
// filter?
if m.fav_servers_version.GetActiveText() != "All versions" && m.fav_servers_version.GetActiveText() != server.Server.Version {
if server.FavServersIterInList && server.FavServersIterSet {
m.fav_servers_store.Remove(iter)
server.FavServersIterInList = false
}
continue
}
// Hide servers that using different gamemode than selected in
// filter?
gm_int_as_str := strconv.Itoa(m.fav_servers_gamemode.GetActive())
if m.fav_servers_gamemode.GetActiveText() != "All gamemodes" && gm_int_as_str != server.Server.Gamemode {
if server.FavServersIterInList && server.FavServersIterSet {
m.fav_servers_store.Remove(iter)
server.FavServersIterInList = false
}
continue
}
// If server on favorites widget, but not favorited (e.g. just // If server on favorites widget, but not favorited (e.g. just
// removed from favorites) - remove it from list. // removed from favorites) - remove it from list.
if server.Server.Favorite != "1" && server.FavServersIterSet && server.FavServersIterInList { if server.Server.Favorite != "1" && server.FavServersIterSet && server.FavServersIterInList {
@@ -482,7 +561,7 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Name"], server_name) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Name"], server_name)
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Mode"], m.getGameModeName(server.Server.Gamemode)) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Mode"], m.getGameModeName(server.Server.Gamemode))
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Map"], server.Server.Map) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Map"], server.Server.Map)
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Players"], server.Server.Players + "/" + server.Server.Maxplayers) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Players"], server.Server.Players + "/" + server.Server.Bots + "/" + server.Server.Maxplayers)
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Ping"], server.Server.Ping) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Ping"], server.Server.Ping)
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Version"], server.Server.Version) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["Version"], server.Server.Version)
m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["IP"], server.Server.Ip + ":" + server.Server.Port) m.fav_servers_store.SetValue(iter, m.column_pos["Favorites"]["IP"], server.Server.Ip + ":" + server.Server.Port)
@@ -568,9 +647,25 @@ func (m *MainWindow) showHide() {
} }
} }
func (m *MainWindow) showServerCVars() {
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if m.use_other_servers_tab {
if strings.Contains(current_tab, "Servers") {
current_tab = "Favorites"
} else if strings.Contains(current_tab, "Favorites") {
current_tab = "Servers"
}
}
srv_address := m.getIpFromServersList(current_tab)
if len(srv_address) > 0 {
m.server_cvars_dialog.Initialize(m.window, srv_address)
}
}
func (m *MainWindow) showShortServerInformation() { func (m *MainWindow) showShortServerInformation() {
fmt.Println("Server selection changed, updating server's information widget...") fmt.Println("Server selection changed, updating server's information widget...")
m.server_info_store.Clear() m.server_info_store.Clear()
m.players_info_store.Clear()
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 m.use_other_servers_tab { if m.use_other_servers_tab {
if strings.Contains(current_tab, "Servers") { if strings.Contains(current_tab, "Servers") {
@@ -589,12 +684,8 @@ func (m *MainWindow) showShortServerInformation() {
// Append to treeview generic info first. After appending it // Append to treeview generic info first. After appending it
// will be deleted from map. // will be deleted from map.
iter := new(gtk.TreeIter)
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "<markup><span font_weight=\"bold\">GENERAL INFO</span></markup>")
// Server's name. // Server's name.
iter = new(gtk.TreeIter) iter := new(gtk.TreeIter)
m.server_info_store.Append(iter) m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "Server's name") m.server_info_store.SetValue(iter, 0, "Server's name")
m.server_info_store.SetValue(iter, 1, ctx.Colorizer.Fix(parsed_general_data["sv_hostname"])) m.server_info_store.SetValue(iter, 1, ctx.Colorizer.Fix(parsed_general_data["sv_hostname"]))
@@ -611,7 +702,7 @@ func (m *MainWindow) showShortServerInformation() {
iter = new(gtk.TreeIter) iter = new(gtk.TreeIter)
m.server_info_store.Append(iter) m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "Players") m.server_info_store.SetValue(iter, 0, "Players")
m.server_info_store.SetValue(iter, 1, server_info.Players + " of " + parsed_general_data["sv_maxclients"]) m.server_info_store.SetValue(iter, 1, server_info.Players + " of " + parsed_general_data["sv_maxclients"] + " (" + server_info.Bots + " bots)")
delete(parsed_general_data, "sv_maxclients") delete(parsed_general_data, "sv_maxclients")
// Ping // Ping
@@ -642,15 +733,6 @@ func (m *MainWindow) showShortServerInformation() {
} }
m.server_info_store.SetValue(iter, 1, passworded_status) m.server_info_store.SetValue(iter, 1, passworded_status)
// Just a separator.
iter = new(gtk.TreeIter)
m.server_info_store.Append(iter)
// Players information
iter = new(gtk.TreeIter)
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "<markup><span font_weight=\"bold\">PLAYERS</span></markup>")
// Sorting keys of map. // Sorting keys of map.
players_map_keys := make([]string, 0, len(parsed_players_info)) players_map_keys := make([]string, 0, len(parsed_players_info))
for k := range parsed_players_info { for k := range parsed_players_info {
@@ -664,11 +746,13 @@ func (m *MainWindow) showShortServerInformation() {
for k := range players_map_keys { for k := range players_map_keys {
iter = new(gtk.TreeIter) iter = new(gtk.TreeIter)
nick := ctx.Colorizer.Fix(parsed_players_info[players_map_keys[k]]["nick"]) nick := ctx.Colorizer.Fix(parsed_players_info[players_map_keys[k]]["nick"])
m.server_info_store.Append(iter) m.players_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, nick) m.players_info_store.SetValue(iter, 0, nick)
m.server_info_store.SetValue(iter, 1, "(frags: " + parsed_players_info[players_map_keys[k]]["frags"] + " | ping: " + parsed_players_info[players_map_keys[k]]["ping"] + ")") m.players_info_store.SetValue(iter, 1, parsed_players_info[players_map_keys[k]]["frags"])
m.players_info_store.SetValue(iter, 2, parsed_players_info[players_map_keys[k]]["ping"])
} }
/*
// Just a separator. // Just a separator.
iter = new(gtk.TreeIter) iter = new(gtk.TreeIter)
m.server_info_store.Append(iter) m.server_info_store.Append(iter)
@@ -692,6 +776,7 @@ func (m *MainWindow) showShortServerInformation() {
m.server_info_store.SetValue(iter, 0, general_data_keys[k]) m.server_info_store.SetValue(iter, 0, general_data_keys[k])
m.server_info_store.SetValue(iter, 1, parsed_general_data[general_data_keys[k]]) m.server_info_store.SetValue(iter, 1, parsed_general_data[general_data_keys[k]])
} }
*/
} }
} }

View File

@@ -5,6 +5,7 @@ import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"runtime" "runtime"
"sort"
"strconv" "strconv"
// local // local
@@ -84,6 +85,7 @@ func (m *MainWindow) Initialize() {
// Dialogs initialization. // Dialogs initialization.
m.options_dialog = &OptionsDialog{} m.options_dialog = &OptionsDialog{}
m.server_cvars_dialog = &ServerCVarsDialog{}
// Main menu. // Main menu.
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
@@ -155,6 +157,10 @@ func (m *MainWindow) Initialize() {
m.window.Add(m.vbox) m.window.Add(m.vbox)
if runtime.GOOS == "darwin" {
m.initializeMacAfter()
}
m.window.ShowAll() m.window.ShowAll()
// Launch events. // Launch events.
@@ -239,6 +245,7 @@ func (m *MainWindow) initializeSidebar() {
// Scrolled thing. // Scrolled thing.
si_scroll := gtk.NewScrolledWindow(nil, nil) si_scroll := gtk.NewScrolledWindow(nil, nil)
si_scroll.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
si_vbox.PackStart(si_scroll, true, true, 5) si_vbox.PackStart(si_scroll, true, true, 5)
// Server's information. // Server's information.
@@ -253,6 +260,33 @@ func (m *MainWindow) initializeSidebar() {
si_scroll.Add(m.server_info) si_scroll.Add(m.server_info)
// Players information.
players_info_frame := gtk.NewFrame("Players")
sidebar_vbox.PackStart(players_info_frame, true, true, 5)
pi_scroll := gtk.NewScrolledWindow(nil, nil)
pi_scroll.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
players_info_frame.Add(pi_scroll)
m.players_info = gtk.NewTreeView()
m.players_info.SetModel(m.players_info_store)
pi_scroll.Add(m.players_info)
name_column := gtk.NewTreeViewColumnWithAttributes("Player name", gtk.NewCellRendererText(), "markup", 0)
m.players_info.AppendColumn(name_column)
frags_column := gtk.NewTreeViewColumnWithAttributes("Frags", gtk.NewCellRendererText(), "markup", 1)
m.players_info.AppendColumn(frags_column)
ping_column := gtk.NewTreeViewColumnWithAttributes("Ping", gtk.NewCellRendererText(), "markup", 2)
m.players_info.AppendColumn(ping_column)
// Show CVars button.
show_cvars_button := gtk.NewButtonWithLabel("Show CVars")
show_cvars_button.SetTooltipText("Show server's CVars")
show_cvars_button.Clicked(m.showServerCVars)
sidebar_vbox.PackStart(show_cvars_button, false, true, 5)
// Quick connect frame. // Quick connect frame.
quick_connect_frame := gtk.NewFrame("Quick connect") quick_connect_frame := gtk.NewFrame("Quick connect")
sidebar_vbox.PackStart(quick_connect_frame, false, true, 5) sidebar_vbox.PackStart(quick_connect_frame, false, true, 5)
@@ -347,6 +381,10 @@ func (m *MainWindow) initializeStorages() {
// Server's information store. Used for quick preview in main window. // Server's information store. Used for quick preview in main window.
m.server_info_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING) m.server_info_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING)
// Players information store. Used in sidebar for players list for
// currently selected server.
m.players_info_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING, glib.G_TYPE_STRING)
// Profiles count after filling combobox. Defaulting to 0. // Profiles count after filling combobox. Defaulting to 0.
m.old_profiles_count = 0 m.old_profiles_count = 0
@@ -488,8 +526,49 @@ func (m *MainWindow) InitializeTabs() {
} }
} }
// Filtering by version.
m.all_servers_version = gtk.NewComboBoxText()
m.all_servers_version.SetTooltipText("Show only servers which uses selected version of Urban Terror")
m.all_servers_version.AppendText("All versions")
for i := range common.SUPPORTED_URT_VERSIONS {
m.all_servers_version.AppendText(common.SUPPORTED_URT_VERSIONS[i])
}
all_servers_version_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/version"]
if ok {
all_servers_version_int, _ := strconv.Atoi(all_servers_version_val)
m.all_servers_version.SetActive(all_servers_version_int)
} else {
m.all_servers_version.SetActive(0)
}
m.all_servers_version.Connect("changed", m.allServersVersionFilterChanged)
tab_all_srv_ctl_vbox.PackStart(m.all_servers_version, false, true, 5)
// Filtering by gamemode
m.all_servers_gamemode = gtk.NewComboBoxText()
m.all_servers_gamemode.SetTooltipText("Show only servers which uses selected game mode")
m.all_servers_gamemode.AppendText("All gamemodes")
// Get sorted gamemodes keys.
gm_keys := make([]int, 0, len(m.gamemodes))
for i := range m.gamemodes {
key, _ := strconv.Atoi(i)
gm_keys = append(gm_keys, key)
}
sort.Ints(gm_keys)
for i := range gm_keys {
m.all_servers_gamemode.AppendText(m.gamemodes[strconv.Itoa(gm_keys[i])])
}
all_servers_gamemode_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/gamemode"]
if ok {
all_servers_gamemode_int, _ := strconv.Atoi(all_servers_gamemode_val)
m.all_servers_gamemode.SetActive(all_servers_gamemode_int)
} else {
m.all_servers_gamemode.SetActive(0)
}
m.all_servers_gamemode.Connect("changed", m.allServersGamemodeFilterChanged)
tab_all_srv_ctl_vbox.PackStart(m.all_servers_gamemode, false, true, 5)
// Final separator. // Final separator.
ctl_sep := gtk.NewVSeparator() ctl_sep := gtk.NewVBox(false, 0)
tab_all_srv_ctl_vbox.PackStart(ctl_sep, true, true, 5) tab_all_srv_ctl_vbox.PackStart(ctl_sep, true, true, 5)
// Favorites servers // Favorites servers
@@ -584,8 +663,43 @@ func (m *MainWindow) InitializeTabs() {
} }
} }
m.fav_servers_version = gtk.NewComboBoxText()
m.fav_servers_version.SetTooltipText("Show only servers which uses selected version of Urban Terror")
m.fav_servers_version.AppendText("All versions")
for i := range common.SUPPORTED_URT_VERSIONS {
m.fav_servers_version.AppendText(common.SUPPORTED_URT_VERSIONS[i])
}
fav_servers_version_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/version"]
if ok {
fav_servers_version_int, _ := strconv.Atoi(fav_servers_version_val)
m.fav_servers_version.SetActive(fav_servers_version_int)
} else {
m.fav_servers_version.SetActive(0)
}
m.fav_servers_version.Connect("changed", m.favServersVersionFilterChanged)
tab_fav_srv_ctl_vbox.PackStart(m.fav_servers_version, false, true, 5)
// Filtering by gamemode
m.fav_servers_gamemode = gtk.NewComboBoxText()
m.fav_servers_gamemode.SetTooltipText("Show only servers which uses selected game mode")
m.fav_servers_gamemode.AppendText("All gamemodes")
// Gamemode keys already sorted while adding same filter to "Servers"
// tab, so just re-use them.
for i := range gm_keys {
m.fav_servers_gamemode.AppendText(m.gamemodes[strconv.Itoa(gm_keys[i])])
}
fav_servers_gamemode_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/gamemode"]
if ok {
fav_servers_gamemode_int, _ := strconv.Atoi(fav_servers_gamemode_val)
m.fav_servers_gamemode.SetActive(fav_servers_gamemode_int)
} else {
m.fav_servers_gamemode.SetActive(0)
}
m.fav_servers_gamemode.Connect("changed", m.favServersGamemodeFilterChanged)
tab_fav_srv_ctl_vbox.PackStart(m.fav_servers_gamemode, false, true, 5)
// Final separator. // Final separator.
ctl_fav_sep := gtk.NewVSeparator() ctl_fav_sep := gtk.NewVBox(false, 0)
tab_fav_srv_ctl_vbox.PackStart(ctl_fav_sep, true, true, 5) tab_fav_srv_ctl_vbox.PackStart(ctl_fav_sep, true, true, 5)
// Add tab_widget widget to window. // Add tab_widget widget to window.

View File

@@ -21,6 +21,10 @@ func (m *MainWindow) initializeMac() {
} }
} }
func (m *MainWindow) initializeMacAfter() {
m.toolbar.SetStyle(gtk.TOOLBAR_ICONS)
}
func (m *MainWindow) initializeMacMenu() { func (m *MainWindow) initializeMacMenu() {
// This is a placeholder, in future we will use native mac menu. // This is a placeholder, in future we will use native mac menu.
// For now it launches default menu initialization. // For now it launches default menu initialization.

104
ui/server_cvars.go Normal file
View File

@@ -0,0 +1,104 @@
// 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
"fmt"
"sort"
// Local
"github.com/pztrn/urtrator/ioq3dataparser"
// Other
"github.com/mattn/go-gtk/gtk"
"github.com/mattn/go-gtk/glib"
)
type ServerCVarsDialog struct {
// Window.
window *gtk.Window
// Main Vertical Box.
vbox *gtk.VBox
// Treeview for CVars.
treeview *gtk.TreeView
// Store for treeview.
treeview_store *gtk.ListStore
}
func (scd *ServerCVarsDialog) Close() {
scd.window.Destroy()
}
func (scd *ServerCVarsDialog) fill(srv_address string) {
server_info := ctx.Cache.Servers[srv_address].Server
parsed_general_data := ioq3dataparser.ParseInfoToMap(server_info.ExtendedConfig)
// Sort it!
general_data_keys := make([]string, 0, len(parsed_general_data))
for k := range parsed_general_data {
general_data_keys = append(general_data_keys, k)
}
sort.Strings(general_data_keys)
for k := range general_data_keys {
iter := new(gtk.TreeIter)
scd.treeview_store.Append(iter)
scd.treeview_store.SetValue(iter, 0, 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) {
fmt.Println("Showing server's CVars...")
scd.initializeStorages()
scd.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
scd.window.SetTitle("URTrator - Server CVars")
scd.window.Connect("destroy", scd.Close)
scd.window.SetTransientFor(w)
scd.window.SetDefaultSize(300, 400)
scd.vbox = gtk.NewVBox(false, 0)
scd.window.Add(scd.vbox)
// CVars scrolls.
si := gtk.NewScrolledWindow(nil, nil)
scd.vbox.PackStart(si, true, true, 5)
// CVars list.
scd.treeview = gtk.NewTreeView()
scd.treeview.SetModel(scd.treeview_store)
si.Add(scd.treeview)
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Key", gtk.NewCellRendererText(), "markup", 0))
scd.treeview.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Value", gtk.NewCellRendererText(), "markup", 1))
// Close button.
hbox := gtk.NewHBox(false, 0)
scd.vbox.PackStart(hbox, false, true, 5)
sep := gtk.NewHBox(false, 0)
hbox.PackStart(sep, true, true, 5)
close_button := gtk.NewButtonWithLabel("Close")
close_button.Clicked(scd.Close)
hbox.PackStart(close_button, false, true, 5)
scd.fill(srv_address)
scd.window.ShowAll()
}
func (scd *ServerCVarsDialog) initializeStorages() {
scd.treeview_store = gtk.NewListStore(glib.G_TYPE_STRING, glib.G_TYPE_STRING)
}

View File

@@ -1,33 +0,0 @@
// 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
"fmt"
// Local
//"github.com/pztrn/urtrator/datamodels"
// Other
"github.com/mattn/go-gtk/gtk"
//"github.com/mattn/go-gtk/glib"
)
type ServerInfoDialog struct {
// Window.
window *gtk.Window
// Main Vertical Box.
vbox *gtk.VBox
}
func (sid *ServerInfoDialog) Initialize() {
fmt.Println("Showing server's information...")
}