Package lacewing :: Package moo :: Module client
[frames] | no frames]

Source Code for Module lacewing.moo.client

  1  # Copyright (c) 2011 Mathias Kaerlev. 
  2  # See LICENSE for details. 
  3   
  4  from twisted.internet.protocol import ClientFactory 
  5   
  6  from lacewing.moo.protocol import MooProtocol 
  7   
  8  from lacewing.moo.packet import ServerPacket, ClientPacket 
  9   
 10  from lacewing.moo.packetloaders.server import * 
 11  from lacewing.moo.packetloaders.client import * 
 12   
 13  from lacewing.multidict import MultikeyDict 
 14   
 15  from lacewing.moo.packetloaders.message import * 
 16   
17 -class Player(object):
18 name = None 19 id = None 20 ip = None 21 channel = None 22
23 - def __init__(self, name, id, ip, channel):
24 self.name = name 25 self.id = id 26 self.ip = ip 27 self.channel = channel
28
29 - def isPeer(self):
30 return self.channel.player != self
31
32 - def isMaster(self):
33 return self.channel.getMaster() == self
34
35 - def sendMessage(self, *arg, **kw):
36 self.channel.sendMessage(toClient = self, *arg, **kw)
37
38 -class Channel(object):
39 name = None 40 id = None 41 connection = None 42 player = None 43 connections = None 44 45 masterId = None 46
47 - def __init__(self, name, id, connection):
48 self.name = name 49 self.id = id 50 self.connection = connection 51 52 self.connections = MultikeyDict()
53
54 - def addConnection(self, connection):
56
57 - def removeConnection(self, connection):
58 del self.connections[connection]
59
60 - def sendMessage(self, value, subchannel, type = None, toClient = None):
61 newValue = Message(**self.connection.settings) 62 newValue.type = type or detectType(value) 63 newValue.value = value 64 if toClient: 65 newMessage = PrivateMessage() 66 newMessage.setConnection(toClient) 67 else: 68 newMessage = ToChannelMessage() 69 70 newMessage.setChannel(self) 71 newMessage.message = newValue 72 newMessage.subchannel = subchannel 73 self.connection.sendLoader(newMessage)
74
75 - def setMaster(self, id):
76 self.masterId = id
77
78 - def getMaster(self):
79 if not self.masterId in self.connections: 80 return None 81 return self.connections[self.masterId]
82
83 -class MooClientProtocol(MooProtocol):
84 _sendPacket = ClientPacket 85 _receivePacket = ServerPacket 86 87 motd = None 88 89 playerClass = Player 90
91 - def __init__(self, **settings):
92 self.settings = settings 93 MooProtocol.__init__(self)
94
95 - def loaderReceived(self, loader):
96 if isinstance(loader, MOTD): 97 self.motd = loader.motd 98 self.motdReceived(loader.motd) 99 100 elif isinstance(loader, AssignedID): 101 self.id = loader.playerId 102 103 newName = SetName() 104 newName.setConnection(self) 105 self.sendLoader(newName) 106 107 self.connectionAccepted() 108 109 elif isinstance(loader, ChannelJoined): 110 channelName = loader.channelName 111 channelId = loader.channelId 112 newChannel = Channel(channelName, channelId, self) 113 newPlayer = self.playerClass(loader.playerName, loader.playerId, 114 loader.playerIp, newChannel) 115 newChannel.player = newPlayer 116 newChannel.addConnection(newPlayer) 117 newChannel.setMaster(loader.masterId) 118 self.channels[channelName, channelId] = newChannel 119 self.channelJoined(newChannel) 120 121 elif isinstance(loader, (PlayerExists, PlayerJoined)): 122 playerName = loader.playerName 123 playerId = loader.playerId 124 playerIp = loader.playerIp 125 channel, = self.channels[loader.channelId] 126 newPlayer = self.playerClass(playerName, playerId, playerIp, channel) 127 channel.addConnection(newPlayer) 128 channel.setMaster(loader.masterId) 129 if isinstance(loader, PlayerExists): 130 self.channelUserExists(channel, newPlayer) 131 elif isinstance(loader, PlayerJoined): 132 self.channelUserJoined(channel, newPlayer) 133 134 elif isinstance(loader, FromChannelMessage): 135 if loader.isServer(): 136 self.messageReceived(loader.message, loader.subchannel) 137 else: 138 channel, = self.channels[loader.channelId] 139 player, = channel.connections[loader.playerId] 140 self.channelMessageReceived(channel, player, loader.message, 141 loader.subchannel) 142 143 elif isinstance(loader, PlayerChanged): 144 playerId = loader.playerId 145 playerName = loader.playerName 146 for channel in self.channels.values(): 147 if playerId in channel.connections: 148 player, = channel.connections[playerId] 149 oldName = player.name 150 player.name = playerName 151 if player.isPeer(): 152 self.channelUserChanged(player, oldName, player.name) 153 else: 154 self.nameChanged(channel, oldName, player.name) 155 156 elif isinstance(loader, PlayerLeft): 157 channel, = self.channels[loader.channelId] 158 player, = channel.connections[loader.playerId] 159 if player.isPeer(): 160 channel.removeConnection(player) 161 channel.setMaster(loader.masterId) 162 self.channelUserLeft(channel, player) 163 else: 164 del self.channels[channel] 165 self.channelLeft(channel) 166 167 else: 168 raise NotImplementedError
169 170 # event-like 171
172 - def motdReceived(self, value):
173 """ 174 Called upon receiving the MOTD 175 """
176
177 - def connectionAccepted(self):
178 """ 179 Called when the connection has been accepted, and the 180 client notified. 181 """
182
183 - def messageReceived(self, message, subchannel):
184 """ 185 Called upon receiving a server message 186 187 @type message: L{Message} object 188 """
189
190 - def channelMessageReceived(self, channel, connection, message, subchannel):
191 """ 192 Called when a channel message has been received 193 194 @type message: lacewing.moo.packetloaders.message.Message object 195 """
196
197 - def channelJoined(self, channel):
198 """ 199 Called when the server has accepted a channel join request. 200 @arg channel: The channel the client has joined. 201 """
202
203 - def channelLeft(self, channel):
204 """ 205 Called when the server has accepted a channel leave request. 206 @arg channel: The channel the client has left. 207 """
208
209 - def nameChanged(self, channel, oldName, newName):
210 """ 211 Called when the server has told us we've changed 212 our name 213 """
214
215 - def channelUserJoined(self, channel, client):
216 """ 217 Called when a client has joined the channel. 218 @arg channel: The channel the client has joined. 219 """
220
221 - def channelUserExists(self, channel, client):
222 """ 223 Called when a client exists in the channel. 224 @arg channel: The channel the client exists in. 225 """
226
227 - def channelUserLeft(self, channel, client):
228 """ 229 Called when a client has left the channel. 230 @arg channel: The channel the client has left. 231 """
232
233 - def channelUserChanged(self, client, oldName, newName):
234 """ 235 Called when a client in the channel (including has changed name. 236 """
237 238 # action-like 239
240 - def changeName(self, name):
241 newChange = ChangeName() 242 newChange.newName = name 243 self.sendLoader(newChange)
244
245 - def sendMessage(self, value, subchannel, type = None):
246 """ 247 Sends a message to the other end 248 """ 249 newValue = Message(**self.settings) 250 newValue.type = type or detectType(value) 251 newValue.value = value 252 newMessage = ClientMessage() 253 newMessage.message = newValue 254 newMessage.subchannel = subchannel 255 self.sendLoader(newMessage)
256
257 - def sendChannelMessage(self, channel, *arg, **kw):
258 channel.sendMessage(self, *arg, **kw)
259
260 - def joinChannel(self, channelName):
261 newJoin = JoinChannel() 262 newJoin.channelName = channelName 263 self.sendLoader(newJoin)
264
265 - def leaveChannel(self, channel):
266 newLeave = LeaveChannel() 267 newLeave.setChannel(channel) 268 self.sendLoader(newLeave)
269