home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / glchess / chess / fics / server.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  17.8 KB  |  586 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import socket
  5. import select
  6. import random
  7. import style12
  8. import telnet
  9.  
  10. class TelnetDecoder(telnet.Decoder):
  11.     
  12.     def __init__(self, decoder):
  13.         self.decoder = decoder
  14.         telnet.Decoder.__init__(self)
  15.  
  16.     
  17.     def onData(self, data):
  18.         self.decoder._processData(data)
  19.  
  20.     
  21.     def onInterruptProcess(self):
  22.         self.decoder.connection.abort()
  23.  
  24.  
  25.  
  26. class Server:
  27.     
  28.     def __init__(self):
  29.         '''
  30.         '''
  31.         self.clients = { }
  32.         self.clientsByUserName = { }
  33.         self.adverts = { }
  34.         self.advertNumber = 1
  35.         self.games = { }
  36.         self.gameNumber = 1
  37.  
  38.     
  39.     def addAdvert(self, client):
  40.         '''
  41.         '''
  42.         advert = Advert(client)
  43.         while True:
  44.             number = self.advertNumber
  45.             self.advertNumber += 1
  46.             if self.advertNumber > 999:
  47.                 self.advertNumber = 1
  48.             
  49.             if not self.adverts.has_key(number):
  50.                 break
  51.                 continue
  52.         advert.number = number
  53.         self.adverts[number] = advert
  54.         client.adverts[number] = advert
  55.         return advert
  56.  
  57.     
  58.     def removeAdverts(self, adverts):
  59.         '''
  60.         '''
  61.         for advert in adverts:
  62.             advert.client.adverts.pop(advert.number)
  63.             self.adverts.pop(advert.number)
  64.         
  65.         notifyLine = '\n<sr>'
  66.         for advert in adverts:
  67.             notifyLine += ' %i' % advert.number
  68.         
  69.         notifyLine += '\n'
  70.         for client in self.clients.itervalues():
  71.             if client.name is None:
  72.                 continue
  73.             
  74.             client.send(notifyLine)
  75.             client.sendPrompt()
  76.         
  77.  
  78.     
  79.     def addGame(self, whiteClient, blackClient):
  80.         '''
  81.         '''
  82.         game = Game(whiteClient, blackClient)
  83.         while True:
  84.             number = self.gameNumber
  85.             self.gameNumber += 1
  86.             if self.gameNumber > 999:
  87.                 self.gameNumber = 1
  88.             
  89.             if not self.games.has_key(number):
  90.                 break
  91.                 continue
  92.         game.number = number
  93.         self.games[number] = game
  94.         return game
  95.  
  96.     
  97.     def reportMove(self, game, move):
  98.         """Report a move in a game.
  99.         
  100.         'game' is the game that the move is in (?)
  101.         'move' is the move that has occured (style12.Move)
  102.         """
  103.         pass
  104.  
  105.     
  106.     def addConnection(self, connection):
  107.         '''
  108.         '''
  109.         client = Client(self, connection)
  110.         self.clients[connection] = client
  111.         client.start()
  112.  
  113.     
  114.     def registerIncomingData(self, connection, data):
  115.         '''
  116.         '''
  117.         client = self.clients[connection]
  118.         client.registerIncomingData(data)
  119.  
  120.     
  121.     def connectionClosed(self, connection, reason):
  122.         '''
  123.         '''
  124.         client = self.clients[connection]
  125.         if client.name is not None:
  126.             self.clientsByUserName.pop(client.name)
  127.         
  128.         self.clients.pop(connection)
  129.  
  130.     
  131.     def onOutgoingData(self, connection, data):
  132.         '''
  133.         '''
  134.         pass
  135.  
  136.  
  137.  
  138. class Challenge:
  139.     '''
  140.     '''
  141.     
  142.     def __init__(self, client):
  143.         self.client = client
  144.  
  145.  
  146.  
  147. class Game:
  148.     '''
  149.     '''
  150.     number = -1
  151.     white = None
  152.     black = None
  153.     time = 2
  154.     inc = 12
  155.     matchType = 'pbu'
  156.     toMove = None
  157.     move = 1
  158.     
  159.     def __init__(self, whiteClient, blackClient):
  160.         '''
  161.         '''
  162.         self.white = whiteClient
  163.         self.black = blackClient
  164.         self.toMove = self.white
  165.  
  166.     
  167.     def genGameLine(self):
  168.         if self.toMove is self.white:
  169.             colour = 'W'
  170.         else:
  171.             colour = 'B'
  172.         if self.white.rating == 0:
  173.             whiteRating = '++++'
  174.         else:
  175.             whiteRating = '%04i' % self.white.rating
  176.         if self.black.rating == 0:
  177.             blackRating = '++++'
  178.         else:
  179.             blackRating = '%04i' % self.black.rating
  180.         return '%3i %s %s %s %s [%s %2i %3i] %s -%s (%2i-%2i) %s: %2i' % (self.number, whiteRating, self.white.name.rjust(10), blackRating, self.black.name.rjust(10), self.matchType.rjust(3), self.time, self.inc, '1:36'.rjust(6), '2:33'.rjust(6), 35, 35, colour, self.move)
  181.  
  182.  
  183.  
  184. class Advert:
  185.     '''
  186.     '''
  187.     number = -1
  188.     client = None
  189.     time = 2
  190.     inc = 12
  191.     rated = False
  192.     colour = None
  193.     variant = 'standard'
  194.     autoStart = True
  195.     checkFormula = False
  196.     minRating = 0
  197.     maxRating = 9999
  198.     
  199.     def __init__(self, client):
  200.         self.client = client
  201.  
  202.     
  203.     def getVariant(self):
  204.         if self.variant != 'standard':
  205.             return self.variant
  206.         expectedDuration = self.time + 2 * self.inc / 3
  207.         if expectedDuration < 3:
  208.             return 'lightning'
  209.         if expectedDuration < 15:
  210.             return 'blitz'
  211.         return 'standard'
  212.  
  213.     
  214.     def genSoughtLine(self):
  215.         gameProps = '%3i %3i' % (self.time, self.inc)
  216.         if self.rated:
  217.             rating = 'rated'
  218.         else:
  219.             rating = 'unrated'
  220.         gameProps += ' ' + (rating + ' ' + self.getVariant()).ljust(18)
  221.         if self.colour is None:
  222.             gameProps += '         '
  223.         else:
  224.             gameProps += (' [' + self.colour + ']').ljust(9)
  225.         if self.client.rating == 0:
  226.             rating = '++++'
  227.         else:
  228.             rating = '%04i' % self.client.rating
  229.         line = '%3i %s %s %s %4i-%4i' % (self.number, rating, self.client.name.ljust(17), gameProps, self.minRating, self.maxRating)
  230.         if self.checkFormula:
  231.             line += ' f'
  232.         
  233.         return line
  234.  
  235.     
  236.     def genSeekLine(self):
  237.         gameProps = '%i %i' % (self.time, self.inc)
  238.         if self.rated:
  239.             gameProps += ' rated'
  240.         else:
  241.             gameProps += ' unrated'
  242.         gameProps += ' ' + self.getVariant()
  243.         if self.colour is not None:
  244.             gameProps += ' [' + self.colour + ']'
  245.         
  246.         if self.checkFormula:
  247.             self.variant += ' f'
  248.         
  249.         if self.client.rating == 0:
  250.             rating = '++++'
  251.         else:
  252.             rating = '%04i' % self.client.rating
  253.         return '%s (%s) seeking %s ("play %i" to respond)' % (self.client.name, rating, gameProps, self.number)
  254.  
  255.     
  256.     def genSeekMessage(self):
  257.         if self.rated:
  258.             rated = 'r'
  259.         else:
  260.             rated = 'u'
  261.         if self.colour is None:
  262.             colour = '?'
  263.         else:
  264.             colour = 'w'
  265.         if self.autoStart:
  266.             automatic = 't'
  267.         else:
  268.             automatic = 'f'
  269.         if self.checkFormula:
  270.             formulaChecked = 't'
  271.         else:
  272.             formulaChecked = 'f'
  273.         return '<s> %i w=%s ti=%02X rt=%i t=%i i=%i r=%s tp=%s c=%s rr=%i-%i a=%s f=%s' % (self.number, self.client.name, self.client.titles, self.client.rating, self.time, self.inc, rated, self.getVariant(), colour, self.minRating, self.maxRating, automatic, formulaChecked)
  274.  
  275.  
  276.  
  277. class Client:
  278.     '''
  279.     '''
  280.     buffer = ''
  281.     name = None
  282.     rating = 0
  283.     titles = 0
  284.     TITLE_UNREGISTERED = 1
  285.     TITLE_COMPUTER = 2
  286.     TITLE_GRAND_MASTER = 4
  287.     TITLE_INTERNATIONAL_MASTER = 8
  288.     TITLE_FIDE_MASTER = 16
  289.     TITLE_WOMAN_GRAND_MASTER = 32
  290.     TITLE_WOMAN_INTERNATIONAL_MASTER = 64
  291.     TITLE_WOMAN_FIDE_MASTER = 128
  292.     LOGIN_SCREEN = 'MINI-FICS SERVER\n'
  293.     STATE_LOGIN = 'LOGIN'
  294.     STATE_PASSWORD = 'PASSWORD'
  295.     STATE_NULL_PASSWORD = 'NULL_PASSWORD'
  296.     STATE_POST_LOGIN = 'POST_LOGIN'
  297.     STATE_MAIN = 'MAIN'
  298.     STATE_GAME = 'GAME'
  299.     state = STATE_LOGIN
  300.     
  301.     def __init__(self, server, connection):
  302.         '''
  303.         '''
  304.         self.server = server
  305.         self.connection = connection
  306.         self.adverts = { }
  307.         self.telnetDecoder = TelnetDecoder(self)
  308.  
  309.     
  310.     def checkPassword(self, user, password):
  311.         '''
  312.         '''
  313.         return True
  314.  
  315.     
  316.     def registerIncomingData(self, data):
  317.         '''
  318.         '''
  319.         self.telnetDecoder.registerIncomingData(data)
  320.  
  321.     
  322.     def _processData(self, data):
  323.         '''
  324.         '''
  325.         self.buffer += data
  326.         while True:
  327.             index = self.buffer.find('\n')
  328.             if index < 0:
  329.                 return None
  330.             line = self.buffer[:index]
  331.             self.buffer = self.buffer[index + 1:]
  332.             self.processLine(line)
  333.             continue
  334.             None if line[-1] == '\r' else self
  335.  
  336.     
  337.     def send(self, data):
  338.         self.server.onOutgoingData(self.connection, data)
  339.  
  340.     
  341.     def start(self):
  342.         '''
  343.         '''
  344.         self.send(self.LOGIN_SCREEN)
  345.         self.setState(self.STATE_LOGIN)
  346.  
  347.     
  348.     def setState(self, state):
  349.         if state is self.STATE_LOGIN:
  350.             self.send('login: ')
  351.         elif state is self.STATE_PASSWORD:
  352.             self.send('password: ')
  353.         elif state is self.STATE_POST_LOGIN:
  354.             self.send('**** Starting FICS session as %s ****\n' % self.name)
  355.             self.send('<sc>\n')
  356.             for ad in self.server.adverts.itervalues():
  357.                 self.send(ad.genSeekMessage() + '\n')
  358.             
  359.         elif state is self.STATE_MAIN:
  360.             self.sendPrompt()
  361.         
  362.         self.state = state
  363.  
  364.     
  365.     def sendPrompt(self):
  366.         self.send('fics% ')
  367.  
  368.     
  369.     def generateGuestLogin(self):
  370.         while True:
  371.             name = 'Guest'
  372.             for i in xrange(4):
  373.                 name += random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  374.             
  375.             if not self.server.clientsByUserName.has_key(name):
  376.                 break
  377.                 continue
  378.         return name
  379.  
  380.     
  381.     def processLine(self, line):
  382.         state = self.state
  383.         if state is self.STATE_LOGIN:
  384.             if line == '':
  385.                 self.setState(self.STATE_LOGIN)
  386.             elif line == 'guest':
  387.                 self.name = self.generateGuestLogin()
  388.                 self.send('Press return to enter the server as "%s":\n' % self.name)
  389.                 self.setState(self.STATE_NULL_PASSWORD)
  390.             elif line.isalpha():
  391.                 self.name = line
  392.                 self.setState(self.STATE_PASSWORD)
  393.             else:
  394.                 self.send('Sorry, names can only consist of lower and upper case letters.  Try again.\n')
  395.                 self.setState(self.STATE_LOGIN)
  396.         elif state is self.STATE_NULL_PASSWORD:
  397.             self.server.clientsByUserName[self.name] = self
  398.             self.setState(self.STATE_POST_LOGIN)
  399.             self.setState(self.STATE_MAIN)
  400.         elif state is self.STATE_PASSWORD:
  401.             if self.checkPassword(self.name, line):
  402.                 self.server.clientsByUserName[self.name] = self
  403.                 self.setState(self.STATE_POST_LOGIN)
  404.                 self.setState(self.STATE_MAIN)
  405.             else:
  406.                 self.setState(self.STATE_LOGIN)
  407.         elif state is self.STATE_MAIN:
  408.             args = line.split(None, 1)
  409.             if len(args) > 0:
  410.                 command = args[0]
  411.                 if len(args) == 1:
  412.                     line = ''
  413.                 else:
  414.                     line = args[1]
  415.                 self.processCommand(command, line)
  416.             
  417.             self.setState(self.STATE_MAIN)
  418.         
  419.  
  420.     
  421.     def processCommand(self, command, line):
  422.         args = line.split()
  423.         if command == 'quit' and len(args) == 0:
  424.             self.quit()
  425.         elif command == 'sought':
  426.             for ad in self.server.adverts.itervalues():
  427.                 self.send(ad.genSoughtLine() + '\n')
  428.             
  429.             if len(self.server.adverts) == 1:
  430.                 self.send('1 ad displayed.\n')
  431.             else:
  432.                 self.send('%i ads displayed.\n' % len(self.server.adverts))
  433.         elif command == 'match' and len(args) == 1:
  434.             user = args[0]
  435.             
  436.             try:
  437.                 client = self.server.clientsByUserName[user]
  438.             except KeyError:
  439.                 pass
  440.  
  441.             advert = Challenge(self)
  442.             advertLine = '?'
  443.             self.send('Issuing: %s.' % advertLine)
  444.             client.send('\n')
  445.             client.send('Challenge: %s.\n' % advertLine)
  446.             client.send('You can "accept" or "decline", or propose different parameters.\n')
  447.             client.sendPrompt()
  448.         elif command == 'accept' and len(args) == 0:
  449.             pass
  450.         elif command == 'decline' and len(args) == 0:
  451.             pass
  452.         elif command == 'seek':
  453.             for arg in args:
  454.                 pass
  455.             
  456.             advert = self.server.addAdvert(self)
  457.             notifyLine = '\n' + advert.genSeekMessage() + '\n'
  458.             for client in self.server.clients.itervalues():
  459.                 if client.name is None:
  460.                     continue
  461.                 
  462.                 client.send(notifyLine)
  463.                 client.sendPrompt()
  464.             
  465.         elif command == 'play' and len(args) == 1:
  466.             
  467.             try:
  468.                 advert = self.server.adverts[int(args[0])]
  469.             except ValueError:
  470.                 user = args[0]
  471.                 
  472.                 try:
  473.                     client = self.server.clientsByUserName[user]
  474.                 except KeyError:
  475.                     self.send('%s is not logged in.\n' % user)
  476.                     return None
  477.  
  478.                 advert = None
  479.             except KeyError:
  480.                 self.send('That seek is not available.\n')
  481.                 return None
  482.  
  483.             client = advert.client
  484.             self.server.removeAdverts([
  485.                 advert])
  486.             game = self.server.addGame(self, client)
  487.         elif command == 'tell' or command == 't':
  488.             (user, text) = line.split(None, 1)
  489.             if user.isalpha():
  490.                 
  491.                 try:
  492.                     client = self.server.clientsByUserName[user]
  493.                 except KeyError:
  494.                     self.send('%s is not logged in.\n' % user)
  495.  
  496.                 self.send('(told %s)\n' % user)
  497.                 client.send('\n')
  498.                 client.send('%s(U) tells you: %s\n' % (self.name, text))
  499.             else:
  500.                 self.send('%s is not a valid handle.\n' % repr(user))
  501.             self.sendPrompt()
  502.         elif command == 'say':
  503.             text = line
  504.         else:
  505.             self.send('%s: Command not found.\n' % command)
  506.  
  507.  
  508. if __name__ == '__main__':
  509.     
  510.     class Connection:
  511.         
  512.         def __init__(self, server, socket):
  513.             self.server = server
  514.             self.socket = socket
  515.  
  516.         
  517.         def read(self):
  518.             (data, _) = self.socket.recvfrom(65535)
  519.             if len(data) == 0:
  520.                 self.abort()
  521.             else:
  522.                 print repr(data)
  523.                 self.server.registerIncomingData(self, data)
  524.  
  525.         
  526.         def quit(self):
  527.             pass
  528.  
  529.         
  530.         def abort(self):
  531.             self.server.fds.remove(self.socket.fileno())
  532.             self.server.connections.pop(self.socket.fileno())
  533.             self.socket.close()
  534.  
  535.  
  536.     
  537.     class S(Server):
  538.         
  539.         def __init__(self):
  540.             self.connections = { }
  541.             self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  542.             
  543.             try:
  544.                 self.socket.bind(('', 6666))
  545.             except socket.error:
  546.                 self.socket.bind(('', 6667))
  547.  
  548.             self.socket.listen(10)
  549.             self.fds = [
  550.                 self.socket.fileno()]
  551.             Server.__init__(self)
  552.  
  553.         
  554.         def onOutgoingData(self, connection, data):
  555.             connection.socket.send(data)
  556.  
  557.         
  558.         def run(self):
  559.             import select
  560.             while True:
  561.                 print '!'
  562.                 (fds, _, _) = select.select(self.fds, [], [])
  563.                 print fds
  564.                 for fd in fds:
  565.                     if fd == self.socket.fileno():
  566.                         
  567.                         try:
  568.                             (s, _) = self.socket.accept()
  569.                         except socket.error:
  570.                             e = None
  571.                             print e
  572.  
  573.                         self.fds.append(s.fileno())
  574.                         c = Connection(self, s)
  575.                         self.connections[s.fileno()] = c
  576.                         self.addConnection(c)
  577.                         continue
  578.                     c = self.connections[fd]
  579.                     c.read()
  580.                 
  581.  
  582.  
  583.     s = S()
  584.     s.run()
  585.  
  586.