| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | from __future__ import annotations | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | import argparse | 
					
						
							|  |  |  | import asyncio | 
					
						
							|  |  |  | import functools | 
					
						
							|  |  |  | import json | 
					
						
							|  |  |  | import logging | 
					
						
							| 
									
										
										
										
											2020-01-04 22:08:13 +01:00
										 |  |  | import zlib | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | import collections | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | import typing | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | import inspect | 
					
						
							| 
									
										
										
										
											2020-04-19 14:05:58 +02:00
										 |  |  | import weakref | 
					
						
							| 
									
										
										
										
											2020-04-20 04:36:56 +02:00
										 |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  | import threading | 
					
						
							| 
									
										
										
										
											2020-07-14 07:01:51 +02:00
										 |  |  | import random | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | import ModuleUpdate | 
					
						
							| 
									
										
										
										
											2020-03-13 03:53:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | ModuleUpdate.update() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import websockets | 
					
						
							| 
									
										
										
										
											2020-03-13 03:53:20 +01:00
										 |  |  | import prompt_toolkit | 
					
						
							|  |  |  | from prompt_toolkit.patch_stdout import patch_stdout | 
					
						
							| 
									
										
										
										
											2020-02-17 13:57:48 +01:00
										 |  |  | from fuzzywuzzy import process as fuzzy_process | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | import Items | 
					
						
							|  |  |  | import Regions | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | import Utils | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  | from Utils import get_item_name_from_id, get_location_name_from_address, ReceivedItem, _version_tuple | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | from NetUtils import Node, Endpoint | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 04:40:09 -08:00
										 |  |  | console_names = frozenset(set(Items.item_table) | set(Items.item_name_groups) | set(Regions.lookup_name_to_id)) | 
					
						
							| 
									
										
										
										
											2020-02-17 13:57:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  | CLIENT_PLAYING = 0 | 
					
						
							|  |  |  | CLIENT_GOAL = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | class Client(Endpoint): | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |     version: typing.List[int] = [0, 0, 0] | 
					
						
							|  |  |  |     tags: typing.List[str] = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     def __init__(self, socket: websockets.server.WebSocketServerProtocol, ctx: Context): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         super().__init__(socket) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         self.auth = False | 
					
						
							|  |  |  |         self.name = None | 
					
						
							|  |  |  |         self.team = None | 
					
						
							|  |  |  |         self.slot = None | 
					
						
							|  |  |  |         self.send_index = 0 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |         self.tags = [] | 
					
						
							|  |  |  |         self.version = [0, 0, 0] | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  |         self.messageprocessor = client_message_processor(ctx, self) | 
					
						
							| 
									
										
										
										
											2020-04-19 14:05:58 +02:00
										 |  |  |         self.ctx = weakref.ref(ctx) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-23 02:47:07 -07:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def wants_item_notification(self): | 
					
						
							|  |  |  |         return self.auth and "FoundItems" in self.tags | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | class Context(Node): | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |     simple_options = {"hint_cost": int, | 
					
						
							|  |  |  |                       "location_check_points": int, | 
					
						
							|  |  |  |                       "server_password": str, | 
					
						
							|  |  |  |                       "password": str, | 
					
						
							|  |  |  |                       "forfeit_mode": str, | 
					
						
							| 
									
										
										
										
											2020-11-30 21:07:02 +01:00
										 |  |  |                       "remaining_mode": str, | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |                       "item_cheat": bool, | 
					
						
							|  |  |  |                       "compatibility": int} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     def __init__(self, host: str, port: int, server_password: str, password: str, location_check_points: int, | 
					
						
							|  |  |  |                  hint_cost: int, item_cheat: bool, forfeit_mode: str = "disabled", remaining_mode: str = "disabled", | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |                  auto_shutdown: typing.SupportsFloat = 0, compatibility: int = 2): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         super(Context, self).__init__() | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |         self.compatibility: int = compatibility | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |         self.shutdown_task = None | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         self.data_filename = None | 
					
						
							|  |  |  |         self.save_filename = None | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.saving = False | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |         self.player_names = {} | 
					
						
							| 
									
										
										
										
											2020-01-04 22:08:13 +01:00
										 |  |  |         self.rom_names = {} | 
					
						
							| 
									
										
										
										
											2020-09-02 02:23:31 -07:00
										 |  |  |         self.allow_forfeits = {} | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  |         self.remote_items = set() | 
					
						
							| 
									
										
										
										
											2020-01-04 22:08:13 +01:00
										 |  |  |         self.locations = {} | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         self.host = host | 
					
						
							|  |  |  |         self.port = port | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |         self.server_password = server_password | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         self.password = password | 
					
						
							|  |  |  |         self.server = None | 
					
						
							| 
									
										
										
										
											2020-01-10 22:44:07 +01:00
										 |  |  |         self.countdown_timer = 0 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         self.received_items = {} | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |         self.name_aliases: typing.Dict[typing.Tuple[int, int], str] = {} | 
					
						
							| 
									
										
										
										
											2020-02-09 12:10:12 +01:00
										 |  |  |         self.location_checks = collections.defaultdict(set) | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |         self.hint_cost = hint_cost | 
					
						
							|  |  |  |         self.location_check_points = location_check_points | 
					
						
							| 
									
										
										
										
											2020-02-22 18:04:35 +01:00
										 |  |  |         self.hints_used = collections.defaultdict(int) | 
					
						
							| 
									
										
										
										
											2020-04-22 05:09:46 +02:00
										 |  |  |         self.hints: typing.Dict[typing.Tuple[int, int], typing.Set[Utils.Hint]] = collections.defaultdict(set) | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |         self.forfeit_mode: str = forfeit_mode | 
					
						
							|  |  |  |         self.remaining_mode: str = remaining_mode | 
					
						
							| 
									
										
										
										
											2020-02-22 19:42:44 +01:00
										 |  |  |         self.item_cheat = item_cheat | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         self.running = True | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.client_activity_timers: typing.Dict[ | 
					
						
							| 
									
										
										
										
											2020-06-23 14:01:01 +02:00
										 |  |  |             typing.Tuple[int, int], datetime.datetime] = {}  # datetime of last new item check | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.client_connection_timers: typing.Dict[ | 
					
						
							|  |  |  |             typing.Tuple[int, int], datetime.datetime] = {}  # datetime of last connection | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |         self.client_game_state: typing.Dict[typing.Tuple[int, int], int] = collections.defaultdict(int) | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |         self.er_hint_data: typing.Dict[int, typing.Dict[int, str]] = {} | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |         self.auto_shutdown = auto_shutdown | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         self.commandprocessor = ServerCommandProcessor(self) | 
					
						
							| 
									
										
										
										
											2020-06-13 22:49:57 +02:00
										 |  |  |         self.embedded_blacklist = {"host", "port"} | 
					
						
							| 
									
										
										
										
											2020-06-16 01:05:32 +02:00
										 |  |  |         self.client_ids: typing.Dict[typing.Tuple[int, int], datetime.datetime] = {} | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |         self.auto_save_interval = 60  # in seconds | 
					
						
							|  |  |  |         self.auto_saver_thread = None | 
					
						
							|  |  |  |         self.save_dirty = False | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  |         self.tags = ['Berserker'] | 
					
						
							| 
									
										
										
										
											2020-12-29 19:23:14 +01:00
										 |  |  |         self.minimum_client_versions: typing.Dict[typing.Tuple[int, int], Utils.Version] = {} | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  |     def load(self, multidatapath: str, use_embedded_server_options: bool = False): | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         with open(multidatapath, 'rb') as f: | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |             self._load(json.loads(zlib.decompress(f.read()).decode("utf-8-sig")), | 
					
						
							|  |  |  |                        use_embedded_server_options) | 
					
						
							| 
									
										
										
										
											2020-07-10 17:42:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.data_filename = multidatapath | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |     def _load(self, jsonobj: dict, use_embedded_server_options: bool): | 
					
						
							| 
									
										
										
										
											2020-12-29 19:23:14 +01:00
										 |  |  |         if "minimum_versions" in jsonobj: | 
					
						
							|  |  |  |             mdata_ver = tuple(jsonobj["minimum_versions"]["server"]) | 
					
						
							|  |  |  |             if mdata_ver > Utils._version_tuple: | 
					
						
							|  |  |  |                 raise RuntimeError(f"Supplied Multidata requires a server of at least version {mdata_ver}," | 
					
						
							|  |  |  |                                    f"however this server is of version {Utils._version_tuple}") | 
					
						
							|  |  |  |             clients_ver = jsonobj["minimum_versions"].get("clients", []) | 
					
						
							|  |  |  |             self.minimum_client_versions = {} | 
					
						
							|  |  |  |             for team, player, version in clients_ver: | 
					
						
							|  |  |  |                 self.minimum_client_versions[team, player] = Utils.Version(*version) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         for team, names in enumerate(jsonobj['names']): | 
					
						
							|  |  |  |             for player, name in enumerate(names, 1): | 
					
						
							|  |  |  |                 self.player_names[(team, player)] = name | 
					
						
							| 
									
										
										
										
											2020-07-14 05:06:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if "rom_strings" in jsonobj: | 
					
						
							|  |  |  |             self.rom_names = {rom: (team, slot) for slot, team, rom in jsonobj['rom_strings']} | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.rom_names = {bytes(letter for letter in rom).decode(): (team, slot) for slot, team, rom in | 
					
						
							|  |  |  |                               jsonobj['roms']} | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.remote_items = set(jsonobj['remote_items']) | 
					
						
							|  |  |  |         self.locations = {tuple(k): tuple(v) for k, v in jsonobj['locations']} | 
					
						
							|  |  |  |         if "er_hint_data" in jsonobj: | 
					
						
							|  |  |  |             self.er_hint_data = {int(player): {int(address): name for address, name in loc_data.items()} | 
					
						
							|  |  |  |                                  for player, loc_data in jsonobj["er_hint_data"].items()} | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  |         if use_embedded_server_options: | 
					
						
							|  |  |  |             server_options = jsonobj.get("server_options", {}) | 
					
						
							|  |  |  |             self._set_options(server_options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _set_options(self, server_options: dict): | 
					
						
							|  |  |  |         for key, value in server_options.items(): | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |             data_type = self.simple_options.get(key, None) | 
					
						
							|  |  |  |             if data_type is not None: | 
					
						
							|  |  |  |                 if value not in {False, True, None}: # some can be boolean OR text, such as password | 
					
						
							|  |  |  |                     try: | 
					
						
							|  |  |  |                         value = data_type(value) | 
					
						
							|  |  |  |                     except Exception as e: | 
					
						
							|  |  |  |                         try: | 
					
						
							|  |  |  |                             raise Exception(f"Could not set server option {key}, skipping.") from e | 
					
						
							|  |  |  |                         except Exception as e: | 
					
						
							|  |  |  |                             logging.exception(e) | 
					
						
							|  |  |  |                 logging.debug(f"Setting server option {key} to {value} from supplied multidata") | 
					
						
							|  |  |  |                 setattr(self, key, value) | 
					
						
							|  |  |  |             elif key == "disable_item_cheat": | 
					
						
							|  |  |  |                 self.item_cheat = not bool(value) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 logging.debug(f"Unrecognized server option {key}") | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |     def save(self, now=False) -> bool: | 
					
						
							|  |  |  |         if self.saving: | 
					
						
							|  |  |  |             if now: | 
					
						
							|  |  |  |                 self.save_dirty = False | 
					
						
							|  |  |  |                 return self._save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.save_dirty = True | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 14:17:05 +02:00
										 |  |  |     def _save(self, exit_save:bool=False) -> bool: | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             jsonstr = json.dumps(self.get_save()) | 
					
						
							|  |  |  |             with open(self.save_filename, "wb") as f: | 
					
						
							|  |  |  |                 f.write(zlib.compress(jsonstr.encode("utf-8"))) | 
					
						
							|  |  |  |         except Exception as e: | 
					
						
							|  |  |  |             logging.exception(e) | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  |     def init_save(self, enabled: bool = True): | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         self.saving = enabled | 
					
						
							|  |  |  |         if self.saving: | 
					
						
							|  |  |  |             if not self.save_filename: | 
					
						
							|  |  |  |                 self.save_filename = (self.data_filename[:-9] if self.data_filename[-9:] == 'multidata' else ( | 
					
						
							|  |  |  |                         self.data_filename + '_')) + 'multisave' | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(self.save_filename, 'rb') as f: | 
					
						
							|  |  |  |                     jsonobj = json.loads(zlib.decompress(f.read()).decode("utf-8")) | 
					
						
							|  |  |  |                     self.set_save(jsonobj) | 
					
						
							|  |  |  |             except FileNotFoundError: | 
					
						
							|  |  |  |                 logging.error('No save data found, starting a new game') | 
					
						
							|  |  |  |             except Exception as e: | 
					
						
							|  |  |  |                 logging.exception(e) | 
					
						
							| 
									
										
										
										
											2020-06-20 20:03:06 +02:00
										 |  |  |             self._start_async_saving() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _start_async_saving(self): | 
					
						
							|  |  |  |         if not self.auto_saver_thread: | 
					
						
							|  |  |  |             def save_regularly(): | 
					
						
							|  |  |  |                 import time | 
					
						
							|  |  |  |                 while self.running: | 
					
						
							|  |  |  |                     time.sleep(self.auto_save_interval) | 
					
						
							|  |  |  |                     if self.save_dirty: | 
					
						
							|  |  |  |                         logging.debug("Saving multisave via thread.") | 
					
						
							|  |  |  |                         self.save_dirty = False | 
					
						
							|  |  |  |                         self._save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.auto_saver_thread = threading.Thread(target=save_regularly, daemon=True) | 
					
						
							|  |  |  |             self.auto_saver_thread.start() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |             import atexit | 
					
						
							| 
									
										
										
										
											2020-07-20 14:17:05 +02:00
										 |  |  |             atexit.register(self._save, True)  # make sure we save on exit too | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |     def get_save(self) -> dict: | 
					
						
							| 
									
										
										
										
											2020-04-22 15:50:14 +02:00
										 |  |  |         d = { | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |             "rom_names": list(self.rom_names.items()), | 
					
						
							| 
									
										
										
										
											2020-02-22 19:42:44 +01:00
										 |  |  |             "received_items": tuple((k, v) for k, v in self.received_items.items()), | 
					
						
							| 
									
										
										
										
											2020-04-22 05:09:46 +02:00
										 |  |  |             "hints_used": tuple((key, value) for key, value in self.hints_used.items()), | 
					
						
							| 
									
										
										
										
											2020-07-27 19:30:31 +02:00
										 |  |  |             "hints": tuple( | 
					
						
							|  |  |  |                 (key, list(hint.re_check(self, key[0]) for hint in value)) for key, value in self.hints.items()), | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |             "location_checks": tuple((key, tuple(value)) for key, value in self.location_checks.items()), | 
					
						
							|  |  |  |             "name_aliases": tuple((key, value) for key, value in self.name_aliases.items()), | 
					
						
							| 
									
										
										
										
											2020-06-23 14:01:01 +02:00
										 |  |  |             "client_game_state": tuple((key, value) for key, value in self.client_game_state.items()), | 
					
						
							|  |  |  |             "client_activity_timers": tuple( | 
					
						
							|  |  |  |                 (key, value.timestamp()) for key, value in self.client_activity_timers.items()), | 
					
						
							|  |  |  |             "client_connection_timers": tuple( | 
					
						
							|  |  |  |                 (key, value.timestamp()) for key, value in self.client_connection_timers.items()), | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-22 15:50:14 +02:00
										 |  |  |         return d | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |     def set_save(self, savedata: dict): | 
					
						
							| 
									
										
										
										
											2020-07-16 02:29:36 +02:00
										 |  |  |         rom_names = savedata["rom_names"]  # convert from TrackerList to List in case of ponyorm | 
					
						
							| 
									
										
										
										
											2020-07-22 12:02:09 +02:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2020-07-24 14:00:59 +02:00
										 |  |  |             adjusted = {rom: (team, slot) for rom, (team, slot) in rom_names} | 
					
						
							| 
									
										
										
										
											2020-07-22 12:02:09 +02:00
										 |  |  |         except TypeError: | 
					
						
							|  |  |  |             adjusted = {tuple(rom): (team, slot) for (rom, (team, slot)) in rom_names}  # old format, ponyorm friendly | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  |             if self.rom_names != adjusted: | 
					
						
							| 
									
										
										
										
											2020-07-16 02:29:36 +02:00
										 |  |  |                 logging.warning('Save file mismatch, will start a new game') | 
					
						
							| 
									
										
										
										
											2020-07-24 14:14:45 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2020-07-22 12:02:09 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if adjusted != self.rom_names: | 
					
						
							|  |  |  |                 logging.warning('Save file mismatch, will start a new game') | 
					
						
							| 
									
										
										
										
											2020-07-16 02:29:36 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         received_items = {tuple(k): [ReceivedItem(*i) for i in v] for k, v in savedata["received_items"]} | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |         self.received_items = received_items | 
					
						
							|  |  |  |         self.hints_used.update({tuple(key): value for key, value in savedata["hints_used"]}) | 
					
						
							| 
									
										
										
										
											2020-04-22 05:09:46 +02:00
										 |  |  |         if "hints" in savedata: | 
					
						
							|  |  |  |             self.hints.update( | 
					
						
							|  |  |  |                 {tuple(key): set(Utils.Hint(*hint) for hint in value) for key, value in savedata["hints"]}) | 
					
						
							|  |  |  |         else:  # backwards compatiblity for <= 2.0.2 | 
					
						
							|  |  |  |             old_hints = {tuple(key): set(value) for key, value in savedata["hints_sent"]} | 
					
						
							|  |  |  |             for team_slot, item_or_location_s in old_hints.items(): | 
					
						
							|  |  |  |                 team, slot = team_slot | 
					
						
							|  |  |  |                 for item_or_location in item_or_location_s: | 
					
						
							|  |  |  |                     if item_or_location in Items.item_table: | 
					
						
							|  |  |  |                         hints = collect_hints(self, team, slot, item_or_location) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         hints = collect_hints_location(self, team, slot, item_or_location) | 
					
						
							|  |  |  |                     for hint in hints: | 
					
						
							|  |  |  |                         self.hints[team, hint.receiving_player].add(hint) | 
					
						
							|  |  |  |                         # even if it is the same hint, it won't be duped due to set | 
					
						
							|  |  |  |                         self.hints[team, hint.finding_player].add(hint) | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |         if "name_aliases" in savedata: | 
					
						
							|  |  |  |             self.name_aliases.update({tuple(key): value for key, value in savedata["name_aliases"]}) | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |             if "client_game_state" in savedata: | 
					
						
							|  |  |  |                 self.client_game_state.update({tuple(key): value for key, value in savedata["client_game_state"]}) | 
					
						
							| 
									
										
										
										
											2020-06-23 14:01:01 +02:00
										 |  |  |                 if "client_activity_timers" in savedata: | 
					
						
							|  |  |  |                     self.client_connection_timers.update( | 
					
						
							|  |  |  |                         {tuple(key): datetime.datetime.fromtimestamp(value, datetime.timezone.utc) for key, value | 
					
						
							|  |  |  |                          in savedata["client_connection_timers"]}) | 
					
						
							|  |  |  |                     self.client_activity_timers.update( | 
					
						
							|  |  |  |                         {tuple(key): datetime.datetime.fromtimestamp(value, datetime.timezone.utc) for key, value | 
					
						
							|  |  |  |                          in savedata["client_activity_timers"]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 12:10:12 +01:00
										 |  |  |         self.location_checks.update({tuple(key): set(value) for key, value in savedata["location_checks"]}) | 
					
						
							| 
									
										
										
										
											2020-06-23 14:01:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |         logging.info(f'Loaded save file with {sum([len(p) for p in received_items.values()])} received items ' | 
					
						
							|  |  |  |                      f'for {len(received_items)} players') | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     def get_aliased_name(self, team: int, slot: int): | 
					
						
							|  |  |  |         if (team, slot) in self.name_aliases: | 
					
						
							|  |  |  |             return f"{self.name_aliases[team, slot]} ({self.player_names[team, slot]})" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return self.player_names[team, slot] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     def notify_all(self, text): | 
					
						
							|  |  |  |         logging.info("Notice (all): %s" % text) | 
					
						
							|  |  |  |         self.broadcast_all([['Print', text]]) | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     def notify_client(self, client: Client, text: str): | 
					
						
							|  |  |  |         if not client.auth: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         logging.info("Notice (Player %s in team %d): %s" % (client.name, client.team + 1, text)) | 
					
						
							|  |  |  |         asyncio.create_task(self.send_msgs(client, [['Print', text]])) | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     def broadcast_team(self, team, msgs): | 
					
						
							|  |  |  |         for client in self.endpoints: | 
					
						
							|  |  |  |             if client.auth and client.team == team: | 
					
						
							|  |  |  |                 asyncio.create_task(self.send_msgs(client, msgs)) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     def broadcast_all(self, msgs): | 
					
						
							|  |  |  |         msgs = json.dumps(msgs) | 
					
						
							|  |  |  |         for endpoint in self.endpoints: | 
					
						
							|  |  |  |             if endpoint.auth: | 
					
						
							|  |  |  |                 asyncio.create_task(self.send_json_msgs(endpoint, msgs)) | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     async def disconnect(self, endpoint): | 
					
						
							|  |  |  |         await super(Context, self).disconnect(endpoint) | 
					
						
							|  |  |  |         await on_client_disconnected(self, endpoint) | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | # separated out, due to compatibilty between clients | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | def notify_hints(ctx: Context, team: int, hints: typing.List[Utils.Hint]): | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     cmd = json.dumps([["Hint", hints]])  # make sure it is a list, as it can be set internally | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |     texts = [['Print', format_hint(ctx, team, hint)] for hint in hints] | 
					
						
							| 
									
										
										
										
											2020-02-17 05:34:02 +01:00
										 |  |  |     for _, text in texts: | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |         logging.info("Notice (Team #%d): %s" % (team + 1, text)) | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |     texts = json.dumps(texts) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     for client in ctx.endpoints: | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |         if client.auth and client.team == team: | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |             if "Berserker" in client.tags and client.version >= [2, 2, 1]: | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |                 payload = cmd | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 payload = texts | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             asyncio.create_task(ctx.send_json_msgs(client, payload)) | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def update_aliases(ctx: Context, team: int, client: typing.Optional[Client] = None): | 
					
						
							|  |  |  |     cmd = json.dumps([["AliasUpdate", | 
					
						
							|  |  |  |                        [(key[1], ctx.get_aliased_name(*key)) for key, value in ctx.player_names.items() if | 
					
						
							| 
									
										
										
										
											2020-04-25 23:16:16 +02:00
										 |  |  |                         key[0] == team]]]) | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     if client is None: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         for client in ctx.endpoints: | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |             if client.team == team and client.auth and client.version > [2, 0, 3]: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 asyncio.create_task(ctx.send_json_msgs(client, cmd)) | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     else: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         asyncio.create_task(ctx.send_json_msgs(client, cmd)) | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | async def server(websocket, path, ctx: Context): | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     client = Client(websocket, ctx) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     ctx.endpoints.append(client) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         await on_client_connected(ctx, client) | 
					
						
							|  |  |  |         async for data in websocket: | 
					
						
							|  |  |  |             for msg in json.loads(data): | 
					
						
							|  |  |  |                 if len(msg) == 1: | 
					
						
							|  |  |  |                     cmd = msg | 
					
						
							|  |  |  |                     args = None | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     cmd = msg[0] | 
					
						
							|  |  |  |                     args = msg[1] | 
					
						
							|  |  |  |                 await process_client_cmd(ctx, client, cmd, args) | 
					
						
							|  |  |  |     except Exception as e: | 
					
						
							| 
									
										
										
										
											2019-12-16 18:39:00 +01:00
										 |  |  |         if not isinstance(e, websockets.WebSocketException): | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             logging.exception(e) | 
					
						
							|  |  |  |     finally: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         await ctx.disconnect(client) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | async def on_client_connected(ctx: Context, client: Client): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     await ctx.send_msgs(client, [['RoomInfo', { | 
					
						
							| 
									
										
										
										
											2020-01-15 03:00:30 +01:00
										 |  |  |         'password': ctx.password is not None, | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |         'players': [(client.team, client.slot, ctx.name_aliases.get((client.team, client.slot), client.name)) for client | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                     in ctx.endpoints if client.auth], | 
					
						
							| 
									
										
										
										
											2020-02-16 15:35:01 +01:00
										 |  |  |         # tags are for additional features in the communication. | 
					
						
							|  |  |  |         # Name them by feature or fork, as you feel is appropriate. | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  |         'tags': ctx.tags, | 
					
						
							| 
									
										
										
										
											2020-05-30 11:36:59 +02:00
										 |  |  |         'version': Utils._version_tuple, | 
					
						
							|  |  |  |         'forfeit_mode': ctx.forfeit_mode, | 
					
						
							|  |  |  |         'remaining_mode': ctx.remaining_mode, | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  |         'hint_cost': ctx.hint_cost, | 
					
						
							| 
									
										
										
										
											2020-05-30 11:36:59 +02:00
										 |  |  |         'location_check_points': ctx.location_check_points | 
					
						
							| 
									
										
										
										
											2020-01-15 03:00:30 +01:00
										 |  |  |     }]]) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | async def on_client_disconnected(ctx: Context, client: Client): | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     if client.auth: | 
					
						
							|  |  |  |         await on_client_left(ctx, client) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | async def on_client_joined(ctx: Context, client: Client): | 
					
						
							| 
									
										
										
										
											2020-07-13 03:38:19 +02:00
										 |  |  |     version_str = '.'.join(str(x) for x in client.version) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     ctx.notify_all( | 
					
						
							| 
									
										
										
										
											2020-07-13 03:38:19 +02:00
										 |  |  |         f"{ctx.get_aliased_name(client.team, client.slot)} (Team #{client.team + 1}) has joined the game. " | 
					
						
							|  |  |  |         f"Client({version_str}), {client.tags}).") | 
					
						
							| 
									
										
										
										
											2021-01-04 22:41:18 +01:00
										 |  |  |     if client.version < [2, 1, 0] and "auto" in ctx.forfeit_mode: | 
					
						
							|  |  |  |         ctx.notify_client( | 
					
						
							|  |  |  |             client, | 
					
						
							|  |  |  |             "Your client is too old to send game beaten information. " | 
					
						
							|  |  |  |             "The automatic forfeit feature will not work." | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 14:01:01 +02:00
										 |  |  |     ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | async def on_client_left(ctx: Context, client: Client): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     ctx.notify_all("%s (Team #%d) has left the game" % (ctx.get_aliased_name(client.team, client.slot), client.team + 1)) | 
					
						
							|  |  |  |     ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc) | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     if ctx.commandprocessor.client == Client: | 
					
						
							|  |  |  |         ctx.commandprocessor.client = None | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | async def countdown(ctx: Context, timer): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     ctx.notify_all(f'[Server]: Starting countdown of {timer}s') | 
					
						
							| 
									
										
										
										
											2020-01-10 22:44:07 +01:00
										 |  |  |     if ctx.countdown_timer: | 
					
						
							| 
									
										
										
										
											2020-03-11 23:08:16 +01:00
										 |  |  |         ctx.countdown_timer = timer  # timer is already running, set it to a different time | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-01-10 22:44:07 +01:00
										 |  |  |         ctx.countdown_timer = timer | 
					
						
							| 
									
										
										
										
											2020-03-11 23:08:16 +01:00
										 |  |  |         while ctx.countdown_timer > 0: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             ctx.notify_all(f'[Server]: {ctx.countdown_timer}') | 
					
						
							| 
									
										
										
										
											2020-03-11 23:08:16 +01:00
										 |  |  |             ctx.countdown_timer -= 1 | 
					
						
							|  |  |  |             await asyncio.sleep(1) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         ctx.notify_all(f'[Server]: GO') | 
					
						
							| 
									
										
										
										
											2020-07-05 21:46:44 +02:00
										 |  |  |         ctx.countdown_timer = 0 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  | async def missing(ctx: Context, client: Client, locations: list, checked_locations: list): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     await ctx.send_msgs(client, [['Missing', { | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  |         'locations': json.dumps(locations), | 
					
						
							|  |  |  |         'checked_locations': json.dumps(checked_locations) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     }]]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 22:44:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 14:51:48 +02:00
										 |  |  | def get_players_string(ctx: Context): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     auth_clients = {(c.team, c.slot) for c in ctx.endpoints if c.auth} | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 09:15:39 +01:00
										 |  |  |     player_names = sorted(ctx.player_names.keys()) | 
					
						
							| 
									
										
										
										
											2020-03-05 02:31:26 +01:00
										 |  |  |     current_team = -1 | 
					
						
							|  |  |  |     text = '' | 
					
						
							| 
									
										
										
										
											2020-03-11 09:15:39 +01:00
										 |  |  |     for team, slot in player_names: | 
					
						
							|  |  |  |         player_name = ctx.player_names[team, slot] | 
					
						
							|  |  |  |         if team != current_team: | 
					
						
							|  |  |  |             text += f':: Team #{team + 1}: ' | 
					
						
							|  |  |  |             current_team = team | 
					
						
							|  |  |  |         if (team, slot) in auth_clients: | 
					
						
							|  |  |  |             text += f'{player_name} ' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             text += f'({player_name}) ' | 
					
						
							|  |  |  |     return f'{len(auth_clients)} players of {len(ctx.player_names)} connected ' + text[:-1] | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-23 02:47:07 -07:00
										 |  |  | def get_received_items(ctx: Context, team: int, player: int) -> typing.List[ReceivedItem]: | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |     return ctx.received_items.setdefault((team, player), []) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | def tuplize_received_items(items): | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |     return [(item.item, item.location, item.player) for item in items] | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def send_new_items(ctx: Context): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     for client in ctx.endpoints: | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         if not client.auth: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         items = get_received_items(ctx, client.team, client.slot) | 
					
						
							|  |  |  |         if len(items) > client.send_index: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             asyncio.create_task(ctx.send_msgs(client, [ | 
					
						
							| 
									
										
										
										
											2020-04-19 14:05:58 +02:00
										 |  |  |                 ['ReceivedItems', (client.send_index, tuplize_received_items(items)[client.send_index:])]])) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             client.send_index = len(items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | def forfeit_player(ctx: Context, team: int, slot: int): | 
					
						
							| 
									
										
										
										
											2021-01-10 14:50:38 +01:00
										 |  |  |     # register any locations that are in the multidata | 
					
						
							|  |  |  |     all_locations = {location_id for location_id, location_slot in ctx.locations if location_slot == slot} | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |     ctx.notify_all("%s (Team #%d) has forfeited" % (ctx.player_names[(team, slot)], team + 1)) | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |     register_location_checks(ctx, team, slot, all_locations) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  | def get_remaining(ctx: Context, team: int, slot: int) -> typing.List[int]: | 
					
						
							|  |  |  |     items = [] | 
					
						
							|  |  |  |     for (location, location_slot) in ctx.locations: | 
					
						
							|  |  |  |         if location_slot == slot and location not in ctx.location_checks[team, slot]: | 
					
						
							|  |  |  |             items.append(ctx.locations[location, slot][0])  # item ID | 
					
						
							|  |  |  |     return sorted(items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | def register_location_checks(ctx: Context, team: int, slot: int, locations): | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     found_items = False | 
					
						
							| 
									
										
										
										
											2020-06-03 21:07:32 +02:00
										 |  |  |     new_locations = set(locations) - ctx.location_checks[team, slot] | 
					
						
							| 
									
										
										
										
											2020-10-27 02:20:56 -07:00
										 |  |  |     known_locations = set() | 
					
						
							| 
									
										
										
										
											2020-06-03 21:07:32 +02:00
										 |  |  |     if new_locations: | 
					
						
							|  |  |  |         ctx.client_activity_timers[team, slot] = datetime.datetime.now(datetime.timezone.utc) | 
					
						
							|  |  |  |         for location in new_locations: | 
					
						
							|  |  |  |             if (location, slot) in ctx.locations: | 
					
						
							| 
									
										
										
										
											2020-10-27 02:20:56 -07:00
										 |  |  |                 known_locations.add(location) | 
					
						
							| 
									
										
										
										
											2020-06-03 21:07:32 +02:00
										 |  |  |                 target_item, target_player = ctx.locations[(location, slot)] | 
					
						
							|  |  |  |                 if target_player != slot or slot in ctx.remote_items: | 
					
						
							|  |  |  |                     found = False | 
					
						
							|  |  |  |                     recvd_items = get_received_items(ctx, team, target_player) | 
					
						
							|  |  |  |                     for recvd_item in recvd_items: | 
					
						
							|  |  |  |                         if recvd_item.location == location and recvd_item.player == slot: | 
					
						
							|  |  |  |                             found = True | 
					
						
							|  |  |  |                             break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if not found: | 
					
						
							|  |  |  |                         new_item = ReceivedItem(target_item, location, slot) | 
					
						
							|  |  |  |                         recvd_items.append(new_item) | 
					
						
							|  |  |  |                         if slot != target_player: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                             ctx.broadcast_team(team, [['ItemSent', (slot, location, target_player, target_item)]]) | 
					
						
							|  |  |  |                     logging.info('(Team #%d) %s sent %s to %s (%s)' % ( | 
					
						
							| 
									
										
										
										
											2021-01-21 16:57:31 -08:00
										 |  |  |                     team + 1, ctx.player_names[(team, slot)], get_item_name_from_id(target_item), | 
					
						
							|  |  |  |                     ctx.player_names[(team, target_player)], get_location_name_from_address(location))) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                     found_items = True | 
					
						
							| 
									
										
										
										
											2020-06-03 21:07:32 +02:00
										 |  |  |                 elif target_player == slot:  # local pickup, notify clients of the pickup | 
					
						
							|  |  |  |                     if location not in ctx.location_checks[team, slot]: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                         for client in ctx.endpoints: | 
					
						
							|  |  |  |                                 if client.team == team and client.wants_item_notification: | 
					
						
							|  |  |  |                                     asyncio.create_task( | 
					
						
							|  |  |  |                                         ctx.send_msgs(client, [['ItemFound', (target_item, location, slot)]])) | 
					
						
							| 
									
										
										
										
											2020-10-27 02:20:56 -07:00
										 |  |  |         ctx.location_checks[team, slot] |= known_locations | 
					
						
							| 
									
										
										
										
											2020-06-03 21:07:32 +02:00
										 |  |  |         send_new_items(ctx) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if found_items: | 
					
						
							| 
									
										
										
										
											2020-06-15 06:30:51 +02:00
										 |  |  |             for client in ctx.endpoints: | 
					
						
							|  |  |  |                 if client.team == team and client.slot == slot: | 
					
						
							|  |  |  |                     asyncio.create_task(ctx.send_msgs(client, [["HintPointUpdate", (get_client_points(ctx, client),)]])) | 
					
						
							| 
									
										
										
										
											2020-06-21 17:04:25 +02:00
										 |  |  |         ctx.save() | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  | def notify_team(ctx: Context, team: int, text: str): | 
					
						
							|  |  |  |     logging.info("Notice (Team #%d): %s" % (team + 1, text)) | 
					
						
							|  |  |  |     ctx.broadcast_team(team, [['Print', text]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[Utils.Hint]: | 
					
						
							| 
									
										
										
										
											2020-02-11 00:44:28 +01:00
										 |  |  |     hints = [] | 
					
						
							| 
									
										
										
										
											2021-01-30 23:40:01 +01:00
										 |  |  |     seeked_item_id = Items.item_table[item][2] | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  |     for check, result in ctx.locations.items(): | 
					
						
							|  |  |  |         item_id, receiving_player = result | 
					
						
							|  |  |  |         if receiving_player == slot and item_id == seeked_item_id: | 
					
						
							|  |  |  |             location_id, finding_player = check | 
					
						
							| 
									
										
										
										
											2020-02-11 00:44:28 +01:00
										 |  |  |             found = location_id in ctx.location_checks[team, finding_player] | 
					
						
							| 
									
										
										
										
											2020-05-18 23:27:56 +02:00
										 |  |  |             entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "") | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |             hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance)) | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 00:44:28 +01:00
										 |  |  |     return hints | 
					
						
							| 
									
										
										
										
											2020-02-09 05:28:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 08:16:17 +01:00
										 |  |  | def collect_hints_location(ctx: Context, team: int, slot: int, location: str) -> typing.List[Utils.Hint]: | 
					
						
							|  |  |  |     hints = [] | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |     seeked_location = Regions.lookup_name_to_id[location] | 
					
						
							| 
									
										
										
										
											2020-02-17 08:16:17 +01:00
										 |  |  |     for check, result in ctx.locations.items(): | 
					
						
							|  |  |  |         location_id, finding_player = check | 
					
						
							|  |  |  |         if finding_player == slot and location_id == seeked_location: | 
					
						
							|  |  |  |             item_id, receiving_player = result | 
					
						
							|  |  |  |             found = location_id in ctx.location_checks[team, finding_player] | 
					
						
							| 
									
										
										
										
											2020-05-18 23:27:56 +02:00
										 |  |  |             entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "") | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |             hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance)) | 
					
						
							|  |  |  |             break  # each location has 1 item | 
					
						
							| 
									
										
										
										
											2020-02-17 08:16:17 +01:00
										 |  |  |     return hints | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | def format_hint(ctx: Context, team: int, hint: Utils.Hint) -> str: | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |     text = f"[Hint]: {ctx.player_names[team, hint.receiving_player]}'s " \ | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |            f"{Items.lookup_id_to_name[hint.item]} is " \ | 
					
						
							| 
									
										
										
										
											2021-01-21 16:57:31 -08:00
										 |  |  |            f"at {get_location_name_from_address(hint.location)} " \ | 
					
						
							| 
									
										
										
										
											2020-05-18 05:40:36 +02:00
										 |  |  |            f"in {ctx.player_names[team, hint.finding_player]}'s World" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if hint.entrance: | 
					
						
							|  |  |  |         text += f" at {hint.entrance}" | 
					
						
							|  |  |  |     return text + (". (found)" if hint.found else ".") | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  | def get_intended_text(input_text: str, possible_answers: typing.Iterable[str]= console_names) -> typing.Tuple[str, bool, str]: | 
					
						
							| 
									
										
										
										
											2020-02-17 13:57:48 +01:00
										 |  |  |     picks = fuzzy_process.extract(input_text, possible_answers, limit=2) | 
					
						
							| 
									
										
										
										
											2020-04-21 21:53:20 +02:00
										 |  |  |     if len(picks) > 1: | 
					
						
							|  |  |  |         dif = picks[0][1] - picks[1][1] | 
					
						
							|  |  |  |         if picks[0][1] == 100: | 
					
						
							|  |  |  |             return picks[0][0], True, "Perfect Match" | 
					
						
							|  |  |  |         elif picks[0][1] < 75: | 
					
						
							|  |  |  |             return picks[0][0], False, f"Didn't find something that closely matches, " \ | 
					
						
							|  |  |  |                                        f"did you mean {picks[0][0]}? ({picks[0][1]}% sure)" | 
					
						
							|  |  |  |         elif dif > 5: | 
					
						
							|  |  |  |             return picks[0][0], True, "Close Match" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return picks[0][0], False, f"Too many close matches, did you mean {picks[0][0]}? ({picks[0][1]}% sure)" | 
					
						
							| 
									
										
										
										
											2020-02-17 13:57:48 +01:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-04-21 21:53:20 +02:00
										 |  |  |         if picks[0][1] > 90: | 
					
						
							|  |  |  |             return picks[0][0], True, "Only Option Match" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return picks[0][0], False, f"Did you mean {picks[0][0]}? ({picks[0][1]}% sure)" | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 18:09:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | class CommandMeta(type): | 
					
						
							|  |  |  |     def __new__(cls, name, bases, attrs): | 
					
						
							|  |  |  |         commands = attrs["commands"] = {} | 
					
						
							|  |  |  |         for base in bases: | 
					
						
							|  |  |  |             commands.update(base.commands) | 
					
						
							|  |  |  |         commands.update({name[5:].lower(): method for name, method in attrs.items() if | 
					
						
							|  |  |  |                          name.startswith("_cmd_")}) | 
					
						
							|  |  |  |         return super(CommandMeta, cls).__new__(cls, name, bases, attrs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  | def mark_raw(function): | 
					
						
							|  |  |  |     function.raw_text = True | 
					
						
							|  |  |  |     return function | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | class CommandProcessor(metaclass=CommandMeta): | 
					
						
							|  |  |  |     commands: typing.Dict[str, typing.Callable] | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     client = None | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     marker = "/" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def output(self, text: str): | 
					
						
							|  |  |  |         print(text) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def __call__(self, raw: str) -> typing.Optional[bool]: | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         if not raw: | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2020-04-15 08:49:30 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             command = raw.split() | 
					
						
							|  |  |  |             basecommand = command[0] | 
					
						
							|  |  |  |             if basecommand[0] == self.marker: | 
					
						
							|  |  |  |                 method = self.commands.get(basecommand[1:].lower(), None) | 
					
						
							|  |  |  |                 if not method: | 
					
						
							|  |  |  |                     self._error_unknown_command(basecommand[1:]) | 
					
						
							|  |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2020-04-19 15:32:27 +02:00
										 |  |  |                     if getattr(method, "raw_text", False):  # method is requesting unprocessed text data | 
					
						
							| 
									
										
										
										
											2020-04-19 15:31:15 +02:00
										 |  |  |                         arg = raw.split(maxsplit=1) | 
					
						
							|  |  |  |                         if len(arg) > 1: | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                             return method(self, arg[1])  # argument text was found, so pass it along | 
					
						
							| 
									
										
										
										
											2020-04-19 15:31:15 +02:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                             return method(self)  # argument may be optional, try running without args | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                         return method(self, *command[1:])  # pass each word as argument | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2020-04-15 08:49:30 +02:00
										 |  |  |                 self.default(raw) | 
					
						
							|  |  |  |         except Exception as e: | 
					
						
							|  |  |  |             self._error_parsing_command(e) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_help_text(self) -> str: | 
					
						
							|  |  |  |         s = "" | 
					
						
							|  |  |  |         for command, method in self.commands.items(): | 
					
						
							|  |  |  |             spec = inspect.signature(method).parameters | 
					
						
							|  |  |  |             argtext = "" | 
					
						
							|  |  |  |             for argname, parameter in spec.items(): | 
					
						
							|  |  |  |                 if argname == "self": | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-04-15 09:56:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 if isinstance(parameter.default, str): | 
					
						
							| 
									
										
										
										
											2020-04-15 09:56:28 +02:00
										 |  |  |                     if not parameter.default: | 
					
						
							|  |  |  |                         argname = f"[{argname}]" | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         argname += "=" + parameter.default | 
					
						
							|  |  |  |                 argtext += argname | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 argtext += " " | 
					
						
							|  |  |  |             s += f"{self.marker}{command} {argtext}\n    {method.__doc__}\n" | 
					
						
							|  |  |  |         return s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _cmd_help(self): | 
					
						
							|  |  |  |         """Returns the help listing""" | 
					
						
							|  |  |  |         self.output(self.get_help_text()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _cmd_license(self): | 
					
						
							|  |  |  |         """Returns the licensing information""" | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         license = getattr(CommandProcessor, "license", None) | 
					
						
							|  |  |  |         if not license: | 
					
						
							| 
									
										
										
										
											2020-04-20 21:15:13 +02:00
										 |  |  |             with open(Utils.local_path("LICENSE")) as f: | 
					
						
							| 
									
										
										
										
											2020-07-21 23:15:19 +02:00
										 |  |  |                 CommandProcessor.license = f.read() | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         self.output(CommandProcessor.license) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def default(self, raw: str): | 
					
						
							|  |  |  |         self.output("Echo: " + raw) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _error_unknown_command(self, raw: str): | 
					
						
							|  |  |  |         self.output(f"Could not find command {raw}. Known commands: {', '.join(self.commands)}") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 08:49:30 +02:00
										 |  |  |     def _error_parsing_command(self, exception: Exception): | 
					
						
							|  |  |  |         self.output(str(exception)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 21:45:52 +02:00
										 |  |  | class CommonCommandProcessor(CommandProcessor): | 
					
						
							|  |  |  |     ctx: Context | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _cmd_countdown(self, seconds: str = "10") -> bool: | 
					
						
							|  |  |  |         """Start a countdown in seconds""" | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             timer = int(seconds, 10) | 
					
						
							|  |  |  |         except ValueError: | 
					
						
							|  |  |  |             timer = 10 | 
					
						
							|  |  |  |         asyncio.create_task(countdown(self.ctx, timer)) | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _cmd_options(self): | 
					
						
							|  |  |  |         """List all current options. Warning: lists password.""" | 
					
						
							|  |  |  |         self.output("Current options:") | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |         for option in self.ctx.simple_options: | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |             if option == "server_password" and self.marker == "!":  #Do not display the server password to the client. | 
					
						
							|  |  |  |                 self.output(f"Option server_password is set to {('*' * random.randint(4,16))}") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.output(f"Option {option} is set to {getattr(self.ctx, option)}") | 
					
						
							| 
									
										
										
										
											2020-07-05 21:45:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-11 13:19:38 -07:00
										 |  |  | class ClientMessageProcessor(CommonCommandProcessor): | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     marker = "!" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, ctx: Context, client: Client): | 
					
						
							|  |  |  |         self.ctx = ctx | 
					
						
							|  |  |  |         self.client = client | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     def __call__(self, raw: str) -> typing.Optional[bool]: | 
					
						
							|  |  |  |         if not raw.startswith("!admin"): | 
					
						
							|  |  |  |             self.ctx.notify_all(self.ctx.get_aliased_name(self.client.team, self.client.slot) + ': ' + raw) | 
					
						
							|  |  |  |         return super(ClientMessageProcessor, self).__call__(raw) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     def output(self, text): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         self.ctx.notify_client(self.client, text) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:26:22 +02:00
										 |  |  |     def default(self, raw: str): | 
					
						
							|  |  |  |         pass  # default is client sending just text | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     def is_authenticated(self): | 
					
						
							|  |  |  |         return self.ctx.commandprocessor.client == self.client | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @mark_raw | 
					
						
							|  |  |  |     def _cmd_admin(self, command: str = ""): | 
					
						
							|  |  |  |         """Allow remote administration of the multiworld server""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = f"!admin {command}" | 
					
						
							|  |  |  |         if output.lower().startswith("!admin login"):  # disallow others from seeing the supplied password, whether or not it is correct. | 
					
						
							|  |  |  |             output = f"!admin login {('*' * random.randint(4, 16))}" | 
					
						
							|  |  |  |         elif output.lower().startswith("!admin /option server_password"):  # disallow others from knowing what the new remote administration password is. | 
					
						
							|  |  |  |             output = f"!admin /option server_password {('*' * random.randint(4, 16))}" | 
					
						
							|  |  |  |         self.ctx.notify_all(self.ctx.get_aliased_name(self.client.team, self.client.slot) + ': ' + output)  # Otherwise notify the others what is happening. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.ctx.server_password: | 
					
						
							|  |  |  |             self.output("Sorry, Remote administration is disabled") | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not command: | 
					
						
							|  |  |  |             if self.is_authenticated(): | 
					
						
							|  |  |  |                 self.output("Usage: !admin [Server command].\nUse !admin /help for help.\nUse !admin logout to log out of the current session.") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.output("Usage: !admin login [password]") | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if command.startswith("login "): | 
					
						
							|  |  |  |             if command == f"login {self.ctx.server_password}": | 
					
						
							|  |  |  |                 self.output("Login successful. You can now issue server side commands.") | 
					
						
							|  |  |  |                 self.ctx.commandprocessor.client = self.client | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.output("Password incorrect.") | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.is_authenticated(): | 
					
						
							|  |  |  |             self.output("You must first login using !admin login [password]") | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if command == "logout": | 
					
						
							|  |  |  |             self.output("Logout successful. You can no longer issue server side commands.") | 
					
						
							|  |  |  |             self.ctx.commandprocessor.client = None | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self.ctx.commandprocessor(command) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_players(self) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         """Get information about connected and missing players""" | 
					
						
							| 
									
										
										
										
											2020-04-20 23:03:52 +02:00
										 |  |  |         if len(self.ctx.player_names) < 10: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             self.ctx.notify_all(get_players_string(self.ctx)) | 
					
						
							| 
									
										
										
										
											2020-04-20 23:03:52 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.output(get_players_string(self.ctx)) | 
					
						
							| 
									
										
										
										
											2020-04-24 05:29:02 +02:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_forfeit(self) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         """Surrender and send your remaining items out to their recipients""" | 
					
						
							| 
									
										
										
										
											2020-09-02 02:23:31 -07:00
										 |  |  |         if self.ctx.allow_forfeits.get((self.client.team, self.client.slot), False): | 
					
						
							|  |  |  |             forfeit_player(self.ctx, self.client.team, self.client.slot) | 
					
						
							|  |  |  |             return True | 
					
						
							| 
									
										
										
										
											2020-05-04 02:47:22 +02:00
										 |  |  |         if "enabled" in self.ctx.forfeit_mode: | 
					
						
							| 
									
										
										
										
											2020-04-16 15:40:31 +02:00
										 |  |  |             forfeit_player(self.ctx, self.client.team, self.client.slot) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2020-05-04 02:47:22 +02:00
										 |  |  |         elif "disabled" in self.ctx.forfeit_mode: | 
					
						
							| 
									
										
										
										
											2020-04-16 15:40:31 +02:00
										 |  |  |             self.output( | 
					
						
							|  |  |  |                 "Sorry, client forfeiting has been disabled on this server. You can ask the server admin for a /forfeit") | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |         else:  # is auto or goal | 
					
						
							|  |  |  |             if self.ctx.client_game_state[self.client.team, self.client.slot] == CLIENT_GOAL: | 
					
						
							|  |  |  |                 forfeit_player(self.ctx, self.client.team, self.client.slot) | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.output( | 
					
						
							|  |  |  |                     "Sorry, client forfeiting requires you to have beaten the game on this server." | 
					
						
							|  |  |  |                     " You can ask the server admin for a /forfeit") | 
					
						
							| 
									
										
										
										
											2020-04-28 05:59:03 +02:00
										 |  |  |                 if self.client.version < [2, 1, 0]: | 
					
						
							|  |  |  |                     self.output( | 
					
						
							|  |  |  |                         "Your client is too old to send game beaten information. Please update, load you savegame and reconnect.") | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _cmd_remaining(self) -> bool: | 
					
						
							|  |  |  |         """List remaining items in your game, but not their location or recipient""" | 
					
						
							|  |  |  |         if self.ctx.remaining_mode == "enabled": | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |             remaining_item_ids = get_remaining(self.ctx, self.client.team, self.client.slot) | 
					
						
							|  |  |  |             if remaining_item_ids: | 
					
						
							|  |  |  |                 self.output("Remaining items: " + ", ".join(Items.lookup_id_to_name.get(item_id, "unknown item") | 
					
						
							|  |  |  |                                                             for item_id in remaining_item_ids)) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.output("No remaining items found.") | 
					
						
							|  |  |  |             return True | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |         elif self.ctx.remaining_mode == "disabled": | 
					
						
							|  |  |  |             self.output( | 
					
						
							|  |  |  |                 "Sorry, !remaining has been disabled on this server.") | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         else:  # is goal | 
					
						
							|  |  |  |             if self.ctx.client_game_state[self.client.team, self.client.slot] == CLIENT_GOAL: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                 remaining_item_ids = get_remaining(self.ctx, self.client.team, self.client.slot) | 
					
						
							|  |  |  |                 if remaining_item_ids: | 
					
						
							|  |  |  |                     self.output("Remaining items: " + ", ".join(Items.lookup_id_to_name.get(item_id, "unknown item") | 
					
						
							|  |  |  |                                                                 for item_id in remaining_item_ids)) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.output("No remaining items found.") | 
					
						
							|  |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.output( | 
					
						
							|  |  |  |                     "Sorry, !remaining requires you to have beaten the game on this server") | 
					
						
							| 
									
										
										
										
											2020-04-28 05:59:03 +02:00
										 |  |  |                 if self.client.version < [2, 1, 0]: | 
					
						
							|  |  |  |                     self.output( | 
					
						
							|  |  |  |                         "Your client is too old to send game beaten information. Please update, load you savegame and reconnect.") | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_missing(self) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-20 11:47:50 +02:00
										 |  |  |         """List all missing location checks from the server's perspective""" | 
					
						
							| 
									
										
										
										
											2020-06-15 22:07:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-27 16:24:21 -07:00
										 |  |  |         locations = get_missing_checks(self.ctx, self.client) | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  |         checked_locations = get_checked_checks(self.ctx, self.client) | 
					
						
							| 
									
										
										
										
											2020-04-20 11:47:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         if len(locations) > 0: | 
					
						
							| 
									
										
										
										
											2020-06-15 22:07:43 +02:00
										 |  |  |             if self.client.version < [2, 3, 0]: | 
					
						
							|  |  |  |                 buffer = "" | 
					
						
							|  |  |  |                 for location in locations: | 
					
						
							|  |  |  |                     buffer += f'Missing: {location}\n' | 
					
						
							|  |  |  |                 self.output(buffer + f"Found {len(locations)} missing location checks") | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  |                 asyncio.create_task(missing(self.ctx, self.client, locations, checked_locations)) | 
					
						
							| 
									
										
										
										
											2020-04-20 11:47:50 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.output("No missing location checks found.") | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-20 11:47:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     @mark_raw | 
					
						
							|  |  |  |     def _cmd_alias(self, alias_name: str = ""): | 
					
						
							| 
									
										
										
										
											2020-06-10 06:13:14 +02:00
										 |  |  |         """Set your alias to the passed name.""" | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |         if alias_name: | 
					
						
							| 
									
										
										
										
											2020-06-10 06:13:14 +02:00
										 |  |  |             alias_name = alias_name[:16].strip() | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |             self.ctx.name_aliases[self.client.team, self.client.slot] = alias_name | 
					
						
							|  |  |  |             self.output(f"Hello, {alias_name}") | 
					
						
							|  |  |  |             update_aliases(self.ctx, self.client.team) | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |             self.ctx.save() | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |             return True | 
					
						
							|  |  |  |         elif (self.client.team, self.client.slot) in self.ctx.name_aliases: | 
					
						
							|  |  |  |             del (self.ctx.name_aliases[self.client.team, self.client.slot]) | 
					
						
							|  |  |  |             self.output("Removed Alias") | 
					
						
							|  |  |  |             update_aliases(self.ctx, self.client.team) | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |             self.ctx.save() | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |             return True | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  |     @mark_raw | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_getitem(self, item_name: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-06-10 06:13:14 +02:00
										 |  |  |         """Cheat in an item, if it is enabled on this server""" | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         if self.ctx.item_cheat: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |             item_name, usable, response = get_intended_text(item_name, Items.item_table.keys()) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             if usable: | 
					
						
							| 
									
										
										
										
											2021-01-30 23:40:01 +01:00
										 |  |  |                 new_item = ReceivedItem(Items.item_table[item_name][2], -1, self.client.slot) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 self.ctx.notify_all('Cheat console: sending "' + item_name + '" to ' + self.ctx.get_aliased_name(self.client.team, self.client.slot)) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 send_new_items(self.ctx) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.output("Cheating is disabled.") | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  |     @mark_raw | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_hint(self, item_or_location: str = "") -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         """Use !hint {item_name/location_name}, for example !hint Lamp or !hint Link's House. """ | 
					
						
							| 
									
										
										
										
											2020-06-15 06:30:51 +02:00
										 |  |  |         points_available = get_client_points(self.ctx, self.client) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         if not item_or_location: | 
					
						
							|  |  |  |             self.output(f"A hint costs {self.ctx.hint_cost} points. " | 
					
						
							|  |  |  |                         f"You have {points_available} points.") | 
					
						
							| 
									
										
										
										
											2020-04-22 05:09:46 +02:00
										 |  |  |             hints = {hint.re_check(self.ctx, self.client.team) for hint in | 
					
						
							|  |  |  |                      self.ctx.hints[self.client.team, self.client.slot]} | 
					
						
							|  |  |  |             self.ctx.hints[self.client.team, self.client.slot] = hints | 
					
						
							|  |  |  |             notify_hints(self.ctx, self.client.team, list(hints)) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |             item_name, usable, response = get_intended_text(item_or_location) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             if usable: | 
					
						
							|  |  |  |                 if item_name in Items.hint_blacklist: | 
					
						
							|  |  |  |                     self.output(f"Sorry, \"{item_name}\" is marked as non-hintable.") | 
					
						
							|  |  |  |                     hints = [] | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                 elif item_name in Items.item_name_groups: | 
					
						
							| 
									
										
										
										
											2020-06-07 00:19:19 +02:00
										 |  |  |                     hints = [] | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                     for item in Items.item_name_groups[item_name]: | 
					
						
							| 
									
										
										
										
											2020-06-07 00:19:19 +02:00
										 |  |  |                         hints.extend(collect_hints(self.ctx, self.client.team, self.client.slot, item)) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 elif item_name in Items.item_table:  # item name | 
					
						
							|  |  |  |                     hints = collect_hints(self.ctx, self.client.team, self.client.slot, item_name) | 
					
						
							|  |  |  |                 else:  # location name | 
					
						
							|  |  |  |                     hints = collect_hints_location(self.ctx, self.client.team, self.client.slot, item_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if hints: | 
					
						
							| 
									
										
										
										
											2020-04-22 15:50:14 +02:00
										 |  |  |                     new_hints = set(hints) - self.ctx.hints[self.client.team, self.client.slot] | 
					
						
							|  |  |  |                     old_hints = set(hints) - new_hints | 
					
						
							|  |  |  |                     if old_hints: | 
					
						
							|  |  |  |                         notify_hints(self.ctx, self.client.team, list(old_hints)) | 
					
						
							|  |  |  |                         if not new_hints: | 
					
						
							|  |  |  |                             self.output("Hint was previously used, no points deducted.") | 
					
						
							|  |  |  |                     if new_hints: | 
					
						
							| 
									
										
										
										
											2020-06-09 05:22:48 +02:00
										 |  |  |                         found_hints = [hint for hint in new_hints if hint.found] | 
					
						
							|  |  |  |                         not_found_hints = [hint for hint in new_hints if not hint.found] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         if not not_found_hints:  # everything's been found, no need to pay | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  |                             can_pay = 1000 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:50:14 +02:00
										 |  |  |                         elif self.ctx.hint_cost: | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  |                             can_pay = points_available // self.ctx.hint_cost | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  |                             can_pay = 1000 | 
					
						
							| 
									
										
										
										
											2020-06-09 05:22:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         random.shuffle(not_found_hints) | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 03:21:28 +02:00
										 |  |  |                         hints = found_hints | 
					
						
							|  |  |  |                         while can_pay > 0: | 
					
						
							|  |  |  |                             if not not_found_hints: | 
					
						
							|  |  |  |                                 break | 
					
						
							|  |  |  |                             hint = not_found_hints.pop() | 
					
						
							|  |  |  |                             hints.append(hint) | 
					
						
							|  |  |  |                             can_pay -= 1 | 
					
						
							|  |  |  |                             self.ctx.hints_used[self.client.team, self.client.slot] += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             if not hint.found: | 
					
						
							|  |  |  |                                 self.ctx.hints[self.client.team, hint.finding_player].add(hint) | 
					
						
							|  |  |  |                                 self.ctx.hints[self.client.team, hint.receiving_player].add(hint) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         if not_found_hints: | 
					
						
							|  |  |  |                             if hints: | 
					
						
							|  |  |  |                                 self.output( | 
					
						
							|  |  |  |                                     "Could not pay for everything. Rerun the hint later with more points to get the remaining hints.") | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  |                             else: | 
					
						
							| 
									
										
										
										
											2020-07-13 03:21:28 +02:00
										 |  |  |                                 self.output(f"You can't afford the hint. " | 
					
						
							|  |  |  |                                             f"You have {points_available} points and need at least " | 
					
						
							|  |  |  |                                             f"{self.ctx.hint_cost}") | 
					
						
							|  |  |  |                         notify_hints(self.ctx, self.client.team, hints) | 
					
						
							|  |  |  |                         self.ctx.save() | 
					
						
							|  |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2020-06-07 02:13:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     self.output("Nothing found. Item/Location may not exist.") | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                     return False | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 03:22:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  | def get_checked_checks(ctx: Context, client: Client) -> list: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |     return [Regions.lookup_id_to_name.get(location_id, f'Unknown Location ID: {location_id}') for | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  |             location_id, slot in ctx.locations if | 
					
						
							|  |  |  |             slot == client.slot and | 
					
						
							|  |  |  |             location_id in ctx.location_checks[client.team, client.slot]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-27 16:24:21 -07:00
										 |  |  | def get_missing_checks(ctx: Context, client: Client) -> list: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |     return [Regions.lookup_id_to_name.get(location_id, f'Unknown Location ID: {location_id}') for | 
					
						
							| 
									
										
										
										
											2021-01-15 03:22:56 +01:00
										 |  |  |             location_id, slot in ctx.locations if | 
					
						
							|  |  |  |             slot == client.slot and | 
					
						
							|  |  |  |             location_id not in ctx.location_checks[client.team, client.slot]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 06:30:51 +02:00
										 |  |  | def get_client_points(ctx: Context, client: Client) -> int: | 
					
						
							|  |  |  |     return (ctx.location_check_points * len(ctx.location_checks[client.team, client.slot]) - | 
					
						
							|  |  |  |             ctx.hint_cost * ctx.hints_used[client.team, client.slot]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 03:22:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  | async def process_client_cmd(ctx: Context, client: Client, cmd, args): | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     if type(cmd) is not str: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         await ctx.send_msgs(client, [['InvalidCmd']]) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if cmd == 'Connect': | 
					
						
							|  |  |  |         if not args or type(args) is not dict or \ | 
					
						
							|  |  |  |                 'password' not in args or type(args['password']) not in [str, type(None)] or \ | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  |                 'rom' not in args or type(args['rom']) not in (list, str): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             await ctx.send_msgs(client, [['InvalidArguments', 'Connect']]) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         errors = set() | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |         if ctx.password is not None and args['password'] != ctx.password: | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             errors.add('InvalidPassword') | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  |         if type(args["rom"]) == list: | 
					
						
							|  |  |  |             args["rom"] = bytes(letter for letter in args["rom"]).decode() | 
					
						
							|  |  |  |         if args['rom'] not in ctx.rom_names: | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |             errors.add('InvalidRom') | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-07-14 04:48:56 +02:00
										 |  |  |             team, slot = ctx.rom_names[args['rom']] | 
					
						
							| 
									
										
										
										
											2020-06-16 01:05:32 +02:00
										 |  |  |             # this can only ever be 0 or 1 elements | 
					
						
							|  |  |  |             clients = [c for c in ctx.endpoints if c.auth and c.slot == slot and c.team == team] | 
					
						
							|  |  |  |             if clients: | 
					
						
							|  |  |  |                 # likely same player with a "ghosted" slot. We bust the ghost. | 
					
						
							|  |  |  |                 if "uuid" in args and ctx.client_ids[team, slot] == args["uuid"]: | 
					
						
							|  |  |  |                     await clients[0].socket.close()  # we have to await the DC of the ghost, so not to create data pasta | 
					
						
							|  |  |  |                     client.name = ctx.player_names[(team, slot)] | 
					
						
							|  |  |  |                     client.team = team | 
					
						
							|  |  |  |                     client.slot = slot | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     errors.add('SlotAlreadyTaken') | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 client.name = ctx.player_names[(team, slot)] | 
					
						
							|  |  |  |                 client.team = team | 
					
						
							|  |  |  |                 client.slot = slot | 
					
						
							| 
									
										
										
										
											2020-12-29 19:23:14 +01:00
										 |  |  |                 minver = Utils.Version(*(ctx.minimum_client_versions.get((team, slot), (0,0,0)))) | 
					
						
							|  |  |  |                 if minver > tuple(args.get('version', Client.version)): | 
					
						
							|  |  |  |                     errors.add('IncompatibleVersion') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |         if ctx.compatibility == 1 and "Berserker" not in args.get('tags', Client.tags): | 
					
						
							|  |  |  |             errors.add('IncompatibleVersion') | 
					
						
							| 
									
										
										
										
											2020-12-29 19:23:14 +01:00
										 |  |  |         #only exact version match allowed | 
					
						
							|  |  |  |         elif ctx.compatibility == 0 and tuple(args.get('version', Client.version)) != _version_tuple: | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |             errors.add('IncompatibleVersion') | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         if errors: | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |             logging.info(f"A client connection was refused due to: {errors}") | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             await ctx.send_msgs(client, [['ConnectionRefused', list(errors)]]) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-06-16 01:05:32 +02:00
										 |  |  |             ctx.client_ids[client.team, client.slot] = args.get("uuid", None) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             client.auth = True | 
					
						
							| 
									
										
										
										
											2020-02-16 15:32:40 +01:00
										 |  |  |             client.version = args.get('version', Client.version) | 
					
						
							|  |  |  |             client.tags = args.get('tags', Client.tags) | 
					
						
							|  |  |  |             reply = [['Connected', [(client.team, client.slot), | 
					
						
							| 
									
										
										
										
											2020-04-25 23:16:16 +02:00
										 |  |  |                                     [(p, ctx.get_aliased_name(t, p)) for (t, p), n in ctx.player_names.items() if | 
					
						
							| 
									
										
										
										
											2021-01-21 16:21:51 -08:00
										 |  |  |                                      t == client.team], get_missing_checks(ctx, client), get_checked_checks(ctx, client)]]] | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             items = get_received_items(ctx, client.team, client.slot) | 
					
						
							|  |  |  |             if items: | 
					
						
							|  |  |  |                 reply.append(['ReceivedItems', (0, tuplize_received_items(items))]) | 
					
						
							|  |  |  |                 client.send_index = len(items) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             await ctx.send_msgs(client, reply) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             await on_client_joined(ctx, client) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |     if client.auth: | 
					
						
							|  |  |  |         if cmd == 'Sync': | 
					
						
							|  |  |  |             items = get_received_items(ctx, client.team, client.slot) | 
					
						
							|  |  |  |             if items: | 
					
						
							|  |  |  |                 client.send_index = len(items) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 await ctx.send_msgs(client, [['ReceivedItems', (0, tuplize_received_items(items))]]) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         elif cmd == 'LocationChecks': | 
					
						
							|  |  |  |             if type(args) is not list: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 await ctx.send_msgs(client, [['InvalidArguments', 'LocationChecks']]) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             register_location_checks(ctx, client.team, client.slot, args) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         elif cmd == 'LocationScouts': | 
					
						
							|  |  |  |             if type(args) is not list: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 await ctx.send_msgs(client, [['InvalidArguments', 'LocationScouts']]) | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             locs = [] | 
					
						
							|  |  |  |             for location in args: | 
					
						
							|  |  |  |                 if type(location) is not int or 0 >= location > len(Regions.location_table): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                     await ctx.send_msgs(client, [['InvalidArguments', 'LocationScouts']]) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                     return | 
					
						
							|  |  |  |                 loc_name = list(Regions.location_table.keys())[location - 1] | 
					
						
							|  |  |  |                 target_item, target_player = ctx.locations[(Regions.location_table[loc_name][0], client.slot)] | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 replacements = {'SmallKey': 0xA2, 'BigKey': 0x9D, 'Compass': 0x8D, 'Map': 0x7D} | 
					
						
							| 
									
										
										
										
											2021-01-30 23:40:01 +01:00
										 |  |  |                 item_type = [i[1] for i in Items.item_table.values() if type(i[2]) is int and i[2] == target_item] | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 if item_type: | 
					
						
							|  |  |  |                     target_item = replacements.get(item_type[0], target_item) | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 locs.append([loc_name, location, target_item, target_player]) | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             # logging.info(f"{client.name} in team {client.team+1} scouted {', '.join([l[0] for l in locs])}") | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |             await ctx.send_msgs(client, [['LocationInfo', [l[1:] for l in locs]]]) | 
					
						
							| 
									
										
										
										
											2020-01-18 09:50:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         elif cmd == 'UpdateTags': | 
					
						
							|  |  |  |             if not args or type(args) is not list: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 await ctx.send_msgs(client, [['InvalidArguments', 'UpdateTags']]) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             client.tags = args | 
					
						
							| 
									
										
										
										
											2020-03-23 02:47:07 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-24 20:07:28 -07:00
										 |  |  |         elif cmd == 'GameFinished': | 
					
						
							| 
									
										
										
										
											2020-04-27 06:13:33 -07:00
										 |  |  |             if ctx.client_game_state[client.team, client.slot] != CLIENT_GOAL: | 
					
						
							| 
									
										
										
										
											2020-04-27 23:49:46 -07:00
										 |  |  |                 finished_msg = f'{ctx.get_aliased_name(client.team, client.slot)} (Team #{client.team + 1}) has found the triforce.' | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 ctx.notify_all(finished_msg) | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |                 ctx.client_game_state[client.team, client.slot] = CLIENT_GOAL | 
					
						
							| 
									
										
										
										
											2020-05-04 02:47:22 +02:00
										 |  |  |                 if "auto" in ctx.forfeit_mode: | 
					
						
							|  |  |  |                     forfeit_player(ctx, client.team, client.slot) | 
					
						
							| 
									
										
										
										
											2020-04-24 20:07:28 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |         if cmd == 'Say': | 
					
						
							|  |  |  |             if type(args) is not str or not args.isprintable(): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 await ctx.send_msgs(client, [['InvalidArguments', 'Say']]) | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             client.messageprocessor(args) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 13:57:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 21:45:52 +02:00
										 |  |  | class ServerCommandProcessor(CommonCommandProcessor): | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |     def __init__(self, ctx: Context): | 
					
						
							|  |  |  |         self.ctx = ctx | 
					
						
							|  |  |  |         super(ServerCommandProcessor, self).__init__() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     def output(self, text: str): | 
					
						
							|  |  |  |         if self.client: | 
					
						
							|  |  |  |             self.ctx.notify_client(self.client, text) | 
					
						
							|  |  |  |         super(ServerCommandProcessor, self).output(text) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |     def default(self, raw: str): | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         self.ctx.notify_all('[Server]: ' + raw) | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  |     @mark_raw | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_kick(self, player_name: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Kick specified player from the server""" | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |         for client in self.ctx.endpoints: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |             if client.auth and client.name.lower() == player_name.lower() and client.socket and not client.socket.closed: | 
					
						
							|  |  |  |                 asyncio.create_task(client.socket.close()) | 
					
						
							| 
									
										
										
										
											2020-04-27 23:49:46 -07:00
										 |  |  |                 self.output(f"Kicked {self.ctx.get_aliased_name(client.team, client.slot)}") | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |                 if self.ctx.commandprocessor.client == client: | 
					
						
							|  |  |  |                     self.ctx.commandprocessor.client = None | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.output(f"Could not find player {player_name} to kick") | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  |     def _cmd_save(self) -> bool: | 
					
						
							|  |  |  |         """Save current state to multidata""" | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |         if self.ctx.saving: | 
					
						
							|  |  |  |             self.ctx.save(True) | 
					
						
							|  |  |  |             self.output("Game saved") | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.output("Saving is disabled.") | 
					
						
							|  |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-23 06:16:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_players(self) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Get information about connected players""" | 
					
						
							| 
									
										
										
										
											2020-04-19 14:51:48 +02:00
										 |  |  |         self.output(get_players_string(self.ctx)) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_exit(self) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Shutdown the server""" | 
					
						
							|  |  |  |         asyncio.create_task(self.ctx.server.ws_server._close()) | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |         if self.ctx.shutdown_task: | 
					
						
							|  |  |  |             self.ctx.shutdown_task.cancel() | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         self.ctx.running = False | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-27 03:47:12 +02:00
										 |  |  |     @mark_raw | 
					
						
							|  |  |  |     def _cmd_alias(self, player_name_then_alias_name): | 
					
						
							| 
									
										
										
										
											2020-06-10 06:13:14 +02:00
										 |  |  |         """Set a player's alias, by listing their base name and then their intended alias.""" | 
					
						
							| 
									
										
										
										
											2020-04-27 03:47:12 +02:00
										 |  |  |         player_name, alias_name = player_name_then_alias_name.split(" ", 1) | 
					
						
							|  |  |  |         player_name, usable, response = get_intended_text(player_name, self.ctx.player_names.values()) | 
					
						
							|  |  |  |         if usable: | 
					
						
							|  |  |  |             for (team, slot), name in self.ctx.player_names.items(): | 
					
						
							|  |  |  |                 if name == player_name: | 
					
						
							|  |  |  |                     if alias_name: | 
					
						
							|  |  |  |                         alias_name = alias_name.strip()[:15] | 
					
						
							|  |  |  |                         self.ctx.name_aliases[team, slot] = alias_name | 
					
						
							|  |  |  |                         self.output(f"Named {player_name} as {alias_name}") | 
					
						
							|  |  |  |                         update_aliases(self.ctx, team) | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |                         self.ctx.save() | 
					
						
							| 
									
										
										
										
											2020-04-27 03:47:12 +02:00
										 |  |  |                         return True | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         del (self.ctx.name_aliases[team, slot]) | 
					
						
							|  |  |  |                         self.output(f"Removed Alias for {player_name}") | 
					
						
							|  |  |  |                         update_aliases(self.ctx, team) | 
					
						
							| 
									
										
										
										
											2020-06-20 15:46:33 +02:00
										 |  |  |                         self.ctx.save() | 
					
						
							| 
									
										
										
										
											2020-04-27 03:47:12 +02:00
										 |  |  |                         return True | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.output(response) | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 03:24:27 +02:00
										 |  |  |     @mark_raw | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_forfeit(self, player_name: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Send out the remaining items from a player's game to their intended recipients""" | 
					
						
							|  |  |  |         seeked_player = player_name.lower() | 
					
						
							|  |  |  |         for (team, slot), name in self.ctx.player_names.items(): | 
					
						
							|  |  |  |             if name.lower() == seeked_player: | 
					
						
							|  |  |  |                 forfeit_player(self.ctx, team, slot) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |         self.output(f"Could not find player {player_name} to forfeit") | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 02:23:31 -07:00
										 |  |  |     @mark_raw | 
					
						
							|  |  |  |     def _cmd_allow_forfeit(self, player_name: str) -> bool: | 
					
						
							|  |  |  |         """Allow the specified player to use the !forfeit command""" | 
					
						
							|  |  |  |         seeked_player = player_name.lower() | 
					
						
							|  |  |  |         for (team, slot), name in self.ctx.player_names.items(): | 
					
						
							|  |  |  |             if name.lower() == seeked_player: | 
					
						
							|  |  |  |                 self.ctx.allow_forfeits[(team, slot)] = True | 
					
						
							|  |  |  |                 self.output(f"Player {player_name} is now allowed to use the !forfeit command at any time.") | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.output(f"Could not find player {player_name} to allow the !forfeit command for.") | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @mark_raw | 
					
						
							|  |  |  |     def _cmd_forbid_forfeit(self, player_name: str) -> bool: | 
					
						
							|  |  |  |         """"Disallow the specified player from using the !forfeit command""" | 
					
						
							|  |  |  |         seeked_player = player_name.lower() | 
					
						
							|  |  |  |         for (team, slot), name in self.ctx.player_names.items(): | 
					
						
							|  |  |  |             if name.lower() == seeked_player: | 
					
						
							|  |  |  |                 self.ctx.allow_forfeits[(team, slot)] = False | 
					
						
							|  |  |  |                 self.output(f"Player {player_name} has to follow the server restrictions on use of the !forfeit command.") | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.output(f"Could not find player {player_name} to forbid the !forfeit command for.") | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_send(self, player_name: str, *item_name: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Sends an item to the specified player""" | 
					
						
							|  |  |  |         seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values()) | 
					
						
							|  |  |  |         if usable: | 
					
						
							|  |  |  |             item = " ".join(item_name) | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |             item, usable, response = get_intended_text(item, Items.item_table.keys()) | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |             if usable: | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                 for client in self.ctx.endpoints: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                     if client.name == seeked_player: | 
					
						
							| 
									
										
										
										
											2021-01-30 23:40:01 +01:00
										 |  |  |                         new_item = ReceivedItem(Items.item_table[item][2], -1, client.slot) | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                         get_received_items(self.ctx, client.team, client.slot).append(new_item) | 
					
						
							| 
									
										
											  
											
												WebUI (#100)
* Object-Oriented base changes for web-ui prep
* remove debug raise
* optimize broadcast to serialize once
* Implement WebUI socket, static assets, and classes
- Still need to wrap logging functions and send output to UI
- UI commands are successfully being sent to the server
* GUI operational. Wrap logging functions, implement server address selection on GUI, automatically launch web browser when client websocket is served
* Update MultiServer status when a user disconnects / reconnects
* Implement colored item and hint checks, improve GUI readability
* Fix improper formatting on received items
* Update SNES connection status on disconnect / reconnect. Implement itemFound, prevent accidentally printing JS objects
* Minor text change for itemFound
* Fixed a very wrong comment
* Fixed client commands not working, fixed un-helpful error messages appearing in GUI
* Fix a bug causing a failure to connect to a multiworld server if a previously existing cached address was present and the client was loaded without an address passed in
* Convert WebUI to React /w Redux. WebSocket communications not yet operational.
* WebUI fully converted to React / Redux.
- Websocket communication operational
- Added a button to connect to the multiserver which appears only when a SNES is connected and a server connection is not active
* Restore some features lost in WebUI
- Restore (found) notification on hints if the item has already been obtained
- Restore (x/y) indicator on received items, which indicates the number of items the client is waiting to receive from the client in a queue
* Fix a grammatical UI big causing player names to show only an apostrophe when possessive
* Add support for multiple SNES Devices, and switching between them
* freeze support for client
* make sure flask works when frozen
* UI Improvements
- Hint messages now actually show a found status via ✔ and ❌ emoji
- Active player name is always a different color than other players (orange for now)
- Add a toggle to show only entries relevant to the active player
- Added a WidgetArea
- Added a notes widget
* Received items now marked as relevant
* Include production build for deployment
* Notes now survive a browser close. Minimum width applied to monitor to prevent CSS issues.
* include webUi folder in setup.py
* Bugfixes for Monitor
- Fix a bug causing the monitor window to grow beyond it's intended content limit
- Reduced monitor content limit to 200 items
- Ensured each monitor entry has a unique key
* Prevent eslint from yelling at me about stupid things
* Add button to collapse sidebar, press enter on empty server input to disconnect on purpose
* WebUI is now aware of client disconnect, message log limit increased to 350, fix !missing output
* Update WebUI to v2.2.1
- Added color to WebUI for entrance-span
- Make !missing show total count at bottom of list to match /missing behavior
* Fix a bug causing clients version <= 2.2.0 to crash when anyone asks for a hint
- Also fix a bug in the WebUI causing the entrance location to always show as "somewhere"
* Update WebUI color palette (this cost me $50)
* allow text console input alongside web-ui
* remove Flask
a bit overkill for what we're doing
* remove jinja2
* Update WebUI to work with new hosting mechanism
* with flask gone, we no longer need subprocess shenanigans
* If multiple web ui clients try to run, at least present a working console
* Update MultiClient and WebUI to handle multiple clients simultaneously.
- The port on which the websocket for the WebUI is hosted is not chosen randomly from 5000 - 5999. This port is passed to the browser so it knows which MultiClient to connect to
- Removed failure condition if a web server is already running, as there is no need to run more than one web server on a single system. If an exception is thrown while attempting to launch a web server, a check is made for the port being unavailable. If the port is unavailable, it probably means the user is launching a second MultiClient. A web browser is then opened with a connection to the correct webui_socket_port.
- Add a /web command to the MultiClient to repoen the appropriate browser window and get params in case a user accidentally closes the tab
* Use proper name for WebUI
* move webui into /data with other data files
* make web ui optional
This is mostly for laptop users wanting to preserve some battery, should not be needed outside of that.
* fix direct server start
* re-add connection timer
* fix indentation
Co-authored-by: Chris <chris@legendserver.info>
											
										 
											2020-06-03 21:29:43 +02:00
										 |  |  |                         self.ctx.notify_all('Cheat console: sending "' + item + '" to ' + self.ctx.get_aliased_name(client.team, client.slot)) | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                         send_new_items(self.ctx) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |     def _cmd_hint(self, player_name: str, *item_or_location: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         """Send out a hint for a player's item or location to their team""" | 
					
						
							|  |  |  |         seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values()) | 
					
						
							|  |  |  |         if usable: | 
					
						
							|  |  |  |             for (team, slot), name in self.ctx.player_names.items(): | 
					
						
							|  |  |  |                 if name == seeked_player: | 
					
						
							|  |  |  |                     item = " ".join(item_or_location) | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                     item, usable, response = get_intended_text(item) | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                     if usable: | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                         if item in Items.item_name_groups: | 
					
						
							| 
									
										
										
										
											2020-06-07 00:19:19 +02:00
										 |  |  |                             hints = [] | 
					
						
							| 
									
										
										
										
											2021-01-21 15:59:28 -08:00
										 |  |  |                             for item in Items.item_name_groups[item]: | 
					
						
							| 
									
										
										
										
											2020-06-07 00:19:19 +02:00
										 |  |  |                                 hints.extend(collect_hints(self.ctx, team, slot, item)) | 
					
						
							|  |  |  |                         elif item in Items.item_table:  # item name | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                             hints = collect_hints(self.ctx, team, slot, item) | 
					
						
							|  |  |  |                         else:  # location name | 
					
						
							|  |  |  |                             hints = collect_hints_location(self.ctx, team, slot, item) | 
					
						
							| 
									
										
										
										
											2020-06-07 00:19:19 +02:00
										 |  |  |                         notify_hints(self.ctx, team, hints) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |                         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.output(response) | 
					
						
							| 
									
										
										
										
											2020-04-21 06:26:51 +02:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-27 14:16:51 +02:00
										 |  |  |     def _cmd_option(self, option_name: str, option: str): | 
					
						
							|  |  |  |         """Set options for the server. Warning: expires on restart""" | 
					
						
							| 
									
										
										
										
											2020-06-27 14:25:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |         attrtype = self.ctx.simple_options.get(option_name, None) | 
					
						
							| 
									
										
										
										
											2020-06-27 14:16:51 +02:00
										 |  |  |         if attrtype: | 
					
						
							| 
									
										
										
										
											2020-06-27 14:25:46 +02:00
										 |  |  |             if attrtype == bool: | 
					
						
							|  |  |  |                 def attrtype(input_text: str): | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |                     return input_text.lower() not in {"off", "0", "false", "none", "null", "no"} | 
					
						
							|  |  |  |             elif attrtype == str and option_name.endswith("password"): | 
					
						
							|  |  |  |                 def attrtype(input_text: str): | 
					
						
							|  |  |  |                     if input_text.lower() in {"null", "none", '""', "''"}: | 
					
						
							|  |  |  |                         return None | 
					
						
							|  |  |  |                     return input_text | 
					
						
							| 
									
										
										
										
											2020-06-27 16:54:07 +02:00
										 |  |  |             setattr(self.ctx, option_name, attrtype(option)) | 
					
						
							|  |  |  |             self.output(f"Set option {option_name} to {getattr(self.ctx, option_name)}") | 
					
						
							| 
									
										
										
										
											2020-06-27 14:16:51 +02:00
										 |  |  |             return True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-11-15 15:21:41 +01:00
										 |  |  |             known = (f"{option}:{otype}" for option, otype in self.ctx.simple_options.items()) | 
					
						
							| 
									
										
										
										
											2020-06-27 14:16:51 +02:00
										 |  |  |             self.output(f"Unrecognized Option {option_name}, known: " | 
					
						
							|  |  |  |                         f"{', '.join(known)}") | 
					
						
							|  |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 17:24:51 +01:00
										 |  |  | async def console(ctx: Context): | 
					
						
							| 
									
										
										
										
											2020-03-13 03:53:20 +01:00
										 |  |  |     session = prompt_toolkit.PromptSession() | 
					
						
							| 
									
										
										
										
											2020-04-13 11:26:50 +02:00
										 |  |  |     while ctx.running: | 
					
						
							| 
									
										
										
										
											2020-03-13 03:53:20 +01:00
										 |  |  |         with patch_stdout(): | 
					
						
							|  |  |  |             input_text = await session.prompt_async() | 
					
						
							| 
									
										
										
										
											2020-01-15 00:34:12 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2020-04-14 20:22:42 +02:00
										 |  |  |             ctx.commandprocessor(input_text) | 
					
						
							| 
									
										
										
										
											2020-01-15 00:34:12 +01:00
										 |  |  |         except: | 
					
						
							|  |  |  |             import traceback | 
					
						
							|  |  |  |             traceback.print_exc() | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-10 00:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:23:39 +01:00
										 |  |  | def parse_args() -> argparse.Namespace: | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     parser = argparse.ArgumentParser() | 
					
						
							| 
									
										
										
										
											2020-04-02 11:21:33 +02:00
										 |  |  |     defaults = Utils.get_options()["server_options"] | 
					
						
							|  |  |  |     parser.add_argument('--host', default=defaults["host"]) | 
					
						
							|  |  |  |     parser.add_argument('--port', default=defaults["port"], type=int) | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     parser.add_argument('--server_password', default=defaults["server_password"]) | 
					
						
							| 
									
										
										
										
											2020-04-02 11:21:33 +02:00
										 |  |  |     parser.add_argument('--password', default=defaults["password"]) | 
					
						
							|  |  |  |     parser.add_argument('--multidata', default=defaults["multidata"]) | 
					
						
							|  |  |  |     parser.add_argument('--savefile', default=defaults["savefile"]) | 
					
						
							|  |  |  |     parser.add_argument('--disable_save', default=defaults["disable_save"], action='store_true') | 
					
						
							|  |  |  |     parser.add_argument('--loglevel', default=defaults["loglevel"], | 
					
						
							|  |  |  |                         choices=['debug', 'info', 'warning', 'error', 'critical']) | 
					
						
							|  |  |  |     parser.add_argument('--location_check_points', default=defaults["location_check_points"], type=int) | 
					
						
							|  |  |  |     parser.add_argument('--hint_cost', default=defaults["hint_cost"], type=int) | 
					
						
							|  |  |  |     parser.add_argument('--disable_item_cheat', default=defaults["disable_item_cheat"], action='store_true') | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |     parser.add_argument('--forfeit_mode', default=defaults["forfeit_mode"], nargs='?', | 
					
						
							| 
									
										
										
										
											2020-05-14 15:17:56 -07:00
										 |  |  |                         choices=['auto', 'enabled', 'disabled', "goal", "auto-enabled"], help='''\
 | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |                              Select !forfeit Accessibility. (default: %(default)s) | 
					
						
							|  |  |  |                              auto:     Automatic "forfeit" on goal completion | 
					
						
							|  |  |  |                              enabled:  !forfeit is always available | 
					
						
							|  |  |  |                              disabled: !forfeit is never available | 
					
						
							|  |  |  |                              goal:     !forfeit can be used after goal completion | 
					
						
							| 
									
										
										
										
											2020-05-04 02:47:22 +02:00
										 |  |  |                              auto-enabled: !forfeit is available and automatically triggered on goal completion | 
					
						
							| 
									
										
										
										
											2020-04-25 15:11:58 +02:00
										 |  |  |                              ''')
 | 
					
						
							|  |  |  |     parser.add_argument('--remaining_mode', default=defaults["remaining_mode"], nargs='?', | 
					
						
							|  |  |  |                         choices=['enabled', 'disabled', "goal"], help='''\
 | 
					
						
							|  |  |  |                              Select !remaining Accessibility. (default: %(default)s) | 
					
						
							|  |  |  |                              enabled:  !remaining is always available | 
					
						
							|  |  |  |                              disabled: !remaining is never available | 
					
						
							|  |  |  |                              goal:     !remaining can be used after goal completion | 
					
						
							|  |  |  |                              ''')
 | 
					
						
							| 
									
										
										
										
											2020-06-13 22:49:57 +02:00
										 |  |  |     parser.add_argument('--auto_shutdown', default=defaults["auto_shutdown"], type=int, | 
					
						
							|  |  |  |                         help="automatically shut down the server after this many minutes without new location checks. " | 
					
						
							|  |  |  |                              "0 to keep running. Not yet implemented.") | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  |     parser.add_argument('--use_embedded_options', action="store_true", | 
					
						
							|  |  |  |                         help='retrieve forfeit, remaining and hint options from the multidata file,' | 
					
						
							|  |  |  |                              ' instead of host.yaml') | 
					
						
							| 
									
										
										
										
											2020-07-16 16:57:38 +02:00
										 |  |  |     parser.add_argument('--compatibility', default=defaults["compatibility"], type=int, | 
					
						
							|  |  |  |                         help="""
 | 
					
						
							|  |  |  |     #2 -> recommended for casual/cooperative play, attempt to be compatible with everything across all versions | 
					
						
							|  |  |  |     #1 -> recommended for friendly racing, only allow Berserker's Multiworld, to disallow old /getitem for example | 
					
						
							|  |  |  |     #0 -> recommended for tournaments to force a level playing field, only allow an exact version match | 
					
						
							|  |  |  |     """)
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     args = parser.parse_args() | 
					
						
							| 
									
										
										
										
											2020-03-22 21:23:39 +01:00
										 |  |  |     return args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  | async def auto_shutdown(ctx, to_cancel=None): | 
					
						
							| 
									
										
										
										
											2020-07-10 17:42:22 +02:00
										 |  |  |     await asyncio.sleep(ctx.auto_shutdown) | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |     while ctx.running: | 
					
						
							|  |  |  |         if not ctx.client_activity_timers.values(): | 
					
						
							|  |  |  |             asyncio.create_task(ctx.server.ws_server._close()) | 
					
						
							|  |  |  |             ctx.running = False | 
					
						
							|  |  |  |             if to_cancel: | 
					
						
							|  |  |  |                 for task in to_cancel: | 
					
						
							|  |  |  |                     task.cancel() | 
					
						
							|  |  |  |             logging.info("Shutting down due to inactivity.") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             newest_activity = max(ctx.client_activity_timers.values()) | 
					
						
							|  |  |  |             delta = datetime.datetime.now(datetime.timezone.utc) - newest_activity | 
					
						
							| 
									
										
										
										
											2020-07-10 17:42:22 +02:00
										 |  |  |             seconds = ctx.auto_shutdown - delta.total_seconds() | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |             if seconds < 0: | 
					
						
							|  |  |  |                 asyncio.create_task(ctx.server.ws_server._close()) | 
					
						
							|  |  |  |                 ctx.running = False | 
					
						
							|  |  |  |                 if to_cancel: | 
					
						
							|  |  |  |                     for task in to_cancel: | 
					
						
							|  |  |  |                         task.cancel() | 
					
						
							|  |  |  |                 logging.info("Shutting down due to inactivity.") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 await asyncio.sleep(seconds) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 22:49:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:23:39 +01:00
										 |  |  | async def main(args: argparse.Namespace): | 
					
						
							| 
									
										
										
										
											2020-01-18 12:21:57 +01:00
										 |  |  |     logging.basicConfig(format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO)) | 
					
						
							| 
									
										
										
										
											2020-03-10 00:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 22:11:19 -07:00
										 |  |  |     ctx = Context(args.host, args.port, args.server_password, args.password, args.location_check_points, | 
					
						
							|  |  |  |                   args.hint_cost, not args.disable_item_cheat, args.forfeit_mode, args.remaining_mode, | 
					
						
							|  |  |  |                   args.auto_shutdown, args.compatibility) | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |     data_filename = args.multidata | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |         if not data_filename: | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |             import tkinter | 
					
						
							|  |  |  |             import tkinter.filedialog | 
					
						
							|  |  |  |             root = tkinter.Tk() | 
					
						
							|  |  |  |             root.withdraw() | 
					
						
							| 
									
										
										
										
											2020-06-10 21:25:14 +02:00
										 |  |  |             data_filename = tkinter.filedialog.askopenfilename(filetypes=(("Multiworld data", "*.multidata"),)) | 
					
						
							| 
									
										
										
										
											2020-03-06 00:48:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 08:37:05 +02:00
										 |  |  |         ctx.load(data_filename, args.use_embedded_options) | 
					
						
							| 
									
										
										
										
											2020-03-10 00:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |     except Exception as e: | 
					
						
							|  |  |  |         logging.exception('Failed to read multiworld data (%s)' % e) | 
					
						
							| 
									
										
										
										
											2020-06-07 00:50:39 +02:00
										 |  |  |         raise | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |     ctx.init_save(not args.disable_save) | 
					
						
							| 
									
										
										
										
											2020-05-30 03:47:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-10 00:38:29 +01:00
										 |  |  |     ctx.server = websockets.serve(functools.partial(server, ctx=ctx), ctx.host, ctx.port, ping_timeout=None, | 
					
						
							|  |  |  |                                   ping_interval=None) | 
					
						
							| 
									
										
										
										
											2020-06-07 00:49:10 +02:00
										 |  |  |     ip = args.host if args.host else Utils.get_public_ipv4() | 
					
						
							| 
									
										
										
										
											2020-03-10 00:38:29 +01:00
										 |  |  |     logging.info('Hosting game at %s:%d (%s)' % (ip, ctx.port, | 
					
						
							|  |  |  |                                                  'No password' if not ctx.password else 'Password: %s' % ctx.password)) | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  |     await ctx.server | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |     console_task = asyncio.create_task(console(ctx)) | 
					
						
							|  |  |  |     if ctx.auto_shutdown: | 
					
						
							|  |  |  |         ctx.shutdown_task = asyncio.create_task(auto_shutdown(ctx, [console_task])) | 
					
						
							|  |  |  |     await console_task | 
					
						
							|  |  |  |     if ctx.shutdown_task: | 
					
						
							|  |  |  |         await ctx.shutdown_task | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-27 13:52:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | client_message_processor = ClientMessageProcessor | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2020-06-21 15:32:31 +02:00
										 |  |  |         asyncio.run(main(parse_args())) | 
					
						
							| 
									
										
										
										
											2020-06-16 11:26:54 +02:00
										 |  |  |     except asyncio.exceptions.CancelledError: | 
					
						
							|  |  |  |         pass |