mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-25 02:23:37 -07:00
Jak 1: There's magic in the air...
This commit is contained in:
@@ -6,9 +6,9 @@ import colorama
|
||||
import Utils
|
||||
from CommonClient import ClientCommandProcessor, CommonContext, logger, server_loop, gui_enabled
|
||||
|
||||
from .GameID import jak1_name
|
||||
from .client.ReplClient import JakAndDaxterReplClient
|
||||
from .client.MemoryReader import JakAndDaxterMemoryReader
|
||||
from worlds.jakanddaxter.GameID import jak1_name
|
||||
from worlds.jakanddaxter.client.ReplClient import JakAndDaxterReplClient
|
||||
from worlds.jakanddaxter.client.MemoryReader import JakAndDaxterMemoryReader
|
||||
|
||||
import ModuleUpdate
|
||||
ModuleUpdate.update()
|
||||
@@ -96,9 +96,16 @@ class JakAndDaxterContext(CommonContext):
|
||||
self.ui = JakAndDaxterManager(self)
|
||||
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")
|
||||
|
||||
async def server_auth(self, password_requested: bool = False):
|
||||
if password_requested and not self.password:
|
||||
await super(JakAndDaxterContext, self).server_auth(password_requested)
|
||||
await self.get_username()
|
||||
await self.send_connect()
|
||||
|
||||
def on_package(self, cmd: str, args: dict):
|
||||
if cmd == "ReceivedItems":
|
||||
for index, item in enumerate(args["items"], start=args["index"]):
|
||||
logger.info(args)
|
||||
self.repl.item_inbox[index] = item
|
||||
|
||||
async def ap_inform_location_checks(self, location_ids: typing.List[int]):
|
||||
@@ -109,12 +116,14 @@ class JakAndDaxterContext(CommonContext):
|
||||
create_task_log_exception(self.ap_inform_location_checks(location_ids))
|
||||
|
||||
async def run_repl_loop(self):
|
||||
await self.repl.main_tick()
|
||||
await asyncio.sleep(0.1)
|
||||
while True:
|
||||
await self.repl.main_tick()
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
async def run_memr_loop(self):
|
||||
await self.memr.main_tick(self.on_locations)
|
||||
await asyncio.sleep(0.1)
|
||||
while True:
|
||||
await self.memr.main_tick(self.on_locations)
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
||||
async def main():
|
||||
@@ -139,4 +148,4 @@ async def main():
|
||||
def launch():
|
||||
colorama.init()
|
||||
asyncio.run(main())
|
||||
colorama.deinit()
|
||||
colorama.deinit()
|
||||
|
||||
@@ -2,7 +2,7 @@ import typing
|
||||
from enum import Enum, auto
|
||||
from BaseClasses import MultiWorld, Region
|
||||
from .GameID import jak1_name
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .JakAndDaxterOptions import JakAndDaxterOptions
|
||||
from .Locations import JakAndDaxterLocation, location_table
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from BaseClasses import MultiWorld, CollectionState
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .JakAndDaxterOptions import JakAndDaxterOptions
|
||||
from .Regions import Jak1Level, Jak1SubLevel, level_table, subLevel_table
|
||||
from .Locations import location_table as item_table
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from BaseClasses import Item, ItemClassification, Tutorial
|
||||
from .GameID import jak1_id, jak1_name
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .JakAndDaxterOptions import JakAndDaxterOptions
|
||||
from .Items import JakAndDaxterItem
|
||||
from .Locations import JakAndDaxterLocation, location_table as item_table
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts, OrbLocations as Orbs
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import typing
|
||||
import subprocess
|
||||
import pymem
|
||||
from pymem import pattern
|
||||
from pymem.exception import ProcessNotFound
|
||||
|
||||
from CommonClient import logger
|
||||
from worlds.jakanddaxter.locs import CellLocations as Cells, ScoutLocations as Flies
|
||||
|
||||
# Some helpful constants.
|
||||
@@ -18,7 +19,7 @@ class JakAndDaxterMemoryReader:
|
||||
connected: bool = False
|
||||
marked: bool = False
|
||||
|
||||
process = None
|
||||
process: pymem.process = None
|
||||
marker_address = None
|
||||
goal_address = None
|
||||
|
||||
@@ -33,17 +34,20 @@ class JakAndDaxterMemoryReader:
|
||||
|
||||
async def main_tick(self, location_callback: typing.Callable):
|
||||
self.read_memory()
|
||||
location_callback(self.location_outbox)
|
||||
|
||||
# Checked Locations in game. Handle 1 location per tick.
|
||||
# Checked Locations in game. Handle the entire outbox every tick until we're up to speed.
|
||||
if len(self.location_outbox) > self.outbox_index:
|
||||
await location_callback(self.location_outbox[self.outbox_index])
|
||||
location_callback(self.location_outbox)
|
||||
self.outbox_index += 1
|
||||
|
||||
def connect(self) -> bool:
|
||||
try:
|
||||
self.process = pymem.Pymem("gk.exe") # The GOAL Kernel
|
||||
logger.info("Found the gk process: " + str(self.process.process_id))
|
||||
return True
|
||||
except ProcessNotFound:
|
||||
logger.error("Could not find the gk process.")
|
||||
return False
|
||||
|
||||
def find_marker(self) -> bool:
|
||||
@@ -59,19 +63,40 @@ class JakAndDaxterMemoryReader:
|
||||
self.goal_address = int.from_bytes(self.process.read_bytes(goal_pointer, 8),
|
||||
byteorder="little",
|
||||
signed=False)
|
||||
logger.info("Found the archipelago memory address: " + str(self.goal_address))
|
||||
return True
|
||||
logger.error("Could not find the archipelago memory address.")
|
||||
return False
|
||||
|
||||
def read_memory(self) -> typing.List[int]:
|
||||
next_cell_index = int.from_bytes(self.process.read_bytes(self.goal_address, 8))
|
||||
next_buzzer_index = int.from_bytes(self.process.read_bytes(self.goal_address + next_buzzer_index_offset, 8))
|
||||
next_cell = int.from_bytes(self.process.read_bytes(self.goal_address + cells_offset + (next_cell_index * 4), 4))
|
||||
next_buzzer = int.from_bytes(self.process.read_bytes(self.goal_address + cells_offset + (next_buzzer_index * 4), 4))
|
||||
next_cell_index = int.from_bytes(
|
||||
self.process.read_bytes(self.goal_address, 8),
|
||||
byteorder="little",
|
||||
signed=False)
|
||||
next_buzzer_index = int.from_bytes(
|
||||
self.process.read_bytes(self.goal_address + next_buzzer_index_offset, 8),
|
||||
byteorder="little",
|
||||
signed=False)
|
||||
|
||||
if next_cell not in self.location_outbox:
|
||||
self.location_outbox.append(Cells.to_ap_id(next_cell))
|
||||
if next_buzzer not in self.location_outbox:
|
||||
self.location_outbox.append(Flies.to_ap_id(next_buzzer))
|
||||
for k in range(0, next_cell_index):
|
||||
next_cell = int.from_bytes(
|
||||
self.process.read_bytes(self.goal_address + cells_offset + (k * 4), 4),
|
||||
byteorder="little",
|
||||
signed=False)
|
||||
cell_ap_id = Cells.to_ap_id(next_cell)
|
||||
if cell_ap_id not in self.location_outbox:
|
||||
self.location_outbox.append(cell_ap_id)
|
||||
logger.info("Checked power cell: " + str(next_cell))
|
||||
|
||||
for k in range(0, next_buzzer_index):
|
||||
next_buzzer = int.from_bytes(
|
||||
self.process.read_bytes(self.goal_address + buzzers_offset + (k * 4), 4),
|
||||
byteorder="little",
|
||||
signed=False)
|
||||
buzzer_ap_id = Flies.to_ap_id(next_buzzer)
|
||||
if buzzer_ap_id not in self.location_outbox:
|
||||
self.location_outbox.append(buzzer_ap_id)
|
||||
logger.info("Checked scout fly: " + str(next_buzzer))
|
||||
|
||||
return self.location_outbox
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ class JakAndDaxterReplClient:
|
||||
time.sleep(1)
|
||||
logger.info(self.socket.recv(1024).decode())
|
||||
return True
|
||||
except ConnectionRefusedError:
|
||||
except ConnectionRefusedError as e:
|
||||
logger.error(e.strerror)
|
||||
return False
|
||||
|
||||
def listen(self) -> bool:
|
||||
@@ -96,7 +97,7 @@ class JakAndDaxterReplClient:
|
||||
return True
|
||||
|
||||
def receive_item(self):
|
||||
ap_id = self.item_inbox[self.inbox_index]["item"]
|
||||
ap_id = getattr(self.item_inbox[self.inbox_index], "item")
|
||||
|
||||
# Determine the type of item to receive.
|
||||
if ap_id in range(jak1_id, jak1_id + Flies.fly_offset):
|
||||
|
||||
Reference in New Issue
Block a user