From f61fc21d4be99083eb6a2c3abd65697af75acf23 Mon Sep 17 00:00:00 2001 From: Azalea Gui <22280294+hykilpikonna@users.noreply.github.com> Date: Sun, 19 Apr 2026 22:19:53 -0400 Subject: [PATCH] [O] Optimize --- color_test.py | 20 ++++++++++++++++++++ docker-compose.yml | 1 + relay.py | 21 ++++++++++++++++++--- telnet_ex.py | 35 +++++++++++++++++++++++++++++++++++ tngame-rs/src/main.rs | 6 +++--- tngame/telnet.py | 28 ++++++++++++++-------------- 6 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 color_test.py create mode 100644 telnet_ex.py diff --git a/color_test.py b/color_test.py new file mode 100644 index 0000000..240455a --- /dev/null +++ b/color_test.py @@ -0,0 +1,20 @@ +from hyfetch.color_util import RGB + +if __name__ == '__main__': + pink = RGB.from_hex('#F6AAB7').to_ansi_rgb() + blue = RGB.from_hex('#55CDFD').to_ansi_rgb() + + # Clear the screen + print('\x1b[2J', end='') + print('\x1b[H', end='') + # Print a message + print('Hello, world!') + # Move cursor to line 10, column 5 + print('\x1b[10;5H', end='') + # Print a message with color + print(f'{pink}Hello, world!\x1b[0m\r\n', end='') + print("Hi, I'm a cat!\r\n", end='') + # Set the color of "world" to blue + # print('\x1b[10;15H', end='') + # print(blue + "w", end='') + diff --git a/docker-compose.yml b/docker-compose.yml index 8d97ca1..27ef6ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: tng: container_name: tng + restart: always image: hykilpikonna/tngame build: . ports: diff --git a/relay.py b/relay.py index 2eb6f58..ce1a63d 100644 --- a/relay.py +++ b/relay.py @@ -1,5 +1,6 @@ import argparse import asyncio +import os import telnetlib3 from telnetlib3 import TelnetReaderUnicode, TelnetWriterUnicode @@ -11,19 +12,33 @@ log = setup_logger() async def shell(reader: TelnetReaderUnicode, writer: TelnetWriterUnicode): # Get the size of the terminal - async def get_size() -> tuple[int, int]: + async def get_size() -> tuple[int, int] | None: + writer.write("Detecting terminal size...") writer.write('\x1b[18t') await writer.drain() size = await reader.read(100) # Parse the size, it's in the format of \x1b[8;{height};{width}t - height, width = size.split(';')[1:3] + sp = size.split(';')[1:3] + if len(sp) != 2: + print("Peer is not a tty") + writer.write("\r\nCannot detect terminal size, please use a better terminal\r\n" + "(like kitty! https://sw.kovidgoyal.net/kitty/)\r\n") + await writer.drain() + return None + height, width = sp height, width = int(height), int(width[:-1]) return height, width # Run tngame-rs - h, w = await get_size() + _size = await get_size() + if _size is None: + writer.close() + reader.close() + return + h, w = _size + proc = await asyncio.create_subprocess_exec( args.bin, stdin=asyncio.subprocess.PIPE, diff --git a/telnet_ex.py b/telnet_ex.py new file mode 100644 index 0000000..a2693d7 --- /dev/null +++ b/telnet_ex.py @@ -0,0 +1,35 @@ +import asyncio + +import telnetlib3 +from telnetlib3 import TelnetReaderUnicode, TelnetWriterUnicode + + +async def shell(reader: TelnetReaderUnicode, writer: TelnetWriterUnicode): + # Handle input function + async def on_input(inp: str): + # Switch case + match inp: + case '\x1b[C' | 'd': # Right + writer.write('Right pressed\r\n') + case '\x1b[D' | 'a': # Left + writer.write('Left pressed\r\n') + case '\x1b' | 'q' | '\x03': # Escape or q or Ctrl+C + writer.write('\r\nBye!\r\n') + writer.close() + return True + case _: + print(f'Unknown input: {repr(inp)}') + + # Listen input + while True: + inp: str = await reader.read(3) + if inp and await on_input(inp): + return + +if __name__ == '__main__': + # Create a new event loop, start the server and wait for it to close + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + coro = telnetlib3.create_server(port=2323, shell=shell) + server = loop.run_until_complete(coro) + loop.run_until_complete(server.wait_closed()) diff --git a/tngame-rs/src/main.rs b/tngame-rs/src/main.rs index d7d6201..63cf418 100644 --- a/tngame-rs/src/main.rs +++ b/tngame-rs/src/main.rs @@ -521,7 +521,7 @@ async fn pull_input(mt: Arc>, cn: &Consts) -> Result<()> { fn run() -> Result<()> { pretty_env_logger::init(); - let cn: &Consts = Box::leak(Box::new(Consts::new())); + let cn: Consts = Consts::new(); let mt = Arc::new(Mutex::new(Mutes::new(&cn))); // Set terminal to raw mode @@ -540,8 +540,8 @@ fn run() -> Result<()> { // Start update_loop and pull_input concurrently and wait for them to finish let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let update_loop = start_update_loop( mt.clone(), cn); - let pull_input = pull_input(mt.clone(), cn); + let update_loop = start_update_loop( mt.clone(), &cn); + let pull_input = pull_input(mt.clone(), &cn); tokio::try_join!(update_loop, pull_input)?; Ok::<(), Error>(()) })?; diff --git a/tngame/telnet.py b/tngame/telnet.py index 85ce647..95657f6 100644 --- a/tngame/telnet.py +++ b/tngame/telnet.py @@ -293,20 +293,6 @@ async def shell(reader: TelnetReaderUnicode, writer: TelnetWriterUnicode): await update() - # Update frame function - async def listen_update(): - while True: - await update() - # 20 fps - await asyncio.sleep(1 / 20) - - # Listen input function - async def listen_input(): - while True: - inp: str = await reader.read(3) - if inp and await on_input(inp): - return - # Initialize the shell clear() height, width = await get_size() @@ -320,6 +306,20 @@ async def shell(reader: TelnetReaderUnicode, writer: TelnetWriterUnicode): snow = create_snow(100) init_buffers() + # Listen input function + async def listen_input(): + while True: + inp: str = await reader.read(3) + if inp and await on_input(inp): + return + + # Update frame function + async def listen_update(): + while True: + await update() + # 20 fps + await asyncio.sleep(1 / 20) + # Run listen and update in parallel await asyncio.gather(listen_input(), listen_update())