feat(telnet): support telnet BINARY mode#943
Merged
thefallentree merged 1 commit intofluffos:masterfrom Dec 11, 2022
Merged
Conversation
Amirani-al
pushed a commit
to Amirani-al/fluffos
that referenced
this pull request
May 30, 2023
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
允许客户端和服务器协商进入 BINARY 传输模式。
需求背景有点复杂,事情是这样的,我用 LPC 写了一个副本架构,允许将单独的游戏功能(比如特定的房间或者地图)放入单独的 driver 进程中运行。然后主世界的 driver 通过 telnet 协议模拟客户端向副本服务器转发来自玩家的命令。
这种方式基本上是可以工作的,但有一个瑕疵,那就是 MUDLIB 的代码通常用
\n来表示换行,按照目前版本 fluffos 的默认行为(实际上是 libtelnet 的默认行为),在「非 BINARY 模式下」,\r会转换成\r\0,\n会自动转换成\r\n传输给玩家。参见这里:https://github.com/fluffos/fluffos/blob/master/src/thirdparty/libtelnet/libtelnet.c#L1372-L1388
这个行为可以通过 telnet BINARY 选项开启或者关闭。默认 BINARY 处于关闭模式,就会发生这种转换,而如果开启 BINARY 模式,则不再进行这种转换。
这么做通常不会有什么问题,因为虽然 MUDLIB 里写的是
\n,客户端收到的是\r\n,但几乎所有的客户端都可以恰当地处理\r\n,将其识别为换行符。但是在前述架构中,副本代码中的
\n被转换成\r\n传输给了主世界服务器,然后主世界服务器会再次进行转换,最后变成\r\0\r\n传输给玩家。这个畸形的换行符在某些版本的客户端上面工作不正常,效果是「什么也不显示」:虽然这个问题理论上也可以在客户端予以纠正,但究其原因实际上是因为服务器传输的畸形的换行符导致的,这也使得修改客户端代码的请求难以获得客户端 onwer 的认同。
我仔细查阅了相关的 telnet 协议规范,例如 rfc854 和 rfc1143,结合 libtelnet 代码所见,以及大量的测试,最终认为,如果能够在主站和副本建连时,进入 BINARY 传输模式,那么就会减少一次额外的转换,使客户端能够看到符合正常预期的结果。
但目前虽然 libtelnet 支持该选项,但
src/net/telnet.cc并未开启相应的支持。所以我发了这个 PR,请 @thefallentree 拨冗考虑。