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 self.slot in self.slot_info[slot].group_members
return False 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): def on_print(self, args: dict):
logger.info(args["text"]) logger.info(args["text"])

View File

@ -4,6 +4,7 @@ import logging
import json import json
import string import string
import copy import copy
import re
import subprocess import subprocess
import time import time
import random import random
@ -46,6 +47,10 @@ class FactorioCommandProcessor(ClientCommandProcessor):
"""Manually trigger a resync.""" """Manually trigger a resync."""
self.ctx.awaiting_bridge = True 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): class FactorioContext(CommonContext):
command_processor = FactorioCommandProcessor command_processor = FactorioCommandProcessor
@ -65,6 +70,7 @@ class FactorioContext(CommonContext):
self.factorio_json_text_parser = FactorioJSONtoTextParser(self) self.factorio_json_text_parser = FactorioJSONtoTextParser(self)
self.energy_link_increment = 0 self.energy_link_increment = 0
self.last_deplete = 0 self.last_deplete = 0
self.filter_item_sends: bool = False
async def server_auth(self, password_requested: bool = False): async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password: if password_requested and not self.password:
@ -85,8 +91,9 @@ class FactorioContext(CommonContext):
def on_print_json(self, args: dict): def on_print_json(self, args: dict):
if self.rcon_client: if self.rcon_client:
text = self.factorio_json_text_parser(copy.deepcopy(args["data"])) if not self.filter_item_sends or not self.is_uninteresting_item_send(args):
self.print_to_game(text) text = self.factorio_json_text_parser(copy.deepcopy(args["data"]))
self.print_to_game(text)
super(FactorioContext, self).on_print_json(args) super(FactorioContext, self).on_print_json(args)
@property @property
@ -123,6 +130,15 @@ class FactorioContext(CommonContext):
f"{Utils.format_SI_prefix(args['value'])}J remaining.") f"{Utils.format_SI_prefix(args['value'])}J remaining.")
self.rcon_client.send_command(f"/ap-energylink {gained}") 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): def run_gui(self):
from kvui import GameManager 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: if not ctx.awaiting_bridge and "Archipelago Bridge Data available for game tick " in msg:
ctx.awaiting_bridge = True ctx.awaiting_bridge = True
factorio_server_logger.debug(msg) 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: else:
factorio_server_logger.info(msg) factorio_server_logger.info(msg)
if ctx.rcon_client: if ctx.rcon_client:
@ -363,6 +382,7 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool:
async def main(args): async def main(args):
ctx = FactorioContext(args.connect, args.password) 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") ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop")
if gui_enabled: 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) server_settings = args.server_settings if args.server_settings else options["factorio_options"].get("server_settings", None)
if server_settings: if server_settings:
server_settings = os.path.abspath(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)): 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.") 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": { "factorio_options": {
"executable": os.path.join("factorio", "bin", "x64", "factorio"), "executable": os.path.join("factorio", "bin", "x64", "factorio"),
"filter_item_sends": False,
}, },
"sni_options": { "sni_options": {
"sni": "SNI", "sni": "SNI",

View File

@ -99,6 +99,8 @@ factorio_options:
executable: "factorio/bin/x64/factorio" 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. # 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" # 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: minecraft_options:
forge_directory: "Minecraft Forge server" forge_directory: "Minecraft Forge server"
max_heap_size: "2G" 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 global.forcedata[force].energy = global.forcedata[force].energy + change
end) 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 -- data
progressive_technologies = {{ dict_to_lua(progressive_technology_table) }} 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 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. "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 ## Troubleshooting
In case any problems should occur, the Archipelago Client will create a file `FactorioClient.txt` in the `/logs`. The In case any problems should occur, the Archipelago Client will create a file `FactorioClient.txt` in the `/logs`. The