1 """
2 Server request response.
3 """
4
5 from struct import unpack_from, pack, calcsize
6
7 from lacewing.constants import RESPONSES, DENY_REASONS, DENIALS
8 from lacewing.baseloader import _BaseLoader
9
11 """
12 The Response packet is sent from the server to reply to an earlier
13 request by the client.
14 It might have been either denied or accepted.
15
16 Use the methods to manipulate the properties (if available).
17
18 @ivar channelId: The channel ID of the granted channel.
19 @ivar channelName: The channel name of the granted channel.
20 @ivar playerName: The selected client name.
21 """
22
23 response = None
24 denyReason = None
25 channelId = None
26 channelName = None
27 playerName = None
28 playerId = None
29 extensions = None
30
31 - def read(self, data):
32 self.response, = unpack_from('<B', data)
33 if self.isDenial():
34 self.denyReason, = unpack_from('<B', data, 1)
35 return
36 response = self.getResponse()
37 if response in ('ChannelJoined', 'ChannelCreated'):
38 self.channelId, = unpack_from('<H', data, 1)
39 self.channelName = str(buffer(data, 3))
40 elif response == 'ChannelLeft':
41 self.channelId, = unpack_from('<H', data, 1)
42 elif response == 'ConnectionAccepted':
43 self.playerId, = unpack_from('<H', data, 1)
44 self.extensions = extensions = {}
45 for item in data[3:].split('\x00'):
46 if not item:
47 continue
48 extensions[unpack_from('<B', item[0])] = item[1:]
49 elif response == 'NameAccepted':
50 self.playerName = str(buffer(data, 1))
51
53 """
54 Get the server deny reason.
55 @return: See L{denyReason}.
56 @rtype: str
57 """
58 reason = DENY_REASONS[self.denyReason]
59 return reason
60
62 """
63 Set the server deny reason.
64 @param reason: See L{denyReason}.
65 """
66 self.denyReason = DENY_REASONS.index(reason)
67 return
68
70 """
71 Returns the response as string.
72 @return: See L{RESPONSES}.
73 """
74 return RESPONSES[self.response]
75
77 """
78 Returns False if the response is a denial
79 """
80 return self.getResponse() in DENIALS
81
83 """
84 Set the response from string.
85 @param response: See L{RESPONSES}
86 """
87 self.response = RESPONSES.index(response)
88
90 if self.isDenial():
91 return pack('<BB', self.response, self.denyReason)
92 response = self.getResponse()
93 if response in ('ChannelJoined','ChannelCreated'):
94 data = pack('<BH', self.response, self.channelId)
95 return data + self.channelName
96 elif response == 'ChannelLeft':
97 return pack('<BH', self.response, self.channelId)
98 elif response == 'ConnectionAccepted':
99 data = ''
100 if self.extensions:
101 for k, v in self.extensions.iteritems():
102 data += pack('<B', k) + v + '\x00'
103 return pack('<BH', self.response, self.playerId) + data
104 elif response == 'NameAccepted':
105 data = pack('<B', self.response)
106 return data + self.playerName
107 return pack('<B', self.response)
108
109 __all__ = ['Response']
110