Factorio: Add optional filtering for item sends displayed in-game (#1142)

* Factorio: Added feature to filter item sends displayed in-game.

* Factorio: Document item send filter feature.

* Factorio: Fix item send filter for item links.

* (Removed superfluous type annotations.)

* CommonClient: Added is_uninteresting_item_send helper.
This commit is contained in:
recklesscoder 2022-10-28 00:07:57 +02:00 committed by GitHub
parent aeb78eaa10
commit 924f484be0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 2 deletions

View File

@ -312,6 +312,12 @@ class CommonContext:
return self.slot in self.slot_info[slot].group_members
return False
def is_uninteresting_item_send(self, print_json_packet: dict) -> bool:
"""Helper function for filtering out ItemSend prints that do not concern the local player."""
return print_json_packet.get("type", "") == "ItemSend" \
and not self.slot_concerns_self(print_json_packet["receiving"]) \
and not self.slot_concerns_self(print_json_packet["item"].player)
def on_print(self, args: dict):
logger.info(args["text"])

View File

@ -4,6 +4,7 @@ import logging
import json
import string
import copy
import re
import subprocess
import time
import random
@ -46,6 +47,10 @@ class FactorioCommandProcessor(ClientCommandProcessor):
"""Manually trigger a resync."""
self.ctx.awaiting_bridge = True
def _cmd_toggle_send_filter(self):
"""Toggle filtering of item sends that get displayed in-game to only those that involve you."""
self.ctx.toggle_filter_item_sends()
class FactorioContext(CommonContext):
command_processor = FactorioCommandProcessor
@ -65,6 +70,7 @@ class FactorioContext(CommonContext):
self.factorio_json_text_parser = FactorioJSONtoTextParser(self)
self.energy_link_increment = 0
self.last_deplete = 0
self.filter_item_sends: bool = False
async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
@ -85,8 +91,9 @@ class FactorioContext(CommonContext):
def on_print_json(self, args: dict):
if self.rcon_client:
text = self.factorio_json_text_parser(copy.deepcopy(args["data"]))
self.print_to_game(text)
if not self.filter_item_sends or not self.is_uninteresting_item_send(args):
text = self.factorio_json_text_parser(copy.deepcopy(args["data"]))
self.print_to_game(text)
super(FactorioContext, self).on_print_json(args)
@property
@ -123,6 +130,15 @@ class FactorioContext(CommonContext):
f"{Utils.format_SI_prefix(args['value'])}J remaining.")
self.rcon_client.send_command(f"/ap-energylink {gained}")
def toggle_filter_item_sends(self) -> None:
self.filter_item_sends = not self.filter_item_sends
if self.filter_item_sends:
announcement = "Item sends are now filtered."
else:
announcement = "Item sends are no longer filtered."
logger.info(announcement)
self.print_to_game(announcement)
def run_gui(self):
from kvui import GameManager
@ -262,6 +278,9 @@ async def factorio_server_watcher(ctx: FactorioContext):
if not ctx.awaiting_bridge and "Archipelago Bridge Data available for game tick " in msg:
ctx.awaiting_bridge = True
factorio_server_logger.debug(msg)
elif re.match(r"^[0-9.]+ Script @[^ ]+\.lua:\d+: Player command toggle-ap-send-filter", msg):
factorio_server_logger.debug(msg)
ctx.toggle_filter_item_sends()
else:
factorio_server_logger.info(msg)
if ctx.rcon_client:
@ -363,6 +382,7 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool:
async def main(args):
ctx = FactorioContext(args.connect, args.password)
ctx.filter_item_sends = initial_filter_item_sends
ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop")
if gui_enabled:
@ -415,6 +435,9 @@ if __name__ == '__main__':
server_settings = args.server_settings if args.server_settings else options["factorio_options"].get("server_settings", None)
if server_settings:
server_settings = os.path.abspath(server_settings)
if not isinstance(options["factorio_options"]["filter_item_sends"], bool):
logging.warning(f"Warning: Option filter_item_sends should be a bool.")
initial_filter_item_sends = bool(options["factorio_options"]["filter_item_sends"])
if not os.path.exists(os.path.dirname(executable)):
raise FileNotFoundError(f"Path {os.path.dirname(executable)} does not exist or could not be accessed.")

View File

@ -231,6 +231,7 @@ def get_default_options() -> OptionsType:
},
"factorio_options": {
"executable": os.path.join("factorio", "bin", "x64", "factorio"),
"filter_item_sends": False,
},
"sni_options": {
"sni": "SNI",

View File

@ -99,6 +99,8 @@ factorio_options:
executable: "factorio/bin/x64/factorio"
# by default, no settings are loaded if this file does not exist. If this file does exist, then it will be used.
# server_settings: "factorio\\data\\server-settings.json"
# Whether to filter item send messages displayed in-game to only those that involve you.
filter_item_sends: false
minecraft_options:
forge_directory: "Minecraft Forge server"
max_heap_size: "2G"

View File

@ -596,5 +596,9 @@ commands.add_command("ap-energylink", "Used by the Archipelago client to manage
global.forcedata[force].energy = global.forcedata[force].energy + change
end)
commands.add_command("toggle-ap-send-filter", "Toggle filtering of item sends that get displayed in-game to only those that involve you.", function(call)
log("Player command toggle-ap-send-filter") -- notifies client
end)
-- data
progressive_technologies = {{ dict_to_lua(progressive_technology_table) }}

View File

@ -141,6 +141,18 @@ you can also issue the `!help` command to learn about additional commands like `
4. Provide your IP address to anyone you want to join your game, and have them follow the steps for
"Connecting to Someone Else's Factorio Game" above.
## Other Settings
- By default, all item sends are displayed in-game. In larger async seeds this may become overly spammy.
To hide all item sends that are not to or from your factory, do one of the following:
- Type `/toggle-ap-send-filter` in-game
- Type `/toggle_send_filter` in the Archipelago Client
- In your `host.yaml` set
```
factorio_options:
filter_item_sends: true
```
## Troubleshooting
In case any problems should occur, the Archipelago Client will create a file `FactorioClient.txt` in the `/logs`. The