tcp-proxy-tried-lineReceiver.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #!/usr/bin/env python3
  2. import sys
  3. import re
  4. from twisted.internet import defer
  5. from twisted.internet import protocol
  6. from twisted.internet import reactor
  7. from twisted.python import log
  8. from twisted.enterprise import adbapi
  9. from twisted.protocols.basic import LineReceiver
  10. # Connect to:
  11. HOST = "127.0.0.1"
  12. PORT = 2002
  13. # Listen on:
  14. LISTEN_PORT = 9999
  15. LISTEN_ON = "127.0.0.1"
  16. class LineRecv(LineReceiver):
  17. def __init__(self, notify):
  18. self.delimiter = b"\n" # \r"
  19. self.notify = notify
  20. def lineReceived(self, line):
  21. log.msg("LR:", line)
  22. self.notify.gotLine(line)
  23. class PlayerProtocol(protocol.Protocol):
  24. def __init__(self):
  25. self.user = None
  26. self.dbinit = False
  27. self.db = None
  28. self.buffer = ""
  29. self.linereader = LineRecv(self)
  30. self.linereader.connectionMade()
  31. def connectionMade(self):
  32. log.msg("Client: connected to peer")
  33. self.queue_twgs = self.factory.queue_twgs
  34. self.queue_twgs.get().addCallback(self.serverDataReceived)
  35. def gotLine(self, line):
  36. log.msg(">>> [{0}]".format(line.decode("utf-8", "ignore")))
  37. def serverDataReceived(self, chunk):
  38. # rlogin looks like this: \x00 password \x00 username \x00 terminal/speed \x00
  39. # b'\x00up2lat3\x00bugz\x00ansi-bbs/115200\x00'
  40. # We're looking for 4 \x00!
  41. # TODO: Line processing, and line cleaning (remove ANSI color codes)
  42. if chunk is False:
  43. self.queue_twgs = None
  44. log.msg("Client: disconnecting from peer")
  45. self.factory.continueTrying = False
  46. self.transport.loseConnection()
  47. else:
  48. self.buffer += chunk.decode("utf-8")
  49. if self.user is None:
  50. # Ok, process this
  51. # self.buffer += chunk.decode('utf-8')
  52. # We don't have the username yet
  53. parts = self.buffer.split("\x00")
  54. if len(parts) >= 5:
  55. # Got it!
  56. self.user = parts[1]
  57. log.msg("User: {0}".format(self.user))
  58. # Reset buffer -- remove everything before last \x00
  59. zpos = self.buffer.rindex("\x00")
  60. self.buffer = self.buffer[zpos + 1 :]
  61. self.buffer = ""
  62. # init sqlite db using the username
  63. else:
  64. # process the buffer
  65. # Handle backspaces by deleting previous character.
  66. # Send the received data into the linereader for "automatic" line processing.
  67. self.linereader.dataReceived(chunk)
  68. #
  69. #
  70. # Strip out ANSI color codes
  71. # self.buffer = re.sub(r'\x1b[\d;?\d+m', '', self.buffer)
  72. # Process lines ...
  73. self.transport.write(chunk)
  74. self.queue_twgs.get().addCallback(self.serverDataReceived)
  75. # elif b"$" == chunk:
  76. # self.factory.svr_queue.put(b"HELLO.\r\n")
  77. # self.cli_queue.get().addCallback(self.serverDataReceived)
  78. # elif self.cli_queue:
  79. # log.msg("Client: writing %d bytes to peer" % len(chunk))
  80. # log.msg(">>", repr(chunk))
  81. # self.transport.write(chunk)
  82. # self.cli_queue.get().addCallback(self.serverDataReceived)
  83. # else:
  84. # self.factory.cli_queue.put(chunk)
  85. def dataReceived(self, chunk):
  86. # log.msg("Client: %d bytes received from peer" % len(chunk))
  87. # clean, strip ANSI, etc.
  88. # log.msg("<<", chunk.decode("utf-8", "ignore"))
  89. log.msg("<<", repr(chunk))
  90. self.factory.queue_client.put(chunk)
  91. def connectionLost(self, why):
  92. log.msg("connectionLost because: %s" % why)
  93. # if self.cli_queue:
  94. # self.cli_queue = None
  95. # log.msg("Client: peer disconnect unexpectedly")
  96. self.factory.queue_client.put(False)
  97. self.queue_twgs = None
  98. self.transport.loseConnection()
  99. class GlueFactory(protocol.ClientFactory):
  100. maxDelay = 10
  101. protocol = PlayerProtocol
  102. def __init__(self, queue_client, queue_twgs):
  103. self.queue_client = queue_client
  104. self.queue_twgs = queue_twgs
  105. def closeIt(self):
  106. log.msg("closeIt")
  107. self.queue_client.put(False)
  108. def clientConnectionFailed(self, connector, why):
  109. log.msg("connectionFailed: %s" % why)
  110. self.queue_client.put(b"Sorry! I'm Unable to connect to the game server.\r\n")
  111. # syncterm gets cranky/locks up if we close this here.
  112. # (Because it is still sending rlogin information?)
  113. reactor.callLater(2, self.closeIt)
  114. # ProxyServer is created for each connection
  115. class TWGSServer(protocol.Protocol):
  116. def connectionMade(self):
  117. self.queue_twgs = defer.DeferredQueue()
  118. self.queue_client = defer.DeferredQueue()
  119. self.queue_client.get().addCallback(self.clientDataReceived)
  120. factory = GlueFactory(self.queue_client, self.queue_twgs)
  121. reactor.connectTCP(HOST, PORT, factory, 5)
  122. def clientDataReceived(self, chunk):
  123. if chunk is False:
  124. self.transport.loseConnection()
  125. else:
  126. # log.msg("Server: writing %d bytes to original client" % len(chunk))
  127. self.transport.write(chunk)
  128. self.queue_client.get().addCallback(self.clientDataReceived)
  129. def dataReceived(self, chunk):
  130. # log.msg("Server: %d bytes received" % len(chunk))
  131. self.queue_twgs.put(chunk)
  132. def connectionLost(self, why):
  133. log.msg("lost connection %s" % why)
  134. self.queue_twgs.put(False)
  135. def connectionFailed(self, why):
  136. log.msg("connectionFailed: %s" % why)
  137. if __name__ == "__main__":
  138. log.startLogging(sys.stdout)
  139. factory = protocol.Factory()
  140. factory.protocol = TWGSServer
  141. reactor.listenTCP(LISTEN_PORT, factory, interface=LISTEN_ON)
  142. reactor.run()