mc5-api-client 1.0.17__py3-none-any.whl → 1.0.18__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.
@@ -15,7 +15,7 @@ messaging, and more.
15
15
 
16
16
  from typing import Optional, Dict, Any
17
17
 
18
- __version__ = "1.0.16"
18
+ __version__ = "1.0.18"
19
19
  __author__ = "Chizoba"
20
20
  __email__ = "chizoba2026@hotmail.com"
21
21
  __license__ = "MIT"
@@ -94,11 +94,185 @@ from .admin_client import (
94
94
  quick_add_squad_rating,
95
95
  quick_update_player_score
96
96
  )
97
+ from .pc_storage_client import PCStorageClient
98
+ from .storage_admin import StorageAdminMixin
99
+ from .easy_mc5 import MC5Easy
97
100
 
98
101
  # Encrypted token convenience functions
99
102
  from .auth import TokenGenerator
100
103
 
101
- def quick_generate_encrypted_token(
104
+ # Convenience functions for global ID operations
105
+ def get_global_id(device_id: str = None, device_type: str = "w10", hdidfv: str = None) -> str:
106
+ """
107
+ Get a global device ID from Gameloft's global ID service.
108
+
109
+ Args:
110
+ device_id: Your device ID (optional, will generate one if not provided)
111
+ device_type: Device type (w10, android, ios, etc.)
112
+ hdidfv: Hardware ID fingerprint (optional)
113
+
114
+ Returns:
115
+ Global device ID string
116
+ """
117
+ import requests
118
+
119
+ # Build request parameters
120
+ params = {
121
+ "source": "Identifiers_6.0.0",
122
+ "client_id": "1875:55979:6.0.0a:windows:windows",
123
+ "device_type": device_type,
124
+ "global_device_id": device_id or "1364509832654538259",
125
+ "hdidfv": hdidfv or "76dfc72e-7850-4d9e-b79c-9861c7e3ea20"
126
+ }
127
+
128
+ headers = {
129
+ "Accept": "*/*",
130
+ "Accept-Encoding": "gzip;q=1.0, deflate;q=1.0, identity;q=0.5, *;q=0"
131
+ }
132
+
133
+ try:
134
+ response = requests.get(
135
+ "https://gdid.datalake.gameloft.com/assign_global_id/",
136
+ params=params,
137
+ headers=headers,
138
+ timeout=30
139
+ )
140
+
141
+ if response.status_code == 200:
142
+ return response.text.strip()
143
+ else:
144
+ return ""
145
+ except Exception:
146
+ return ""
147
+
148
+ def generate_device_id() -> str:
149
+ """
150
+ Generate a unique device ID for the current device.
151
+
152
+ Returns:
153
+ Generated device ID string
154
+ """
155
+ import uuid
156
+
157
+ # Generate a unique device ID
158
+ device_id = f"mc5_{uuid.uuid4().hex[:16]}"
159
+ return device_id
160
+
161
+ def create_federation_session(username: str = None, password: str = None, device_id: str = None) -> Dict[str, Any]:
162
+ """
163
+ Create a federation session for MC5 game launch.
164
+
165
+ Args:
166
+ username: MC5 username (can use MC5_USERNAME env var)
167
+ password: MC5 password (can use MC5_PASSWORD env var)
168
+ device_id: Device ID for the session (optional)
169
+
170
+ Returns:
171
+ Dictionary with session information
172
+ """
173
+ import os
174
+ import requests
175
+
176
+ # Use environment variables if not provided
177
+ username = username or os.getenv('MC5_USERNAME')
178
+ password = password or os.getenv('MC5_PASSWORD')
179
+
180
+ if not username or not password:
181
+ return {"error": "Username and password are required"}
182
+
183
+ try:
184
+ # Build request parameters
185
+ params = {
186
+ "password": password,
187
+ "device_id": device_id or "1364509832654538259"
188
+ }
189
+
190
+ headers = {
191
+ "Accept": "*/*",
192
+ "Content-Type": "application/x-www-form-urlencoded"
193
+ }
194
+
195
+ # Build URL with encoded credential
196
+ encoded_credential = username.replace(":", "%3A")
197
+ url = f"https://federation-eur.gameloft.com/sessions/1875%3A55979%3A6.0.0a%3Awindows%3Awindows/{encoded_credential}"
198
+
199
+ # Make request
200
+ response = requests.post(
201
+ url,
202
+ data=params,
203
+ headers=headers,
204
+ timeout=30
205
+ )
206
+
207
+ if response.status_code == 200:
208
+ return response.json()
209
+ else:
210
+ return {"error": f"HTTP {response.status_code}", "response": response.text}
211
+
212
+ except Exception as e:
213
+ return {"error": str(e)}
214
+
215
+ def locate_service(service: str) -> str:
216
+ """
217
+ Locate a service endpoint for MC5.
218
+
219
+ Args:
220
+ service: Service name (leaderboard, matchmaker, auth, social, alert, message, lobby, gs, sp)
221
+
222
+ Returns:
223
+ Service endpoint URL or empty string if not found
224
+ """
225
+ import requests
226
+
227
+ try:
228
+ # Build request parameters
229
+ params = {
230
+ "service": service,
231
+ "client_id": "1875:55979:6.0.0a:windows:windows"
232
+ }
233
+
234
+ headers = {
235
+ "Accept": "*/*"
236
+ }
237
+
238
+ # Make request
239
+ response = requests.get(
240
+ "https://vgold-eur.gameloft.com/1875:55979:6.0.0a:windows:windows/locate",
241
+ params=params,
242
+ headers=headers,
243
+ timeout=30
244
+ )
245
+
246
+ if response.status_code == 200:
247
+ return response.text.strip()
248
+ else:
249
+ return ""
250
+
251
+ except Exception:
252
+ return ""
253
+
254
+ def get_all_services() -> Dict[str, str]:
255
+ """
256
+ Get all available service endpoints.
257
+
258
+ Returns:
259
+ Dictionary mapping service names to endpoints
260
+ """
261
+ services = [
262
+ "leaderboard", "matchmaker", "auth", "social",
263
+ "alert", "message", "lobby", "gs", "sp"
264
+ ]
265
+
266
+ service_endpoints = {}
267
+
268
+ for service in services:
269
+ endpoint = locate_service(service)
270
+ if endpoint:
271
+ service_endpoints[service] = endpoint
272
+
273
+ return service_endpoints
274
+
275
+ def generate_encrypted_token(
102
276
  username: str,
103
277
  password: str,
104
278
  device_id: Optional[str] = None,
@@ -106,7 +280,7 @@ def quick_generate_encrypted_token(
106
280
  nonce: str = "*"
107
281
  ) -> Dict[str, Any]:
108
282
  """
109
- Quick function to generate and encrypt an access token.
283
+ Generate and encrypt an access token.
110
284
 
111
285
  Args:
112
286
  username: MC5 username
@@ -125,12 +299,12 @@ def quick_generate_encrypted_token(
125
299
  finally:
126
300
  token_gen.close()
127
301
 
128
- def quick_encrypt_token(
302
+ def encrypt_token(
129
303
  access_token: str,
130
304
  nonce: str = "*"
131
305
  ) -> str:
132
306
  """
133
- Quick function to encrypt an existing access token.
307
+ Encrypt an existing access token.
134
308
 
135
309
  Args:
136
310
  access_token: Raw access token string
@@ -216,6 +390,16 @@ __all__ = [
216
390
  "help",
217
391
  "examples",
218
392
  "quick_reference",
219
- "quick_generate_encrypted_token",
220
- "quick_encrypt_token"
393
+ "generate_encrypted_token",
394
+ "encrypt_token",
395
+ "MC5Easy",
396
+ "quick_connect",
397
+ "check_my_daily_tasks",
398
+ "get_my_mc5_profile",
399
+ "find_mc5_player",
400
+ "get_global_id",
401
+ "generate_device_id",
402
+ "create_federation_session",
403
+ "locate_service",
404
+ "get_all_services"
221
405
  ]
mc5_api_client/client.py CHANGED
@@ -27,6 +27,7 @@ from .alerts import AlertsMixin
27
27
  from .account import AccountMixin
28
28
  from .transfer import TransferMixin
29
29
  from .platform import Platform, get_platform_config, detect_platform_from_client_id
30
+ from .storage_admin import StorageAdminMixin
30
31
  from .exceptions import (
31
32
  MC5APIError,
32
33
  AuthenticationError,
@@ -37,7 +38,7 @@ from .exceptions import (
37
38
  )
38
39
 
39
40
 
40
- class MC5Client(SquadBattleMixin, FederationMixin, AlertsMixin, AccountMixin, TransferMixin):
41
+ class MC5Client(SquadBattleMixin, FederationMixin, AlertsMixin, AccountMixin, TransferMixin, StorageAdminMixin):
41
42
  """
42
43
  Comprehensive MC5 API client with support for all major endpoints.
43
44
  """
@@ -2271,6 +2272,28 @@ class MC5Client(SquadBattleMixin, FederationMixin, AlertsMixin, AccountMixin, Tr
2271
2272
  response = self._make_request("GET", url, params=params)
2272
2273
  return response if isinstance(response, list) else []
2273
2274
 
2275
+ def get_squad_members(self, squad_id: str, offset: int = 0, limit: int = 100) -> Dict[str, Any]:
2276
+ """
2277
+ Get squad members list.
2278
+
2279
+ Args:
2280
+ squad_id: Squad ID
2281
+ offset: Offset for pagination
2282
+ limit: Number of members to retrieve
2283
+
2284
+ Returns:
2285
+ Squad members list
2286
+ """
2287
+ url = f"{self.BASE_URLS['osiris']}/groups/{squad_id}/members"
2288
+ params = {
2289
+ "access_token": self._token_data['access_token'],
2290
+ "group_id": squad_id,
2291
+ "offset": str(offset),
2292
+ "limit": str(limit)
2293
+ }
2294
+
2295
+ return self._make_request("GET", url, params=params)
2296
+
2274
2297
  def get_clan_info(self, clan_id: str) -> Dict[str, Any]:
2275
2298
  """
2276
2299
  Get detailed information about a clan.