1
0

finish trainer protocol update

This commit is contained in:
2026-01-10 16:39:16 +08:00
parent 58bb974394
commit 1abafeb0ca
3 changed files with 89 additions and 18 deletions

View File

@@ -26,9 +26,18 @@ class PixelKind(IntEnum):
@dataclass
class HandshakePayload:
headless: bool
pixel_kind: PixelKind
width: int
height: int
engine_name: str
engine_device: int
deliver_name: str
deliver_device: int
object_loader_name: str
object_loader_file: str
anime_loader_name: str
anime_loader_file: str
class ServerStatus(Enum):
@@ -38,7 +47,9 @@ class ServerStatus(Enum):
CODE_PACKER: struct.Struct = struct.Struct("=B")
HANDSHAKE_REQUEST_PACKER: struct.Struct = struct.Struct("=BII")
U8_PACKER: struct.Struct = struct.Struct("=B")
U32_PACKER: struct.Struct = struct.Struct("=I")
USIZE_PACKER: struct.Struct = struct.Struct("=N")
class CmdServer:
@@ -66,17 +77,23 @@ class CmdServer:
raise RuntimeError("unexpected server status")
# Send handshake request to Presenter
self.__pipe_operator.write(CODE_PACKER.pack(ProtocolCode.HANDSHAKE_REQUEST))
self.__pipe_operator.write_pod(CODE_PACKER, ProtocolCode.HANDSHAKE_REQUEST)
# And the payload data
self.__pipe_operator.write(
HANDSHAKE_REQUEST_PACKER.pack(
payload.pixel_kind, payload.width, payload.height
)
)
self.__pipe_operator.write_pod(U8_PACKER, 1 if payload.headless else 0)
self.__pipe_operator.write_pod(U8_PACKER, payload.pixel_kind)
self.__pipe_operator.write_pod(U32_PACKER, payload.width)
self.__pipe_operator.write_pod(U32_PACKER, payload.height)
self.__pipe_operator.write_bsstring(payload.engine_name)
self.__pipe_operator.write_pod(USIZE_PACKER, payload.engine_device)
self.__pipe_operator.write_bsstring(payload.deliver_name)
self.__pipe_operator.write_pod(USIZE_PACKER, payload.deliver_device)
self.__pipe_operator.write_bsstring(payload.object_loader_name)
self.__pipe_operator.write_bsstring(payload.object_loader_file)
self.__pipe_operator.write_bsstring(payload.anime_loader_name)
self.__pipe_operator.write_bsstring(payload.anime_loader_file)
# Wait for handshake response from Presenter (code 0x62)
code_bytes = self.__pipe_operator.read(CODE_PACKER.size)
(code,) = CODE_PACKER.unpack(code_bytes)
(code,) = self.__pipe_operator.read_pod(CODE_PACKER)
if ProtocolCode(code) != ProtocolCode.HANDSHAKE_RESPONSE:
raise RuntimeError("expect handshake response code, but got another")
@@ -95,12 +112,11 @@ class CmdServer:
# If there is stop requested from us,
# we order Presenter exit and enter next step.
if request_stop:
self.__pipe_operator.write(CODE_PACKER.pack(ProtocolCode.STOP_REQUEST))
self.__pipe_operator.write_pod(CODE_PACKER, ProtocolCode.STOP_REQUEST)
while True:
# Wait for code from Presenter
code_bytes = self.__pipe_operator.read(CODE_PACKER.size)
(code,) = CODE_PACKER.unpack(code_bytes)
(code,) = self.__pipe_operator.read_pod(CODE_PACKER)
# Analyse code
match ProtocolCode(code):
@@ -108,15 +124,15 @@ class CmdServer:
# Receive data
data_receiver()
# Send data received symbol
self.__pipe_operator.write(
CODE_PACKER.pack(ProtocolCode.DATA_RECEIVED)
self.__pipe_operator.write_pod(
CODE_PACKER, ProtocolCode.DATA_RECEIVED
)
return False
case ProtocolCode.ACTIVELY_STOP:
# Presenter requested stop.
# Agree with it, send code and wait response
self.__pipe_operator.write(
CODE_PACKER.pack(ProtocolCode.STOP_REQUEST)
self.__pipe_operator.write_pod(
CODE_PACKER, ProtocolCode.STOP_REQUEST
)
case ProtocolCode.STOP_RESPONSE:
# Set self status and return

View File

@@ -15,7 +15,20 @@ def main():
input()
logging.info("Waiting BasaltPresenter...")
server.wait_handshake(HandshakePayload(PixelKind.GRAY_U8, 600, 600))
server.wait_handshake(HandshakePayload(
headless=False,
pixel_kind=PixelKind.GRAY_U8,
width=600,
height=600,
engine_name="BasaltDirectX11Engine",
engine_device=0,
deliver_name="BasaltPipeDeliver",
deliver_device=0,
object_loader_name="BasaltObjObjectLoader",
object_loader_file="",
anime_loader_name="BasaltChickenNuggetAnimeLoader",
anime_loader_file="",
))
logging.info("Start to running.")
STOPPER.register()

View File

@@ -1,8 +1,10 @@
import os
import sys
from typing import Optional, Any
import struct
from typing import Optional, Any, ClassVar
IS_WINDOWS: bool = sys.platform == "win32"
IS_LITTLE_ENDIAN: bool = sys.byteorder == "little"
if IS_WINDOWS:
import win32pipe
@@ -151,3 +153,43 @@ class PipeOperator:
total_written += bytes_written
except OSError as e:
raise RuntimeError(f"Failed to write to named pipe: {e}")
def read_pod(self, pattern: struct.Struct) -> tuple[Any, ...]:
return pattern.unpack(self.read(pattern.size))
def write_pod(self, pattern: struct.Struct, *args) -> None:
self.write(pattern.pack(*args))
STR_LEN_PACKER: ClassVar[struct.Struct] = struct.Struct("=N")
def read_string(self) -> str:
(length,) = self.read_pod(PipeOperator.STR_LEN_PACKER)
str_bytes = self.read(length)
return str_bytes.decode("utf-8")
def write_string(self, s: str) -> None:
str_bytes = s.encode("utf-8")
self.write_pod(PipeOperator.STR_LEN_PACKER, len(str_bytes))
self.write(str_bytes)
def read_bsstring(self) -> str:
(length,) = self.read_pod(PipeOperator.STR_LEN_PACKER)
str_bytes = self.read(length)
return self.__decode_bsstring(str_bytes)
def write_bsstring(self, s: str) -> None:
str_bytes = self.__encode_bsstring(s)
self.write_pod(PipeOperator.STR_LEN_PACKER, len(str_bytes))
self.write(str_bytes)
def __encode_bsstring(self, s: str) -> bytes:
if IS_LITTLE_ENDIAN:
return s.encode("utf_16_le")
else:
return s.encode("utf_16_be")
def __decode_bsstring(self, b: bytes) -> str:
if IS_LITTLE_ENDIAN:
return b.decode("utf_16_le")
else:
return b.decode("utf_16_be")