Skip to content

Commit

Permalink
Merge branch 'main' into civ6-1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hesto2 authored Sep 27, 2024
2 parents 12ab641 + 7337309 commit 32883a3
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 153 deletions.
4 changes: 3 additions & 1 deletion BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ def add_group(self, name: str, game: str, players: AbstractSet[int] = frozenset(
self.player_types[new_id] = NetUtils.SlotType.group
world_type = AutoWorld.AutoWorldRegister.world_types[game]
self.worlds[new_id] = world_type.create_group(self, new_id, players)
self.worlds[new_id].collect_item = classmethod(AutoWorld.World.collect_item).__get__(self.worlds[new_id])
self.worlds[new_id].collect_item = AutoWorld.World.collect_item.__get__(self.worlds[new_id])
self.worlds[new_id].collect = AutoWorld.World.collect.__get__(self.worlds[new_id])
self.worlds[new_id].remove = AutoWorld.World.remove.__get__(self.worlds[new_id])
self.player_name[new_id] = name

new_group = self.groups[new_id] = Group(name=name, game=game, players=players,
Expand Down
31 changes: 27 additions & 4 deletions CommonClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,21 @@ def get_ssl_context():


class ClientCommandProcessor(CommandProcessor):
"""
The Command Processor will parse every method of the class that starts with "_cmd_" as a command to be called
when parsing user input, i.e. _cmd_exit will be called when the user sends the command "/exit".
The decorator @mark_raw can be imported from MultiServer and tells the parser to only split on the first
space after the command i.e. "/exit one two three" will be passed in as method("one two three") with mark_raw
and method("one", "two", "three") without.
In addition all docstrings for command methods will be displayed to the user on launch and when using "/help"
"""
def __init__(self, ctx: CommonContext):
self.ctx = ctx

def output(self, text: str):
"""Helper function to abstract logging to the CommonClient UI"""
logger.info(text)

def _cmd_exit(self) -> bool:
Expand Down Expand Up @@ -164,13 +175,14 @@ def _cmd_ready(self):
async_start(self.ctx.send_msgs([{"cmd": "StatusUpdate", "status": state}]), name="send StatusUpdate")

def default(self, raw: str):
"""The default message parser to be used when parsing any messages that do not match a command"""
raw = self.ctx.on_user_say(raw)
if raw:
async_start(self.ctx.send_msgs([{"cmd": "Say", "text": raw}]), name="send Say")


class CommonContext:
# Should be adjusted as needed in subclasses
# The following attributes are used to Connect and should be adjusted as needed in subclasses
tags: typing.Set[str] = {"AP"}
game: typing.Optional[str] = None
items_handling: typing.Optional[int] = None
Expand Down Expand Up @@ -429,7 +441,10 @@ async def get_username(self):
self.auth = await self.console_input()

async def send_connect(self, **kwargs: typing.Any) -> None:
""" send `Connect` packet to log in to server """
"""
Send a `Connect` packet to log in to the server,
additional keyword args can override any value in the connection packet
"""
payload = {
'cmd': 'Connect',
'password': self.password, 'name': self.auth, 'version': Utils.version_tuple,
Expand Down Expand Up @@ -459,13 +474,15 @@ def cancel_autoreconnect(self) -> bool:
return False

def slot_concerns_self(self, slot) -> bool:
"""Helper function to abstract player groups, should be used instead of checking slot == self.slot directly."""
if slot == self.slot:
return True
if slot in self.slot_info:
return self.slot in self.slot_info[slot].group_members
return False

def is_echoed_chat(self, print_json_packet: dict) -> bool:
"""Helper function for filtering out messages sent by self."""
return print_json_packet.get("type", "") == "Chat" \
and print_json_packet.get("team", None) == self.team \
and print_json_packet.get("slot", None) == self.slot
Expand Down Expand Up @@ -497,13 +514,14 @@ def on_user_say(self, text: str) -> typing.Optional[str]:
"""Gets called before sending a Say to the server from the user.
Returned text is sent, or sending is aborted if None is returned."""
return text

def on_ui_command(self, text: str) -> None:
"""Gets called by kivy when the user executes a command starting with `/` or `!`.
The command processor is still called; this is just intended for command echoing."""
self.ui.print_json([{"text": text, "type": "color", "color": "orange"}])

def update_permissions(self, permissions: typing.Dict[str, int]):
"""Internal method to parse and save server permissions from RoomInfo"""
for permission_name, permission_flag in permissions.items():
try:
flag = Permission(permission_flag)
Expand Down Expand Up @@ -613,6 +631,7 @@ def on_deathlink(self, data: typing.Dict[str, typing.Any]) -> None:
logger.info(f"DeathLink: Received from {data['source']}")

async def send_death(self, death_text: str = ""):
"""Helper function to send a deathlink using death_text as the unique death cause string."""
if self.server and self.server.socket:
logger.info("DeathLink: Sending death to your friends...")
self.last_death_link = time.time()
Expand All @@ -626,6 +645,7 @@ async def send_death(self, death_text: str = ""):
}])

async def update_death_link(self, death_link: bool):
"""Helper function to set Death Link connection tag on/off and update the connection if already connected."""
old_tags = self.tags.copy()
if death_link:
self.tags.add("DeathLink")
Expand All @@ -635,7 +655,7 @@ async def update_death_link(self, death_link: bool):
await self.send_msgs([{"cmd": "ConnectUpdate", "tags": self.tags}])

def gui_error(self, title: str, text: typing.Union[Exception, str]) -> typing.Optional["kvui.MessageBox"]:
"""Displays an error messagebox"""
"""Displays an error messagebox in the loaded Kivy UI. Override if using a different UI framework"""
if not self.ui:
return None
title = title or "Error"
Expand Down Expand Up @@ -987,6 +1007,7 @@ async def console_loop(ctx: CommonContext):


def get_base_parser(description: typing.Optional[str] = None):
"""Base argument parser to be reused for components subclassing off of CommonClient"""
import argparse
parser = argparse.ArgumentParser(description=description)
parser.add_argument('--connect', default=None, help='Address of the multiworld host.')
Expand Down Expand Up @@ -1037,6 +1058,7 @@ async def main(args):
parser.add_argument("url", nargs="?", help="Archipelago connection url")
args = parser.parse_args(args)

# handle if text client is launched using the "archipelago://name:pass@host:port" url from webhost
if args.url:
url = urllib.parse.urlparse(args.url)
if url.scheme == "archipelago":
Expand All @@ -1048,6 +1070,7 @@ async def main(args):
else:
parser.error(f"bad url, found {args.url}, expected url in form of archipelago://archipelago.gg:38281")

# use colorama to display colored text highlighting on windows
colorama.init()

asyncio.run(main(args))
Expand Down
4 changes: 2 additions & 2 deletions worlds/bumpstik/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ def set_rules(self):
lambda state: state.has("Hazard Bumper", self.player, 25)

self.multiworld.completion_condition[self.player] = \
lambda state: state.has("Booster Bumper", self.player, 5) and \
state.has("Treasure Bumper", self.player, 32)
lambda state: state.has_all_counts({"Booster Bumper": 5, "Treasure Bumper": 32, "Hazard Bumper": 25}, \
self.player)

31 changes: 25 additions & 6 deletions worlds/dark_souls_3/docs/setup_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
## Required Software

- [Dark Souls III](https://store.steampowered.com/app/374320/DARK_SOULS_III/)
- [Dark Souls III AP Client](https://github.com/Marechal-L/Dark-Souls-III-Archipelago-client/releases)
- [Dark Souls III AP Client](https://github.com/nex3/Dark-Souls-III-Archipelago-client/releases/latest)

## Optional Software

- Map tracker not yet updated for 3.0.0

## Setting Up

First, download the client from the link above. It doesn't need to go into any particular directory;
it'll automatically locate _Dark Souls III_ in your Steam installation folder.
First, download the client from the link above (`DS3.Archipelago.*.zip`). It doesn't need to go
into any particular directory; it'll automatically locate _Dark Souls III_ in your Steam
installation folder.

Version 3.0.0 of the randomizer _only_ supports the latest version of _Dark Souls III_, 1.15.2. This
is the latest version, so you don't need to do any downpatching! However, if you've already
Expand All @@ -35,8 +36,9 @@ randomized item and (optionally) enemy locations. You only need to do this once

To run _Dark Souls III_ in Archipelago mode:

1. Start Steam. **Do not run in offline mode.** The mod will make sure you don't connect to the
DS3 servers, and running Steam in offline mode will make certain scripted invaders fail to spawn.
1. Start Steam. **Do not run in offline mode.** Running Steam in offline mode will make certain
scripted invaders fail to spawn. Instead, change the game itself to offline mode on the menu
screen.

2. Run `launchmod_darksouls3.bat`. This will start _Dark Souls III_ as well as a command prompt that
you can use to interact with the Archipelago server.
Expand All @@ -52,4 +54,21 @@ To run _Dark Souls III_ in Archipelago mode:
### Where do I get a config file?

The [Player Options](/games/Dark%20Souls%20III/player-options) page on the website allows you to
configure your personal options and export them into a config file.
configure your personal options and export them into a config file. The [AP client archive] also
includes an options template.

[AP client archive]: https://github.com/nex3/Dark-Souls-III-Archipelago-client/releases/latest

### Does this work with Proton?

The *Dark Souls III* Archipelago randomizer supports running on Linux under Proton. There are a few
things to keep in mind:

* Because `DS3Randomizer.exe` relies on the .NET runtime, you'll need to install
the [.NET Runtime] under **plain [WINE]**, then run `DS3Randomizer.exe` under
plain WINE as well. It won't work as a Proton app!

* To run the game itself, just run `launchmod_darksouls3.bat` under Proton.

[.NET Runtime]: https://dotnet.microsoft.com/en-us/download/dotnet/8.0
[WINE]: https://www.winehq.org/
Loading

0 comments on commit 32883a3

Please sign in to comment.