| 
									
										
											  
											
												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 __future__ import annotations | 
					
						
							|  |  |  | import asyncio | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | import typing | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  | import enum | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | from json import JSONEncoder, JSONDecoder | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							|  |  |  | import websockets | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 20:48:30 +01:00
										 |  |  | from Utils import Version | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  | class JSONMessagePart(typing.TypedDict, total=False): | 
					
						
							|  |  |  |     text: str | 
					
						
							|  |  |  |     # optional | 
					
						
							|  |  |  |     type: str | 
					
						
							|  |  |  |     color: str | 
					
						
							|  |  |  |     # mainly for items, optional | 
					
						
							|  |  |  |     found: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-01 11:40:58 +02:00
										 |  |  | class ClientStatus(enum.IntEnum): | 
					
						
							| 
									
										
										
										
											2021-02-28 20:32:15 +01:00
										 |  |  |     CLIENT_UNKNOWN = 0 | 
					
						
							| 
									
										
										
										
											2021-03-07 22:05:07 +01:00
										 |  |  |     CLIENT_CONNECTED = 5 | 
					
						
							| 
									
										
										
										
											2021-02-28 20:32:15 +01:00
										 |  |  |     CLIENT_READY = 10 | 
					
						
							|  |  |  |     CLIENT_PLAYING = 20 | 
					
						
							|  |  |  |     CLIENT_GOAL = 30 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NetworkPlayer(typing.NamedTuple): | 
					
						
							|  |  |  |     team: int | 
					
						
							|  |  |  |     slot: int | 
					
						
							|  |  |  |     alias: str | 
					
						
							|  |  |  |     name: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NetworkItem(typing.NamedTuple): | 
					
						
							|  |  |  |     item: int | 
					
						
							|  |  |  |     location: int | 
					
						
							|  |  |  |     player: int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def _scan_for_TypedTuples(obj: typing.Any) -> typing.Any: | 
					
						
							|  |  |  |     if isinstance(obj, tuple) and hasattr(obj, "_fields"):  # NamedTuple is not actually a parent class | 
					
						
							|  |  |  |         data = obj._asdict() | 
					
						
							|  |  |  |         data["class"] = obj.__class__.__name__ | 
					
						
							|  |  |  |         return data | 
					
						
							|  |  |  |     if isinstance(obj, (tuple, list)): | 
					
						
							|  |  |  |         return tuple(_scan_for_TypedTuples(o) for o in obj) | 
					
						
							|  |  |  |     if isinstance(obj, dict): | 
					
						
							|  |  |  |         return {key: _scan_for_TypedTuples(value) for key, value in obj.items()} | 
					
						
							|  |  |  |     return obj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _encode = JSONEncoder( | 
					
						
							|  |  |  |     ensure_ascii=False, | 
					
						
							|  |  |  |     check_circular=False, | 
					
						
							|  |  |  | ).encode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def encode(obj): | 
					
						
							|  |  |  |     return _encode(_scan_for_TypedTuples(obj)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 04:14:59 +01:00
										 |  |  | def get_any_version(data: dict) -> Version: | 
					
						
							|  |  |  |     data = {key.lower(): value for key, value in data.items()}  # .NET version classes have capitalized keys | 
					
						
							|  |  |  |     return Version(int(data["major"]), int(data["minor"]), int(data["build"])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 20:32:15 +01:00
										 |  |  | whitelist = {"NetworkPlayer": NetworkPlayer, | 
					
						
							|  |  |  |              "NetworkItem": NetworkItem, | 
					
						
							| 
									
										
										
										
											2021-03-19 04:14:59 +01:00
										 |  |  |              } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | custom_hooks = { | 
					
						
							|  |  |  |     "Version": get_any_version | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | def _object_hook(o: typing.Any) -> typing.Any: | 
					
						
							|  |  |  |     if isinstance(o, dict): | 
					
						
							| 
									
										
										
										
											2021-03-19 04:14:59 +01:00
										 |  |  |         hook = custom_hooks.get(o.get("class", None), None) | 
					
						
							|  |  |  |         if hook: | 
					
						
							|  |  |  |             return hook(o) | 
					
						
							| 
									
										
										
										
											2021-02-28 20:32:15 +01:00
										 |  |  |         cls = whitelist.get(o.get("class", None), None) | 
					
						
							|  |  |  |         if cls: | 
					
						
							|  |  |  |             for key in tuple(o): | 
					
						
							|  |  |  |                 if key not in cls._fields: | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  |                     del (o[key]) | 
					
						
							| 
									
										
										
										
											2021-02-28 20:32:15 +01:00
										 |  |  |             return cls(**o) | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return o | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | decode = JSONDecoder(object_hook=_object_hook).decode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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 Node: | 
					
						
							|  |  |  |     endpoints: typing.List | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  |     dumper = staticmethod(encode) | 
					
						
							|  |  |  |     loader = staticmethod(decode) | 
					
						
							| 
									
										
											  
											
												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 __init__(self): | 
					
						
							|  |  |  |         self.endpoints = [] | 
					
						
							| 
									
										
										
										
											2021-01-19 06:37:35 +01:00
										 |  |  |         super(Node, self).__init__() | 
					
						
							| 
									
										
										
										
											2021-04-07 02:37:21 +02:00
										 |  |  |         self.log_network = 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
										 |  |  | 
 | 
					
						
							|  |  |  |     def broadcast_all(self, msgs): | 
					
						
							| 
									
										
										
										
											2020-10-19 08:26:31 +02:00
										 |  |  |         msgs = self.dumper(msgs) | 
					
						
							| 
									
										
											  
											
												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 endpoint in self.endpoints: | 
					
						
							| 
									
										
										
										
											2020-10-19 08:26:31 +02:00
										 |  |  |             asyncio.create_task(self.send_encoded_msgs(endpoint, msgs)) | 
					
						
							| 
									
										
											  
											
												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-02-21 23:46:05 +01:00
										 |  |  |     async def send_msgs(self, endpoint: Endpoint, msgs: typing.Iterable[dict]): | 
					
						
							| 
									
										
											  
											
												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 not endpoint.socket or not endpoint.socket.open or endpoint.socket.closed: | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  |         msg = self.dumper(msgs) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  |             await endpoint.socket.send(msg) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |         except websockets.ConnectionClosed: | 
					
						
							| 
									
										
										
										
											2021-02-21 23:46:05 +01:00
										 |  |  |             logging.exception(f"Exception during send_msgs, could not send {msg}") | 
					
						
							| 
									
										
											  
											
												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 self.disconnect(endpoint) | 
					
						
							| 
									
										
										
										
											2021-04-07 02:37:21 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if self.log_network: | 
					
						
							|  |  |  |                 logging.info(f"Outgoing message: {msg}") | 
					
						
							| 
									
										
											  
											
												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-10-19 08:26:31 +02:00
										 |  |  |     async def send_encoded_msgs(self, endpoint: Endpoint, msg: 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
										 |  |  |         if not endpoint.socket or not endpoint.socket.open or endpoint.socket.closed: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             await endpoint.socket.send(msg) | 
					
						
							|  |  |  |         except websockets.ConnectionClosed: | 
					
						
							|  |  |  |             logging.exception("Exception during send_msgs") | 
					
						
							|  |  |  |             await self.disconnect(endpoint) | 
					
						
							| 
									
										
										
										
											2021-04-07 02:37:21 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if self.log_network: | 
					
						
							|  |  |  |                 logging.info(f"Outgoing message: {msg}") | 
					
						
							| 
									
										
											  
											
												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): | 
					
						
							|  |  |  |         if endpoint in self.endpoints: | 
					
						
							|  |  |  |             self.endpoints.remove(endpoint) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Endpoint: | 
					
						
							|  |  |  |     socket: websockets.WebSocketServerProtocol | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, socket): | 
					
						
							|  |  |  |         self.socket = socket | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async def disconnect(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							| 
									
										
										
										
											2021-01-21 23:37:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  | class HandlerMeta(type): | 
					
						
							|  |  |  |     def __new__(mcs, name, bases, attrs): | 
					
						
							|  |  |  |         handlers = attrs["handlers"] = {} | 
					
						
							|  |  |  |         trigger: str = "_handle_" | 
					
						
							|  |  |  |         for base in bases: | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  |             handlers.update(base.handlers) | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         handlers.update({handler_name[len(trigger):]: method for handler_name, method in attrs.items() if | 
					
						
							|  |  |  |                          handler_name.startswith(trigger)}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         orig_init = attrs.get('__init__', None) | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  |         if not orig_init: | 
					
						
							|  |  |  |             for base in bases: | 
					
						
							|  |  |  |                 orig_init = getattr(base, '__init__', None) | 
					
						
							|  |  |  |                 if orig_init: | 
					
						
							|  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def __init__(self, *args, **kwargs): | 
					
						
							|  |  |  |             # turn functions into bound methods | 
					
						
							|  |  |  |             self.handlers = {name: method.__get__(self, type(self)) for name, method in | 
					
						
							|  |  |  |                              handlers.items()} | 
					
						
							|  |  |  |             if orig_init: | 
					
						
							|  |  |  |                 orig_init(self, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         attrs['__init__'] = __init__ | 
					
						
							|  |  |  |         return super(HandlerMeta, mcs).__new__(mcs, name, bases, attrs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  | class JSONTypes(str, enum.Enum): | 
					
						
							|  |  |  |     color = "color" | 
					
						
							|  |  |  |     text = "text" | 
					
						
							|  |  |  |     player_id = "player_id" | 
					
						
							|  |  |  |     player_name = "player_name" | 
					
						
							|  |  |  |     item_name = "item_name" | 
					
						
							|  |  |  |     item_id = "item_id" | 
					
						
							|  |  |  |     location_name = "location_name" | 
					
						
							|  |  |  |     location_id = "location_id" | 
					
						
							|  |  |  |     entrance_name = "entrance_name" | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  | class JSONtoTextParser(metaclass=HandlerMeta): | 
					
						
							| 
									
										
										
										
											2021-02-26 21:49:23 +01:00
										 |  |  |     def __init__(self, ctx): | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         self.ctx = ctx | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def __call__(self, input_object: typing.List[JSONMessagePart]) -> str: | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         return "".join(self.handle_node(section) for section in input_object) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def handle_node(self, node: JSONMessagePart): | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         type = node.get("type", None) | 
					
						
							|  |  |  |         handler = self.handlers.get(type, self.handlers["text"]) | 
					
						
							|  |  |  |         return handler(node) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def _handle_color(self, node: JSONMessagePart): | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  |         codes = node["color"].split(";") | 
					
						
							|  |  |  |         buffer = "".join(color_code(code) for code in codes) | 
					
						
							|  |  |  |         return buffer + self._handle_text(node) + color_code("reset") | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def _handle_text(self, node: JSONMessagePart): | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         return node.get("text", "") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def _handle_player_id(self, node: JSONMessagePart): | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  |         player = int(node["text"]) | 
					
						
							|  |  |  |         node["color"] = 'magenta' if player == self.ctx.slot else 'yellow' | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         node["text"] = self.ctx.player_names[player] | 
					
						
							|  |  |  |         return self._handle_color(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # for other teams, spectators etc.? Only useful if player isn't in the clientside mapping | 
					
						
							| 
									
										
										
										
											2021-02-21 20:17:24 +01:00
										 |  |  |     def _handle_player_name(self, node: JSONMessagePart): | 
					
						
							| 
									
										
										
										
											2021-01-31 11:33:39 +01:00
										 |  |  |         node["color"] = 'yellow' | 
					
						
							|  |  |  |         return self._handle_color(node) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  |     def _handle_item_name(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         # todo: use a better info source | 
					
						
							|  |  |  |         from worlds.alttp.Items import progression_items | 
					
						
							|  |  |  |         node["color"] = 'green' if node.get("found", False) else 'cyan' | 
					
						
							|  |  |  |         if node["text"] in progression_items: | 
					
						
							|  |  |  |             node["color"] += ";white_bg" | 
					
						
							|  |  |  |         return self._handle_color(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _handle_item_id(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         item_id = int(node["text"]) | 
					
						
							|  |  |  |         node["text"] = self.ctx.item_name_getter(item_id) | 
					
						
							|  |  |  |         return self._handle_item_name(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _handle_location_name(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         node["color"] = 'blue_bg;white' | 
					
						
							|  |  |  |         return self._handle_color(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _handle_location_id(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         item_id = int(node["text"]) | 
					
						
							|  |  |  |         node["text"] = self.ctx.location_name_getter(item_id) | 
					
						
							|  |  |  |         return self._handle_item_name(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _handle_entrance_name(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         node["color"] = 'white_bg;black' | 
					
						
							|  |  |  |         return self._handle_color(node) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 23:37:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  | class RawJSONtoTextParser(JSONtoTextParser): | 
					
						
							|  |  |  |     def _handle_color(self, node: JSONMessagePart): | 
					
						
							|  |  |  |         return self._handle_text(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 23:37:58 +01:00
										 |  |  | color_codes = {'reset': 0, 'bold': 1, 'underline': 4, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, | 
					
						
							|  |  |  |                'magenta': 35, 'cyan': 36, 'white': 37, 'black_bg': 40, 'red_bg': 41, 'green_bg': 42, 'yellow_bg': 43, | 
					
						
							|  |  |  |                'blue_bg': 44, 'purple_bg': 45, 'cyan_bg': 46, 'white_bg': 47} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def color_code(*args): | 
					
						
							|  |  |  |     return '\033[' + ';'.join([str(color_codes[arg]) for arg in args]) + 'm' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def color(text, *args): | 
					
						
							|  |  |  |     return color_code(*args) + text + color_code('reset') | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def add_json_text(parts: list, text: typing.Any, **kwargs) -> None: | 
					
						
							|  |  |  |     parts.append({"text": str(text), **kwargs}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Hint(typing.NamedTuple): | 
					
						
							|  |  |  |     receiving_player: int | 
					
						
							|  |  |  |     finding_player: int | 
					
						
							|  |  |  |     location: int | 
					
						
							|  |  |  |     item: int | 
					
						
							|  |  |  |     found: bool | 
					
						
							|  |  |  |     entrance: str = "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def re_check(self, ctx, team) -> Hint: | 
					
						
							|  |  |  |         if self.found: | 
					
						
							|  |  |  |             return self | 
					
						
							|  |  |  |         found = self.location in ctx.location_checks[team, self.finding_player] | 
					
						
							|  |  |  |         if found: | 
					
						
							|  |  |  |             return Hint(self.receiving_player, self.finding_player, self.location, self.item, found, self.entrance) | 
					
						
							|  |  |  |         return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash((self.receiving_player, self.finding_player, self.location, self.item, self.entrance)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def as_network_message(self) -> dict: | 
					
						
							|  |  |  |         parts = [] | 
					
						
							|  |  |  |         add_json_text(parts, "[Hint]: ") | 
					
						
							|  |  |  |         add_json_text(parts, self.receiving_player, type="player_id") | 
					
						
							|  |  |  |         add_json_text(parts, "'s ") | 
					
						
							|  |  |  |         add_json_text(parts, self.item, type="item_id", found=self.found) | 
					
						
							|  |  |  |         add_json_text(parts, " is at ") | 
					
						
							|  |  |  |         add_json_text(parts, self.location, type="location_id") | 
					
						
							|  |  |  |         add_json_text(parts, " in ") | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  |         add_json_text(parts, self.finding_player, type="player_id") | 
					
						
							| 
									
										
										
										
											2021-03-02 22:31:44 +01:00
										 |  |  |         if self.entrance: | 
					
						
							|  |  |  |             add_json_text(parts, "'s World at ") | 
					
						
							|  |  |  |             add_json_text(parts, self.entrance, type="entrance_name") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             add_json_text(parts, "'s World") | 
					
						
							|  |  |  |         if self.found: | 
					
						
							|  |  |  |             add_json_text(parts, ". (found)") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             add_json_text(parts, ".") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 14:49:32 +02:00
										 |  |  |         return {"cmd": "PrintJSON", "data": parts, "type": "hint"} |