finish trainer protocol update
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user