MultiServer: allow multiple, ordered operations
MultiServer: rename "data" on Get, Retrieved and SetNotify to "keys" MultiServer: add some more operators SniClient: some pep8 cleanup
This commit is contained in:
parent
2c3e3f0d43
commit
7ca6f24e6c
|
@ -169,8 +169,9 @@ async def game_watcher(ctx: FactorioContext):
|
||||||
# attempt to refill
|
# attempt to refill
|
||||||
ctx.last_deplete = time.time()
|
ctx.last_deplete = time.time()
|
||||||
asyncio.create_task(ctx.send_msgs([{
|
asyncio.create_task(ctx.send_msgs([{
|
||||||
"cmd": "Set", "key": "EnergyLink", "operation": "deplete",
|
"cmd": "Set", "key": "EnergyLink", "operations":
|
||||||
"value": -ctx.energy_link_increment * in_world_bridges,
|
[{"operation": "add", "value": -ctx.energy_link_increment * in_world_bridges},
|
||||||
|
{"operation": "max", "value": 0}],
|
||||||
"last_deplete": ctx.last_deplete
|
"last_deplete": ctx.last_deplete
|
||||||
}]))
|
}]))
|
||||||
# Above Capacity - (len(Bridges) * ENERGY_INCREMENT)
|
# Above Capacity - (len(Bridges) * ENERGY_INCREMENT)
|
||||||
|
@ -178,8 +179,8 @@ async def game_watcher(ctx: FactorioContext):
|
||||||
ctx.energy_link_increment*in_world_bridges:
|
ctx.energy_link_increment*in_world_bridges:
|
||||||
value = ctx.energy_link_increment * in_world_bridges
|
value = ctx.energy_link_increment * in_world_bridges
|
||||||
asyncio.create_task(ctx.send_msgs([{
|
asyncio.create_task(ctx.send_msgs([{
|
||||||
"cmd": "Set", "key": "EnergyLink", "operation": "add",
|
"cmd": "Set", "key": "EnergyLink", "operations":
|
||||||
"value": value
|
[{"operation": "add", "value": value}]
|
||||||
}]))
|
}]))
|
||||||
ctx.rcon_client.send_command(
|
ctx.rcon_client.send_command(
|
||||||
f"/ap-energylink -{value}")
|
f"/ap-energylink -{value}")
|
||||||
|
|
|
@ -41,12 +41,20 @@ colorama.init()
|
||||||
|
|
||||||
# functions callable on storable data on the server by clients
|
# functions callable on storable data on the server by clients
|
||||||
modify_functions = {
|
modify_functions = {
|
||||||
"add": operator.add,
|
"add": operator.add, # add together two objects, using python's "+" operator (works on strings and lists as append)
|
||||||
"mul": operator.mul,
|
"mul": operator.mul,
|
||||||
|
"mod": operator.mod,
|
||||||
"max": max,
|
"max": max,
|
||||||
"min": min,
|
"min": min,
|
||||||
"replace": lambda old, new: new,
|
"replace": lambda old, new: new,
|
||||||
"deplete": lambda value, change: max(0, value + change)
|
"default": lambda old, new: old,
|
||||||
|
"pow": operator.pow,
|
||||||
|
# bitwise:
|
||||||
|
"xor": operator.xor,
|
||||||
|
"or": operator.or_,
|
||||||
|
"and": operator.and_,
|
||||||
|
"left_shift": operator.lshift,
|
||||||
|
"right_shift": operator.rshift,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1544,26 +1552,27 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
|
||||||
await ctx.send_encoded_msgs(bounceclient, msg)
|
await ctx.send_encoded_msgs(bounceclient, msg)
|
||||||
|
|
||||||
elif cmd == "Get":
|
elif cmd == "Get":
|
||||||
if "data" not in args or type(args["data"]) != list:
|
if "keys" not in args or type(args["keys"]) != list:
|
||||||
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
||||||
"text": 'Retrieve', "original_cmd": cmd}])
|
"text": 'Retrieve', "original_cmd": cmd}])
|
||||||
return
|
return
|
||||||
args["cmd"] = "Retrieved"
|
args["cmd"] = "Retrieved"
|
||||||
keys = args["data"]
|
keys = args["keys"]
|
||||||
args["data"] = {key: ctx.stored_data.get(key, None) for key in keys}
|
args["keys"] = {key: ctx.stored_data.get(key, None) for key in keys}
|
||||||
await ctx.send_msgs(client, [args])
|
await ctx.send_msgs(client, [args])
|
||||||
|
|
||||||
elif cmd == "Set":
|
elif cmd == "Set":
|
||||||
if "key" not in args or "value" not in args:
|
if "key" not in args or "value" not in args or \
|
||||||
|
"operations" not in args or not type(args["operations"]) == list:
|
||||||
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
||||||
"text": 'Set', "original_cmd": cmd}])
|
"text": 'Set', "original_cmd": cmd}])
|
||||||
return
|
return
|
||||||
args["cmd"] = "SetReply"
|
args["cmd"] = "SetReply"
|
||||||
value = ctx.stored_data.get(args["key"], args.get("default", 0))
|
value = ctx.stored_data.get(args["key"], args.get("default", 0))
|
||||||
args["original_value"] = value
|
args["original_value"] = value
|
||||||
operation = args.get("operation", "replace")
|
for operation in args["operations"]:
|
||||||
func = modify_functions[operation]
|
func = modify_functions[operation["operation"]]
|
||||||
value = func(value, args.get("value"))
|
value = func(value, operation["value"])
|
||||||
ctx.stored_data[args["key"]] = args["value"] = value
|
ctx.stored_data[args["key"]] = args["value"] = value
|
||||||
targets = set(ctx.stored_data_notification_clients[args["key"]])
|
targets = set(ctx.stored_data_notification_clients[args["key"]])
|
||||||
if args.get("want_reply", True):
|
if args.get("want_reply", True):
|
||||||
|
@ -1572,11 +1581,11 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
|
||||||
ctx.broadcast(targets, [args])
|
ctx.broadcast(targets, [args])
|
||||||
|
|
||||||
elif cmd == "SetNotify":
|
elif cmd == "SetNotify":
|
||||||
if "data" not in args or type(args["data"]) != list:
|
if "keys" not in args or type(args["keys"]) != list:
|
||||||
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments",
|
||||||
"text": 'SetNotify', "original_cmd": cmd}])
|
"text": 'SetNotify', "original_cmd": cmd}])
|
||||||
return
|
return
|
||||||
for key in args["data"]:
|
for key in args["keys"]:
|
||||||
ctx.stored_data_notification_clients[key].add(client)
|
ctx.stored_data_notification_clients[key].add(client)
|
||||||
|
|
||||||
|
|
||||||
|
|
92
SNIClient.py
92
SNIClient.py
|
@ -11,9 +11,8 @@ import shutil
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from json import loads, dumps
|
from json import loads, dumps
|
||||||
from tkinter import font
|
|
||||||
|
|
||||||
from Utils import get_item_name_from_id, init_logging
|
from Utils import init_logging
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
init_logging("SNIClient", exception_logger="Client")
|
init_logging("SNIClient", exception_logger="Client")
|
||||||
|
@ -22,14 +21,12 @@ import colorama
|
||||||
|
|
||||||
from NetUtils import *
|
from NetUtils import *
|
||||||
from worlds.alttp import Regions, Shops
|
from worlds.alttp import Regions, Shops
|
||||||
from worlds.alttp import Items
|
|
||||||
from worlds.alttp.Rom import ROM_PLAYER_LIMIT
|
from worlds.alttp.Rom import ROM_PLAYER_LIMIT
|
||||||
from worlds.sm.Rom import ROM_PLAYER_LIMIT as SM_ROM_PLAYER_LIMIT
|
from worlds.sm.Rom import ROM_PLAYER_LIMIT as SM_ROM_PLAYER_LIMIT
|
||||||
import Utils
|
import Utils
|
||||||
from CommonClient import CommonContext, server_loop, console_loop, ClientCommandProcessor, gui_enabled, get_base_parser
|
from CommonClient import CommonContext, server_loop, console_loop, ClientCommandProcessor, gui_enabled, get_base_parser
|
||||||
from Patch import GAME_ALTTP, GAME_SM
|
from Patch import GAME_ALTTP, GAME_SM
|
||||||
|
|
||||||
|
|
||||||
snes_logger = logging.getLogger("SNES")
|
snes_logger = logging.getLogger("SNES")
|
||||||
|
|
||||||
from MultiServer import mark_raw
|
from MultiServer import mark_raw
|
||||||
|
@ -41,7 +38,7 @@ class DeathState(enum.IntEnum):
|
||||||
dead = 3
|
dead = 3
|
||||||
|
|
||||||
|
|
||||||
class LttPCommandProcessor(ClientCommandProcessor):
|
class SNIClientCommandProcessor(ClientCommandProcessor):
|
||||||
ctx: Context
|
ctx: Context
|
||||||
|
|
||||||
def _cmd_slow_mode(self, toggle: str = ""):
|
def _cmd_slow_mode(self, toggle: str = ""):
|
||||||
|
@ -72,7 +69,6 @@ class LttPCommandProcessor(ClientCommandProcessor):
|
||||||
snes_address = options[0]
|
snes_address = options[0]
|
||||||
snes_device_number = int(options[1])
|
snes_device_number = int(options[1])
|
||||||
|
|
||||||
|
|
||||||
self.ctx.snes_reconnect_address = None
|
self.ctx.snes_reconnect_address = None
|
||||||
asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number), name="SNES Connect")
|
asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number), name="SNES Connect")
|
||||||
return True
|
return True
|
||||||
|
@ -92,15 +88,23 @@ class LttPCommandProcessor(ClientCommandProcessor):
|
||||||
# if self.ctx.snes_state != SNESState.SNES_ATTACHED:
|
# if self.ctx.snes_state != SNESState.SNES_ATTACHED:
|
||||||
# self.output("No attached SNES Device.")
|
# self.output("No attached SNES Device.")
|
||||||
# return False
|
# return False
|
||||||
#
|
|
||||||
# snes_buffered_write(self.ctx, int(address, 16), bytes([int(data)]))
|
# snes_buffered_write(self.ctx, int(address, 16), bytes([int(data)]))
|
||||||
# asyncio.create_task(snes_flush_writes(self.ctx))
|
# asyncio.create_task(snes_flush_writes(self.ctx))
|
||||||
# self.output("Data Sent")
|
# self.output("Data Sent")
|
||||||
# return True
|
# return True
|
||||||
|
|
||||||
|
# def _cmd_snes_read(self, address, size=1):
|
||||||
|
# """Read the SNES' memory address (base16)."""
|
||||||
|
# if self.ctx.snes_state != SNESState.SNES_ATTACHED:
|
||||||
|
# self.output("No attached SNES Device.")
|
||||||
|
# return False
|
||||||
|
# data = await snes_read(self.ctx, int(address, 16), size)
|
||||||
|
# self.output(f"Data Read: {data}")
|
||||||
|
# return True
|
||||||
|
|
||||||
|
|
||||||
class Context(CommonContext):
|
class Context(CommonContext):
|
||||||
command_processor = LttPCommandProcessor
|
command_processor = SNIClientCommandProcessor
|
||||||
game = "A Link to the Past"
|
game = "A Link to the Past"
|
||||||
items_handling = None # set in game_watcher
|
items_handling = None # set in game_watcher
|
||||||
|
|
||||||
|
@ -183,7 +187,8 @@ async def deathlink_kill_player(ctx: Context):
|
||||||
continue
|
continue
|
||||||
if not invincible[0] and last_health[0] == health[0]:
|
if not invincible[0] and last_health[0] == health[0]:
|
||||||
snes_buffered_write(ctx, WRAM_START + 0xF36D, bytes([0])) # set current health to 0
|
snes_buffered_write(ctx, WRAM_START + 0xF36D, bytes([0])) # set current health to 0
|
||||||
snes_buffered_write(ctx, WRAM_START + 0x0373, bytes([8])) # deal 1 full heart of damage at next opportunity
|
snes_buffered_write(ctx, WRAM_START + 0x0373,
|
||||||
|
bytes([8])) # deal 1 full heart of damage at next opportunity
|
||||||
elif ctx.game == GAME_SM:
|
elif ctx.game == GAME_SM:
|
||||||
snes_buffered_write(ctx, WRAM_START + 0x09C2, bytes([0, 0])) # set current health to 0
|
snes_buffered_write(ctx, WRAM_START + 0x09C2, bytes([0, 0])) # set current health to 0
|
||||||
if not ctx.death_link_allow_survive:
|
if not ctx.death_link_allow_survive:
|
||||||
|
@ -200,7 +205,8 @@ async def deathlink_kill_player(ctx: Context):
|
||||||
health = await snes_read(ctx, WRAM_START + 0x09C2, 2)
|
health = await snes_read(ctx, WRAM_START + 0x09C2, 2)
|
||||||
if health is not None:
|
if health is not None:
|
||||||
health = health[0] | (health[1] << 8)
|
health = health[0] | (health[1] << 8)
|
||||||
if not gamemode or gamemode[0] in SM_DEATH_MODES or (ctx.death_link_allow_survive and health is not None and health > 0):
|
if not gamemode or gamemode[0] in SM_DEATH_MODES or (
|
||||||
|
ctx.death_link_allow_survive and health is not None and health > 0):
|
||||||
ctx.death_state = DeathState.dead
|
ctx.death_state = DeathState.dead
|
||||||
ctx.last_death_link = time.time()
|
ctx.last_death_link = time.time()
|
||||||
|
|
||||||
|
@ -914,7 +920,7 @@ async def game_watcher(ctx: Context):
|
||||||
|
|
||||||
ctx.rom = rom
|
ctx.rom = rom
|
||||||
death_link = await snes_read(ctx, DEATH_LINK_ACTIVE_ADDR if ctx.game == GAME_ALTTP else
|
death_link = await snes_read(ctx, DEATH_LINK_ACTIVE_ADDR if ctx.game == GAME_ALTTP else
|
||||||
SM_DEATH_LINK_ACTIVE_ADDR, 1)
|
SM_DEATH_LINK_ACTIVE_ADDR, 1)
|
||||||
if death_link:
|
if death_link:
|
||||||
ctx.death_link_allow_survive = bool(death_link[0] & 0b10)
|
ctx.death_link_allow_survive = bool(death_link[0] & 0b10)
|
||||||
await ctx.update_death_link(bool(death_link[0] & 0b1))
|
await ctx.update_death_link(bool(death_link[0] & 0b1))
|
||||||
|
@ -976,7 +982,8 @@ async def game_watcher(ctx: Context):
|
||||||
item = ctx.items_received[recv_index]
|
item = ctx.items_received[recv_index]
|
||||||
recv_index += 1
|
recv_index += 1
|
||||||
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
||||||
color(ctx.item_name_getter(item.item), 'red', 'bold'), color(ctx.player_names[item.player], 'yellow'),
|
color(ctx.item_name_getter(item.item), 'red', 'bold'),
|
||||||
|
color(ctx.player_names[item.player], 'yellow'),
|
||||||
ctx.location_name_getter(item.location), recv_index, len(ctx.items_received)))
|
ctx.location_name_getter(item.location), recv_index, len(ctx.items_received)))
|
||||||
|
|
||||||
snes_buffered_write(ctx, RECV_PROGRESS_ADDR,
|
snes_buffered_write(ctx, RECV_PROGRESS_ADDR,
|
||||||
|
@ -998,7 +1005,7 @@ async def game_watcher(ctx: Context):
|
||||||
if scout_location > 0 and scout_location not in ctx.locations_scouted:
|
if scout_location > 0 and scout_location not in ctx.locations_scouted:
|
||||||
ctx.locations_scouted.add(scout_location)
|
ctx.locations_scouted.add(scout_location)
|
||||||
await ctx.send_msgs([{"cmd": "LocationScouts", "locations": [scout_location]}])
|
await ctx.send_msgs([{"cmd": "LocationScouts", "locations": [scout_location]}])
|
||||||
await track_locations(ctx, roomid, roomdata)
|
await track_locations(ctx, roomid, roomdata)
|
||||||
elif ctx.game == GAME_SM:
|
elif ctx.game == GAME_SM:
|
||||||
gamemode = await snes_read(ctx, WRAM_START + 0x0998, 1)
|
gamemode = await snes_read(ctx, WRAM_START + 0x0998, 1)
|
||||||
if "DeathLink" in ctx.tags and gamemode and ctx.last_death_link + 1 < time.time():
|
if "DeathLink" in ctx.tags and gamemode and ctx.last_death_link + 1 < time.time():
|
||||||
|
@ -1025,14 +1032,16 @@ async def game_watcher(ctx: Context):
|
||||||
itemIndex = (message[4] | (message[5] << 8)) >> 3
|
itemIndex = (message[4] | (message[5] << 8)) >> 3
|
||||||
|
|
||||||
recv_index += 1
|
recv_index += 1
|
||||||
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + 0x680, bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF]))
|
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + 0x680,
|
||||||
|
bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF]))
|
||||||
|
|
||||||
from worlds.sm.Locations import locations_start_id
|
from worlds.sm.Locations import locations_start_id
|
||||||
location_id = locations_start_id + itemIndex
|
location_id = locations_start_id + itemIndex
|
||||||
|
|
||||||
ctx.locations_checked.add(location_id)
|
ctx.locations_checked.add(location_id)
|
||||||
location = ctx.location_name_getter(location_id)
|
location = ctx.location_name_getter(location_id)
|
||||||
snes_logger.info(f'New Check: {location} ({len(ctx.locations_checked)}/{len(ctx.missing_locations) + len(ctx.checked_locations)})')
|
snes_logger.info(
|
||||||
|
f'New Check: {location} ({len(ctx.locations_checked)}/{len(ctx.missing_locations) + len(ctx.checked_locations)})')
|
||||||
await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": [location_id]}])
|
await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": [location_id]}])
|
||||||
|
|
||||||
data = await snes_read(ctx, SM_RECV_PROGRESS_ADDR + 0x600, 4)
|
data = await snes_read(ctx, SM_RECV_PROGRESS_ADDR + 0x600, 4)
|
||||||
|
@ -1048,11 +1057,14 @@ async def game_watcher(ctx: Context):
|
||||||
itemId = item.item - items_start_id
|
itemId = item.item - items_start_id
|
||||||
|
|
||||||
playerID = item.player if item.player <= SM_ROM_PLAYER_LIMIT else 0
|
playerID = item.player if item.player <= SM_ROM_PLAYER_LIMIT else 0
|
||||||
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + itemOutPtr * 4, bytes([playerID & 0xFF, (playerID >> 8) & 0xFF, itemId & 0xFF, (itemId >> 8) & 0xFF]))
|
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + itemOutPtr * 4, bytes(
|
||||||
|
[playerID & 0xFF, (playerID >> 8) & 0xFF, itemId & 0xFF, (itemId >> 8) & 0xFF]))
|
||||||
itemOutPtr += 1
|
itemOutPtr += 1
|
||||||
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + 0x602, bytes([itemOutPtr & 0xFF, (itemOutPtr >> 8) & 0xFF]))
|
snes_buffered_write(ctx, SM_RECV_PROGRESS_ADDR + 0x602,
|
||||||
|
bytes([itemOutPtr & 0xFF, (itemOutPtr >> 8) & 0xFF]))
|
||||||
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
||||||
color(ctx.item_name_getter(item.item), 'red', 'bold'), color(ctx.player_names[item.player], 'yellow'),
|
color(ctx.item_name_getter(item.item), 'red', 'bold'),
|
||||||
|
color(ctx.player_names[item.player], 'yellow'),
|
||||||
ctx.location_name_getter(item.location), itemOutPtr, len(ctx.items_received)))
|
ctx.location_name_getter(item.location), itemOutPtr, len(ctx.items_received)))
|
||||||
await snes_flush_writes(ctx)
|
await snes_flush_writes(ctx)
|
||||||
|
|
||||||
|
@ -1130,6 +1142,7 @@ async def main():
|
||||||
if input_task:
|
if input_task:
|
||||||
input_task.cancel()
|
input_task.cancel()
|
||||||
|
|
||||||
|
|
||||||
def get_alttp_settings(romfile: str):
|
def get_alttp_settings(romfile: str):
|
||||||
lastSettings = Utils.get_adjuster_settings(GAME_ALTTP)
|
lastSettings = Utils.get_adjuster_settings(GAME_ALTTP)
|
||||||
adjusted = False
|
adjusted = False
|
||||||
|
@ -1139,8 +1152,8 @@ def get_alttp_settings(romfile: str):
|
||||||
if not hasattr(lastSettings, 'auto_apply') or 'ask' in lastSettings.auto_apply:
|
if not hasattr(lastSettings, 'auto_apply') or 'ask' in lastSettings.auto_apply:
|
||||||
|
|
||||||
whitelist = {"music", "menuspeed", "heartbeep", "heartcolor", "ow_palettes", "quickswap",
|
whitelist = {"music", "menuspeed", "heartbeep", "heartcolor", "ow_palettes", "quickswap",
|
||||||
"uw_palettes", "sprite", "sword_palettes", "shield_palettes", "hud_palettes",
|
"uw_palettes", "sprite", "sword_palettes", "shield_palettes", "hud_palettes",
|
||||||
"reduceflashing", "deathlink"}
|
"reduceflashing", "deathlink"}
|
||||||
printed_options = {name: value for name, value in vars(lastSettings).items() if name in whitelist}
|
printed_options = {name: value for name, value in vars(lastSettings).items() if name in whitelist}
|
||||||
if hasattr(lastSettings, "sprite_pool"):
|
if hasattr(lastSettings, "sprite_pool"):
|
||||||
sprite_pool = {}
|
sprite_pool = {}
|
||||||
|
@ -1154,40 +1167,41 @@ def get_alttp_settings(romfile: str):
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
if gui_enabled:
|
if gui_enabled:
|
||||||
|
|
||||||
from tkinter import Tk, PhotoImage, Label, LabelFrame, Frame, Button
|
from tkinter import Tk, PhotoImage, Label, LabelFrame, Frame, Button
|
||||||
applyPromptWindow = Tk()
|
applyPromptWindow = Tk()
|
||||||
applyPromptWindow.resizable(False, False)
|
applyPromptWindow.resizable(False, False)
|
||||||
applyPromptWindow.protocol('WM_DELETE_WINDOW',lambda: onButtonClick())
|
applyPromptWindow.protocol('WM_DELETE_WINDOW', lambda: onButtonClick())
|
||||||
logo = PhotoImage(file=Utils.local_path('data', 'icon.png'))
|
logo = PhotoImage(file=Utils.local_path('data', 'icon.png'))
|
||||||
applyPromptWindow.tk.call('wm', 'iconphoto', applyPromptWindow._w, logo)
|
applyPromptWindow.tk.call('wm', 'iconphoto', applyPromptWindow._w, logo)
|
||||||
applyPromptWindow.wm_title("Last adjuster settings LttP")
|
applyPromptWindow.wm_title("Last adjuster settings LttP")
|
||||||
|
|
||||||
label = LabelFrame(applyPromptWindow,
|
label = LabelFrame(applyPromptWindow,
|
||||||
text='Last used adjuster settings were found. Would you like to apply these?')
|
text='Last used adjuster settings were found. Would you like to apply these?')
|
||||||
label.grid(column=0,row=0, padx=5, pady=5, ipadx=5, ipady=5)
|
label.grid(column=0, row=0, padx=5, pady=5, ipadx=5, ipady=5)
|
||||||
label.grid_columnconfigure (0, weight=1)
|
label.grid_columnconfigure(0, weight=1)
|
||||||
label.grid_columnconfigure (1, weight=1)
|
label.grid_columnconfigure(1, weight=1)
|
||||||
label.grid_columnconfigure (2, weight=1)
|
label.grid_columnconfigure(2, weight=1)
|
||||||
label.grid_columnconfigure (3, weight=1)
|
label.grid_columnconfigure(3, weight=1)
|
||||||
def onButtonClick(answer: str='no'):
|
|
||||||
|
def onButtonClick(answer: str = 'no'):
|
||||||
setattr(onButtonClick, 'choice', answer)
|
setattr(onButtonClick, 'choice', answer)
|
||||||
applyPromptWindow.destroy()
|
applyPromptWindow.destroy()
|
||||||
|
|
||||||
framedOptions = Frame(label)
|
framedOptions = Frame(label)
|
||||||
framedOptions.grid(column=0, columnspan=4,row=0)
|
framedOptions.grid(column=0, columnspan=4, row=0)
|
||||||
framedOptions.grid_columnconfigure(0, weight=1)
|
framedOptions.grid_columnconfigure(0, weight=1)
|
||||||
framedOptions.grid_columnconfigure(1, weight=1)
|
framedOptions.grid_columnconfigure(1, weight=1)
|
||||||
framedOptions.grid_columnconfigure(2, weight=1)
|
framedOptions.grid_columnconfigure(2, weight=1)
|
||||||
curRow = 0
|
curRow = 0
|
||||||
curCol = 0
|
curCol = 0
|
||||||
for name, value in printed_options.items():
|
for name, value in printed_options.items():
|
||||||
Label(framedOptions, text=name+": "+str(value)).grid(column=curCol, row=curRow, padx=5)
|
Label(framedOptions, text=name + ": " + str(value)).grid(column=curCol, row=curRow, padx=5)
|
||||||
if(curCol==2):
|
if (curCol == 2):
|
||||||
curRow+=1
|
curRow += 1
|
||||||
curCol=0
|
curCol = 0
|
||||||
else:
|
else:
|
||||||
curCol+=1
|
curCol += 1
|
||||||
|
|
||||||
yesButton = Button(label, text='Yes', command=lambda: onButtonClick('yes'), width=10)
|
yesButton = Button(label, text='Yes', command=lambda: onButtonClick('yes'), width=10)
|
||||||
yesButton.grid(column=0, row=1)
|
yesButton.grid(column=0, row=1)
|
||||||
|
@ -1203,8 +1217,8 @@ def get_alttp_settings(romfile: str):
|
||||||
choice = getattr(onButtonClick, 'choice')
|
choice = getattr(onButtonClick, 'choice')
|
||||||
else:
|
else:
|
||||||
choice = input(f"Last used adjuster settings were found. Would you like to apply these? \n"
|
choice = input(f"Last used adjuster settings were found. Would you like to apply these? \n"
|
||||||
f"{pprint.pformat(printed_options)}\n"
|
f"{pprint.pformat(printed_options)}\n"
|
||||||
f"Enter yes, no, always or never: ")
|
f"Enter yes, no, always or never: ")
|
||||||
if choice and choice.startswith("y"):
|
if choice and choice.startswith("y"):
|
||||||
choice = 'yes'
|
choice = 'yes'
|
||||||
elif choice and "never" in choice:
|
elif choice and "never" in choice:
|
||||||
|
@ -1221,7 +1235,7 @@ def get_alttp_settings(romfile: str):
|
||||||
choice = 'no'
|
choice = 'no'
|
||||||
elif 'always' in lastSettings.auto_apply:
|
elif 'always' in lastSettings.auto_apply:
|
||||||
choice = 'yes'
|
choice = 'yes'
|
||||||
|
|
||||||
if 'yes' in choice:
|
if 'yes' in choice:
|
||||||
from worlds.alttp.Rom import get_base_rom_path
|
from worlds.alttp.Rom import get_base_rom_path
|
||||||
lastSettings.rom = romfile
|
lastSettings.rom = romfile
|
||||||
|
@ -1247,10 +1261,10 @@ def get_alttp_settings(romfile: str):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
adjusted = False
|
adjusted = False
|
||||||
return adjustedromfile, adjusted
|
return adjustedromfile, adjusted
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
colorama.init()
|
colorama.init()
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
Loading…
Reference in New Issue