mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-24 18:33:32 -07:00
Jak & Daxter Client : queue game text messages to get items faster during release (#48)
* queue game text messages to write them during the main_tick function and empty the message queue faster during release * wrap comment for code style character limit Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * remove useless blank line Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * whitespace code style Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * Move JsonMessageData dataclass outside of ReplClient class for code clarity --------- Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com>
This commit is contained in:
@@ -160,31 +160,35 @@ class JakAndDaxterContext(CommonContext):
|
||||
|
||||
async def json_to_game_text(self, args: dict):
|
||||
if "type" in args and args["type"] in {"ItemSend"}:
|
||||
my_item_name = Optional[str]
|
||||
my_item_finder = Optional[str]
|
||||
their_item_name = Optional[str]
|
||||
their_item_owner = Optional[str]
|
||||
item = args["item"]
|
||||
recipient = args["receiving"]
|
||||
|
||||
# Receiving an item from the server.
|
||||
if self.slot_concerns_self(recipient):
|
||||
self.repl.my_item_name = self.item_names.lookup_in_game(item.item)
|
||||
my_item_name = self.item_names.lookup_in_game(item.item)
|
||||
|
||||
# Did we find it, or did someone else?
|
||||
if self.slot_concerns_self(item.player):
|
||||
self.repl.my_item_finder = "MYSELF"
|
||||
my_item_finder = "MYSELF"
|
||||
else:
|
||||
self.repl.my_item_finder = self.player_names[item.player]
|
||||
my_item_finder = self.player_names[item.player]
|
||||
|
||||
# Sending an item to the server.
|
||||
if self.slot_concerns_self(item.player):
|
||||
self.repl.their_item_name = self.item_names.lookup_in_slot(item.item, recipient)
|
||||
their_item_name = self.item_names.lookup_in_slot(item.item, recipient)
|
||||
|
||||
# Does it belong to us, or to someone else?
|
||||
if self.slot_concerns_self(recipient):
|
||||
self.repl.their_item_owner = "MYSELF"
|
||||
their_item_owner = "MYSELF"
|
||||
else:
|
||||
self.repl.their_item_owner = self.player_names[recipient]
|
||||
their_item_owner = self.player_names[recipient]
|
||||
|
||||
# Write to game display.
|
||||
await self.repl.write_game_text()
|
||||
self.repl.queue_game_text(my_item_name, my_item_finder, their_item_name, their_item_owner)
|
||||
|
||||
def on_print_json(self, args: dict) -> None:
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import json
|
||||
import queue
|
||||
import time
|
||||
import struct
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from queue import Queue
|
||||
from typing import Dict, Optional
|
||||
|
||||
import pymem
|
||||
@@ -22,6 +25,14 @@ from ..locs import (
|
||||
OrbCacheLocations as Caches)
|
||||
|
||||
|
||||
@dataclass
|
||||
class JsonMessageData:
|
||||
my_item_name: Optional[str] = None
|
||||
my_item_finder: Optional[str] = None
|
||||
their_item_name: Optional[str] = None
|
||||
their_item_owner: Optional[str] = None
|
||||
|
||||
|
||||
class JakAndDaxterReplClient:
|
||||
ip: str
|
||||
port: int
|
||||
@@ -40,11 +51,7 @@ class JakAndDaxterReplClient:
|
||||
|
||||
item_inbox: Dict[int, NetworkItem] = {}
|
||||
inbox_index = 0
|
||||
|
||||
my_item_name: Optional[str] = None
|
||||
my_item_finder: Optional[str] = None
|
||||
their_item_name: Optional[str] = None
|
||||
their_item_owner: Optional[str] = None
|
||||
json_message_queue: Queue[JsonMessageData] = queue.Queue()
|
||||
|
||||
def __init__(self, ip: str = "127.0.0.1", port: int = 8181):
|
||||
self.ip = ip
|
||||
@@ -81,6 +88,13 @@ class JakAndDaxterReplClient:
|
||||
await self.receive_deathlink()
|
||||
self.received_deathlink = False
|
||||
|
||||
# Progressively empty the queue during each tick
|
||||
# if text messages happen to be too slow we could pool dequeuing here,
|
||||
# but it'd slow down the ItemReceived message during release
|
||||
if not self.json_message_queue.empty():
|
||||
json_txt_data = self.json_message_queue.get_nowait()
|
||||
await self.write_game_text(json_txt_data)
|
||||
|
||||
# This helper function formats and sends `form` as a command to the REPL.
|
||||
# ALL commands to the REPL should be sent using this function.
|
||||
async def send_form(self, form: str, print_ok: bool = True) -> bool:
|
||||
@@ -203,20 +217,25 @@ class JakAndDaxterReplClient:
|
||||
result = result[:32].upper()
|
||||
return f"\"{result}\""
|
||||
|
||||
# Pushes a JsonMessageData object to the json message queue to be processed during the repl main_tick
|
||||
def queue_game_text(self, my_item_name, my_item_finder, their_item_name, their_item_owner):
|
||||
self.json_message_queue.put(self.JsonMessageData(my_item_name, my_item_finder,
|
||||
their_item_name, their_item_owner))
|
||||
|
||||
# OpenGOAL can handle both its own string datatype and C-like character pointers (charp).
|
||||
# So for the game to constantly display this information in the HUD, we have to write it
|
||||
# to a memory address as a char*.
|
||||
async def write_game_text(self):
|
||||
async def write_game_text(self, data: JsonMessageData):
|
||||
logger.debug(f"Sending info to in-game display!")
|
||||
await self.send_form(f"(begin "
|
||||
f" (charp<-string (-> *ap-info-jak1* my-item-name) "
|
||||
f" {self.sanitize_game_text(self.my_item_name)}) "
|
||||
f" {self.sanitize_game_text(data.my_item_name)}) "
|
||||
f" (charp<-string (-> *ap-info-jak1* my-item-finder) "
|
||||
f" {self.sanitize_game_text(self.my_item_finder)}) "
|
||||
f" {self.sanitize_game_text(data.my_item_finder)}) "
|
||||
f" (charp<-string (-> *ap-info-jak1* their-item-name) "
|
||||
f" {self.sanitize_game_text(self.their_item_name)}) "
|
||||
f" {self.sanitize_game_text(data.their_item_name)}) "
|
||||
f" (charp<-string (-> *ap-info-jak1* their-item-owner) "
|
||||
f" {self.sanitize_game_text(self.their_item_owner)}) "
|
||||
f" {self.sanitize_game_text(data.their_item_owner)}) "
|
||||
f" (none))", print_ok=False)
|
||||
|
||||
async def receive_item(self):
|
||||
|
||||
Reference in New Issue
Block a user