mc5-api-client 1.0.19__py3-none-any.whl → 1.0.21__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.19"
18
+ __version__ = "1.0.21"
19
19
  __author__ = "Chizoba"
20
20
  __email__ = "chizoba2026@hotmail.com"
21
21
  __license__ = "MIT"
@@ -88,6 +88,37 @@ from .auth import TokenGenerator
88
88
  from .exceptions import MC5APIError, AuthenticationError, RateLimitError
89
89
  from .help import help, examples, quick_reference
90
90
 
91
+ # Automatic Squad Management (NEW!)
92
+ from .client import MC5Client
93
+
94
+ # Add automatic squad management methods as standalone functions
95
+ def get_my_squad_id(client=None, **kwargs):
96
+ """Get user's squad ID automatically."""
97
+ if client is None:
98
+ client = MC5Client(**kwargs)
99
+ return client.get_my_squad_id()
100
+
101
+ def get_my_squad_info(client=None, **kwargs):
102
+ """Get user's squad information automatically."""
103
+ if client is None:
104
+ client = MC5Client(**kwargs)
105
+ return client.get_my_squad_info()
106
+
107
+ def update_my_squad_info(client=None, **squad_kwargs):
108
+ """Update user's squad information automatically."""
109
+ client_kwargs = {k: v for k, v in squad_kwargs.items() if k in ['username', 'password', 'client_id']}
110
+ update_kwargs = {k: v for k, v in squad_kwargs.items() if k not in ['username', 'password', 'client_id']}
111
+
112
+ if client is None:
113
+ client = MC5Client(**client_kwargs)
114
+ return client.update_my_squad_info(**update_kwargs)
115
+
116
+ def get_my_squad_members(client=None, **kwargs):
117
+ """Get user's squad members automatically."""
118
+ if client is None:
119
+ client = MC5Client(**kwargs)
120
+ return client.get_my_squad_members()
121
+
91
122
  # Add MC5ApiClient as an alias for backward compatibility
92
123
  MC5ApiClient = MC5Client
93
124
  from .admin_client import (
@@ -399,9 +430,13 @@ __all__ = [
399
430
  "MC5Easy",
400
431
  "quick_connect",
401
432
  "check_my_daily_tasks",
402
- "get_my_mc5_profile",
403
- "find_mc5_player",
404
- "get_global_id",
433
+ "get_server_status",
434
+ "get_online_players",
435
+ "get_server_info",
436
+ "get_my_squad_id",
437
+ "get_my_squad_info",
438
+ "update_my_squad_info",
439
+ "get_my_squad_members",
405
440
  "generate_device_id",
406
441
  "create_federation_session",
407
442
  "locate_service",
mc5_api_client/client.py CHANGED
@@ -1652,6 +1652,186 @@ class MC5Client(SquadBattleMixin, FederationMixin, AlertsMixin, AccountMixin, Tr
1652
1652
  "timestamp": time.time()
1653
1653
  }
1654
1654
 
1655
+ # Automatic Squad Management (NEW!)
1656
+
1657
+ def get_my_squad_id(self) -> Optional[str]:
1658
+ """
1659
+ Automatically fetch the user's squad ID from their profile.
1660
+
1661
+ This method eliminates the need to manually specify squad ID for squad operations.
1662
+ It fetches the user's profile and extracts the squad/group ID from their groups.
1663
+
1664
+ Returns:
1665
+ Squad ID if found, None otherwise
1666
+ """
1667
+ try:
1668
+ # Get user profile which contains groups information
1669
+ profile = self.get_profile()
1670
+
1671
+ if not profile:
1672
+ return None
1673
+
1674
+ # Check if user has groups
1675
+ groups = profile.get('groups', [])
1676
+ if not groups:
1677
+ return None
1678
+
1679
+ # Extract squad ID from groups (usually the first group is the squad)
1680
+ # Groups can be in different formats, handle multiple cases
1681
+ for group in groups:
1682
+ if isinstance(group, str):
1683
+ # Simple string ID
1684
+ return group
1685
+ elif isinstance(group, dict):
1686
+ # Dictionary with ID field
1687
+ if 'id' in group:
1688
+ return group['id']
1689
+ elif '_id' in group:
1690
+ return group['_id']
1691
+ elif 'group_id' in group:
1692
+ return group['group_id']
1693
+
1694
+ # If no group found in the expected format, try to extract from the groups string
1695
+ if groups and isinstance(groups[0], str):
1696
+ return groups[0]
1697
+
1698
+ return None
1699
+
1700
+ except Exception as e:
1701
+ print(f"🔴 Error fetching squad ID: {e}")
1702
+ return None
1703
+
1704
+ def get_my_squad_info(self) -> Dict[str, Any]:
1705
+ """
1706
+ Get complete squad information using automatically fetched squad ID.
1707
+
1708
+ Returns:
1709
+ Dictionary with squad information or error details
1710
+ """
1711
+ try:
1712
+ squad_id = self.get_my_squad_id()
1713
+ if not squad_id:
1714
+ return {
1715
+ "error": "No squad found for this user",
1716
+ "message": "User is not in any squad",
1717
+ "timestamp": time.time()
1718
+ }
1719
+
1720
+ # Get squad information using the fetched ID
1721
+ squad_info = self.get_clan_settings(squad_id)
1722
+
1723
+ if squad_info:
1724
+ squad_info['auto_fetched_squad_id'] = squad_id
1725
+ squad_info['fetch_method'] = 'automatic'
1726
+ return squad_info
1727
+ else:
1728
+ return {
1729
+ "error": "Failed to fetch squad details",
1730
+ "squad_id": squad_id,
1731
+ "message": "Squad ID found but could not fetch details",
1732
+ "timestamp": time.time()
1733
+ }
1734
+
1735
+ except Exception as e:
1736
+ return {
1737
+ "error": str(e),
1738
+ "message": "Failed to get squad information",
1739
+ "timestamp": time.time()
1740
+ }
1741
+
1742
+ def update_my_squad_info(self, **kwargs) -> Dict[str, Any]:
1743
+ """
1744
+ Update squad information using automatically fetched squad ID.
1745
+
1746
+ This is a convenience method that combines get_my_squad_id() and update_clan_settings().
1747
+ Users don't need to specify squad ID - it's automatically fetched from their profile.
1748
+
1749
+ Args:
1750
+ **kwargs: Squad settings to update (same as update_clan_settings)
1751
+ - name: Squad name
1752
+ - description: Squad description
1753
+ - rating: Squad rating
1754
+ - min_join_value: Minimum join value
1755
+ - logo: Squad logo ID
1756
+ - logo_clr_prim: Primary logo color
1757
+ - logo_clr_sec: Secondary logo color
1758
+
1759
+ Returns:
1760
+ Dictionary with update result or error details
1761
+ """
1762
+ try:
1763
+ squad_id = self.get_my_squad_id()
1764
+ if not squad_id:
1765
+ return {
1766
+ "error": "No squad found for this user",
1767
+ "message": "Cannot update squad - user is not in any squad",
1768
+ "timestamp": time.time()
1769
+ }
1770
+
1771
+ # Update squad using the fetched ID
1772
+ result = self.update_clan_settings(squad_id, **kwargs)
1773
+
1774
+ if result:
1775
+ result['auto_fetched_squad_id'] = squad_id
1776
+ result['update_method'] = 'automatic'
1777
+ return result
1778
+ else:
1779
+ return {
1780
+ "error": "Failed to update squad",
1781
+ "squad_id": squad_id,
1782
+ "message": "Squad ID found but update failed",
1783
+ "timestamp": time.time()
1784
+ }
1785
+
1786
+ except Exception as e:
1787
+ return {
1788
+ "error": str(e),
1789
+ "message": "Failed to update squad information",
1790
+ "timestamp": time.time()
1791
+ }
1792
+
1793
+ def get_my_squad_members(self) -> Dict[str, Any]:
1794
+ """
1795
+ Get squad members using automatically fetched squad ID.
1796
+
1797
+ Returns:
1798
+ Dictionary with squad members or error details
1799
+ """
1800
+ try:
1801
+ squad_id = self.get_my_squad_id()
1802
+ if not squad_id:
1803
+ return {
1804
+ "error": "No squad found for this user",
1805
+ "message": "Cannot get squad members - user is not in any squad",
1806
+ "timestamp": time.time()
1807
+ }
1808
+
1809
+ # Get squad members using the fetched ID
1810
+ members = self.get_clan_members(squad_id)
1811
+
1812
+ if members:
1813
+ return {
1814
+ "squad_id": squad_id,
1815
+ "members": members,
1816
+ "member_count": len(members) if isinstance(members, list) else 0,
1817
+ "fetch_method": "automatic",
1818
+ "timestamp": time.time()
1819
+ }
1820
+ else:
1821
+ return {
1822
+ "error": "Failed to fetch squad members",
1823
+ "squad_id": squad_id,
1824
+ "message": "Squad ID found but could not fetch members",
1825
+ "timestamp": time.time()
1826
+ }
1827
+
1828
+ except Exception as e:
1829
+ return {
1830
+ "error": str(e),
1831
+ "message": "Failed to get squad members",
1832
+ "timestamp": time.time()
1833
+ }
1834
+
1655
1835
  # Events API
1656
1836
 
1657
1837
  def get_events(self, event_type: str = None, status: str = None) -> List[Dict[str, Any]]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mc5_api_client
3
- Version: 1.0.19
3
+ Version: 1.0.21
4
4
  Summary: A comprehensive Python library for interacting with the Modern Combat 5 API
5
5
  Home-page: https://pypi.org/project/mc5-api-client/
6
6
  Author: Chizoba
@@ -143,10 +143,109 @@ Think of this as your remote control for Modern Combat 5! Here's what you can do
143
143
  ### 🎉 MC5 API Client v1.0.18 - Super Easy Interface & Clean API!
144
144
 
145
145
  ```bash
146
- pip install mc5_api_client==1.0.18
146
+ pip install mc5_api_client==1.0.20
147
147
  ```
148
148
 
149
- ### **Major Features Completed!**
149
+ ## 🎯 **Usage Examples**
150
+
151
+ ### **🎮 Basic Usage (MC5Client)**
152
+ ```python
153
+ from mc5_api_client import MC5Client
154
+
155
+ # Initialize the client
156
+ client = MC5Client(
157
+ client_id="1875:55979:6.0.0a:windows:windows",
158
+ username="your_credential",
159
+ password="your_password"
160
+ )
161
+
162
+ # Authenticate
163
+ client.authenticate()
164
+
165
+ # Get profile
166
+ profile = client.get_profile()
167
+ print(f"Profile: {profile}")
168
+
169
+ # Get events
170
+ events = client.get_events()
171
+ print(f"Events: {len(events)} found")
172
+
173
+ # Server status (NEW!)
174
+ status = client.get_server_status()
175
+ print(f"Server Status: {status['status']}")
176
+
177
+ # Close connection
178
+ client.close()
179
+ ```
180
+
181
+ ### **🎯 MC5ApiClient (Backward Compatible)**
182
+ ```python
183
+ from mc5_api_client import MC5ApiClient
184
+
185
+ # MC5ApiClient is an alias for MC5Client
186
+ client = MC5ApiClient(
187
+ client_id="1875:55979:6.0.0a:windows:windows",
188
+ username="your_credential",
189
+ password="your_password"
190
+ )
191
+
192
+ # Use the same methods as MC5Client
193
+ client.authenticate()
194
+ status = client.get_server_status()
195
+ info = client.get_server_info()
196
+ ```
197
+
198
+ ### **🔧 Quick Functions (Standalone)**
199
+ ```python
200
+ from mc5_api_client import quick_get_account_info, quick_get_active_sessions
201
+
202
+ # Quick functions are standalone, not client methods
203
+ # They require credentials as parameters
204
+ account_info = quick_get_account_info("your_credential", "your_password")
205
+ sessions = quick_get_active_sessions("your_password")
206
+ ```
207
+
208
+ ### **🎮 Game Launch & Service Location (NEW!)**
209
+ ```python
210
+ from mc5_api_client import MC5Easy, get_all_services, create_federation_session
211
+
212
+ # Get all MC5 services dynamically
213
+ services = get_all_services()
214
+ print(f"Found {len(services)} services:")
215
+ for service, endpoint in services.items():
216
+ print(f" {service}: {endpoint}")
217
+
218
+ # Create federation session for game launch
219
+ session = create_federation_session(username, password)
220
+ if session.get("success"):
221
+ print(f"Room ID: {session['room_id']}")
222
+ print(f"Controller: {session['controller_host']}")
223
+
224
+ # Or use MC5Easy for complete game management
225
+ with MC5Easy(username, password) as mc5:
226
+ launch_info = mc5.launch_game_session()
227
+ print(f"Game ready: {launch_info['launch_command']}")
228
+ ```
229
+
230
+ ### **🌐 Global ID & Device Management (NEW!)**
231
+ ```python
232
+ from mc5_api_client import get_global_id, generate_device_id
233
+
234
+ # Get global device ID
235
+ global_id = get_global_id()
236
+ print(f"Global ID: {global_id}")
237
+
238
+ # Generate unique device ID
239
+ device_id = generate_device_id()
240
+ print(f"Device ID: {device_id}")
241
+
242
+ # With MC5Easy
243
+ with MC5Easy(username, password) as mc5:
244
+ device_info = mc5.get_device_info()
245
+ print(f"Device: {device_info}")
246
+ ```
247
+
248
+ ## 📱 **Run Examples:** Completed!
150
249
 
151
250
  **🎯 Super Easy Interface (NEW in v1.0.18):**
152
251
  - ✅ **MC5Easy Module** - One-line functions for everyday tasks
@@ -1348,8 +1447,6 @@ finally:
1348
1447
  **Security Benefits:**
1349
1448
  - ✅ **Additional Layer**: Tokens are encrypted before transmission
1350
1449
  - ✅ **Custom Nonce**: Support for custom nonce values
1351
- - ✅ **Backward Compatible**: Works with existing authentication flow
1352
- - ✅ **Error Handling**: Proper validation and error recovery
1353
1450
 
1354
1451
  ### 🏆 **Checking Leaderboards**
1355
1452
 
@@ -1369,7 +1466,6 @@ if hasattr(client, 'get_leaderboard'):
1369
1466
  # print(f"Top {len(leaderboard.get('players', []))} players")
1370
1467
  else:
1371
1468
  print("❌ get_leaderboard method not found")
1372
- ```
1373
1469
 
1374
1470
  ### 🖥️ CLI Commands - Currently Available
1375
1471
 
@@ -1,4 +1,4 @@
1
- mc5_api_client/__init__.py,sha256=dwst7ePR-608bLju9sGSZ5XE_5KkyUI3BJJITktpcsU,11942
1
+ mc5_api_client/__init__.py,sha256=it6XDA9bQyWk2T_J0MBPa06usNQix2f1vFioAUmY5Zw,13226
2
2
  mc5_api_client/account.py,sha256=EmydXCsCXaKqMw21oVttQfYuDl50pa2dwhcTeHtnxbQ,14396
3
3
  mc5_api_client/account_quick.py,sha256=t4ki4ujYENmcnd_004f0pO9SPxPyCllz4WHpBG9wNbo,10458
4
4
  mc5_api_client/admin_client.py,sha256=527aavolxVhY2M5ceFxVbbE5YTczU9Z86Fdt1UzdRZM,15220
@@ -6,7 +6,7 @@ mc5_api_client/alerts.py,sha256=zW-cEwSSShuHkGxTBQaS8Ynf1a0hh5RMQ0G3WC_ajI0,1322
6
6
  mc5_api_client/alerts_quick.py,sha256=D1j0RiHteYqoAgc4KYqTxYG1Hkud3b-xWRV_VOUEnY0,7946
7
7
  mc5_api_client/auth.py,sha256=z8vmyQIHUdAzk0pUyKCesT8gTv4jboLIFGBxAu1v_-8,13396
8
8
  mc5_api_client/cli.py,sha256=6xciRjWkUMOxgxlbDsoOiHRuirXPy7uc9WURXPKmgGc,17255
9
- mc5_api_client/client.py,sha256=EWL0IWiP9mwr9GTnnzWwTKHZUPe2LXaY7YxzjKTDjWM,112524
9
+ mc5_api_client/client.py,sha256=v3EQYzuSpNPF0n3xGaSsP8GjaJ0eOjchh0ZbiCvInQA,119226
10
10
  mc5_api_client/debug.py,sha256=524vNCE7jM_KP5JM81-3eI2cmFBBA-Hf7Uy0cIL75W0,8240
11
11
  mc5_api_client/easy_mc5.py,sha256=kfjOJMW-VRAZcXEF1yHiGsACgjb-ZjXGuw1U_gepSQY,24202
12
12
  mc5_api_client/exceptions.py,sha256=o7od4GrEIlgq6xSNUjZdh74xoDTytF3PLcMq5ewRiJw,2683
@@ -24,9 +24,9 @@ mc5_api_client/storage_admin.py,sha256=l-nwskbpa3KpeIoWcwVRicgBSvrTvQ5aE2QU_e366
24
24
  mc5_api_client/telemetry.py,sha256=k8qOimPg-AKsnMclIgeqYCJ_97j2pWyiN7Lg80D4sKo,13246
25
25
  mc5_api_client/transfer.py,sha256=-pln70360mo4cKBQIUzp_wt9ce1Cr4YA6aJDFPKEjzQ,14381
26
26
  mc5_api_client/transfer_quick.py,sha256=HhRbp4FVzFwuzHDcqOyYiVjeVEIfgezlWd8SN6sh874,11310
27
- mc5_api_client-1.0.19.dist-info/licenses/LICENSE,sha256=M0UBQ4B3pB9XcV54_jhVP681xyauF8GB6YK_rKmuXzk,1064
28
- mc5_api_client-1.0.19.dist-info/METADATA,sha256=eTEmXuKWRw8Z6wtY4bVAtGljnBB_G667PT2wGfnuEuY,80598
29
- mc5_api_client-1.0.19.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
30
- mc5_api_client-1.0.19.dist-info/entry_points.txt,sha256=2kruOpleFYK3Jl1MoQwGyqCd-Pj4kQWngXmIjnXx_gE,48
31
- mc5_api_client-1.0.19.dist-info/top_level.txt,sha256=eYJe4ue9j1ig_jFY5Z05mDqpizUEV7TYpk5lBXVd4kA,15
32
- mc5_api_client-1.0.19.dist-info/RECORD,,
27
+ mc5_api_client-1.0.21.dist-info/licenses/LICENSE,sha256=M0UBQ4B3pB9XcV54_jhVP681xyauF8GB6YK_rKmuXzk,1064
28
+ mc5_api_client-1.0.21.dist-info/METADATA,sha256=DbiivFEmDu7_UhtTFUCqBc9S95HQhZ0NpyiHPSTrnUY,83121
29
+ mc5_api_client-1.0.21.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
30
+ mc5_api_client-1.0.21.dist-info/entry_points.txt,sha256=2kruOpleFYK3Jl1MoQwGyqCd-Pj4kQWngXmIjnXx_gE,48
31
+ mc5_api_client-1.0.21.dist-info/top_level.txt,sha256=eYJe4ue9j1ig_jFY5Z05mDqpizUEV7TYpk5lBXVd4kA,15
32
+ mc5_api_client-1.0.21.dist-info/RECORD,,