2010-08-18 15:46:58 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
|
|
|
|
# See LICENSE.txt for copyright info
|
|
|
|
|
2011-01-22 21:38:06 +00:00
|
|
|
from twisted.internet.defer import Deferred, succeed
|
2010-08-18 15:46:58 +00:00
|
|
|
from twisted.internet.protocol import ServerFactory
|
|
|
|
from twisted.protocols.policies import TimeoutMixin
|
|
|
|
from twisted.internet.task import LoopingCall
|
|
|
|
from twisted.python import log
|
|
|
|
from frn.user import FRNUser
|
2010-08-21 15:32:22 +00:00
|
|
|
from frn.clienttracker import ClientTracker
|
2010-08-18 15:46:58 +00:00
|
|
|
from frn.protocol import versions
|
|
|
|
from frn.protocol.common import BufferingLineReceiver
|
|
|
|
from frn.utility import *
|
|
|
|
|
|
|
|
|
|
|
|
class FRNServer(BufferingLineReceiver, TimeoutMixin):
|
|
|
|
|
2010-08-25 08:10:43 +00:00
|
|
|
PING_PERIOD = 0.5
|
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def connectionMade(self):
|
|
|
|
BufferingLineReceiver.connectionMade(self)
|
|
|
|
log.msg("Connection from %s" % self.transport.getPeer().host)
|
|
|
|
self.clientAddress = self.transport.getPeer()
|
|
|
|
self.user = None
|
|
|
|
self.role = None
|
|
|
|
self.kp = makeRandomChallange()
|
|
|
|
self.waitingKey = False
|
|
|
|
self.pingTimer = LoopingCall(self.sendPing)
|
|
|
|
self.setTimeout(25.0)
|
|
|
|
|
|
|
|
def connectionLost(self, reason):
|
|
|
|
log.msg("Client disconnected: %s" % self.clientAddress.host)
|
2011-01-30 01:29:31 +00:00
|
|
|
self.disconnect()
|
2010-08-18 15:46:58 +00:00
|
|
|
BufferingLineReceiver.connectionLost(self, reason)
|
|
|
|
|
2011-01-30 01:29:31 +00:00
|
|
|
def timeoutConnection(self):
|
|
|
|
log.msg("Client dead: disconnecting %s" % self.user)
|
|
|
|
self.disconnect()
|
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def lineReceived(self, line):
|
|
|
|
self.resetTimeout()
|
|
|
|
sline = line.strip()
|
|
|
|
if self.waitingKey:
|
|
|
|
if responseToChallange(self.kp) != sline:
|
2011-01-30 01:29:31 +00:00
|
|
|
self.disconnect()
|
2010-08-18 15:46:58 +00:00
|
|
|
return
|
|
|
|
else:
|
|
|
|
self.waitingKey = False
|
2010-08-21 15:32:22 +00:00
|
|
|
self.factory.tracker.login(self)
|
2010-08-18 15:46:58 +00:00
|
|
|
if self.role in ['OWNER', 'ADMIN']:
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendMuteList(self.factory.tracker.getMuteList())
|
|
|
|
self.sendBlockList(self.factory.tracker.getBlockList())
|
2010-08-18 15:46:58 +00:00
|
|
|
if self.role == 'OWNER':
|
2010-10-16 11:57:47 +00:00
|
|
|
self.sendAdminList(self.factory.tracker.getAdminList())
|
2010-10-31 22:08:32 +00:00
|
|
|
ac, tx = self.factory.tracker.getAclFlags(self.user.NT)
|
|
|
|
self.sendAccessFlags(ac,tx)
|
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
if self.role not in ['OK', 'ADMIN', 'OWNER']:
|
2011-01-30 01:29:31 +00:00
|
|
|
self.disconnect()
|
2010-10-31 22:08:32 +00:00
|
|
|
return
|
2010-08-24 13:56:37 +00:00
|
|
|
self.startPinging()
|
2010-08-18 15:46:58 +00:00
|
|
|
self.setTimeout(10.0)
|
|
|
|
return
|
|
|
|
if sline == 'P': # Pong
|
|
|
|
#log.msg('Pong')
|
|
|
|
return
|
|
|
|
if sline in ['RX0', 'TX0', 'TX1']:
|
|
|
|
command, body = sline[:2], sline[2:]
|
|
|
|
else:
|
|
|
|
command, body = sline.split(':', 1)
|
|
|
|
if command != 'CT' and self.user is None:
|
2011-01-30 01:29:31 +00:00
|
|
|
self.disconnect()
|
2010-08-18 15:46:58 +00:00
|
|
|
return
|
|
|
|
handler = getattr(self, 'decode'+command, None)
|
|
|
|
if body[0] == '<' and body[-1] == '>':
|
|
|
|
body = parseSimpleXML(body)
|
|
|
|
if handler is not None:
|
|
|
|
handler(body)
|
|
|
|
else:
|
|
|
|
self.unimplemented(command, body)
|
2010-08-21 15:32:22 +00:00
|
|
|
#self.transport.loseConnection() # ???
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def expectedReceived(self, data):
|
|
|
|
self.resetTimeout()
|
|
|
|
self.setLineMode()
|
|
|
|
self.audioFrameReceived(data)
|
|
|
|
|
|
|
|
def unimplemented(self, command, body):
|
|
|
|
log.err("Unimplemented message: %s: %s" % (command, body))
|
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def getIndex(self):
|
2010-08-22 08:57:39 +00:00
|
|
|
return self.factory.tracker.getClientIndex(self.user.ID)
|
2010-08-21 15:32:22 +00:00
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def authenticate(self, user):
|
|
|
|
def loginReturned(userId):
|
2010-08-21 15:32:22 +00:00
|
|
|
if userId not in ['WRONG', 'DUPL']:
|
|
|
|
if self.factory.tracker.isBlocked(userId):
|
|
|
|
return ("BLOCK", userId)
|
2010-08-18 15:46:58 +00:00
|
|
|
return ("OK", userId) # FIXME: return OWNER or ADMIN eventually
|
|
|
|
else:
|
2010-08-21 15:32:22 +00:00
|
|
|
return (userId, "")
|
2010-08-18 15:46:58 +00:00
|
|
|
user.IP = self.clientAddress.host
|
2011-01-22 21:38:06 +00:00
|
|
|
if self.factory.tracker.canLogin(user):
|
2011-01-30 14:59:29 +00:00
|
|
|
return self.factory.manager.clientLogin(self.factory.serverAuth, user).addCallback(loginReturned)
|
2011-01-22 21:38:06 +00:00
|
|
|
else:
|
|
|
|
log.msg("BLOCK %s" % repr(user))
|
|
|
|
return succeed(("BLOCK", ""))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def disconnect(self):
|
2011-01-30 01:29:31 +00:00
|
|
|
self.stopPinging()
|
|
|
|
if self.user is not None:
|
2011-01-30 14:59:29 +00:00
|
|
|
log.msg("Logging out client %s" % self.user)
|
|
|
|
self.factory.manager.clientLogout(self.factory.serverAuth, self.user)
|
|
|
|
self.factory.tracker.logout(self)
|
2011-02-20 11:14:09 +00:00
|
|
|
if self.factory.talking.get(self.user.NT) == self:
|
|
|
|
del self.factory.talking[self.user.NT]
|
2011-01-30 14:59:29 +00:00
|
|
|
self.transport.loseConnection()
|
2010-08-21 15:32:22 +00:00
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def decodeCT(self, body):
|
|
|
|
def authReturned(result):
|
|
|
|
self.role, clientId = result
|
|
|
|
log.msg("AUTH result: %s %s" % (self.role, clientId))
|
2010-08-21 18:32:56 +00:00
|
|
|
self.user = FRNUser(**body)
|
|
|
|
self.user.ID = clientId
|
2010-08-18 15:46:58 +00:00
|
|
|
if self.role == 'OK':
|
|
|
|
if self.user.EA == self.factory.serverAuth.OW:
|
|
|
|
self.role = 'OWNER'
|
2010-10-31 22:08:32 +00:00
|
|
|
log.msg("%s promoted to OWNER" % clientId)
|
2010-08-28 17:54:25 +00:00
|
|
|
elif self.factory.tracker.isAdmin(self.user.ID):
|
2010-08-18 15:46:58 +00:00
|
|
|
self.role = 'ADMIN'
|
2010-10-31 22:08:32 +00:00
|
|
|
log.msg("%s promoted to ADMIN" % clientId)
|
2010-08-18 15:46:58 +00:00
|
|
|
if versions.server > 2009004:
|
|
|
|
self.waitingKey = True
|
|
|
|
self.sendLine(str(versions.client))
|
|
|
|
self.factory.serverAuth.update(MT='', SV=versions.server,
|
|
|
|
AL=self.role, KP=self.kp)
|
2010-09-07 21:50:14 +00:00
|
|
|
if self.role == 'DUPL':
|
|
|
|
self.factory.serverAuth.AL = 'BLOCK' # TODO: verify other results
|
2010-08-18 15:46:58 +00:00
|
|
|
self.sendLine(
|
|
|
|
self.factory.serverAuth.asXML('MT','SV','AL','BN','BP','KP'))
|
|
|
|
if self.role not in ['OK', 'OWNER', 'ADMIN']:
|
2011-01-30 01:29:31 +00:00
|
|
|
self.disconnect()
|
2010-08-24 13:56:37 +00:00
|
|
|
else:
|
2010-08-29 08:10:07 +00:00
|
|
|
self.sendNetworkList(self.factory.tracker.getNetworkList())
|
2010-08-29 08:27:53 +00:00
|
|
|
self.transport.setTcpNoDelay(True)
|
2010-08-24 13:56:37 +00:00
|
|
|
self.startPinging()
|
2010-08-18 15:46:58 +00:00
|
|
|
return self.authenticate(FRNUser(**body)).addCallback(
|
|
|
|
authReturned)
|
|
|
|
|
2010-08-24 13:56:37 +00:00
|
|
|
def startPinging(self):
|
|
|
|
if not self.pingTimer.running:
|
2010-08-25 08:10:43 +00:00
|
|
|
self.pingTimer.start(self.PING_PERIOD, True)
|
2010-08-24 13:56:37 +00:00
|
|
|
|
|
|
|
def stopPinging(self):
|
|
|
|
if self.pingTimer.running:
|
|
|
|
self.pingTimer.stop()
|
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def decodeRX(self, body):
|
|
|
|
log.msg("RX%d" % int(body))
|
2010-08-24 13:56:37 +00:00
|
|
|
self.startPinging()
|
2011-02-20 11:14:09 +00:00
|
|
|
if self.factory.talking.get(self.user.NT) == self:
|
|
|
|
del self.factory.talking[self.user.NT]
|
2010-08-24 13:56:37 +00:00
|
|
|
for c in self.factory.tracker.getClientList(self.user.NT):
|
|
|
|
cp = self.factory.tracker.getClientProtocol(c.ID).startPinging()
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def decodeST(self, body):
|
|
|
|
log.msg("Set status = %d" % int(body))
|
2010-09-06 21:26:46 +00:00
|
|
|
if int(body) > 1:
|
|
|
|
self.startPinging()
|
2010-08-21 15:32:22 +00:00
|
|
|
self.factory.tracker.setStatus(self.user.ID, int(body))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def decodeTM(self, body):
|
|
|
|
log.msg("TM: %s" % str(body))
|
2011-01-30 14:59:29 +00:00
|
|
|
if body['ID'] == '':
|
2010-08-18 15:46:58 +00:00
|
|
|
msgtype = 'A'
|
|
|
|
else:
|
|
|
|
msgtype = 'P'
|
2010-08-21 15:32:22 +00:00
|
|
|
for c in self.factory.tracker.getClientList(self.user.NT):
|
2011-01-30 14:59:29 +00:00
|
|
|
if msgtype == 'A' or c.ID == body['ID']:
|
2010-08-24 13:56:37 +00:00
|
|
|
if c.ID != self.user.ID or msgtype == 'A':
|
2010-08-21 15:32:22 +00:00
|
|
|
client = self.factory.tracker.getClientProtocol(c.ID)
|
2011-01-30 14:59:29 +00:00
|
|
|
client.sendTextMessage(self.user.ID, body['MS'], msgtype)
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def decodeTX(self, body):
|
2010-08-21 15:32:22 +00:00
|
|
|
if body == '0':
|
|
|
|
if not self.factory.tracker.isMute(self.user.ID):
|
2011-02-20 11:14:09 +00:00
|
|
|
if not self.factory.talking.get(self.user.NT):
|
|
|
|
self.factory.talking[self.user.NT] = self
|
2011-02-20 10:18:04 +00:00
|
|
|
ih,il = divmod(self.getIndex(), 256)
|
|
|
|
self.transport.write(chr(1)+chr(ih)+chr(il))
|
2010-08-18 15:46:58 +00:00
|
|
|
elif body == '1':
|
2010-08-24 13:56:37 +00:00
|
|
|
self.stopPinging()
|
2010-08-18 15:46:58 +00:00
|
|
|
self.expectRawData(325)
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeMC(self, body):
|
|
|
|
if self.role in ["OWNER","ADMIN"]:
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.mute(self.user, body['IP'])
|
|
|
|
if self.factory.tracker.isLoggedIn(body['IP']):
|
|
|
|
self.factory.tracker.getClientProtocol(body['IP']).decodeRX('0')
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeUM(self, body):
|
|
|
|
if self.role in ["OWNER","ADMIN"]:
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.unMute(body['IP'])
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeBC(self, body):
|
|
|
|
if self.role in ["OWNER","ADMIN"]:
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.block(self.user, body['IP'])
|
|
|
|
self.factory.tracker.getClientProtocol(body['IP']).disconnect()
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeUC(self, body):
|
|
|
|
if self.role in ["OWNER","ADMIN"]:
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.unBlock(body['IP'])
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeAA(self, body):
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.admin(body['IP'])
|
2010-08-21 15:32:22 +00:00
|
|
|
|
|
|
|
def decodeDA(self, body):
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.unAdmin(body['IP'])
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-10-31 22:08:32 +00:00
|
|
|
def decodeETX(self, body):
|
|
|
|
log.msg("decodeETX(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.setAclTx(self.user.NT, body['EA'], True)
|
2010-10-31 22:08:32 +00:00
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
|
|
|
def decodeRTX(self, body):
|
|
|
|
log.msg("decodeRTX(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.setAclTx(self.user.NT, body['EA'], False)
|
2010-10-31 22:08:32 +00:00
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
|
|
|
def decodeDT(self, body):
|
|
|
|
log.msg("decodeDT(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.delAcl(self.user.NT, body['EA'])
|
2010-10-31 22:08:32 +00:00
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
|
|
|
def decodeAT(self, body):
|
|
|
|
log.msg("decodeAT(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
2011-01-30 14:59:29 +00:00
|
|
|
self.factory.tracker.addAcl(self.user.NT, body['EA'])
|
2010-10-31 22:08:32 +00:00
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
|
|
|
def decodeTXR(self, body):
|
|
|
|
log.msg("decodeTXR(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
|
|
|
en, _ = self.factory.tracker.getAclFlags(self.user.NT)
|
|
|
|
tx = body == '1'
|
|
|
|
self.factory.tracker.setAclFlags(self.user.NT, en, tx)
|
|
|
|
en,tx = self.factory.tracker.getAclFlags(self.user.NT)
|
|
|
|
self.sendAccessFlags(en, tx)
|
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
|
|
|
def decodeENA(self, body):
|
|
|
|
log.msg("decodeENA(%s)" % str(body))
|
|
|
|
if self.role == "OWNER":
|
|
|
|
_, tx = self.factory.tracker.getAclFlags(self.user.NT)
|
|
|
|
en = body == '1'
|
|
|
|
self.factory.tracker.setAclFlags(self.user.NT, en, tx)
|
|
|
|
en,tx = self.factory.tracker.getAclFlags(self.user.NT)
|
|
|
|
self.sendAccessFlags(en, tx)
|
|
|
|
self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
|
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
def audioFrameReceived(self, frame):
|
2010-08-21 15:32:22 +00:00
|
|
|
#log.msg("audioFrameReceived")
|
2011-02-20 11:14:09 +00:00
|
|
|
if self.factory.tracker.canTalk(self.user.ID) and self.factory.talking.get(self.user.NT) == self:
|
2010-08-21 15:32:22 +00:00
|
|
|
clientIdx = self.getIndex()
|
|
|
|
for c in self.factory.tracker.getClientList(self.user.NT):
|
|
|
|
if int(c.S) < 2 and c.ID != self.user.ID:
|
|
|
|
#log.msg("Sending to %s" % c.ON)
|
|
|
|
self.factory.tracker.getClientProtocol(c.ID).sendAudioFrame(clientIdx, frame)
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def sendPing(self):
|
|
|
|
self.transport.write(chr(0))
|
|
|
|
|
|
|
|
def sendClientList(self, clients):
|
|
|
|
self.transport.write(chr(3)+chr(0)+chr(0))
|
|
|
|
self.sendLine(str(len(clients)))
|
|
|
|
for client in clients:
|
|
|
|
self.sendLine(client.asXML(
|
|
|
|
'S','M','NN','CT','BC','ON','ID','DS'
|
|
|
|
))
|
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendNetworkList(self, networks):
|
2010-08-18 15:46:58 +00:00
|
|
|
log.msg("Send network list")
|
|
|
|
self.transport.write(chr(5))
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(str(len(networks)))
|
|
|
|
for net in networks:
|
2010-08-18 15:46:58 +00:00
|
|
|
self.sendLine(net)
|
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendMuteList(self, clients):
|
|
|
|
log.msg("Sending mute list to %s: %s" % (self.user.ON, str(clients)))
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(9))
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(str(len(clients)))
|
|
|
|
for c in clients:
|
|
|
|
self.sendLine(c.asXML('AI','NN','CT','BC','ON','ID'))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendBlockList(self, clients):
|
|
|
|
log.msg("Sending block list to %s: %s" % (self.user.ON, str(clients)))
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(8))
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(str(len(clients)))
|
|
|
|
for c in clients:
|
|
|
|
self.sendLine(c.asXML('AI','NN','CT','BC','ON','ID'))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendAdminList(self, clients):
|
|
|
|
log.msg("Sending admin list to %s: %s" % (self.user.ON, str(clients)))
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(6))
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(str(len(clients)))
|
|
|
|
for c in clients:
|
|
|
|
self.sendLine(c.asXML('NN','CT','BC','ON','ID'))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendAccessList(self, clients):
|
2010-10-31 22:08:32 +00:00
|
|
|
log.msg("Sending ACL to %s: %s" % (self.user.ON, str(clients)))
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(7))
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(str(len(clients)))
|
2011-01-30 01:29:31 +00:00
|
|
|
for c in clients:
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendLine(c.asXML('AI','NN','CT','BC','ON','ID'))
|
2010-08-18 15:46:58 +00:00
|
|
|
|
2010-10-31 22:08:32 +00:00
|
|
|
def sendAccessFlags(self, access, talk):
|
|
|
|
log.msg("Sending ACL flags to %s: %s" % (self.user.ON, str((access, talk))))
|
|
|
|
FV = {True: '1', False: 'o'}
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(10))
|
2011-01-30 01:29:31 +00:00
|
|
|
self.sendLine('2')
|
2010-10-31 22:08:32 +00:00
|
|
|
self.sendLine(FV[access])
|
|
|
|
self.sendLine(FV[talk])
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def sendTextMessage(self, clientId, message, target):
|
|
|
|
self.transport.write(chr(4))
|
|
|
|
self.sendLine('3')
|
|
|
|
self.sendLine(clientId)
|
|
|
|
self.sendLine(message)
|
|
|
|
self.sendLine(target)
|
|
|
|
|
|
|
|
def sendAudioFrame(self, clientIdx, frame):
|
2010-08-24 13:56:37 +00:00
|
|
|
self.stopPinging()
|
2010-08-18 15:46:58 +00:00
|
|
|
ih,il = divmod(clientIdx, 256)
|
2010-08-24 13:56:37 +00:00
|
|
|
self.transport.write(chr(2))
|
2010-08-18 15:46:58 +00:00
|
|
|
self.transport.write(chr(ih)+chr(il))
|
|
|
|
self.transport.write(frame)
|
|
|
|
|
|
|
|
|
|
|
|
class FRNServerFactory(ServerFactory):
|
|
|
|
|
|
|
|
protocol = FRNServer
|
|
|
|
|
2010-08-21 18:32:56 +00:00
|
|
|
def __init__(self, trackerfile, manager, serverAuth):
|
2010-08-18 15:46:58 +00:00
|
|
|
self.manager = manager
|
|
|
|
self.serverAuth = serverAuth
|
2011-02-20 11:14:09 +00:00
|
|
|
self.talking = {}
|
2010-08-18 15:46:58 +00:00
|
|
|
self.officialNets = []
|
2010-08-21 15:32:22 +00:00
|
|
|
self.tracker = ClientTracker(
|
2010-08-21 18:32:56 +00:00
|
|
|
trackerfile,
|
2010-08-21 15:32:22 +00:00
|
|
|
self.sendClientList, self.sendNetworkList,
|
|
|
|
self.sendMuteList, self.sendBlockList,
|
|
|
|
self.sendAdminList)
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
def startFactory(self):
|
|
|
|
ServerFactory.startFactory(self)
|
|
|
|
self.manager.serverLogin(self.serverAuth)
|
|
|
|
|
|
|
|
def stopFactory(self):
|
|
|
|
self.manager.serverLogout(self.serverAuth)
|
|
|
|
ServerFactory.stopFactory(self)
|
|
|
|
|
2010-08-21 15:32:22 +00:00
|
|
|
def sendNetworkList(self, networks):
|
|
|
|
nets = self.officialNets+list(set(networks) - set(self.officialNets))
|
|
|
|
for c in self.tracker.getClientList():
|
|
|
|
self.tracker.getClientProtocol(c.ID).sendNetworkList(nets)
|
|
|
|
|
|
|
|
def sendClientList(self, network, clients):
|
|
|
|
for c in clients:
|
|
|
|
self.tracker.getClientProtocol(c.ID).sendClientList(clients)
|
|
|
|
|
|
|
|
def sendMuteList(self, clients):
|
|
|
|
for c in self.tracker.getClientList():
|
|
|
|
if self.tracker.isAdmin(c.ID) or c.EA == self.serverAuth.OW:
|
|
|
|
self.tracker.getClientProtocol(c.ID).sendMuteList(clients)
|
|
|
|
|
|
|
|
def sendBlockList(self, clients):
|
|
|
|
for c in self.tracker.getClientList():
|
|
|
|
if self.tracker.isAdmin(c.ID) or c.EA == self.serverAuth.OW:
|
|
|
|
self.tracker.getClientProtocol(c.ID).sendBlockList(clients)
|
|
|
|
|
|
|
|
def sendAdminList(self, clients):
|
|
|
|
for c in self.tracker.getClientList():
|
|
|
|
if c.EA == self.serverAuth.OW:
|
|
|
|
self.tracker.getClientProtocol(c.ID).sendAdminList(clients)
|
|
|
|
|
2010-08-18 15:46:58 +00:00
|
|
|
|
|
|
|
# vim: set et ai sw=4 ts=4 sts=4:
|