CommonClient.py UI: add progressbar representing % of checks done.

CommonClient.py UI: add Commands button that points out /help and !help
CommonClient.py: track permissions
CommonClient.py: track missing locations and checked locations in lib
This commit is contained in:
Fabian Dill 2021-10-22 05:25:09 +02:00
parent 8e35372aad
commit 6af1f98c88
4 changed files with 40 additions and 9 deletions

View File

@ -105,6 +105,11 @@ class CommonContext():
self.server_task = None self.server_task = None
self.server: typing.Optional[Endpoint] = None self.server: typing.Optional[Endpoint] = None
self.server_version = Version(0, 0, 0) self.server_version = Version(0, 0, 0)
self.permissions = {
"forfeit": "disabled",
"collect": "disabled",
"remaining": "disabled",
}
# own state # own state
self.finished_game = False self.finished_game = False
@ -230,6 +235,15 @@ class CommonContext():
"""For custom package handling in subclasses.""" """For custom package handling in subclasses."""
pass pass
def update_permissions(self, permissions: typing.Dict[str, int]):
for permission_name, permission_flag in permissions.items():
try:
flag = Permission(permission_flag)
logger.info(f"{permission_name.capitalize()} permission: {flag.name}")
self.permissions[permission_name] = flag.name
except Exception as e: # safeguard against permissions that may be implemented in the future
logger.exception(e)
async def keep_alive(ctx: CommonContext, seconds_between_checks=100): async def keep_alive(ctx: CommonContext, seconds_between_checks=100):
"""some ISPs/network configurations drop TCP connections if no payload is sent (ignore TCP-keep-alive) """some ISPs/network configurations drop TCP connections if no payload is sent (ignore TCP-keep-alive)
@ -319,10 +333,7 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
logger.info("Server protocol tags: " + ", ".join(args["tags"])) logger.info("Server protocol tags: " + ", ".join(args["tags"]))
if args['password']: if args['password']:
logger.info('Password required') logger.info('Password required')
ctx.update_permissions(args.get("permissions", {}))
for permission_name, permission_flag in args.get("permissions", {}).items():
flag = Permission(permission_flag)
logger.info(f"{permission_name.capitalize()} permission: {flag.name}")
logger.info( logger.info(
f"A !hint costs {args['hint_cost']}% of your total location count as points" f"A !hint costs {args['hint_cost']}% of your total location count as points"
f" and you get {args['location_check_points']}" f" and you get {args['location_check_points']}"
@ -419,6 +430,12 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
ctx.consume_players_package(args["players"]) ctx.consume_players_package(args["players"])
if "hint_points" in args: if "hint_points" in args:
ctx.hint_points = args['hint_points'] ctx.hint_points = args['hint_points']
if "checked_locations" in args:
checked = set(args["checked_locations"])
ctx.checked_locations |= checked
ctx.missing_locations -= checked
if "permissions" in args:
ctx.update_permissions(args["permissions"])
elif cmd == 'Print': elif cmd == 'Print':
ctx.on_print(args) ctx.on_print(args)

View File

@ -248,7 +248,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
import NetUtils import NetUtils
slot_data = {} slot_data = {}
client_versions = {} client_versions = {}
minimum_versions = {"server": (0, 1, 1), "clients": client_versions} minimum_versions = {"server": (0, 1, 8), "clients": client_versions}
games = {} games = {}
for slot in world.player_ids: for slot in world.player_ids:
client_versions[slot] = world.worlds[slot].get_required_client_version() client_versions[slot] = world.worlds[slot].get_required_client_version()

View File

@ -1230,8 +1230,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
"players": ctx.get_players_package(), "players": ctx.get_players_package(),
"missing_locations": get_missing_checks(ctx, team, slot), "missing_locations": get_missing_checks(ctx, team, slot),
"checked_locations": get_checked_checks(ctx, team, slot), "checked_locations": get_checked_checks(ctx, team, slot),
# get is needed for old multidata that was sparsely populated "slot_data": ctx.slot_data[client.slot]
"slot_data": ctx.slot_data.get(client.slot, {})
}] }]
items = get_received_items(ctx, client.team, client.slot) items = get_received_items(ctx, client.team, client.slot)
if items: if items:

19
kvui.py
View File

@ -15,6 +15,7 @@ from kivy.uix.recycleview import RecycleView
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelItem from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelItem
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from kivy.utils import escape_markup from kivy.utils import escape_markup
from kivy.lang import Builder from kivy.lang import Builder
@ -48,6 +49,7 @@ class GameManager(App):
self.grid = GridLayout() self.grid = GridLayout()
self.grid.cols = 1 self.grid.cols = 1
connect_layout = BoxLayout(orientation="horizontal", size_hint_y=None, height=30) connect_layout = BoxLayout(orientation="horizontal", size_hint_y=None, height=30)
# top part
server_label = Label(text="Server:", size_hint_x=None) server_label = Label(text="Server:", size_hint_x=None)
connect_layout.add_widget(server_label) connect_layout.add_widget(server_label)
self.server_connect_bar = TextInput(text="archipelago.gg", size_hint_y=None, height=30, multiline=False) self.server_connect_bar = TextInput(text="archipelago.gg", size_hint_y=None, height=30, multiline=False)
@ -55,8 +57,11 @@ class GameManager(App):
self.server_connect_button = Button(text="Connect", size=(100, 30), size_hint_y=None, size_hint_x=None) self.server_connect_button = Button(text="Connect", size=(100, 30), size_hint_y=None, size_hint_x=None)
self.server_connect_button.bind(on_press=self.connect_button_action) self.server_connect_button.bind(on_press=self.connect_button_action)
connect_layout.add_widget(self.server_connect_button) connect_layout.add_widget(self.server_connect_button)
self.grid.add_widget(connect_layout) self.grid.add_widget(connect_layout)
self.progressbar = ProgressBar(size_hint_y=None, height=3)
self.grid.add_widget(self.progressbar)
# middle part
self.tabs = TabbedPanel(size_hint_y=1) self.tabs = TabbedPanel(size_hint_y=1)
self.tabs.default_tab_text = "All" self.tabs.default_tab_text = "All"
self.log_panels["All"] = self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name) self.log_panels["All"] = self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name)
@ -78,9 +83,16 @@ class GameManager(App):
self.tabs.current_tab.height = 0 self.tabs.current_tab.height = 0
self.tabs.tab_height = 0 self.tabs.tab_height = 0
# bottom part
bottom_layout = BoxLayout(orientation="horizontal", size_hint_y=None, height=30)
info_button = Button(height=30, text="Command:", size_hint_x=None)
info_button.bind(on_release=lambda button: logging.getLogger("Client").info(
"/help for client commands and !help for server commands."))
bottom_layout.add_widget(info_button)
textinput = TextInput(size_hint_y=None, height=30, multiline=False) textinput = TextInput(size_hint_y=None, height=30, multiline=False)
textinput.bind(on_text_validate=self.on_message) textinput.bind(on_text_validate=self.on_message)
self.grid.add_widget(textinput) bottom_layout.add_widget(textinput)
self.grid.add_widget(bottom_layout)
self.commandprocessor("/help") self.commandprocessor("/help")
Clock.schedule_interval(self.update_texts, 1 / 30) Clock.schedule_interval(self.update_texts, 1 / 30)
return self.grid return self.grid
@ -89,9 +101,12 @@ class GameManager(App):
if self.ctx.server: if self.ctx.server:
self.title = self.base_title + f" | Connected to: {self.ctx.server_address}" self.title = self.base_title + f" | Connected to: {self.ctx.server_address}"
self.server_connect_button.text = "Disconnect" self.server_connect_button.text = "Disconnect"
self.progressbar.max = len(self.ctx.checked_locations) + len(self.ctx.missing_locations)
self.progressbar.value = len(self.ctx.checked_locations)
else: else:
self.server_connect_button.text = "Connect" self.server_connect_button.text = "Connect"
self.title = self.base_title self.title = self.base_title
self.progressbar.value = 0
def connect_button_action(self, button): def connect_button_action(self, button):
if self.ctx.server: if self.ctx.server: