mirror of
https://github.com/aclist/dztui.git
synced 2026-08-27 18:27:07 +02:00
feat: refresh player count
This commit is contained in:
parent
06450ddadc
commit
e1f54bd75d
@ -453,11 +453,24 @@ def query_by_id(addr: str, key: str) -> Optional[dict]:
|
||||
return None
|
||||
|
||||
|
||||
def query_playercount(record: Record) -> Optional[tuple[int]]:
|
||||
try:
|
||||
res = query_direct(record.ip, record.qport)
|
||||
players = int(res["players"])
|
||||
r = res["gametype"].split("lqs")
|
||||
try:
|
||||
queue = int(r[1].split(",")[0])
|
||||
except IndexError:
|
||||
queue = 0
|
||||
return (players, queue)
|
||||
except Exception as e:
|
||||
logger.critical(e)
|
||||
return None
|
||||
|
||||
def query_by_ip(addr: str) -> Optional[dict]:
|
||||
record = short_ip_to_record(addr)
|
||||
return query_by_record(record)
|
||||
|
||||
|
||||
def query_by_record(record: Record) -> Optional[dict]:
|
||||
try:
|
||||
return query_direct(record.ip, record.qport)
|
||||
|
||||
@ -604,6 +604,10 @@ class Controller(GObject.GObject):
|
||||
saved_tree = self.get_servers().get_saved()
|
||||
ServerModelManager(self, saved_tree).add_by_record(record)
|
||||
|
||||
def remove_by_record(self, record: "Record") -> None:
|
||||
saved_tree = self.get_servers().get_saved()
|
||||
ServerModelManager(self, saved_tree).remove_by_record(record)
|
||||
|
||||
def connect_by_str(self, addr: str) -> None:
|
||||
if addr.isdigit():
|
||||
config_man = self.get_config_man()
|
||||
@ -652,3 +656,8 @@ class Controller(GObject.GObject):
|
||||
tv = self.get_active_treeview()
|
||||
record = tv.get_record_string()
|
||||
self.notes_man.delete_note(record)
|
||||
|
||||
def refresh_players(self, record: "Record") -> None:
|
||||
treeview = self.get_active_treeview()
|
||||
model, treeiter = treeview.get_selection().get_selected()
|
||||
ServerModelManager(self, treeview).update_playercount(treeiter, record)
|
||||
|
||||
@ -48,6 +48,11 @@ class ConfigManager:
|
||||
ips.append(record)
|
||||
self.update_config(Preferences.IP_LIST, ips)
|
||||
|
||||
def remove_saved_server(self, record: str) -> None:
|
||||
ips = self.lookup(Preferences.IP_LIST)
|
||||
ips.remove(record)
|
||||
self.update_config(Preferences.IP_LIST, ips)
|
||||
|
||||
# TODO: drop/reroute
|
||||
def update_config(self, key: Preferences, value: str) -> None:
|
||||
self.write_config(key, value)
|
||||
|
||||
@ -66,7 +66,10 @@ class ContextMenuManager:
|
||||
|
||||
case ContextMenu.REFRESH_PLAYERS:
|
||||
print("DEBUG: unimplemented")
|
||||
# get record
|
||||
record = self.treeview.get_record()
|
||||
self.controller.refresh_players(record)
|
||||
|
||||
# TODO: just updates proxy model, this info is ephemeral
|
||||
# call a2s on thread
|
||||
pass
|
||||
case ContextMenu.REMOVE_HISTORY:
|
||||
@ -75,9 +78,8 @@ class ContextMenuManager:
|
||||
# see dq.py
|
||||
pass
|
||||
case ContextMenu.REMOVE_SERVER:
|
||||
print("DEBUG: unimplemented")
|
||||
# reverse of ADD_SERVER
|
||||
pass
|
||||
record = self.treeview.get_record()
|
||||
self.controller.remove_by_record(record)
|
||||
case ContextMenu.SHOW_DETAILS:
|
||||
record = self.treeview.get_record()
|
||||
self.controller.get_details(record)
|
||||
|
||||
@ -10,7 +10,12 @@ from dzgui.util import strings
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.managers.filter_man import FilterManager
|
||||
from dzgui.model.model_factory import FastInsertListStore
|
||||
from dzgui.model.servers import NewPlayerCount
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository.Gtk import TreeIter
|
||||
|
||||
class ProxyModelManager:
|
||||
"""
|
||||
@ -35,9 +40,27 @@ class ProxyModelManager:
|
||||
self.filtered: list = None
|
||||
self.success = True
|
||||
|
||||
def has_control_model(self) -> bool:
|
||||
pass
|
||||
|
||||
def append_row(self, row: list) -> None:
|
||||
self.proxy_model.append(row)
|
||||
|
||||
def append_row_to_control(self, row: list) -> None:
|
||||
self.control_model.append(row)
|
||||
self.filter(FilterMode.INITIAL, skip_cache=True)
|
||||
|
||||
def remove_row_from_control(self, row: list) -> None:
|
||||
for record in self.control_model:
|
||||
if row[7] == record[7] and row[8] == record[8]:
|
||||
self.control_model.remove(record)
|
||||
self.filter(FilterMode.INITIAL, skip_cache=True)
|
||||
|
||||
def update_playercount(self, playercount: "NewPlayerCount") -> None:
|
||||
treeiter = playercount.treeiter
|
||||
self.proxy_model[treeiter][4] = playercount.players
|
||||
self.proxy_model[treeiter][6] = playercount.queue
|
||||
|
||||
def clear_proxy_model(self) -> None:
|
||||
self.proxy_model.clear()
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from concurrent.futures import as_completed
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import dzgui.api.servers as Servers
|
||||
@ -29,9 +31,15 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# TODO: failure: spawns error dialog
|
||||
# TODO: failure should spawn error dialog
|
||||
# TODO: non failure with empty model: updates statusbar with help text
|
||||
|
||||
@dataclass
|
||||
class NewPlayerCount:
|
||||
treeiter: Gtk.TreeIter
|
||||
players: int
|
||||
queue: int
|
||||
|
||||
|
||||
class ServerModelManager:
|
||||
def __init__(self, controller: "Controller", tv: Gtk.TreeView) -> None:
|
||||
@ -207,50 +215,65 @@ class ServerModelManager:
|
||||
# FIXME: use "adding server" string
|
||||
@call_on_thread(dialog.querying)
|
||||
def add_by_record(self, record: Servers.Record) -> None:
|
||||
"""
|
||||
Record as shown in server browser may resolve to a different IP
|
||||
"""
|
||||
res = Servers.query_by_record(record)
|
||||
self._parse_single_record(res)
|
||||
|
||||
@call_on_thread(dialog.querying)
|
||||
def remove_by_record(self, record: Servers.Record) -> None:
|
||||
res = Servers.query_by_record(record)
|
||||
self._parse_single_record(res, delete=True)
|
||||
|
||||
def add_by_str(self, addr: str) -> None:
|
||||
if addr.isdigit():
|
||||
self.add_by_id(addr)
|
||||
else:
|
||||
self.add_by_ip(addr)
|
||||
|
||||
def _parse_single_record(self, response: dict) -> None:
|
||||
@call_on_thread(dialog.querying)
|
||||
def update_playercount(self, treeiter: Gtk.TreeIter, record: Servers.Record) -> None:
|
||||
proxy_man = self._get_proxy_man()
|
||||
res = Servers.query_playercount(record)
|
||||
if res is None:
|
||||
return
|
||||
players, queue = res
|
||||
|
||||
self.playercount = NewPlayerCount(treeiter, players, queue)
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._push_playercount))
|
||||
|
||||
def _push_playercount(self) -> None:
|
||||
proxy_man = self._get_proxy_man()
|
||||
proxy_man.update_playercount(self.playercount)
|
||||
|
||||
def _parse_single_record(self, response: dict, delete: bool = False) -> None:
|
||||
if response is None:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
return
|
||||
|
||||
# NOTE: expected to only contain one item
|
||||
records = Servers.parse_json([response])
|
||||
record = records[0]
|
||||
|
||||
proxy_man = self._get_proxy_man()
|
||||
raw_model = proxy_man.get_control()
|
||||
|
||||
fqip = Servers.response_to_fq_ip(response)
|
||||
config_man = self.controller.get_config_man()
|
||||
config_man.add_saved_server(fqip)
|
||||
|
||||
# NOTE: abort early if Saved Servers tab was not loaded yet
|
||||
if raw_model is None:
|
||||
return
|
||||
if delete:
|
||||
# NOTE: abort early if Saved Servers tab was not loaded yet
|
||||
config_man.remove_saved_server(fqip)
|
||||
if proxy_man.has_control_model() is False:
|
||||
return
|
||||
proxy_man.remove_row_from_control(record)
|
||||
else:
|
||||
config_man.add_saved_server(fqip)
|
||||
if proxy_man.has_control_model() is False:
|
||||
return
|
||||
proxy_man.append_row_to_control(record)
|
||||
|
||||
# NOTE: expected to only contain one item
|
||||
raw_model.append(record)
|
||||
|
||||
# TODO: if all filters are already applied, strange behavior may occur
|
||||
# -> need to insert and reupdate tree per current filters
|
||||
# for example, non-empty will only show up in empty because it is not cached
|
||||
|
||||
# FIXME: new results are not being shown when tabbing over to Saved Servers
|
||||
proxy_man.filter(FilterMode.INITIAL, skip_cache=True)
|
||||
|
||||
filter_man = self.tv.get_filter_man()
|
||||
old_maps = filter_man.get_unique_maps()
|
||||
cur_map = record[1]
|
||||
if cur_map not in old_maps:
|
||||
old_maps.append(cur_map)
|
||||
self._set_new_maps(old_maps)
|
||||
control_model = proxy_man.get_control()
|
||||
self._sort_unique_maps(control_model)
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_single_ip))
|
||||
|
||||
def _dump_history(self) -> None:
|
||||
@ -295,8 +318,8 @@ class ServerModelManager:
|
||||
# TODO: animate saved servers tab if we are on other tab
|
||||
self.emitter.emit("servers_loaded", self.enum)
|
||||
|
||||
# TODO: consolidate methods and handle multi/single map addition
|
||||
filter_man = self.tv.get_filter_man()
|
||||
# NOTE: maps are set outside of thread because it triggers map changed signals
|
||||
maps = self._get_new_maps()
|
||||
filter_man.set_unique_maps(maps)
|
||||
|
||||
@ -314,8 +337,6 @@ class ServerModelManager:
|
||||
self.tv.set_model(proxy)
|
||||
|
||||
# TODO: make sure control model len is N + 1
|
||||
# inserting a row serializes file on disk, updates control model for that tab, and updates model
|
||||
# NOTE: when inserting new rows, the entire control model is wiped and rebuilt, then proxy model is swapped in
|
||||
# TODO: signals or other approach to deferring map
|
||||
# model insertion after thread closes
|
||||
# cf. servers_loaded signal
|
||||
|
||||
Loading…
Reference in New Issue
Block a user