2020-01-12 16:03:30 +00:00
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2020-04-10 12:27:54 +00:00
|
|
|
import threading
|
|
|
|
import concurrent.futures
|
2020-04-21 04:02:03 +00:00
|
|
|
import argparse
|
2020-11-28 22:51:13 +00:00
|
|
|
import logging
|
2021-04-12 07:45:07 +00:00
|
|
|
import random
|
2020-01-12 16:03:30 +00:00
|
|
|
|
2020-04-10 12:27:54 +00:00
|
|
|
|
|
|
|
def feedback(text: str):
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(text)
|
2020-01-12 16:03:30 +00:00
|
|
|
input("Press Enter to ignore and probably crash.")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.basicConfig(format='%(message)s', level=logging.INFO)
|
2020-01-17 19:24:21 +00:00
|
|
|
try:
|
2020-01-18 14:45:52 +00:00
|
|
|
import ModuleUpdate
|
2020-03-05 23:48:23 +00:00
|
|
|
|
2020-01-18 14:45:52 +00:00
|
|
|
ModuleUpdate.update()
|
|
|
|
|
2020-04-21 04:02:03 +00:00
|
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
|
|
parser.add_argument('--disable_autohost', action='store_true')
|
|
|
|
args = parser.parse_args()
|
2020-04-02 12:47:46 +00:00
|
|
|
|
|
|
|
from Utils import get_public_ipv4, get_options
|
2021-04-12 07:45:07 +00:00
|
|
|
from Mystery import get_seed_name
|
2020-03-05 23:48:23 +00:00
|
|
|
|
2020-04-02 09:21:33 +00:00
|
|
|
options = get_options()
|
2020-02-09 04:28:48 +00:00
|
|
|
|
2020-03-05 23:48:23 +00:00
|
|
|
multi_mystery_options = options["multi_mystery_options"]
|
2020-08-20 13:43:22 +00:00
|
|
|
output_path = options["general_options"]["output_path"]
|
2020-02-09 04:28:48 +00:00
|
|
|
enemizer_path = multi_mystery_options["enemizer_path"]
|
|
|
|
player_files_path = multi_mystery_options["player_files_path"]
|
2020-11-28 22:51:13 +00:00
|
|
|
target_player_count = multi_mystery_options["players"]
|
2021-03-22 20:14:19 +00:00
|
|
|
glitch_triforce = multi_mystery_options["glitch_triforce_room"]
|
2020-02-09 04:28:48 +00:00
|
|
|
race = multi_mystery_options["race"]
|
2021-01-02 11:49:43 +00:00
|
|
|
plando_options = multi_mystery_options["plando_options"]
|
2020-02-09 04:28:48 +00:00
|
|
|
create_spoiler = multi_mystery_options["create_spoiler"]
|
|
|
|
zip_roms = multi_mystery_options["zip_roms"]
|
2020-03-05 23:48:23 +00:00
|
|
|
zip_diffs = multi_mystery_options["zip_diffs"]
|
Minecraft updates (#13)
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
* Minecraft logic updates
Wither kill now considers nether fortresses as a valid source of soul sand
A Furious Cocktail now requires beacons for resistance and village access for carrots
Uneasy Alliance now requires fishing rod to pull the ghast through the portal
On a Rail now requires iron pickaxe to make powered rails
Overkill now may require strength II without stone axe, which needs nether access
* embed all apmc info into slot_data
* updated MC tests for logic changes
* put apmc into zipfile
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
2021-05-15 22:49:58 +00:00
|
|
|
zip_apmcs = multi_mystery_options["zip_apmcs"]
|
2020-02-17 01:09:33 +00:00
|
|
|
zip_spoiler = multi_mystery_options["zip_spoiler"]
|
|
|
|
zip_multidata = multi_mystery_options["zip_multidata"]
|
2020-02-21 09:57:57 +00:00
|
|
|
zip_format = multi_mystery_options["zip_format"]
|
2020-11-08 06:31:32 +00:00
|
|
|
# zip_password = multi_mystery_options["zip_password"] not at this time
|
2020-02-09 04:28:48 +00:00
|
|
|
player_name = multi_mystery_options["player_name"]
|
2020-02-18 08:14:31 +00:00
|
|
|
meta_file_path = multi_mystery_options["meta_file_path"]
|
2020-11-28 22:51:13 +00:00
|
|
|
weights_file_path = multi_mystery_options["weights_file_path"]
|
2021-03-03 10:20:37 +00:00
|
|
|
pre_roll = multi_mystery_options["pre_roll"]
|
2020-02-23 16:06:44 +00:00
|
|
|
teams = multi_mystery_options["teams"]
|
2021-04-01 09:40:58 +00:00
|
|
|
rom_file = options["lttp_options"]["rom_file"]
|
2020-04-02 17:40:38 +00:00
|
|
|
host = options["server_options"]["host"]
|
2020-04-02 09:21:33 +00:00
|
|
|
port = options["server_options"]["port"]
|
2020-02-09 04:28:48 +00:00
|
|
|
|
|
|
|
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"
|
|
|
|
|
|
|
|
if not os.path.exists(enemizer_path):
|
2020-11-08 06:31:32 +00:00
|
|
|
feedback(
|
|
|
|
f"Enemizer not found at {enemizer_path}, please adjust the path in MultiMystery.py's config or put Enemizer in the default location.")
|
2020-02-23 16:12:21 +00:00
|
|
|
if not os.path.exists(rom_file):
|
|
|
|
feedback(f"Base rom is expected as {rom_file} in the Multiworld root folder please place/rename it there.")
|
2020-01-17 19:24:21 +00:00
|
|
|
player_files = []
|
2020-02-09 04:28:48 +00:00
|
|
|
os.makedirs(player_files_path, exist_ok=True)
|
|
|
|
for file in os.listdir(player_files_path):
|
2020-02-18 08:14:31 +00:00
|
|
|
lfile = file.lower()
|
2020-11-08 06:26:50 +00:00
|
|
|
if lfile.endswith(".yaml") and lfile != meta_file_path.lower() and lfile != weights_file_path.lower():
|
2020-01-17 19:24:21 +00:00
|
|
|
player_files.append(file)
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"Found player's file {file}.")
|
2020-01-17 19:24:21 +00:00
|
|
|
|
|
|
|
player_string = ""
|
2020-02-23 16:06:44 +00:00
|
|
|
for i, file in enumerate(player_files, 1):
|
2020-08-30 01:18:10 +00:00
|
|
|
player_string += f"--p{i} \"{os.path.join(player_files_path, file)}\" "
|
2020-01-17 19:24:21 +00:00
|
|
|
|
2021-01-03 13:32:32 +00:00
|
|
|
if os.path.exists("ArchipelagoMystery.exe"):
|
|
|
|
basemysterycommand = "ArchipelagoMystery.exe" # compiled windows
|
|
|
|
elif os.path.exists("ArchipelagoMystery"):
|
|
|
|
basemysterycommand = "ArchipelagoMystery" # compiled linux
|
2020-02-02 21:36:55 +00:00
|
|
|
else:
|
2020-08-26 20:28:48 +00:00
|
|
|
basemysterycommand = f"py -{py_version} Mystery.py" # source
|
2020-02-02 21:36:55 +00:00
|
|
|
|
2020-11-08 06:26:50 +00:00
|
|
|
weights_file_path = os.path.join(player_files_path, weights_file_path)
|
|
|
|
if os.path.exists(weights_file_path):
|
|
|
|
target_player_count = max(len(player_files), target_player_count)
|
|
|
|
else:
|
|
|
|
target_player_count = len(player_files)
|
|
|
|
|
|
|
|
if target_player_count == 0:
|
|
|
|
feedback(f"No player files found. Please put them in a {player_files_path} folder.")
|
|
|
|
else:
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"{target_player_count} Players found.")
|
2021-04-12 07:45:07 +00:00
|
|
|
seed_name = get_seed_name(random)
|
2020-11-08 06:26:50 +00:00
|
|
|
command = f"{basemysterycommand} --multi {target_player_count} {player_string} " \
|
2020-02-23 16:06:44 +00:00
|
|
|
f"--rom \"{rom_file}\" --enemizercli \"{enemizer_path}\" " \
|
2021-04-12 07:45:07 +00:00
|
|
|
f"--outputpath \"{output_path}\" --teams {teams} --plando \"{plando_options}\" " \
|
|
|
|
f"--seed_name {seed_name}"
|
2020-02-18 08:14:31 +00:00
|
|
|
|
|
|
|
if create_spoiler:
|
2020-02-23 16:06:44 +00:00
|
|
|
command += " --create_spoiler"
|
2020-05-30 22:28:03 +00:00
|
|
|
if create_spoiler == 2:
|
|
|
|
command += " --skip_playthrough"
|
2020-08-26 20:28:48 +00:00
|
|
|
if zip_diffs:
|
|
|
|
command += " --create_diff"
|
2021-03-22 20:14:19 +00:00
|
|
|
if glitch_triforce:
|
|
|
|
command += " --glitch_triforce"
|
2020-02-18 08:14:31 +00:00
|
|
|
if race:
|
|
|
|
command += " --race"
|
|
|
|
if os.path.exists(os.path.join(player_files_path, meta_file_path)):
|
|
|
|
command += f" --meta {os.path.join(player_files_path, meta_file_path)}"
|
2020-11-08 06:26:50 +00:00
|
|
|
if os.path.exists(weights_file_path):
|
|
|
|
command += f" --weights {weights_file_path}"
|
2021-03-03 10:20:37 +00:00
|
|
|
if pre_roll:
|
|
|
|
command += " --pre_roll"
|
2020-02-18 08:14:31 +00:00
|
|
|
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(command)
|
2020-01-17 19:24:21 +00:00
|
|
|
import time
|
2020-08-26 20:28:48 +00:00
|
|
|
|
2020-01-17 19:24:21 +00:00
|
|
|
start = time.perf_counter()
|
|
|
|
text = subprocess.check_output(command, shell=True).decode()
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"Took {time.perf_counter() - start:.3f} seconds to generate multiworld.")
|
2020-01-17 19:24:21 +00:00
|
|
|
|
2021-04-12 07:45:07 +00:00
|
|
|
multidataname = f"AP_{seed_name}.archipelago"
|
|
|
|
spoilername = f"AP_{seed_name}_Spoiler.txt"
|
2020-01-17 19:24:21 +00:00
|
|
|
romfilename = ""
|
2020-02-17 01:09:33 +00:00
|
|
|
|
2020-01-17 19:24:21 +00:00
|
|
|
if player_name:
|
2020-02-16 08:44:32 +00:00
|
|
|
for file in os.listdir(output_path):
|
|
|
|
if player_name in file:
|
2020-07-15 15:19:16 +00:00
|
|
|
import MultiClient
|
|
|
|
import asyncio
|
2020-02-16 08:44:32 +00:00
|
|
|
|
2020-07-15 15:19:16 +00:00
|
|
|
asyncio.run(MultiClient.run_game(os.path.join(output_path, file)))
|
2020-02-16 08:44:32 +00:00
|
|
|
break
|
2020-01-17 19:24:21 +00:00
|
|
|
|
Minecraft updates (#13)
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
* Minecraft logic updates
Wither kill now considers nether fortresses as a valid source of soul sand
A Furious Cocktail now requires beacons for resistance and village access for carrots
Uneasy Alliance now requires fishing rod to pull the ghast through the portal
On a Rail now requires iron pickaxe to make powered rails
Overkill now may require strength II without stone axe, which needs nether access
* embed all apmc info into slot_data
* updated MC tests for logic changes
* put apmc into zipfile
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
2021-05-15 22:49:58 +00:00
|
|
|
if any((zip_roms, zip_multidata, zip_spoiler, zip_diffs, zip_apmcs)):
|
2020-02-17 01:09:33 +00:00
|
|
|
import zipfile
|
2020-11-08 06:31:32 +00:00
|
|
|
|
|
|
|
compression = {1: zipfile.ZIP_DEFLATED,
|
|
|
|
2: zipfile.ZIP_LZMA,
|
|
|
|
3: zipfile.ZIP_BZIP2}[zip_format]
|
2020-02-21 09:57:57 +00:00
|
|
|
|
|
|
|
typical_zip_ending = {1: "zip",
|
|
|
|
2: "7z",
|
|
|
|
3: "bz2"}[zip_format]
|
2020-02-17 01:09:33 +00:00
|
|
|
|
2020-04-10 12:27:54 +00:00
|
|
|
ziplock = threading.Lock()
|
|
|
|
|
|
|
|
|
2020-02-17 01:09:33 +00:00
|
|
|
def pack_file(file: str):
|
2020-04-10 12:27:54 +00:00
|
|
|
with ziplock:
|
|
|
|
zf.write(os.path.join(output_path, file), file)
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"Packed {file} into zipfile {zipname}")
|
2020-04-10 12:27:54 +00:00
|
|
|
|
2020-02-17 01:09:33 +00:00
|
|
|
|
|
|
|
def remove_zipped_file(file: str):
|
|
|
|
os.remove(os.path.join(output_path, file))
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"Removed {file} which is now present in the zipfile")
|
2020-02-17 01:09:33 +00:00
|
|
|
|
2020-04-10 12:27:54 +00:00
|
|
|
|
2021-04-12 07:45:07 +00:00
|
|
|
zipname = os.path.join(output_path, f"AP_{seed_name}.{typical_zip_ending}")
|
2020-02-21 09:57:57 +00:00
|
|
|
|
2020-11-28 22:51:13 +00:00
|
|
|
logging.info(f"Creating zipfile {zipname}")
|
2020-04-02 17:40:38 +00:00
|
|
|
ipv4 = (host if host else get_public_ipv4()) + ":" + str(port)
|
2020-04-10 12:27:54 +00:00
|
|
|
|
|
|
|
|
2020-08-26 20:28:48 +00:00
|
|
|
def _handle_sfc_file(file: str):
|
2020-04-10 12:27:54 +00:00
|
|
|
if zip_roms:
|
|
|
|
pack_file(file)
|
|
|
|
if zip_roms == 2 and player_name.lower() not in file.lower():
|
|
|
|
remove_zipped_file(file)
|
|
|
|
|
|
|
|
|
2020-08-26 20:28:48 +00:00
|
|
|
def _handle_diff_file(file: str):
|
|
|
|
if zip_diffs > 0:
|
|
|
|
pack_file(file)
|
|
|
|
if zip_diffs == 2:
|
|
|
|
remove_zipped_file(file)
|
|
|
|
|
|
|
|
|
2021-05-15 23:16:51 +00:00
|
|
|
def _handle_apmc_file(file: str):
|
Minecraft updates (#13)
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
* Minecraft logic updates
Wither kill now considers nether fortresses as a valid source of soul sand
A Furious Cocktail now requires beacons for resistance and village access for carrots
Uneasy Alliance now requires fishing rod to pull the ghast through the portal
On a Rail now requires iron pickaxe to make powered rails
Overkill now may require strength II without stone axe, which needs nether access
* embed all apmc info into slot_data
* updated MC tests for logic changes
* put apmc into zipfile
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
2021-05-15 22:49:58 +00:00
|
|
|
if zip_apmcs:
|
|
|
|
pack_file(file)
|
2021-05-15 23:16:51 +00:00
|
|
|
if zip_apmcs == 2:
|
Minecraft updates (#13)
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
* Minecraft logic updates
Wither kill now considers nether fortresses as a valid source of soul sand
A Furious Cocktail now requires beacons for resistance and village access for carrots
Uneasy Alliance now requires fishing rod to pull the ghast through the portal
On a Rail now requires iron pickaxe to make powered rails
Overkill now may require strength II without stone axe, which needs nether access
* embed all apmc info into slot_data
* updated MC tests for logic changes
* put apmc into zipfile
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
2021-05-15 22:49:58 +00:00
|
|
|
remove_zipped_file(file)
|
|
|
|
|
|
|
|
|
2020-04-10 12:27:54 +00:00
|
|
|
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
|
|
futures = []
|
2021-05-15 23:16:51 +00:00
|
|
|
files = os.listdir(output_path)
|
2020-04-10 12:27:54 +00:00
|
|
|
with zipfile.ZipFile(zipname, "w", compression=compression, compresslevel=9) as zf:
|
2021-05-15 23:16:51 +00:00
|
|
|
for file in files:
|
2021-04-12 07:45:07 +00:00
|
|
|
if seed_name in file:
|
2020-08-26 20:28:48 +00:00
|
|
|
if file.endswith(".sfc"):
|
|
|
|
futures.append(pool.submit(_handle_sfc_file, file))
|
2020-10-19 06:26:31 +00:00
|
|
|
elif file.endswith(".apbp"):
|
2020-08-26 20:28:48 +00:00
|
|
|
futures.append(pool.submit(_handle_diff_file, file))
|
Minecraft updates (#13)
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
* Minecraft logic updates
Wither kill now considers nether fortresses as a valid source of soul sand
A Furious Cocktail now requires beacons for resistance and village access for carrots
Uneasy Alliance now requires fishing rod to pull the ghast through the portal
On a Rail now requires iron pickaxe to make powered rails
Overkill now may require strength II without stone axe, which needs nether access
* embed all apmc info into slot_data
* updated MC tests for logic changes
* put apmc into zipfile
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
2021-05-15 22:49:58 +00:00
|
|
|
elif file.endswith(".apmc"):
|
|
|
|
futures.append(pool.submit(_handle_apmc_file, file))
|
2021-05-15 23:16:51 +00:00
|
|
|
# just handle like a diff file for now
|
|
|
|
elif file.endswith(".zip"):
|
|
|
|
futures.append(pool.submit(_handle_diff_file, file))
|
2020-04-10 12:27:54 +00:00
|
|
|
|
|
|
|
if zip_multidata and os.path.exists(os.path.join(output_path, multidataname)):
|
|
|
|
pack_file(multidataname)
|
|
|
|
if zip_multidata == 2:
|
|
|
|
remove_zipped_file(multidataname)
|
|
|
|
|
|
|
|
if zip_spoiler and create_spoiler:
|
|
|
|
pack_file(spoilername)
|
|
|
|
if zip_spoiler == 2:
|
|
|
|
remove_zipped_file(spoilername)
|
|
|
|
|
|
|
|
for future in futures:
|
|
|
|
future.result() # make sure we close the zip AFTER any packing is done
|
2020-02-17 01:09:33 +00:00
|
|
|
|
2020-04-21 04:02:03 +00:00
|
|
|
if not args.disable_autohost:
|
|
|
|
if os.path.exists(os.path.join(output_path, multidataname)):
|
2021-01-03 13:32:32 +00:00
|
|
|
if os.path.exists("ArchipelagoServer.exe"):
|
|
|
|
baseservercommand = "ArchipelagoServer.exe" # compiled windows
|
|
|
|
elif os.path.exists("ArchipelagoServer"):
|
|
|
|
baseservercommand = "ArchipelagoServer" # compiled linux
|
2020-04-21 04:02:03 +00:00
|
|
|
else:
|
|
|
|
baseservercommand = f"py -{py_version} MultiServer.py" # source
|
2020-11-08 06:31:32 +00:00
|
|
|
# don't have a mac to test that. If you try to run compiled on mac, good luck.
|
2020-04-21 04:02:03 +00:00
|
|
|
|
|
|
|
subprocess.call(f"{baseservercommand} --multidata {os.path.join(output_path, multidataname)}")
|
2020-01-17 19:24:21 +00:00
|
|
|
except:
|
|
|
|
import traceback
|
2020-11-08 06:31:32 +00:00
|
|
|
|
2020-01-17 19:24:21 +00:00
|
|
|
traceback.print_exc()
|
|
|
|
input("Press enter to close")
|