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

New Game Implementation: Civilization VI #3736

Open
wants to merge 130 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
843f903
Init
hesto2 Jul 31, 2024
15d7e3c
remove submodule
hesto2 Jul 31, 2024
1f522e8
Init
hesto2 Jul 31, 2024
2d77757
Update docs
hesto2 Jul 31, 2024
76a7c36
Fix tests
hesto2 Jul 31, 2024
0cc1b87
Update to use apcivvi
hesto2 Aug 6, 2024
52b64d4
Update Readme and codeowners
hesto2 Aug 6, 2024
822aaec
Merge branch 'main' into civ6-1.0
hesto2 Aug 6, 2024
5cbbe9a
Minor changes
hesto2 Aug 6, 2024
0980a5d
Remove .value from options (except starting hint)
hesto2 Aug 6, 2024
3b7cc06
Minor updates
hesto2 Aug 6, 2024
185df3d
remove unnecessary property
hesto2 Aug 6, 2024
8781851
Cleanup Rules and Region
hesto2 Aug 6, 2024
b249a97
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Aug 6, 2024
ee16a83
Merge branch 'main' into civ6-1.0
hesto2 Aug 6, 2024
a670097
Fix output file generation
hesto2 Aug 21, 2024
2c490ef
Implement feedback
hesto2 Aug 21, 2024
c836377
Merge branch 'main' into civ6-1.0
hesto2 Aug 21, 2024
8b3bfe7
Merge branch 'main' into civ6-1.0
hesto2 Aug 21, 2024
a2a88cb
Merge branch 'main' into civ6-1.0
hesto2 Aug 23, 2024
598ae5d
Merge branch 'main' into civ6-1.0
hesto2 Aug 24, 2024
5ffb259
Merge branch 'main' into civ6-1.0
hesto2 Aug 24, 2024
2e0e509
Merge branch 'main' into civ6-1.0
hesto2 Aug 26, 2024
2aeb463
Remove 'AP' tag and fix issue with format strings and using same quotes
hesto2 Aug 28, 2024
a428e35
Merge branch 'main' into civ6-1.0
hesto2 Aug 30, 2024
06c7f9c
Merge branch 'main' into civ6-1.0
hesto2 Sep 1, 2024
0f8aee8
Update worlds/civ_6/__init__.py
hesto2 Sep 3, 2024
37e8413
Minor docs changes
hesto2 Sep 3, 2024
28d7179
minor updates
hesto2 Sep 4, 2024
821d8fc
Small rework of create items
hesto2 Sep 4, 2024
01d6400
Minor updates
hesto2 Sep 4, 2024
0478a94
Merge branch 'main' into civ6-1.0
hesto2 Sep 4, 2024
f0b767f
Merge branch 'main' into civ6-1.0
hesto2 Sep 4, 2024
ea19636
Remove unused variable
hesto2 Sep 4, 2024
dc1f56f
M hesto2erge branch 'civ6-1.0' of github.com:hesto2/Archipelago into …
hesto2 Sep 4, 2024
ffb095f
Merge branch 'main' into civ6-1.0
hesto2 Sep 5, 2024
24d6a10
Merge branch 'main' into civ6-1.0
hesto2 Sep 5, 2024
f9fd5df
Move client to Launcher Components with rest of similar clients
hesto2 Sep 6, 2024
c6fd296
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Sep 6, 2024
0d58739
Merge branch 'main' into civ6-1.0
hesto2 Sep 6, 2024
6a3340f
Revert "Move client to Launcher Components with rest of similar clients"
hesto2 Sep 8, 2024
4e71e59
modify component
hesto2 Sep 8, 2024
7ce8473
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Sep 8, 2024
29bcec7
Merge branch 'main' into civ6-1.0
hesto2 Sep 8, 2024
0f4810a
Merge branch 'main' into civ6-1.0
hesto2 Sep 12, 2024
05e51c0
Fix generation issues
hesto2 Sep 12, 2024
e1a3dfc
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Sep 12, 2024
8cf3806
Fix tests
hesto2 Sep 12, 2024
2f44726
Minor change
hesto2 Sep 13, 2024
38717b2
Add improvement and test case
hesto2 Sep 14, 2024
2fd31dd
Minor options changes
hesto2 Sep 14, 2024
5705e81
Merge branch 'main' into civ6-1.0
hesto2 Sep 14, 2024
4a244f9
Merge branch 'main' into civ6-1.0
hesto2 Sep 22, 2024
1d497dd
Merge branch 'main' into civ6-1.0
hesto2 Sep 24, 2024
12ab641
Merge branch 'main' into civ6-1.0
hesto2 Sep 25, 2024
32883a3
Merge branch 'main' into civ6-1.0
hesto2 Sep 27, 2024
7ae7940
Merge branch 'main' into civ6-1.0
hesto2 Sep 30, 2024
05a3c76
Merge branch 'main' into civ6-1.0
hesto2 Oct 8, 2024
61968e8
Merge branch 'main' into civ6-1.0
hesto2 Oct 12, 2024
4460edb
Merge branch 'main' into civ6-1.0
hesto2 Oct 15, 2024
37c869f
.
Exempt-Medic Oct 15, 2024
bc8448c
Preliminary Review
Exempt-Medic Oct 15, 2024
4383c4f
Merge pull request #1 from Exempt-Medic/civ6
hesto2 Oct 15, 2024
99c5432
Fix failing test due to slot data serialization
hesto2 Oct 16, 2024
a6eba68
Format json
hesto2 Oct 16, 2024
9e4aebf
Remove exclude missable boosts
hesto2 Oct 16, 2024
3a48699
Update options (update goody hut text, make research multiplier a range)
hesto2 Oct 16, 2024
c5b0e9b
Update docs punctuation and slot data init
hesto2 Oct 16, 2024
dd486a0
Move priority/excluded locations into options
hesto2 Oct 16, 2024
7478de4
Implement docs PR feedback
hesto2 Oct 16, 2024
d205ace
PR Feedback for options
hesto2 Oct 16, 2024
d38fcaa
PR feedback misc
hesto2 Oct 16, 2024
2e9705b
Update location classification and fix client type
hesto2 Oct 16, 2024
8050450
Merge branch 'main' into civ6-1.0
hesto2 Oct 16, 2024
62645f6
Fix typings
hesto2 Oct 16, 2024
29942b0
Update research cost multiplier
hesto2 Oct 16, 2024
4e9ac87
Remove unnecessary location priority code
hesto2 Oct 16, 2024
f371c92
Remove extrenous use of items()
hesto2 Oct 16, 2024
c340b3e
Merge branch 'main' into civ6-1.0
hesto2 Oct 16, 2024
4dcddb6
Merge branch 'main' into civ6-1.0
hesto2 Oct 16, 2024
e47cfd6
Merge branch 'main' into civ6-1.0
hesto2 Oct 17, 2024
29b0d8a
WIP PR Feedback
hesto2 Oct 18, 2024
97ed55e
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Oct 18, 2024
c8e8dd3
WIP PR Feedback
hesto2 Oct 18, 2024
56a55b5
Add victory event
hesto2 Oct 18, 2024
54939f0
Add option set for death link effect
hesto2 Oct 19, 2024
1d1688b
Merge branch 'main' into civ6-1.0
hesto2 Oct 19, 2024
96dd8a5
PR improvements
hesto2 Oct 19, 2024
ad451f7
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Oct 19, 2024
04c2af2
Merge branch 'main' into civ6-1.0
hesto2 Oct 19, 2024
3ffcbe3
Update post fill hint to support items with multiple classifications
hesto2 Oct 19, 2024
4398523
Merge branch 'civ6-1.0' of github.com:hesto2/Archipelago into civ6-1.0
hesto2 Oct 19, 2024
d88813d
remove unnecessary len
hesto2 Oct 19, 2024
80f94ee
Move location exclusion logic
hesto2 Oct 19, 2024
40750cb
Update test to use set instead of accidental dict
hesto2 Oct 19, 2024
555d852
Update docs around progressive eras and boost locations
hesto2 Oct 20, 2024
0f10369
Update docs for options to be more readable
hesto2 Oct 20, 2024
978255a
Merge branch 'main' into civ6-1.0
hesto2 Oct 22, 2024
e4f9901
Fix issue with filler items and prehints
hesto2 Oct 22, 2024
8d18207
Update filler_data to be static
hesto2 Oct 22, 2024
e08b884
Update links in docs
hesto2 Oct 22, 2024
bb22cf8
Merge branch 'main' into civ6-1.0
hesto2 Oct 22, 2024
6f3a801
Merge branch 'main' into civ6-1.0
hesto2 Oct 23, 2024
957931d
Minor updates and PR feedback
hesto2 Oct 23, 2024
9e7079d
Merge branch 'main' into civ6-1.0
hesto2 Oct 25, 2024
7a049c6
Merge branch 'main' into civ6-1.0
hesto2 Oct 27, 2024
b1ed565
Merge branch 'main' into civ6-1.0
hesto2 Nov 1, 2024
1c2eafc
Merge branch 'main' into civ6-1.0
hesto2 Nov 12, 2024
961c210
Merge branch 'main' into civ6-1.0
hesto2 Nov 14, 2024
88c6c9b
Merge branch 'main' into civ6-1.0
hesto2 Nov 20, 2024
7579d65
Merge branch 'main' into civ6-1.0
hesto2 Nov 24, 2024
3be62d6
Merge branch 'main' into civ6-1.0
hesto2 Nov 28, 2024
dba1b28
Update boosts data
hesto2 Dec 1, 2024
6027b77
Update era required items
hesto2 Dec 1, 2024
48a2a2a
Update existing techs
hesto2 Dec 1, 2024
f50602a
Update existing techs
hesto2 Dec 1, 2024
e65ca08
move boost data class
hesto2 Dec 1, 2024
7ce8b23
Update reward data
hesto2 Dec 1, 2024
1024bc8
Update prereq data
hesto2 Dec 1, 2024
9217969
Update new items and progressive districts
hesto2 Dec 1, 2024
6ff0b6d
Remove unused code
hesto2 Dec 1, 2024
ed55e93
Merge branch 'main' into civ6-1.0
hesto2 Dec 1, 2024
1982950
Merge branch 'main' into civ6-1.0
hesto2 Dec 3, 2024
ca00319
Merge branch 'main' into civ6-1.0
hesto2 Dec 4, 2024
8da6014
Merge branch 'main' into civ6-1.0
hesto2 Dec 5, 2024
e8062ab
Merge branch 'main' into civ6-1.0
hesto2 Dec 7, 2024
633cd81
Merge branch 'main' into civ6-1.0
hesto2 Dec 8, 2024
21cc558
Merge branch 'main' into civ6-1.0
hesto2 Dec 9, 2024
e055fca
Merge branch 'main' into civ6-1.0
hesto2 Dec 11, 2024
b92796c
Merge branch 'main' into civ6-1.0
hesto2 Dec 15, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*_Spoiler.txt
*.bmbp
*.apbp
*.apcivvi
*.apl2ac
*.apm3
*.apmc
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Currently, the following games are supported:
* Aquaria
* Yu-Gi-Oh! Ultimate Masters: World Championship Tournament 2006
* A Hat in Time
* Civilization VI

For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled
Expand Down
3 changes: 3 additions & 0 deletions docs/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
# ChecksFinder
/worlds/checksfinder/ @SunCatMC

# Civilization VI
/worlds/civ6/ @hesto2

# Clique
/worlds/clique/ @ThePhar

Expand Down
338 changes: 338 additions & 0 deletions worlds/civ_6/Civ6Client.py
hesto2 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
import asyncio
import logging
import os
import traceback
from typing import Dict, List
import zipfile

from CommonClient import ClientCommandProcessor, CommonContext, get_base_parser, logger, server_loop, gui_enabled
from .Data import get_progressive_districts_data
from .DeathLink import handle_check_deathlink
from NetUtils import ClientStatus
import Utils
from .CivVIInterface import CivVIInterface, ConnectionState
from .Enum import CivVICheckType
from .Items import CivVIItemData, generate_item_table, get_item_by_civ_name
from .Locations import generate_era_location_table
from .TunerClient import TunerErrorException, TunerTimeoutException


class CivVICommandProcessor(ClientCommandProcessor):
def __init__(self, ctx: CommonContext):
super().__init__(ctx)

def _cmd_deathlink(self):
"""Toggle deathlink from client. Overrides default setting."""
if isinstance(self.ctx, CivVIContext):
self.ctx.death_link_enabled = not self.ctx.death_link_enabled
self.ctx.death_link_just_changed = True
Utils.async_start(self.ctx.update_death_link(
self.ctx.death_link_enabled), name="Update Deathlink")
self.ctx.logger.info(
f"Deathlink is now {'enabled' if self.ctx.death_link_enabled else 'disabled'}")
hesto2 marked this conversation as resolved.
Show resolved Hide resolved

def _cmd_resync(self):
"""Resends all items to client, and has client resend all locations to server. This can take up to a minute if the player has received a lot of items"""
if isinstance(self.ctx, CivVIContext):
logger.info("Resyncing...")
asyncio.create_task(self.ctx.resync())

def _cmd_toggle_progressive_eras(self):
"""If you get stuck for some reason and unable to continue your game, you can run this command to disable the defeat that comes from pushing past the max unlocked era """
if isinstance(self.ctx, CivVIContext):
print("Toggling progressive eras, stand by...")
self.ctx.is_pending_toggle_progressive_eras = True


class CivVIContext(CommonContext):
is_pending_death_link_reset = False
is_pending_toggle_progressive_eras = False
command_processor = CivVICommandProcessor
game = "Civilization VI"
items_handling = 0b111
tuner_sync_task = None
game_interface: CivVIInterface
location_name_to_civ_location = {}
location_name_to_id = {}
hesto2 marked this conversation as resolved.
Show resolved Hide resolved
item_id_to_civ_item: Dict[int, CivVIItemData] = {}
item_table: Dict[str, CivVIItemData] = {}
processing_multiple_items = False
received_death_link = False
death_link_message = ""
death_link_enabled = False

death_link_just_changed = False
# Used to prevent the deathlink from triggering when someone re enables it

logger = logger
progressive_items_by_type = get_progressive_districts_data()
item_name_to_id = {
item.name: item.code for item in generate_item_table().values()}
connection_state = ConnectionState.DISCONNECTED

def __init__(self, server_address, password, apcivvi_file=None):
super().__init__(server_address, password)
self.game_interface = CivVIInterface(logger)
location_by_era = generate_era_location_table()
self.item_table = generate_item_table()
self.apcivvi_file = apcivvi_file

# Get tables formatted in a way that is easier to use here
for era, locations in location_by_era.items():
for item_name, location in locations.items():
self.location_name_to_id[location.name] = location.code
self.location_name_to_civ_location[location.name] = location

for item_name, item in self.item_table.items():
self.item_id_to_civ_item[item.code] = item

async def resync(self):
if self.processing_multiple_items:
logger.info(
"Waiting for items to finish processing, try again later")
return
await self.game_interface.resync()
await handle_receive_items(self, -1)
logger.info("Resynced")

def on_deathlink(self, data: Utils.Dict[str, Utils.Any]) -> None:
super().on_deathlink(data)
text = data.get("cause", "")
if text:
message = text
else:
message = f"Received from {data['source']}"
self.death_link_message = message
self.received_death_link = True

async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
await super(CivVIContext, self).server_auth(password_requested)
await self.get_username()
await self.send_connect()
hesto2 marked this conversation as resolved.
Show resolved Hide resolved

def run_gui(self):
from kvui import GameManager

class CivVIManager(GameManager):
logging_pairs = [
("Client", "Archipelago")
]
base_title = "Archipelago Civlization VI Client"
hesto2 marked this conversation as resolved.
Show resolved Hide resolved

self.ui = CivVIManager(self)
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")

def on_package(self, cmd: str, args: dict):
if cmd == "Connected":
self.slot_data = args["slot_data"]
if "death_link" in args["slot_data"]:
self.death_link_enabled = bool(args["slot_data"]["death_link"])
Utils.async_start(self.update_death_link(
bool(args["slot_data"]["death_link"])))


def update_connection_status(ctx: CivVIContext, status):
if ctx.connection_state == status:
return
elif status == ConnectionState.IN_GAME:
ctx.logger.info("Connected to Civ VI")
elif status == ConnectionState.IN_MENU:
ctx.logger.info("Connected to Civ VI, waiting for game to start")
elif status == ConnectionState.DISCONNECTED:
ctx.logger.info("Disconnected from Civ VI, attempting to reconnect...")

ctx.connection_state = status


async def tuner_sync_task(ctx: CivVIContext):
logger.info("Starting CivVI connector")
while not ctx.exit_event.is_set():
if not ctx.slot:
await asyncio.sleep(3)
continue
else:
try:
if ctx.processing_multiple_items == True:
hesto2 marked this conversation as resolved.
Show resolved Hide resolved
await asyncio.sleep(3)
else:
state = await ctx.game_interface.is_in_game()
update_connection_status(ctx, state)
if state == ConnectionState.IN_GAME:
await _handle_game_ready(ctx)
else:
await asyncio.sleep(3)
except TunerTimeoutException:
logger.error(
"Timeout occurred while receiving data from Civ VI, this usually isn't a problem unless you see it repeatedly")
await asyncio.sleep(3)
except Exception as e:
if isinstance(e, TunerErrorException):
logger.debug(str(e))
else:
logger.debug(traceback.format_exc())

await asyncio.sleep(3)
continue


async def handle_toggle_progressive_eras(ctx: CivVIContext):
if ctx.is_pending_toggle_progressive_eras:
ctx.is_pending_toggle_progressive_eras = False
current = await ctx.game_interface.get_max_allowed_era()
if current > -1:
await ctx.game_interface.set_max_allowed_era(-1)
logger.info("Disabled progressive eras")
else:
count = 0
for _, network_item in enumerate(ctx.items_received):
item: CivVIItemData = ctx.item_id_to_civ_item[network_item.item]
if item.item_type == CivVICheckType.ERA:
count += 1
await ctx.game_interface.set_max_allowed_era(count)
logger.info(f"Enabled progressive eras, set to {count}")


async def handle_checked_location(ctx: CivVIContext):
checked_locations = await ctx.game_interface.get_checked_locations()
checked_location_ids = [location.code for location_name, location in ctx.location_name_to_civ_location.items(
) if location_name in checked_locations]

await ctx.send_msgs([{"cmd": "LocationChecks", "locations": checked_location_ids}])


async def handle_receive_items(ctx: CivVIContext, last_received_index_override: int = None):
hesto2 marked this conversation as resolved.
Show resolved Hide resolved
try:
last_received_index = last_received_index_override or await ctx.game_interface.get_last_received_index()
if len(ctx.items_received) - last_received_index > 1:
ctx.processing_multiple_items = True

progressive_districts: List[CivVIItemData] = []
progressive_eras: List[CivVIItemData] = []
for index, network_item in enumerate(ctx.items_received):

# Track these separately so if we replace "PROGRESSIVE_DISTRICT" with a specific tech, we can still check if need to add it to the list of districts
item: CivVIItemData = ctx.item_id_to_civ_item[network_item.item]
item_to_send: CivVIItemData = ctx.item_id_to_civ_item[network_item.item]
if index > last_received_index:
if item.item_type == CivVICheckType.PROGRESSIVE_DISTRICT:
# if the item is progressive, then check how far in that progression type we are and send the appropriate item
count = sum(
1 for count_item in progressive_districts if count_item.civ_name == item.civ_name)

if count >= len(ctx.progressive_items_by_type[item.civ_name]):
logger.error(
f"Received more progressive items than expected for {item.civ_name}")
continue

item_civ_name = ctx.progressive_items_by_type[item.civ_name][count]
actual_item_name = get_item_by_civ_name(item_civ_name, ctx.item_table).name
item_to_send = ctx.item_table[actual_item_name]

sender = ctx.player_names[network_item.player]
if item.item_type == CivVICheckType.ERA:
count = len(progressive_eras) + 1
await ctx.game_interface.give_item_to_player(item_to_send, sender, count)
elif item.item_type == CivVICheckType.GOODY:
item_to_send.civ_vi_id = item_to_send.civ_name
hesto2 marked this conversation as resolved.
Show resolved Hide resolved
await ctx.game_interface.give_item_to_player(item_to_send, sender)
else:
await ctx.game_interface.give_item_to_player(item_to_send, sender)
await asyncio.sleep(0.02)

if item.item_type == CivVICheckType.PROGRESSIVE_DISTRICT:
progressive_districts.append(item)
elif item.item_type == CivVICheckType.ERA:
progressive_eras.append(item)

ctx.processing_multiple_items = False
finally:
# If something errors out, then unblock item processing
ctx.processing_multiple_items = False


async def handle_check_goal_complete(ctx: CivVIContext):
result = await ctx.game_interface.check_victory()
if result:
logger.info("Sending Victory to server!")
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])


async def _handle_game_ready(ctx: CivVIContext):
if ctx.server:
if not ctx.slot:
await asyncio.sleep(3)
return

await handle_receive_items(ctx)
await handle_checked_location(ctx)
await handle_check_goal_complete(ctx)

if ctx.death_link_enabled:
await handle_check_deathlink(ctx)

# process pending commands
await handle_toggle_progressive_eras(ctx)
await asyncio.sleep(3)
else:
logger.info("Waiting for player to connect to server")
await asyncio.sleep(3)


def main(connect=None, password=None, name=None):
Utils.init_logging("Civilization VI Client")

async def _main(connect, password, name):
parser = get_base_parser()
parser.add_argument('apcivvi_file', default="", type=str, nargs='?', help="Path to apcivvi file")
args = parser.parse_args()
ctx = CivVIContext(connect, password, args.apcivvi_file)

if args.apcivvi_file:
parent_dir = os.path.dirname(args.apcivvi_file)
target_name = os.path.basename(args.apcivvi_file).replace(".apcivvi", "-MOD-FILES")
target_path = os.path.join(parent_dir, target_name)
if not os.path.exists(target_path):
os.makedirs(target_path, exist_ok=True)
logger.info("Extracting mod files to %s", target_path)
with zipfile.ZipFile(args.apcivvi_file, 'r') as zip_ref:
for member in zip_ref.namelist():
zip_ref.extract(member, target_path)

ctx.auth = name
ctx.server_task = asyncio.create_task(
server_loop(ctx), name="ServerLoop")
if gui_enabled:
ctx.run_gui()
await asyncio.sleep(1)

ctx.tuner_sync_task = asyncio.create_task(
tuner_sync_task(ctx), name="TunerSync")

await ctx.exit_event.wait()
ctx.server_address = None

await ctx.shutdown()

if ctx.tuner_sync_task:
await asyncio.sleep(3)
await ctx.tuner_sync_task

import colorama

colorama.init()
asyncio.run(_main(connect, password, name))
colorama.deinit()


def debug_main():
parser = get_base_parser()
parser.add_argument('apcivvi_file', default="", type=str, nargs='?', help="Path to apcivvi file")
parser.add_argument('--name', default=None,
help="Slot Name to connect as.")
parser.add_argument('--debug', default=None,
help="debug mode, additional logging")
args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
main(args.connect, args.password, args.name)
Loading