Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Messenger: content update #2823

Merged
Merged
Show file tree
Hide file tree
Changes from 198 commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
24471ce
map option objects to a `World.options` dict
alwaysintreble Sep 2, 2022
220571f
convert RoR2 to options dict system for testing
alwaysintreble Sep 2, 2022
643205c
add temp behavior for lttp with notes
alwaysintreble Sep 2, 2022
695c94c
copy/paste bad
alwaysintreble Sep 25, 2022
caaf051
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Sep 25, 2022
d481eed
convert `set_default_common_options` to a namespace property
alwaysintreble Sep 29, 2022
f9a8bb2
reorganize test call order
alwaysintreble Sep 29, 2022
cded105
have fill_restrictive use the new options system
alwaysintreble Sep 29, 2022
be3fa3a
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Oct 18, 2022
52290df
update world api
alwaysintreble Oct 18, 2022
5896e6c
update soe tests
alwaysintreble Oct 18, 2022
cdcd06c
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Oct 29, 2022
2581d57
fix world api
alwaysintreble Oct 29, 2022
121152b
core: auto initialize a dataclass on the World class with the option …
el-u Jan 9, 2023
82ff125
core: auto initialize a dataclass on the World class with the option …
el-u Jan 9, 2023
ad2f59e
Merge pull request #14 from el-u/options_dict
alwaysintreble Jan 9, 2023
43353de
add `as_dict` method to the options dataclass
alwaysintreble Jan 9, 2023
af5647d
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Jan 9, 2023
76833d5
fix namespace issues with tests
alwaysintreble Jan 9, 2023
d85fb69
have current option updates use `.value` instead of changing the option
alwaysintreble Feb 12, 2023
42c1abb
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Feb 12, 2023
cfdc0b1
update ror2 to use the new options system again
alwaysintreble Feb 12, 2023
eaadb6e
revert the junk pool dict since it's cased differently
alwaysintreble Feb 12, 2023
d890de4
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Feb 14, 2023
0658a5b
fix begin_with_loop typo
alwaysintreble Feb 14, 2023
effbca0
write new and old options to spoiler
alwaysintreble Feb 14, 2023
b78b7d3
change factorio option behavior back
alwaysintreble Feb 14, 2023
94d18dc
fix comparisons
alwaysintreble Feb 14, 2023
0c0663b
move common and per_game_common options to new system
alwaysintreble Feb 14, 2023
a638582
core: automatically create missing options_dataclass from legacy opti…
el-u Feb 14, 2023
11214aa
Merge pull request #15 from el-u/options_dict
alwaysintreble Feb 14, 2023
fe679fc
remove spoiler special casing and add back the Factorio option changi…
alwaysintreble Feb 14, 2023
c5684bb
give ArchipIDLE the default options_dataclass so its options get gene…
alwaysintreble Feb 15, 2023
cecd3f7
reimplement `inspect.get_annotations`
alwaysintreble Feb 17, 2023
1fbc1a4
move option info generation for webhost to new system
alwaysintreble Feb 17, 2023
c3ad00b
need to include Common and PerGame common since __annotations__ doesn…
alwaysintreble Feb 17, 2023
1730eaf
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Feb 17, 2023
1b1ee31
use get_type_hints for the options dictionary
alwaysintreble Feb 21, 2023
85e98a0
typing.get_type_hints returns the bases too.
alwaysintreble Feb 21, 2023
a24bb2e
forgot to sweep through generate
alwaysintreble Feb 21, 2023
9df025d
sweep through all the tests
alwaysintreble Feb 21, 2023
337133c
swap to a metaclass property
alwaysintreble Feb 22, 2023
aadbd56
move remaining usages from get_type_hints to metaclass property
el-u Feb 25, 2023
2584535
move remaining usages from __annotations__ to metaclass property
el-u Feb 25, 2023
0ae2acc
move remaining usages from legacy dictionaries to metaclass property
el-u Feb 25, 2023
a147aae
remove legacy dictionaries
el-u Feb 25, 2023
88db4f7
cache the metaclass property
el-u Feb 25, 2023
01374e0
clarify inheritance in world api
el-u Feb 25, 2023
9d4ab5b
Merge pull request #16 from el-u/options_dict
alwaysintreble Feb 25, 2023
069328c
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Mar 6, 2023
b831bac
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Mar 13, 2023
ac123db
move the messenger to new options system
alwaysintreble Mar 13, 2023
e6806ed
add an assert for my dumb
alwaysintreble Mar 13, 2023
7c7a49f
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Mar 14, 2023
2c8afbc
update the doc
alwaysintreble Mar 14, 2023
f8ba777
rename o to options
alwaysintreble Mar 14, 2023
984d659
missed a spot
alwaysintreble Mar 14, 2023
61b82f1
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Apr 1, 2023
e959c49
update new messenger options
alwaysintreble Apr 1, 2023
ec8c75b
comment spacing
alwaysintreble Apr 1, 2023
5f32194
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble May 21, 2023
2b46533
fix tests
alwaysintreble May 21, 2023
e6424e2
fix missing import
alwaysintreble May 21, 2023
f189f5d
make the documentation definition more accurate
alwaysintreble May 25, 2023
73e5875
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble May 31, 2023
2ba7464
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Jun 28, 2023
3e1be1e
use options system for loc creation
alwaysintreble Jun 28, 2023
fc93f97
type cast MessengerWorld
alwaysintreble Jun 28, 2023
0b9959e
fix typo and use quotes for cast
alwaysintreble Jun 28, 2023
996697f
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Jul 19, 2023
266acd2
LTTP: set random seed in tests
alwaysintreble Jul 19, 2023
c39081a
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Jul 23, 2023
4596be9
ArchipIdle: remove change here as it's default on AutoWorld
alwaysintreble Jul 23, 2023
41ed545
Stardew: Need to set state because `set_default_common_options` used to
alwaysintreble Jul 23, 2023
26976b8
The Messenger: update shop rando and helpers to new system; optimize …
alwaysintreble Jul 23, 2023
7a114d4
Add a kwarg to `as_dict` to do the casing for you
alwaysintreble Jul 23, 2023
bb06b3a
RoR2: use new kwarg for less code
alwaysintreble Jul 23, 2023
8c8adbf
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Sep 1, 2023
f5da39e
RoR2: revert some accidental reverts
alwaysintreble Sep 2, 2023
9cf454b
The Messenger: remove an unnecessary variable
alwaysintreble Sep 2, 2023
37f6d8b
remove TypeVar that isn't used
beauxq Sep 2, 2023
d381d1d
CommonOptions not abstract
beauxq Sep 2, 2023
6d418f9
Docs: fix mistake in options api.md
alwaysintreble Sep 2, 2023
c02be73
remove unused TypeVar
alwaysintreble Sep 2, 2023
2e30f07
create options for item link worlds
alwaysintreble Sep 3, 2023
8583c2a
revert accidental doc removals
alwaysintreble Sep 3, 2023
c58f4a5
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Sep 26, 2023
c3a666f
Merge remote-tracking branch 'Main/main' into options_dict
alwaysintreble Sep 27, 2023
833f09c
Item Links: set default options on group
alwaysintreble Sep 27, 2023
06dae6e
Messenger: Limited Movement option first draft
alwaysintreble Sep 28, 2023
3927342
The Messenger: add automated setup through the launcher
alwaysintreble Oct 7, 2023
cb07043
drop tomllib
alwaysintreble Oct 7, 2023
50394ed
don't uselessly import launcher
alwaysintreble Oct 7, 2023
24b9c80
The Messenger: fix missing goal requirement for power seal hunt
alwaysintreble Oct 10, 2023
e9b6fca
make hard mode goal harder
alwaysintreble Oct 11, 2023
27a1488
make fire seal a bit more lenient
alwaysintreble Oct 12, 2023
096dc06
Merge branch 'messenger-limited-movement' into seal-hunt-fix
alwaysintreble Oct 12, 2023
271398d
have limited movement force minimal accessibility
alwaysintreble Oct 12, 2023
f0d921f
add an early meditation option
alwaysintreble Oct 12, 2023
aceeb50
clean up precollected notes tests a bit
alwaysintreble Oct 12, 2023
1f87adc
Merge branch 'messenger-ux-update' into seal-hunt-fix
alwaysintreble Oct 12, 2023
cf119a9
add linux support
alwaysintreble Oct 12, 2023
9c8e08b
add steam deck support
alwaysintreble Oct 12, 2023
79d7062
await monokickstart
alwaysintreble Oct 12, 2023
7054c2e
minor styling cleanup
alwaysintreble Oct 12, 2023
070df13
more minor styling cleanup
alwaysintreble Oct 12, 2023
ab4856c
Initial implementation of Generic ER
BadMagic100 Nov 19, 2023
7be8ce5
Move ERType to Entrance.Type, fix typing imports
BadMagic100 Nov 20, 2023
0507134
updates based on testing (read: flailing)
qwint Nov 20, 2023
907cea6
Updates from feedback
qwint Nov 21, 2023
15b2f03
Merge pull request #1 from qwint/generic-entrance-rando
BadMagic100 Nov 24, 2023
ec7fdf7
Various bug fixes in ERCollectionState
BadMagic100 Nov 25, 2023
8241f5f
Use deque instead of queue.Queue
BadMagic100 Nov 25, 2023
e78b804
Allow partial entrances in collection state earlier, doc improvements
BadMagic100 Nov 26, 2023
9f17b59
Prevent early loops in region graph, improve reusability of ER stage …
BadMagic100 Nov 27, 2023
1592f42
Merge branch 'main' into generic-entrance-rando
alwaysintreble Dec 1, 2023
2977509
Typos, grammar, PEP8, and style "fixes"
alwaysintreble Dec 1, 2023
144d8f4
use RuntimeError instead of bare Exceptions
alwaysintreble Dec 1, 2023
95dfd27
return tuples from connect since it's slightly faster for our purposes
alwaysintreble Dec 1, 2023
5806ac3
move the shuffle to the beginning of find_pairing
alwaysintreble Dec 1, 2023
11e4d83
do er_state placements within pairing lookups to remove code duplication
alwaysintreble Dec 1, 2023
cbb31f4
requested adjustments
alwaysintreble Dec 2, 2023
f94a484
Merge pull request #2 from alwaysintreble/generic-entrance-rando
BadMagic100 Dec 2, 2023
858727e
Merge branch 'ArchipelagoMW:main' into generic-entrance-rando
BadMagic100 Dec 10, 2023
486d3c6
Add some temporary performance logging
BadMagic100 Dec 5, 2023
5d7fe13
Use CollectionState to track available exits and placed regions
BadMagic100 Dec 10, 2023
e03045b
Merge branch 'ArchipelagoMW:main' into generic-entrance-rando
BadMagic100 Dec 24, 2023
1160e18
Merge branch 'main' into seal-hunt-fix
alwaysintreble Jan 7, 2024
c01d36e
remove seal shuffle option
alwaysintreble Jan 7, 2024
ff28793
some cleanup stuff
alwaysintreble Jan 7, 2024
f60c2f3
portal rando progress
alwaysintreble Jan 12, 2024
7164d34
pre-emptive region creation
alwaysintreble Jan 16, 2024
676bac9
seals need to be in the datapackage
alwaysintreble Jan 16, 2024
a5369bb
put mega shards in old order
alwaysintreble Jan 16, 2024
44fd0df
fix typos and make it actually work
alwaysintreble Jan 16, 2024
a2abae1
fix more missed connections and add portal events
alwaysintreble Jan 16, 2024
dbbbc9f
fix all the portal rando code
alwaysintreble Jan 17, 2024
7acf628
finish initial logic implementation
alwaysintreble Jan 24, 2024
84d6333
remove/comment out debug stuff
alwaysintreble Jan 25, 2024
56889f5
does not actually support plando yet
alwaysintreble Jan 25, 2024
bbaa19f
typos and fix a crash when 3 available portals was selected
alwaysintreble Jan 25, 2024
90163f6
finish initial logic for all connections and remove/rename as necessary
alwaysintreble Jan 26, 2024
2ac7d5f
fix typos and add some more leniency
alwaysintreble Jan 26, 2024
863518e
move item classification determination to its own method rather than …
alwaysintreble Jan 26, 2024
8f9e9a2
super complicated solution for handling installing the alpha builds
alwaysintreble Jan 26, 2024
f6ca678
fix logic bugs and add a test
alwaysintreble Jan 28, 2024
bf753af
implement logic to shuffle the cutscene portals even though it's prob…
alwaysintreble Jan 28, 2024
866e0e4
just use the one list
alwaysintreble Jan 28, 2024
7dcccc8
fix some issues with the mod checking/downloading
alwaysintreble Jan 29, 2024
96f7fb5
Core: have webhost slot name links go through the launcher so that co…
alwaysintreble Jan 29, 2024
6d10f54
Merge branch 'webhost_launch_clients' into big_messenger_update
alwaysintreble Jan 29, 2024
09f5e4c
add uri support to the launcher component function
alwaysintreble Jan 30, 2024
244d970
generate output file under specific conditions
alwaysintreble Jan 31, 2024
af5af4e
cleanup connections.py
alwaysintreble Jan 31, 2024
81d2472
set topology_present to true when portals are shuffled
alwaysintreble Jan 31, 2024
33b74e5
add requirement for ghost pit loc since it's pretty hard without move…
alwaysintreble Jan 31, 2024
88ea78a
bring hard logic back
alwaysintreble Feb 4, 2024
94ea004
misc cleanup
alwaysintreble Feb 4, 2024
2b4a15a
fix asset grabbing of latest version
alwaysintreble Feb 4, 2024
433a1a8
Merge remote-tracking branch 'BadMagic100/generic-entrance-rando' int…
alwaysintreble Feb 4, 2024
90fd209
implement ER
alwaysintreble Feb 4, 2024
dbb7ba8
just use the entrances for the spoiler instead of manipulating the cache
alwaysintreble Feb 4, 2024
e2866b1
remove test defaults
alwaysintreble Feb 4, 2024
981d278
remove excessive comprehension
alwaysintreble Feb 4, 2024
3647fb4
cleanup and cater data for the client
alwaysintreble Feb 4, 2024
1553a9e
add elemental skylands to the shuffle pools
alwaysintreble Feb 5, 2024
5668772
initial attempts at hint text
alwaysintreble Feb 5, 2024
afd3b4b
use network items for offline seeds
alwaysintreble Feb 6, 2024
900c50c
change around the offline seed data again
alwaysintreble Feb 6, 2024
5ec5ecf
move er after portal shuffle and ensure a minimal sphere 1
alwaysintreble Feb 10, 2024
5304e00
Merge branch 'ArchipelagoMW:main' into generic-entrance-rando
BadMagic100 Feb 10, 2024
e8a6b94
Add a method to automatically disconnect entrances in a coupled-compl…
BadMagic100 Feb 11, 2024
893068f
Make find_placeable_exits deterministic by sorting blocked_connection…
BadMagic100 Feb 11, 2024
a7a724c
Merge remote-tracking branch 'BadMagic100/generic-entrance-rando' int…
alwaysintreble Feb 11, 2024
2527ee2
add more ER transitions
alwaysintreble Feb 11, 2024
1f039bd
fix spoiler output of portal warps
alwaysintreble Feb 11, 2024
1449090
add path to hint_data
alwaysintreble Feb 15, 2024
d7b08dc
rename entrance to tot to be a bit clearer
alwaysintreble Feb 15, 2024
978d462
cleanup imports and update description for hard logic
alwaysintreble Feb 15, 2024
f187e2e
Merge remote-tracking branch 'Main/main' into big_messenger_update
alwaysintreble Feb 15, 2024
529973a
cleanup for PR to main
alwaysintreble Feb 15, 2024
33c1af5
missed a spot
alwaysintreble Feb 15, 2024
95cfb67
cleanup monokickstart
alwaysintreble Feb 15, 2024
94dec1d
add location_name_groups
alwaysintreble Feb 15, 2024
4768e61
update docs for new setup
alwaysintreble Feb 15, 2024
892aa40
client can reconnect on its own now, no need for a button.
alwaysintreble Feb 15, 2024
5c40bbb
fix mod download link grabbing the wrong assets
alwaysintreble Feb 16, 2024
4066a6a
cleanup mod pulling a bit and display version it's trying to update to
alwaysintreble Feb 16, 2024
228d09d
plando support
alwaysintreble Feb 26, 2024
6f9c751
comment out broken steam deck support
alwaysintreble Feb 26, 2024
d20b4ad
supports plando
alwaysintreble Feb 26, 2024
e6d0eb8
satisfy flake for currently unused file
alwaysintreble Feb 26, 2024
a8c09b4
Merge branch 'main' into messenger_update_for_main
alwaysintreble Feb 26, 2024
67b8bd0
Merge branch 'main' into messenger_update_for_main
alwaysintreble Mar 8, 2024
e2174c7
fix the items accessibility test
alwaysintreble Mar 8, 2024
d062e78
review comments
alwaysintreble Mar 9, 2024
20ea94b
add searing crags portal to starting portals when disabled like optio…
alwaysintreble Mar 9, 2024
5889384
address sliver comments
alwaysintreble Mar 10, 2024
77f79a6
rip out currently unused transition shuffle
alwaysintreble Mar 10, 2024
6d8b92f
add aerobatics warrior requirement to fire seal
alwaysintreble Mar 10, 2024
513beb3
add comments explaining the output stuff
alwaysintreble Mar 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
316 changes: 272 additions & 44 deletions worlds/messenger/__init__.py

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions worlds/messenger/client_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import io
import logging
import os.path
import subprocess
import urllib.request
from shutil import which
from tkinter.messagebox import askyesnocancel
from typing import Any, Optional
from zipfile import ZipFile
from Utils import open_file

import requests

from Utils import is_windows, messagebox, tuplize_version


MOD_URL = "https://api.github.com/repos/alwaysintreble/TheMessengerRandomizerModAP/releases/latest"


def launch_game(url: Optional[str] = None) -> None:
"""Check the game installation, then launch it"""
def courier_installed() -> bool:
"""Check if Courier is installed"""
return os.path.exists(os.path.join(game_folder, "TheMessenger_Data", "Managed", "Assembly-CSharp.Courier.mm.dll"))

def mod_installed() -> bool:
"""Check if the mod is installed"""
return os.path.exists(os.path.join(game_folder, "Mods", "TheMessengerRandomizerAP", "courier.toml"))

def request_data(request_url: str) -> Any:
"""Fetches json response from given url"""
logging.info(f"requesting {request_url}")
response = requests.get(request_url)
if response.status_code == 200: # success
try:
data = response.json()
except requests.exceptions.JSONDecodeError:
raise RuntimeError(f"Unable to fetch data. (status code {response.status_code})")
else:
raise RuntimeError(f"Unable to fetch data. (status code {response.status_code})")
return data

def install_courier() -> None:
"""Installs latest version of Courier"""
# can't use latest since courier uses pre-release tags
courier_url = "https://api.github.com/repos/Brokemia/Courier/releases"
latest_download = request_data(courier_url)[0]["assets"][-1]["browser_download_url"]

with urllib.request.urlopen(latest_download) as download:
with ZipFile(io.BytesIO(download.read()), "r") as zf:
for member in zf.infolist():
zf.extract(member, path=game_folder)

os.chdir(game_folder)
# linux and mac handling
if not is_windows:
mono_exe = which("mono")
if not mono_exe:
# steam deck support but doesn't currently work
messagebox("Failure", "Failed to install Courier", True)
raise RuntimeError("Failed to install Courier")
# # download and use mono kickstart
# # this allows steam deck support
# mono_kick_url = "https://github.com/flibitijibibo/MonoKickstart/archive/refs/heads/master.zip"
# target = os.path.join(folder, "monoKickstart")
# os.makedirs(target, exist_ok=True)
# with urllib.request.urlopen(mono_kick_url) as download:
# with ZipFile(io.BytesIO(download.read()), "r") as zf:
# for member in zf.infolist():
# zf.extract(member, path=target)
# installer = subprocess.Popen([os.path.join(target, "precompiled"),
# os.path.join(folder, "MiniInstaller.exe")], shell=False)
# os.remove(target)
else:
installer = subprocess.Popen([mono_exe, os.path.join(game_folder, "MiniInstaller.exe")], shell=False)
else:
installer = subprocess.Popen(os.path.join(game_folder, "MiniInstaller.exe"), shell=False)

failure = installer.wait()
if failure:
messagebox("Failure", "Failed to install Courier", True)
os.chdir(working_directory)
raise RuntimeError("Failed to install Courier")
os.chdir(working_directory)

if courier_installed():
messagebox("Success!", "Courier successfully installed!")
return
messagebox("Failure", "Failed to install Courier", True)
raise RuntimeError("Failed to install Courier")

def install_mod() -> None:
"""Installs latest version of the mod"""
assets = request_data(MOD_URL)["assets"]
if len(assets) == 1:
release_url = assets[0]["browser_download_url"]
else:
for asset in assets:
if "TheMessengerRandomizerAP" in asset["name"]:
release_url = asset["browser_download_url"]
break
else:
messagebox("Failure", "Failed to find latest mod download", True)
raise RuntimeError("Failed to install Mod")

mod_folder = os.path.join(game_folder, "Mods")
os.makedirs(mod_folder, exist_ok=True)
with urllib.request.urlopen(release_url) as download:
with ZipFile(io.BytesIO(download.read()), "r") as zf:
for member in zf.infolist():
zf.extract(member, path=mod_folder)

messagebox("Success!", "Latest mod successfully installed!")

def available_mod_update(latest_version: str) -> bool:
"""Check if there's an available update"""
latest_version = latest_version.lstrip("v")
toml_path = os.path.join(game_folder, "Mods", "TheMessengerRandomizerAP", "courier.toml")
with open(toml_path, "r") as f:
installed_version = f.read().splitlines()[1].strip("version = \"")

logging.info(f"Installed version: {installed_version}. Latest version: {latest_version}")
# one of the alpha builds
return "alpha" in latest_version or tuplize_version(latest_version) > tuplize_version(installed_version)

from . import MessengerWorld
game_folder = os.path.dirname(MessengerWorld.settings.game_path)
working_directory = os.getcwd()
if not courier_installed():
should_install = askyesnocancel("Install Courier",
"No Courier installation detected. Would you like to install now?")
if not should_install:
return
logging.info("Installing Courier")
install_courier()
if not mod_installed():
should_install = askyesnocancel("Install Mod",
"No randomizer mod detected. Would you like to install now?")
if not should_install:
return
logging.info("Installing Mod")
install_mod()
else:
latest = request_data(MOD_URL)["tag_name"]
if available_mod_update(latest):
should_update = askyesnocancel("Update Mod",
f"New mod version detected. Would you like to update to {latest} now?")
if should_update:
logging.info("Updating mod")
install_mod()
elif should_update is None:
return
if not is_windows:
if url:
open_file(f"steam://rungameid/764790//{url}/")
else:
open_file("steam://rungameid/764790")
else:
os.chdir(game_folder)
if url:
subprocess.Popen([MessengerWorld.settings.game_path, str(url)])
else:
subprocess.Popen(MessengerWorld.settings.game_path)
os.chdir(working_directory)
Loading