Skip to content

Commit

Permalink
Factorio: Add optional filtering for item sends displayed in-game (Ar…
Browse files Browse the repository at this point in the history
…chipelagoMW#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.
  • Loading branch information
recklesscoder authored Oct 27, 2022
1 parent aeb78ea commit 924f484
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CommonClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ def slot_concerns_self(self, slot) -> bool:
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"])

Expand Down
27 changes: 25 additions & 2 deletions FactorioClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
import string
import copy
import re
import subprocess
import time
import random
Expand Down Expand Up @@ -46,6 +47,10 @@ def _cmd_resync(self):
"""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
Expand All @@ -65,6 +70,7 @@ def __init__(self, server_address, password):
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:
Expand All @@ -85,8 +91,9 @@ def on_print(self, args: dict):

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
Expand Down Expand Up @@ -123,6 +130,15 @@ def on_package(self, cmd: str, args: dict):
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

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -415,6 +435,9 @@ def _handle_color(self, node: JSONMessagePart):
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.")
Expand Down
1 change: 1 addition & 0 deletions Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions host.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions worlds/factorio/data/mod_template/control.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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) }}
12 changes: 12 additions & 0 deletions worlds/factorio/docs/setup_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 924f484

Please sign in to comment.