mc5-api-client 1.0.3__py3-none-any.whl → 1.0.4__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.
mc5_api_client/client.py CHANGED
@@ -1724,6 +1724,183 @@ class MC5Client:
1724
1724
 
1725
1725
  return config_data
1726
1726
 
1727
+ # Batch Operations
1728
+
1729
+ def get_batch_profiles(self, credentials: List[str], include_fields: List[str] = None) -> Dict[str, Any]:
1730
+ """
1731
+ Get batch player profiles with detailed statistics and game save data.
1732
+
1733
+ Args:
1734
+ credentials: List of player credentials to fetch
1735
+ include_fields: List of fields to include (default: ['_game_save', 'inventory'])
1736
+
1737
+ Returns:
1738
+ Dictionary with player profiles containing detailed statistics
1739
+ """
1740
+ if include_fields is None:
1741
+ include_fields = ['_game_save', 'inventory']
1742
+
1743
+ url = "https://app-468561b3-9ecd-4d21-8241-30ed288f4d8b.gold0009.gameloft.com/1875/windows/09/public/OfficialScripts/mc5Portal.wsgi"
1744
+
1745
+ data = {
1746
+ 'op_code': 'get_batch_profiles',
1747
+ 'client_id': self.client_id,
1748
+ 'credentials': ','.join(credentials),
1749
+ 'pandora': f"https://vgold-eur.gameloft.com/{self.client_id}",
1750
+ 'include_fields': ','.join(include_fields)
1751
+ }
1752
+
1753
+ headers = {
1754
+ 'Accept': '*/*',
1755
+ 'Content-Type': 'application/x-www-form-urlencoded',
1756
+ 'accept-encoding': 'identity'
1757
+ }
1758
+
1759
+ return self._make_request("POST", url, data=data, headers=headers)
1760
+
1761
+ def get_player_stats_by_dogtag(self, dogtag: str) -> Dict[str, Any]:
1762
+ """
1763
+ Get detailed player statistics using their dogtag (in-game ID).
1764
+
1765
+ Args:
1766
+ dogtag: Player's dogtag in XXXX format (hexadecimal)
1767
+
1768
+ Returns:
1769
+ Player statistics and profile information
1770
+ """
1771
+ # Convert dogtag to alias for API lookup
1772
+ alias = self.convert_dogtag_to_alias(dogtag)
1773
+
1774
+ # Get player info using alias
1775
+ player_info = self.get_alias_info(alias)
1776
+ if not player_info.get('credential'):
1777
+ return {'error': f'Player not found for dogtag: {dogtag}', 'alias': alias}
1778
+
1779
+ # Get detailed stats using the credential
1780
+ try:
1781
+ stats = self.get_batch_profiles([player_info['credential']])
1782
+
1783
+ # Add dogtag and alias info to the response
1784
+ if player_info['credential'] in stats:
1785
+ stats[player_info['credential']]['dogtag'] = dogtag
1786
+ stats[player_info['credential']]['alias'] = alias
1787
+ stats[player_info['credential']]['player_info'] = player_info
1788
+
1789
+ return stats
1790
+
1791
+ except Exception as e:
1792
+ return {
1793
+ 'error': f'Failed to get stats for dogtag {dogtag}: {e}',
1794
+ 'dogtag': dogtag,
1795
+ 'alias': alias,
1796
+ 'player_info': player_info
1797
+ }
1798
+
1799
+ def search_player_by_dogtag(self, dogtag: str) -> Dict[str, Any]:
1800
+ """
1801
+ Search for a player using their dogtag and return their profile information.
1802
+
1803
+ Args:
1804
+ dogtag: Player's dogtag in XXXX format (hexadecimal)
1805
+
1806
+ Returns:
1807
+ Complete player information including stats if found
1808
+ """
1809
+ return self.get_player_stats_by_dogtag(dogtag)
1810
+
1811
+ def get_player_detailed_stats(self, credential: str) -> Dict[str, Any]:
1812
+ """
1813
+ Get detailed player statistics including game save and inventory.
1814
+
1815
+ Args:
1816
+ credential: Player's credential
1817
+
1818
+ Returns:
1819
+ Detailed player statistics and game data
1820
+ """
1821
+ return self.get_batch_profiles([credential])
1822
+
1823
+ def parse_player_stats(self, stats_data: Dict[str, Any]) -> Dict[str, Any]:
1824
+ """
1825
+ Parse and structure player statistics for easier consumption.
1826
+
1827
+ Args:
1828
+ stats_data: Raw stats data from get_batch_profiles
1829
+
1830
+ Returns:
1831
+ Structured player statistics
1832
+ """
1833
+ if not stats_data or not isinstance(stats_data, dict):
1834
+ return {'error': 'Invalid stats data'}
1835
+
1836
+ # Get the first (and likely only) player's data
1837
+ player_credential = list(stats_data.keys())[0] if stats_data else None
1838
+ if not player_credential or player_credential not in stats_data:
1839
+ return {'error': 'No player data found'}
1840
+
1841
+ player_data = stats_data[player_credential]
1842
+
1843
+ # Extract game save data
1844
+ game_save = player_data.get('_game_save', {})
1845
+ inventory = player_data.get('inventory', {})
1846
+
1847
+ # Parse statistics
1848
+ parsed_stats = {
1849
+ 'credential': player_credential,
1850
+ 'rating': game_save.get('rating', 0),
1851
+ 'rating_duel': game_save.get('rating_duel', 0),
1852
+ 'rating_last': game_save.get('rating_last', 0),
1853
+ 'current_skill': game_save.get('current_skill', 'unknown'),
1854
+ 'current_weapon': game_save.get('current_weapon', 'unknown'),
1855
+ 'current_loadout': game_save.get('current_loadout', 0),
1856
+ 'kill_signature': game_save.get('killsig', {}),
1857
+ 'progress': game_save.get('progress', []),
1858
+ 'loadouts': game_save.get('loadouts', []),
1859
+ 'statistics': game_save.get('statistics', {}),
1860
+ 'inventory': inventory,
1861
+ 'xp': inventory.get('xp', 0),
1862
+ 'vip_points': inventory.get('vip_points', 0)
1863
+ }
1864
+
1865
+ # Parse weapon statistics
1866
+ weapons = inventory.get('weapons', {})
1867
+ weapon_stats = []
1868
+
1869
+ for weapon_id, weapon_data in weapons.items():
1870
+ if isinstance(weapon_data, dict):
1871
+ weapon_stats.append({
1872
+ 'id': weapon_id,
1873
+ 'kills': weapon_data.get('kills', 0),
1874
+ 'shots': weapon_data.get('shots', 0),
1875
+ 'hits': weapon_data.get('hits', 0),
1876
+ 'score': weapon_data.get('score', 0),
1877
+ 'time_used': weapon_data.get('time_used', 0)
1878
+ })
1879
+
1880
+ # Sort by kills
1881
+ weapon_stats.sort(key=lambda x: x['kills'], reverse=True)
1882
+ parsed_stats['weapon_stats'] = weapon_stats
1883
+
1884
+ # Parse overall statistics
1885
+ stats = game_save.get('statistics', {})
1886
+ if stats:
1887
+ sp_stats = stats.get('sp', {})
1888
+ mp_stats = stats.get('mp', {})
1889
+
1890
+ parsed_stats['overall_stats'] = {
1891
+ 'total_kills': sp_stats.get('kill.total', 0) + mp_stats.get('kill.total', 0),
1892
+ 'total_deaths': sp_stats.get('death.total', 0) + mp_stats.get('death.total', 0),
1893
+ 'total_headshots': sp_stats.get('kill.headshots', 0) + mp_stats.get('kill.headshots', 0),
1894
+ 'total_assists': sp_stats.get('kill.assists', 0) + mp_stats.get('kill.assists', 0),
1895
+ 'total_time_played': sp_stats.get('time.played', 0) + mp_stats.get('time.played', 0),
1896
+ 'sp_kills': sp_stats.get('kill.total', 0),
1897
+ 'mp_kills': mp_stats.get('kill.total', 0),
1898
+ 'sp_headshots': sp_stats.get('kill.headshots', 0),
1899
+ 'mp_headshots': mp_stats.get('kill.headshots', 0)
1900
+ }
1901
+
1902
+ return parsed_stats
1903
+
1727
1904
  def __enter__(self):
1728
1905
  """Context manager entry."""
1729
1906
  return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mc5-api-client
3
- Version: 1.0.3
3
+ Version: 1.0.4
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
@@ -960,6 +960,7 @@ The library comes with comprehensive examples to get you started:
960
960
  - `examples/private_messaging.py` - Private messaging and inbox management
961
961
  - `examples/message_management.py` - Advanced message management and bulk deletion
962
962
  - `examples/advanced_features.py` - Events, account management, alias system, game config
963
+ - `examples/player_stats.py` - Player statistics, batch profiles, dogtag search
963
964
 
964
965
  ### 🚀 Advanced Examples
965
966
  - Squad management bot with automated updates
@@ -1028,14 +1029,44 @@ The library comes with comprehensive examples to get you started:
1028
1029
  - ✅ Support for cross-platform data transfer
1029
1030
  - ✅ Account verification and validation
1030
1031
 
1031
- ### 🏷️ Alias/Dogtags System (4+ Methods)
1032
- - ✅ Convert dogtags to alias format
1033
- - Convert aliases back to dogtags
1034
- - ✅ Get player information using alias/dogtag
1035
- - ✅ Search for players by alias
1036
- - Support for hexadecimal player IDs
1037
- - Automatic format detection
1038
- - Mathematical conversion algorithms
1032
+ ### 📊 Player Statistics & Batch Profiles
1033
+
1034
+ Get detailed player statistics using dogtags (in-game IDs) or credentials:
1035
+
1036
+ ```python
1037
+ # Search player by their in-game dogtag
1038
+ player_stats = client.get_player_stats_by_dogtag("f55f")
1039
+ print(f"Player found: {player_stats.get('player_info', {}).get('account', 'Unknown')}")
1040
+
1041
+ # Parse and analyze statistics
1042
+ parsed = client.parse_player_stats(player_stats)
1043
+ print(f"Rating: {parsed.get('rating', 0)}")
1044
+ print(f"K/D Ratio: {parsed.get('overall_stats', {}).get('total_kills', 0) / max(parsed.get('overall_stats', {}).get('total_deaths', 1), 1):.2f}")
1045
+
1046
+ # Get detailed stats for multiple players
1047
+ credentials = ["player1_cred", "player2_cred", "player3_cred"]
1048
+ batch_stats = client.get_batch_profiles(credentials)
1049
+
1050
+ # Search players using dogtags
1051
+ for dogtag in ["f55f", "ff11", "g6765"]:
1052
+ player = client.search_player_by_dogtag(dogtag)
1053
+ if 'error' not in player:
1054
+ print(f"Found: {player.get('player_info', {}).get('account')}")
1055
+ ```
1056
+
1057
+ ### 📊 Player Statistics & Batch Profiles (6+ Methods)
1058
+ - ✅ Get batch player profiles with detailed statistics
1059
+ - ✅ Search players by dogtag (in-game ID)
1060
+ - ✅ Get detailed player statistics using credentials
1061
+ - ✅ Parse and structure player statistics
1062
+ - ✅ Convert dogtags to aliases for API lookup
1063
+ - ✅ Combine alias lookup with stats retrieval
1064
+ - ✅ Support for multiple player batch operations
1065
+ - ✅ Detailed game save and inventory data access
1066
+ - ✅ Weapon statistics and performance analysis
1067
+ - ✅ Campaign progress tracking
1068
+ - ✅ Overall statistics calculation (K/D, accuracy, etc.)
1069
+ - ✅ Player performance analysis tools
1039
1070
 
1040
1071
  ### ⚙️ Game Configuration (4+ Methods)
1041
1072
  - ✅ Get asset hash metadata
@@ -1,12 +1,12 @@
1
1
  mc5_api_client/__init__.py,sha256=VtZ8P-CwnjHSq6VmSuBwVttNXIK3qoOrFuNxXMVeaMc,1021
2
2
  mc5_api_client/auth.py,sha256=Yj_6s8KmtbswWbR6q816d8soIirUF2aD_KWxg-jNqR0,9978
3
3
  mc5_api_client/cli.py,sha256=KegNTxwq28gu_vrffc_cXcALrHzUBDHd-5DqKyYp4p0,17284
4
- mc5_api_client/client.py,sha256=JJxXvPZMJh_Gfp_tO-X2cBmLlbWb-V3zp5RgDT71hsI,58264
4
+ mc5_api_client/client.py,sha256=dHngiS2KgLBJ_WF2Xb0kMAOkWsLggH9jkM2Hz1W0m-w,65469
5
5
  mc5_api_client/exceptions.py,sha256=o7od4GrEIlgq6xSNUjZdh74xoDTytF3PLcMq5ewRiJw,2683
6
6
  mc5_api_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- mc5_api_client-1.0.3.dist-info/LICENSE,sha256=M0UBQ4B3pB9XcV54_jhVP681xyauF8GB6YK_rKmuXzk,1064
8
- mc5_api_client-1.0.3.dist-info/METADATA,sha256=Z6-UrwQ13kJ4n0RmEkWIbbOb6aaZvkFDaY5E9VU_URo,35719
9
- mc5_api_client-1.0.3.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
10
- mc5_api_client-1.0.3.dist-info/entry_points.txt,sha256=2kruOpleFYK3Jl1MoQwGyqCd-Pj4kQWngXmIjnXx_gE,48
11
- mc5_api_client-1.0.3.dist-info/top_level.txt,sha256=eYJe4ue9j1ig_jFY5Z05mDqpizUEV7TYpk5lBXVd4kA,15
12
- mc5_api_client-1.0.3.dist-info/RECORD,,
7
+ mc5_api_client-1.0.4.dist-info/LICENSE,sha256=M0UBQ4B3pB9XcV54_jhVP681xyauF8GB6YK_rKmuXzk,1064
8
+ mc5_api_client-1.0.4.dist-info/METADATA,sha256=oyW9LIWxY9Ov5aAkzRD6JcxUHgEOu0DpcYtIPvNo3vE,37125
9
+ mc5_api_client-1.0.4.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
10
+ mc5_api_client-1.0.4.dist-info/entry_points.txt,sha256=2kruOpleFYK3Jl1MoQwGyqCd-Pj4kQWngXmIjnXx_gE,48
11
+ mc5_api_client-1.0.4.dist-info/top_level.txt,sha256=eYJe4ue9j1ig_jFY5Z05mDqpizUEV7TYpk5lBXVd4kA,15
12
+ mc5_api_client-1.0.4.dist-info/RECORD,,