123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #!/usr/bin/env python3
- import sys
- import re
- from twisted.internet import defer
- from twisted.internet import protocol
- from twisted.internet import reactor
- from twisted.python import log
- from twisted.python.logfile import DailyLogFile
- # from twisted.enterprise import adbapi
- import pendulum
- from subprocess import check_output
- # This isn't the best configuration, but it's simple
- # and works. Mostly.
- try:
- from config_dev import *
- except ModuleNotFoundError:
- from config import *
- # from config import *
- # Connect to:
- # HOST = "twgs"
- # PORT = 2002
- # Listen on:
- # LISTEN_PORT = 2002
- # LISTEN_ON = "0.0.0.0"
- version = check_output(
- [
- "git",
- "describe",
- "--long",
- "--tags",
- # "--dirty",
- "--always",
- "--match",
- "v[0-9]\.[0-9]\.[0-9]",
- ],
- universal_newlines=True,
- ).strip()
- # Cleans all ANSI
- cleaner = re.compile(r"\x1b\[[0-9;]*[A-Zmh]")
- # Looks for ANSI (that should be considered to be a newline)
- makeNL = re.compile(r"\x1b\[[0-9;]*[J]")
- def treatAsNL(line):
- """ Replace any ANSI codes that would be better understood as newlines. """
- global makeNL
- return makeNL.sub("\n", line)
- def cleanANSI(line):
- """ Remove all ANSI codes. """
- global cleaner
- return cleaner.sub("", line)
- # return re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?', '', line)
- class Game(protocol.Protocol):
- def __init__(self):
- self.buffer = ""
- def connectionMade(self):
- log.msg("Connected to Game Server")
- self.queue_player = self.factory.queue_player
- self.queue_game = self.factory.queue_game
- self.setPlayerReceived()
- # self.queue_twgs.get().addCallback(self.serverDataReceived)
- def setPlayerReceived(self):
- """ Get deferred from client queue, callback clientDataReceived. """
- self.queue_player.get().addCallback(self.playerDataReceived)
- def playerDataReceived(self, chunk):
- if chunk is False:
- self.queue_game = None
- log.msg("Player: disconnected, close connection to game")
- self.factory.continueTrying = False
- self.transport.loseConnection()
- else:
- # Pass received data to the server
- self.transport.write(chunk)
- self.setPlayerReceived()
- def dataReceived(self, chunk):
- self.queue_game.put(chunk)
- def connectionLost(self, why):
- log.msg("Game connectionLost because: %s" % why)
- self.queue_game.put(False)
- self.transport.loseConnection()
- class GlueFactory(protocol.ClientFactory):
- # class GlueFactory(protocol.Factory):
- maxDelay = 10
- protocol = Game
- def __init__(self, player):
- self.player = player
- self.queue_player = player.queue_player
- self.queue_game = player.queue_game
- def closeIt(self):
- log.msg("closeIt")
- self.queue_game.put(False)
- def getUser(self, user):
- log.msg("getUser( %s )" % user)
- self.twgs.logUser(user)
- # This was needed when I replaced ClientFactory with Factory.
- # def clientConnectionLost(self, connector, why):
- # log.msg("clientconnectionlost: %s" % why)
- # self.queue_client.put(False)
- def clientConnectionFailed(self, connector, why):
- log.msg("connection to game failed: %s" % why)
- self.queue_game.put(b"Sorry! I'm Unable to connect to the game server.\r\n")
- # syncterm gets cranky/locks up if we close this here.
- # (Because it is still sending rlogin information?)
- reactor.callLater(2, self.closeIt)
- class Player(protocol.Protocol):
- def __init__(self):
- self.buffer = ""
- self.fpRaw = None
- self.fpLines = None
- self.action = None
- self.username = ""
- self.game = ""
- self.passon = True
- def connectionMade(self):
- """ connected, setup queues.
-
- queue_player is data from player.
- queue_game is data to player. (possibly from game)
- """
- self.queue_player = defer.DeferredQueue()
- self.queue_game = defer.DeferredQueue()
- self.setGameReceived()
- # Connect GlueFactory to this Player object.
- factory = GlueFactory(self)
- # Make connection to the game server
- reactor.connectTCP(HOST, PORT, factory, 5)
- def setGameReceived(self):
- """ Get deferred from client queue, callback clientDataReceived. """
- self.queue_game.get().addCallback(self.gameDataReceived)
- def gameDataReceived(self, chunk):
- """ Data received from the client/player. """
- if chunk is False:
- self.transport.loseConnection()
- else:
- self.transport.write(chunk)
- self.setGameReceived()
- def dataReceived(self, chunk):
- self.queue_player.put(chunk)
- def connectionLost(self, why):
- log.msg("lost connection %s" % why)
- self.queue_player.put(False)
- def connectionFailed(self, why):
- log.msg("connectionFailed: %s" % why)
- if __name__ == "__main__":
- if LOGFILE:
- log.startLogging(DailyLogFile("proxy.log", "."))
- else:
- log.startLogging(sys.stdout)
- log.msg("This is version: %s" % version)
- factory = protocol.Factory()
- factory.protocol = Player
- reactor.listenTCP(LISTEN_PORT, factory, interface=LISTEN_ON)
- reactor.run()
|