Skip to content

add tab completion for multiplayer #44

Open

Description

@YtvwlD
No description provided.

Activity

  1. YtvwlD commented on Aug 17, 2025

    @YtvwlD
    MemberAuthor

    I took a look at this last Thursday (together with @vitasomething) and this is more difficult than it might look like:

    telnet clients usually send a whole line at a time

    (This also applies to nc, even though it's technically not a telnet client.)

    This is RFC 1116 ("Telnet Linemode Option").
    This is a good idea, because it drastically reduces latency: Users can type and they get to see their characters immediately.

    But this doesn't work for us: When we want to complete, we need to see the part of the line that has already been entered.

    According to StackOverflow, we could instruct the client to send each char right as it is entered:

    # telnet: IAC WONT LINEMODE IAC WILL ECHO
    # see: https://stackoverflow.com/a/279271/2192464
    self.wfile.write(b"\377\375\042\377\373\001")
    # the client will ACK this, ignore this message
    self.rfile.read(65)

    This is ugly because this doesn't actually parses the client answer, but it basically works.

    But, this comes with two new problems:

    we're now responsible for line editing

    The easiest part of this is receiving each char, storing it in a buffer and returning it on enter:

    text = b""
    while True:
        char = self.file.read(1)
        if char == b"\0":
            break
        text += char

    But there's more problems here: What if the users presses backspace? Or even uses the arrow keys? This gets difficult.
    What if we're at the end of the line? How do we even know how wide the client's terminal is? (There's a telnet command for this!)

    It would be great if there were libraries for this. We'd need a telnet server library and a readline-like library and we'd need to stitch them together.

    But there just isn't? Apparently?

    There's telnetlib3 which seems pretty promising, but it's async, so it completely breaks cmd.
    And readline needs stdin to be the single real terminal – we want multiple connections with their own state at the same time.

    the client might not support this

    nc is not a telnet client. It'll probably print the IACs as garbled text and won't answer anything.
    This could be solved by first printing something like "Configuring your telnet client... If this doesn't work, press Enter.\r" and then the IAC. We would then need to match if the next character that the client sends is an IAC (0xff) or a newline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions