multiplayer 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,103 @@
1
+ name
2
+ Nile
3
+ Amazon
4
+ Yangtze
5
+ Mississippi
6
+ Yenisei
7
+ Yellow River
8
+ Ob
9
+ Parana
10
+ Congo
11
+ Amur
12
+ Lena
13
+ Mekong
14
+ Mackenzie
15
+ Niger
16
+ Murray
17
+ Tocantins
18
+ Volga
19
+ Shatt al-Arab
20
+ Madeira
21
+ Purus
22
+ Yukon
23
+ Indus
24
+ Sao Francisco
25
+ Syr Darya
26
+ Salween
27
+ Saint Lawrence
28
+ Rio Grande
29
+ Lower Tunguska
30
+ Brahmaputra
31
+ Danube
32
+ Zambezi
33
+ Vilyuy
34
+ Araguaia
35
+ Nelson
36
+ Paraguay
37
+ Kolyma
38
+ Ganges
39
+ Amu Darya
40
+ Japura
41
+ Ural
42
+ Arkansas
43
+ Colorado
44
+ Dnieper
45
+ Aldan
46
+ Ubangi
47
+ Negro
48
+ Orinoco
49
+ Irtysh
50
+ Xingu
51
+ Salado
52
+ Tigris
53
+ Songhua
54
+ Tapajos
55
+ Don
56
+ Pechora
57
+ Kama
58
+ Liao
59
+ Zeya
60
+ Kasai
61
+ Ohio
62
+ Iriri
63
+ Tarim
64
+ Vitim
65
+ Tunguska
66
+ Euphrates
67
+ Godavari
68
+ Krishna
69
+ Indigirka
70
+ Saskatchewan
71
+ Peace
72
+ Orange
73
+ Olenyok
74
+ Jubba
75
+ Magdalena
76
+ Lomami
77
+ Ogooue
78
+ Pecos
79
+ Kura
80
+ Columbia
81
+ Sankuru
82
+ Ishim
83
+ Jialing
84
+ Benue
85
+ Guapore
86
+ Yamuna
87
+ Senegal
88
+ Churchill
89
+ Tobol
90
+ Alazeya
91
+ Han
92
+ Khatanga
93
+ Olekma
94
+ Platte
95
+ Trisuli
96
+ Ica
97
+ Mara
98
+ Vaal
99
+ Okavango
100
+ Limpopo
101
+ Helmand
102
+ Cunene
103
+ Chari
@@ -0,0 +1,109 @@
1
+ name
2
+ Jupiter
3
+ Juno
4
+ Neptune
5
+ Minerva
6
+ Apollo
7
+ Diana
8
+ Mars
9
+ Venus
10
+ Mercury
11
+ Vesta
12
+ Ceres
13
+ Vulcan
14
+ Bacchus
15
+ Pluto
16
+ Proserpina
17
+ Saturn
18
+ Uranus
19
+ Janus
20
+ Cupid
21
+ Psyche
22
+ Sol
23
+ Luna
24
+ Fortuna
25
+ Victoria
26
+ Concordia
27
+ Fides
28
+ Spes
29
+ Salus
30
+ Pax
31
+ Libertas
32
+ Honos
33
+ Virtus
34
+ Pietas
35
+ Felicitas
36
+ Genius
37
+ Lares
38
+ Penates
39
+ Manes
40
+ Faunus
41
+ Flora
42
+ Pomona
43
+ Vertumnus
44
+ Terminus
45
+ Consus
46
+ Ops
47
+ Portunus
48
+ Carmenta
49
+ Bellona
50
+ Quirinus
51
+ Volturnus
52
+ Tiberinus
53
+ Aesculapius
54
+ Hercules
55
+ Castor
56
+ Pollux
57
+ Aeneas
58
+ Romulus
59
+ Remus
60
+ Numa
61
+ Camenae
62
+ Egeria
63
+ Muses
64
+ Graces
65
+ Fates
66
+ Furies
67
+ Horae
68
+ Nymphs
69
+ Sylvanus
70
+ Tellus
71
+ Maia
72
+ Acca Larentia
73
+ Anna Perenna
74
+ Cardea
75
+ Carna
76
+ Clementia
77
+ Disciplina
78
+ Eventus Bonus
79
+ Febris
80
+ Feronia
81
+ Fons
82
+ Furrina
83
+ Justitia
84
+ Laetitia
85
+ Laverna
86
+ Libitina
87
+ Mellona
88
+ Muta
89
+ Nemesis
90
+ Nox
91
+ Pales
92
+ Robigo
93
+ Rumina
94
+ Rusina
95
+ Securitas
96
+ Trivia
97
+ Veritas
98
+ Voluptas
99
+ Volturna
100
+ Angerona
101
+ Bubona
102
+ Candelifera
103
+ Lucina
104
+ Mena
105
+ Nascio
106
+ Partula
107
+ Strenia
108
+ Viduus
109
+ Volumnus
@@ -0,0 +1,104 @@
1
+ name
2
+ Pacific Ocean
3
+ Atlantic Ocean
4
+ Indian Ocean
5
+ Arctic Ocean
6
+ Southern Ocean
7
+ Mediterranean Sea
8
+ Caribbean Sea
9
+ South China Sea
10
+ Bering Sea
11
+ Gulf of Mexico
12
+ Okhotsk Sea
13
+ East China Sea
14
+ Hudson Bay
15
+ Japan Sea
16
+ Andaman Sea
17
+ North Sea
18
+ Red Sea
19
+ Baltic Sea
20
+ Black Sea
21
+ Arabian Sea
22
+ Coral Sea
23
+ Tasman Sea
24
+ Philippine Sea
25
+ Sargasso Sea
26
+ Greenland Sea
27
+ Barents Sea
28
+ Kara Sea
29
+ Laptev Sea
30
+ East Siberian Sea
31
+ Chukchi Sea
32
+ Beaufort Sea
33
+ Lincoln Sea
34
+ Wandel Sea
35
+ Norwegian Sea
36
+ Irish Sea
37
+ Celtic Sea
38
+ English Channel
39
+ Bay of Biscay
40
+ Adriatic Sea
41
+ Aegean Sea
42
+ Ionian Sea
43
+ Tyrrhenian Sea
44
+ Ligurian Sea
45
+ Alboran Sea
46
+ Balearic Sea
47
+ Sea of Crete
48
+ Sea of Marmara
49
+ Sea of Azov
50
+ Caspian Sea
51
+ Aral Sea
52
+ Salton Sea
53
+ Dead Sea
54
+ Sea of Galilee
55
+ White Sea
56
+ Pechora Sea
57
+ Timor Sea
58
+ Arafura Sea
59
+ Banda Sea
60
+ Celebes Sea
61
+ Sulu Sea
62
+ Molucca Sea
63
+ Java Sea
64
+ Flores Sea
65
+ Savu Sea
66
+ Halmahera Sea
67
+ Ceram Sea
68
+ Bismarck Sea
69
+ Solomon Sea
70
+ Gulf of Carpentaria
71
+ Gulf of Thailand
72
+ Gulf of Tonkin
73
+ Yellow Sea
74
+ Bohai Sea
75
+ Seto Inland Sea
76
+ Sea of Japan
77
+ Gulf of Alaska
78
+ Gulf of California
79
+ Labrador Sea
80
+ Irminger Sea
81
+ Davis Strait
82
+ Baffin Bay
83
+ James Bay
84
+ Gulf of St. Lawrence
85
+ Bay of Fundy
86
+ Sunda Strait
87
+ Makassar Strait
88
+ Lombok Strait
89
+ Malacca Strait
90
+ Singapore Strait
91
+ Palk Strait
92
+ Bab-el-Mandeb
93
+ Strait of Hormuz
94
+ Persian Gulf
95
+ Gulf of Oman
96
+ Gulf of Aden
97
+ Gulf of Guinea
98
+ Mozambique Channel
99
+ Great Australian Bight
100
+ Spencer Gulf
101
+ Gulf St Vincent
102
+ Bass Strait
103
+ Cook Strait
104
+ Foveaux Strait
@@ -0,0 +1,39 @@
1
+ """
2
+ Custom exceptions for the multiplayer module.
3
+ """
4
+
5
+ class MultiplayerError(Exception):
6
+ """Base class for exceptions in this module."""
7
+ pass
8
+
9
+ class GameLogicError(MultiplayerError):
10
+ """Raised for errors in game logic (e.g., starting a game with no players)."""
11
+ pass
12
+
13
+ class PlayerLimitReachedError(GameLogicError):
14
+ """Raised when trying to add a player to a full game."""
15
+ pass
16
+
17
+ class ObserverLimitReachedError(GameLogicError):
18
+ """Raised when trying to add an observer to a full game."""
19
+ pass
20
+
21
+ class GameNotFoundError(MultiplayerError):
22
+ """Raised when a game_id is not found on the server."""
23
+ pass
24
+
25
+ class NetworkError(MultiplayerError):
26
+ """Base class for network-related errors."""
27
+ pass
28
+
29
+ class ConnectionError(NetworkError):
30
+ """Raised for errors connecting to the server."""
31
+ pass
32
+
33
+ class ServerError(NetworkError):
34
+ """Raised when the server reports a generic internal error."""
35
+ pass
36
+
37
+ class AuthenticationError(NetworkError):
38
+ """Raised for password authentication failures."""
39
+ pass
multiplayer/game.py ADDED
@@ -0,0 +1,275 @@
1
+ """
2
+ This module provides classes for managing a multiplayer game.
3
+ """
4
+
5
+ import enum
6
+ import uuid
7
+ from .exceptions import GameLogicError, PlayerLimitReachedError, ObserverLimitReachedError, AuthenticationError
8
+
9
+ class GameState(enum.Enum):
10
+ """
11
+ Represents the state of the game.
12
+ """
13
+ PENDING = "pending"
14
+ IN_PROGRESS = "in_progress"
15
+ FINISHED = "finished"
16
+
17
+ class Player:
18
+ """
19
+ Represents a player in the game.
20
+
21
+ Args:
22
+ name (str): The name of the player.
23
+ id (str, optional): The player's ID.
24
+ **kwargs: Additional attributes for the player.
25
+ """
26
+ def __init__(self, name, id=None, **kwargs):
27
+ self.name = name
28
+ self.attributes = kwargs
29
+ self._id = id or str(uuid.uuid4())
30
+
31
+ @property
32
+ def ID(self):
33
+ """
34
+ The unique ID of the player.
35
+ """
36
+ return self._id
37
+
38
+ class GameGroup:
39
+ """
40
+ Represents a group of games on a server.
41
+
42
+ Args:
43
+ name (str): The name of the group.
44
+ admin_password (str, optional): A password for administrative actions on this group.
45
+ **kwargs: Additional attributes for the group.
46
+ """
47
+ def __init__(self, name, admin_password=None, **kwargs):
48
+ self.name = name
49
+ self.admin_password = admin_password
50
+ self.attributes = kwargs
51
+ self.games = []
52
+ self._id = str(uuid.uuid4())
53
+
54
+ @property
55
+ def ID(self):
56
+ """
57
+ The unique ID of the group.
58
+ """
59
+ return self._id
60
+
61
+ def add_game(self, game):
62
+ """
63
+ Adds a game to the group.
64
+
65
+ Args:
66
+ game (Game): The game to add.
67
+ """
68
+ if game not in self.games:
69
+ self.games.append(game)
70
+
71
+ def remove_game(self, game_id):
72
+ """
73
+ Removes a game from the group by ID.
74
+
75
+ Args:
76
+ game_id (str): The ID of the game to remove.
77
+ """
78
+ game_to_remove = next((g for g in self.games if g.ID == game_id), None)
79
+ if game_to_remove:
80
+ self.games.remove(game_to_remove)
81
+
82
+ class Observer:
83
+ """
84
+ Represents an observer in the game.
85
+
86
+ Args:
87
+ name (str): The name of the observer.
88
+ id (str, optional): The observer's ID.
89
+ **kwargs: Additional attributes for the observer.
90
+ """
91
+ def __init__(self, name, id=None, **kwargs):
92
+ self.name = name
93
+ self.attributes = kwargs
94
+ self._id = id or str(uuid.uuid4())
95
+
96
+ @property
97
+ def ID(self):
98
+ """
99
+ The unique ID of the observer.
100
+ """
101
+ return self._id
102
+
103
+ class Game:
104
+ """
105
+ Represents a multiplayer game.
106
+
107
+ Args:
108
+ name (str, optional): The name of the game session. Defaults to None.
109
+ max_players (int, optional): The maximum number of players allowed in the game. Defaults to None.
110
+ max_observers (int, optional): The maximum number of observers allowed in the game. Defaults to None.
111
+ turn_based (bool, optional): Whether the game is turn-based or simultaneous. Defaults to False.
112
+ password (str, optional): A password to protect this specific game.
113
+ **kwargs: Additional attributes for the game.
114
+ """
115
+ def __init__(self, name=None, max_players=None, max_observers=None, turn_based=False, password=None, observer_password=None, **kwargs):
116
+ self.name = name
117
+ self.max_players = max_players
118
+ self.max_observers = max_observers
119
+ self.turn_based = turn_based
120
+ self.password = password
121
+ self.observer_password = observer_password
122
+ self.attributes = kwargs
123
+ self.players = []
124
+ self.observers = []
125
+ self.state = GameState.PENDING
126
+ self.current_player_index = 0
127
+ self.custom_state = {}
128
+ self._id = str(uuid.uuid4())
129
+
130
+ @property
131
+ def ID(self):
132
+ """
133
+ The unique ID of the game.
134
+ """
135
+ return self._id
136
+
137
+ def add_player(self, player, password=None):
138
+ """
139
+ Adds a player to the game.
140
+
141
+ Args:
142
+ player (Player): The player to add.
143
+ password (str, optional): The password required to join the game.
144
+
145
+ Raises:
146
+ AuthenticationError: If the provided password does not match the game's password.
147
+ PlayerLimitReachedError: If the maximum number of players has been reached.
148
+ """
149
+ if self.password is not None and self.password != password:
150
+ raise AuthenticationError("Invalid password for this game")
151
+ if self.max_players is not None and len(self.players) >= self.max_players:
152
+ raise PlayerLimitReachedError("Maximum number of players reached")
153
+ self.players.append(player)
154
+
155
+ def add_observer(self, observer, password=None):
156
+ """
157
+ Adds an observer to the game.
158
+
159
+ Args:
160
+ observer (Observer): The observer to add.
161
+ password (str, optional): The password required to join the game as an observer.
162
+
163
+ Raises:
164
+ AuthenticationError: If the provided password does not match the observer password (or game password if no observer password is set).
165
+ ObserverLimitReachedError: If the maximum number of observers has been reached.
166
+ """
167
+ required_password = self.observer_password if self.observer_password is not None else self.password
168
+ if required_password is not None and required_password != password:
169
+ raise AuthenticationError("Invalid password for this game")
170
+ if self.max_observers is not None and len(self.observers) >= self.max_observers:
171
+ raise ObserverLimitReachedError("Maximum number of observers reached")
172
+ self.observers.append(observer)
173
+
174
+ def remove_player(self, player_id):
175
+ """
176
+ Removes a player from the game by ID.
177
+
178
+ Args:
179
+ player_id (str): The ID of the player to remove.
180
+ """
181
+ player_to_remove = next((p for p in self.players if p.ID == player_id), None)
182
+ if player_to_remove:
183
+ removed_player_index = self.players.index(player_to_remove)
184
+ self.players.remove(player_to_remove)
185
+
186
+ if self.turn_based and self.state == GameState.IN_PROGRESS:
187
+ if not self.players:
188
+ self.state = GameState.PENDING
189
+ elif self.current_player_index >= removed_player_index:
190
+ self.current_player_index = self.current_player_index % len(self.players)
191
+
192
+ def remove_observer(self, observer_id):
193
+ """
194
+ Removes an observer from the game by ID.
195
+
196
+ Args:
197
+ observer_id (str): The ID of the observer to remove.
198
+ """
199
+ observer_to_remove = next((o for o in self.observers if o.ID == observer_id), None)
200
+ if observer_to_remove:
201
+ self.observers.remove(observer_to_remove)
202
+
203
+ def start(self):
204
+ """
205
+ Starts the game.
206
+
207
+ Raises:
208
+ GameLogicError: If there are no players in the game or if the game is already in progress.
209
+ """
210
+ if self.state == GameState.IN_PROGRESS:
211
+ raise GameLogicError("Game is already in progress")
212
+ if not self.players:
213
+ raise GameLogicError("Cannot start a game with no players")
214
+ self.state = GameState.IN_PROGRESS
215
+
216
+ def pause(self):
217
+ """
218
+ Pauses the game.
219
+
220
+ Raises:
221
+ GameLogicError: If the game is not in progress.
222
+ """
223
+ if self.state != GameState.IN_PROGRESS:
224
+ raise GameLogicError("Game is not in progress")
225
+ self.state = GameState.PENDING
226
+
227
+ def resume(self):
228
+ """
229
+ Resumes the game.
230
+
231
+ Raises:
232
+ GameLogicError: If the game is not pending.
233
+ """
234
+ if self.state != GameState.PENDING:
235
+ raise GameLogicError("Game is not pending")
236
+ self.state = GameState.IN_PROGRESS
237
+
238
+ def stop(self):
239
+ """
240
+ Stops the game.
241
+ """
242
+ self.state = GameState.FINISHED
243
+
244
+ def next_turn(self):
245
+ """
246
+ Advances to the next turn in a turn-based game.
247
+
248
+ Raises:
249
+ GameLogicError: If the game is not turn-based or not in progress.
250
+ """
251
+ if not self.turn_based:
252
+ raise GameLogicError("Game is not turn-based")
253
+ if self.state != GameState.IN_PROGRESS:
254
+ raise GameLogicError("Game is not in progress")
255
+ if self.players:
256
+ self.current_player_index = (self.current_player_index + 1) % len(self.players)
257
+
258
+ @property
259
+ def current_player(self):
260
+ """
261
+ The current player in a turn-based game.
262
+
263
+ Returns:
264
+ Player: The current player.
265
+
266
+ Raises:
267
+ GameLogicError: If the game is not turn-based or not in progress.
268
+ """
269
+ if not self.turn_based:
270
+ raise GameLogicError("Game is not turn-based")
271
+ if self.state != GameState.IN_PROGRESS:
272
+ raise GameLogicError("Game is not in progress")
273
+ if not self.players:
274
+ return None
275
+ return self.players[self.current_player_index]
@@ -0,0 +1,23 @@
1
+ """
2
+ multiplayer, a Python library for managing multiplayer games
3
+ Copyright (C) 2025 [devfred78](https://github.com/devfred78)
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ This package provides tools for managing interface languages.
19
+ """
20
+
21
+ from .language import Language, Languages
22
+
23
+ __all__ = ["Language", "Languages"]