forked from Ganapati/Simple-Game-Server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rooms.py
201 lines (163 loc) · 5 KB
/
rooms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
import uuid
from player import Player
class Rooms:
def __init__(self, capacity=2):
"""
Handle rooms and set maximum rooms capacity
"""
self.rooms = {}
self.players = {}
self.room_capacity = capacity
def register(self, addr, udp_port):
"""
Register player
"""
player = None
for registered_player in self.players.values():
if registered_player.addr == addr:
player = registered_player
player.udp_addr((addr[0], udp_port))
break
if player is None:
player = Player(addr, udp_port)
self.players[player.identifier] = player
return player
def join(self, player_identifier, room_id=None):
"""
Add player to room
"""
if player_identifier not in self.players:
raise ClientNotRegistered()
player = self.players[player_identifier]
if room_id is None:
for room_id in self.rooms.keys():
if not self.rooms[room_id].is_full():
self.rooms[room_id].players.append(player)
return room_id
break
room_id = self.create()
self.join(player_identifier, room_id)
return room_id
elif room_id in self.rooms:
if not self.rooms[room_id].is_full():
self.rooms[room_id].players.append(player)
return room_id
else:
raise RoomFull()
else:
raise RoomNotFound()
def leave(self, player_identifier, room_id):
"""
Remove a player from a room
"""
if player_identifier not in self.players:
raise ClientNotRegistered()
player = self.players[player_identifier]
if room_id in self.rooms:
self.rooms[room_id].leave(player)
else:
raise RoomNotFound()
def create(self, room_name=None):
"""
Create a new room
"""
identifier = str(uuid.uuid4())
self.rooms[identifier] = Room(identifier,
self.room_capacity,
room_name)
return identifier
def remove_empty(self):
"""
Delete empty rooms
"""
for room_id in list(self.rooms.keys()):
if self.rooms[room_id].is_empty():
del self.rooms[room_id]
def send(self, identifier, room_id, message, sock):
"""
Send data to all players in room, except sender
"""
if room_id not in self.rooms:
raise RoomNotFound()
room = self.rooms[room_id]
if not room.is_in_room(identifier):
raise NotInRoom()
for player in room.players:
if player.identifier != identifier:
player.send_udp(identifier, message)
def sendto(self, identifier, room_id, recipients, message, sock):
"""
Send data to specific player(s)
"""
if room_id not in self.rooms:
raise RoomNotFound()
room = self.rooms[room_id]
if not room.is_in_room(identifier):
raise NotInRoom()
if isinstance(recipients, str):
recipients = [recipients]
for player in room.players:
if player.identifier in recipients:
player.send_udp(identifier, message)
class Room:
def __init__(self, identifier, capacity, room_name):
"""
Create a new room on server
"""
self.capacity = capacity
self.players = []
self.identifier = identifier
if room_name is not None:
self.name = room_name
else:
self.name = self.identifier
def join(self, player):
"""
Add player to room
"""
if not self.is_full():
self.players.append(player)
else:
raise RoomFull()
def leave(self, player):
"""
Remove player from room
"""
if player in self.players:
self.players.remove(player)
else:
raise NotInRoom()
def is_empty(self):
"""
Check if room is empty or not
"""
if len(self.players) == 0:
return True
else:
return False
def is_full(self):
"""
Check if room is full or not
"""
if len(self.players) == self.capacity:
return True
else:
return False
def is_in_room(self, player_identifier):
"""
Check if player is in room
"""
in_room = False
for player in self.players:
if player.identifier == player_identifier:
in_room = True
break
return in_room
class RoomFull(Exception):
pass
class RoomNotFound(Exception):
pass
class NotInRoom(Exception):
pass
class ClientNotRegistered(Exception):
pass