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:
parent
aeb78eaa10
commit
924f484be0
|
@ -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"])
|
||||||
|
|
||||||
|
|
|
@ -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.")
|
||||||
|
|
1
Utils.py
1
Utils.py
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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) }}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue