#!/usr/bin/env python3
"""
FreeFire API CLI - Interactive Command Line Interface
Untuk mengakses statistik dan data pemain Free Fire
"""
import requests
import json
from typing import Optional, Dict, Any
import sys
class FreeFire_CLI:
def __init__(self):
self.base_url = "https://epep-api.vercel.app/api/freefire"
self.servers = ["IND", "SG", "RU", "ID", "TW", "US", "VN", "TH", "ME", "PK", "CIS", "BR"]
self.default_server = "IND"
def print_header(self):
"""Menampilkan header aplikasi"""
print("\n" + "="*60)
print(" ๐ฎ FREEFIRE API CLI - Player Statistics Tool ๐ฎ")
print("="*60 + "\n")
def print_menu(self):
"""Menampilkan menu utama"""
print("\n๐ MENU UTAMA:")
print("1. ๐ Cek Statistik Pemain (Player Stats)")
print("2. ๐ค Cek Profil Pemain (Player Profile)")
print("3. ๐ Cari Akun (Search Account)")
print("4. ๐ Ganti Server Region")
print("5. โ Keluar")
print("-" * 60)
def get_player_stats(self):
"""Mendapatkan statistik pemain"""
print("\n๐ CEK STATISTIK PEMAIN")
print("-" * 60)
server = input(f"Server Region [{self.default_server}]: ").strip().upper() or self.default_server
if server not in self.servers:
print(f"โ Server tidak valid! Gunakan: {', '.join(self.servers)}")
return
uid = input("Masukkan Player UID: ").strip()
if not uid:
print("โ UID tidak boleh kosong!")
return
print("\nPilih Game Mode:")
print("1. BR (Battle Royale)")
print("2. CS (Clash Squad)")
gamemode_choice = input("Pilihan [1]: ").strip() or "1"
gamemode = "br" if gamemode_choice == "1" else "cs"
print("\nPilih Match Mode:")
print("1. CAREER")
print("2. NORMAL")
print("3. RANKED")
matchmode_choice = input("Pilihan [1]: ").strip() or "1"
matchmode_map = {"1": "CAREER", "2": "NORMAL", "3": "RANKED"}
matchmode = matchmode_map.get(matchmode_choice, "CAREER")
print("\nโณ Mengambil data...")
try:
response = requests.get(
f"{self.base_url}/player/stats",
params={
"server": server,
"uid": uid,
"gamemode": gamemode,
"matchmode": matchmode
},
timeout=10
)
if response.status_code == 200:
data = response.json()
self.display_stats(data, gamemode, matchmode)
else:
print(f"โ Error: {response.status_code}")
print(response.text)
except Exception as e:
print(f"โ Terjadi kesalahan: {str(e)}")
def display_stats(self, data: Dict[Any, Any], gamemode: str, matchmode: str):
"""Menampilkan statistik pemain"""
print("\n" + "="*60)
print(f"๐ STATISTIK PEMAIN - {gamemode.upper()} ({matchmode})")
print("="*60)
if not data.get("success"):
print("โ Gagal mendapatkan data!")
print(json.dumps(data, indent=2, ensure_ascii=False))
return
stats_data = data.get("data", {})
metadata = data.get("metadata", {})
print(f"\n๐ฎ Server: {metadata.get('server')}")
print(f"๐ UID: {metadata.get('uid')}")
print(f"๐ฏ Mode: {metadata.get('gamemode').upper()} - {metadata.get('matchmode')}")
# Solo Stats
solo = stats_data.get("solostats", {})
if solo and solo.get("gamesplayed", 0) > 0:
print(f"\n{'='*60}")
print("๐ค SOLO STATISTICS")
print(f"{'='*60}")
print(f"๐ฎ Games Played: {solo.get('gamesplayed', 0)}")
print(f"๐ Wins: {solo.get('wins', 0)}")
print(f"๐ Kills: {solo.get('kills', 0)}")
detailed = solo.get("detailedstats", {})
if detailed:
print(f"\n๐ Detailed Stats:")
print(f" ๐ Deaths: {detailed.get('deaths', 0)}")
print(f" ๐ฏ Highest Kills: {detailed.get('highestkills', 0)}")
print(f" ๐ฏ Headshots: {detailed.get('headshots', 0)}")
print(f" ๐ฅ Headshot Kills: {detailed.get('headshotkills', 0)}")
print(f" ๐ฅ Damage: {detailed.get('damage', 0):,}")
print(f" โฑ๏ธ Survival Time: {detailed.get('survivaltime', 0):,}s")
print(f" ๐บ๏ธ Distance Travelled: {detailed.get('distancetravelled', 0):,}m")
print(f" ๐ฆ Pickups: {detailed.get('pickups', 0)}")
print(f" ๐
Top N Times: {detailed.get('topntimes', 0)}")
# Duo Stats
duo = stats_data.get("duostats", {})
if duo and duo.get("gamesplayed", 0) > 0:
print(f"\n{'='*60}")
print("๐ฅ DUO STATISTICS")
print(f"{'='*60}")
print(f"๐ฎ Games Played: {duo.get('gamesplayed', 0)}")
print(f"๐ Wins: {duo.get('wins', 0)}")
print(f"๐ Kills: {duo.get('kills', 0)}")
detailed = duo.get("detailedstats", {})
if detailed:
print(f"\n๐ Detailed Stats:")
print(f" ๐ Deaths: {detailed.get('deaths', 0)}")
print(f" ๐ฏ Highest Kills: {detailed.get('highestkills', 0)}")
print(f" ๐ฏ Headshots: {detailed.get('headshots', 0)}")
print(f" ๐ฅ Headshot Kills: {detailed.get('headshotkills', 0)}")
print(f" ๐ฅ Damage: {detailed.get('damage', 0):,}")
# Squad Stats
quad = stats_data.get("quadstats", {})
if quad and quad.get("gamesplayed", 0) > 0:
print(f"\n{'='*60}")
print("๐จโ๐ฉโ๐งโ๐ฆ SQUAD STATISTICS")
print(f"{'='*60}")
print(f"๐ฎ Games Played: {quad.get('gamesplayed', 0)}")
print(f"๐ Wins: {quad.get('wins', 0)}")
print(f"๐ Kills: {quad.get('kills', 0)}")
detailed = quad.get("detailedstats", {})
if detailed:
print(f"\n๐ Detailed Stats:")
print(f" ๐ Deaths: {detailed.get('deaths', 0)}")
print(f" ๐ฏ Highest Kills: {detailed.get('highestkills', 0)}")
print(f" ๐ฏ Headshots: {detailed.get('headshots', 0)}")
print(f" ๐ฅ Headshot Kills: {detailed.get('headshotkills', 0)}")
print(f" ๐ฅ Damage: {detailed.get('damage', 0):,}")
print(f"\n{'='*60}")
def get_player_profile(self):
"""Mendapatkan profil pemain"""
print("\n๐ค CEK PROFIL PEMAIN")
print("-" * 60)
server = input(f"Server Region [{self.default_server}]: ").strip().upper() or self.default_server
if server not in self.servers:
print(f"โ Server tidak valid! Gunakan: {', '.join(self.servers)}")
return
uid = input("Masukkan Player UID: ").strip()
if not uid:
print("โ UID tidak boleh kosong!")
return
gallery_info = input("Include Gallery Info? (y/n) [n]: ").strip().lower()
need_gallery = "true" if gallery_info == "y" else "false"
print("\nโณ Mengambil data profil...")
try:
response = requests.get(
f"{self.base_url}/player/profile",
params={
"server": server,
"uid": uid,
"need_gallery_info": need_gallery
},
timeout=10
)
if response.status_code == 200:
data = response.json()
self.display_profile(data)
else:
print(f"โ Error: {response.status_code}")
print(response.text)
except Exception as e:
print(f"โ Terjadi kesalahan: {str(e)}")
def display_profile(self, data: Dict[Any, Any]):
"""Menampilkan profil pemain"""
print("\n" + "="*60)
print("๐ค PROFIL PEMAIN")
print("="*60)
basic = data.get("basicinfo", {})
if basic:
print(f"\n๐ Basic Information:")
print(f" ๐ Account ID: {basic.get('accountid')}")
print(f" ๐ค Nickname: {basic.get('nickname')}")
print(f" ๐ Region: {basic.get('region')}")
print(f" โญ Level: {basic.get('level')} (EXP: {basic.get('exp', 0):,})")
print(f" ๐ Rank: {basic.get('rank')} (Points: {basic.get('rankingpoints', 0):,})")
print(f" ๐๏ธ CS Rank: {basic.get('csrank')} (Peak: {basic.get('cspeakpoints', 0):,})")
print(f" ๐ญ Badge ID: {basic.get('badgeid')}")
print(f" โค๏ธ Liked: {basic.get('liked', 0)}")
print(f" ๐
Season ID: {basic.get('seasonid')}")
print(f" ๐ Last Login: {basic.get('lastloginat')}")
if basic.get('weaponskinshows'):
print(f" ๐ซ Weapon Skins: {', '.join(map(str, basic.get('weaponskinshows', [])))}")
if basic.get('gamebagshow'):
print(f" ๐ Game Bag: {basic.get('gamebagshow')}")
social = data.get("socialinfo", {})
if social:
print(f"\n๐ฅ Social Information:")
print(f" ๐ฃ๏ธ Language: {social.get('language', 'N/A')}")
print(f" โ๏ธ Signature: {social.get('signature', 'N/A')}")
print(f" ๐
Rank Show: {social.get('rankshow', 'N/A')}")
if social.get('battletag'):
print(f" ๐ฏ Battle Tags: {', '.join(social.get('battletag', []))}")
clan = data.get("clanbasicinfo", {})
if clan and clan.get('clanname'):
print(f"\n๐ฐ Clan Information:")
print(f" ๐ฐ Clan Name: {clan.get('clanname')}")
print(f" ๐ Clan ID: {clan.get('clanid')}")
print(f" ๐๏ธ Badge ID: {clan.get('clanbadgeid')}")
print(f" ๐ผ๏ธ Frame ID: {clan.get('clanframeid')}")
pet = data.get("petinfo", {})
if pet and pet.get('id'):
print(f"\n๐พ Pet Information:")
print(f" ๐ Pet ID: {pet.get('id')}")
print(f" โญ Level: {pet.get('level')}")
print(f" ๐จ Skin ID: {pet.get('skinid')}")
print(f" โจ Selected: {pet.get('isselected')}")
print(f" ๐ฏ Skill ID: {pet.get('selectedskillid')}")
history = data.get("historyepinfo", [])
if history:
print(f"\n๐ Elite Pass History:")
for i, ep in enumerate(history[:5], 1): # Show top 5
print(f" {i}. EP {ep.get('epeventid')} - Badge {ep.get('epbadge')} (x{ep.get('badgecnt')})")
diamond = data.get("diamondcostres", {})
if diamond and diamond.get('diamondcost'):
print(f"\n๐ Diamond Cost: {diamond.get('diamondcost'):,}")
print(f"\n{'='*60}")
def search_account(self):
"""Mencari akun pemain"""
print("\n๐ CARI AKUN PEMAIN")
print("-" * 60)
server = input(f"Server Region [{self.default_server}]: ").strip().upper() or self.default_server
if server not in self.servers:
print(f"โ Server tidak valid! Gunakan: {', '.join(self.servers)}")
return
keyword = input("Masukkan keyword pencarian (min 3 karakter): ").strip()
if len(keyword) < 3:
print("โ Keyword minimal 3 karakter!")
return
print(f"\nโณ Mencari '{keyword}'...")
try:
response = requests.get(
f"{self.base_url}/search/account",
params={
"server": server,
"keyword": keyword
},
timeout=10
)
if response.status_code == 200:
data = response.json()
self.display_search_results(data, keyword)
else:
print(f"โ Error: {response.status_code}")
print(response.text)
except Exception as e:
print(f"โ Terjadi kesalahan: {str(e)}")
def display_search_results(self, data: Dict[Any, Any], keyword: str):
"""Menampilkan hasil pencarian"""
print("\n" + "="*60)
print(f"๐ HASIL PENCARIAN: '{keyword}'")
print("="*60)
infos = data.get("infos", [])
if not infos:
print("\nโ Tidak ada hasil ditemukan!")
return
print(f"\nโ
Ditemukan {len(infos)} akun:\n")
for i, account in enumerate(infos, 1):
print(f"{i}. {'='*55}")
print(f" ๐ UID: {account.get('accountid')}")
print(f" ๐ค Nickname: {account.get('nickname')}")
print(f" ๐ Region: {account.get('region')}")
print(f" โญ Level: {account.get('level')} (EXP: {account.get('exp', 0):,})")
print(f" ๐ BR Rank: {account.get('rank')} ({account.get('rankingpoints', 0):,} pts)")
print(f" ๐๏ธ CS Rank: {account.get('csrank')} (Max: {account.get('csmaxrank')})")
print(f" โค๏ธ Liked: {account.get('liked', 0)}")
print(f" ๐ญ Badge ID: {account.get('badgeid')}")
if account.get('clanname'):
print(f" ๐ฐ Clan: {account.get('clanname')} (ID: {account.get('clanid')})")
if account.get('weaponskinshows'):
print(f" ๐ซ Weapon Skins: {len(account.get('weaponskinshows', []))} shown")
if account.get('gamebagshow'):
print(f" ๐ Game Bag: {account.get('gamebagshow')}")
print(f" ๐ Last Login: {account.get('lastloginat')}")
print(f"\n{'='*60}")
def change_server(self):
"""Mengganti server region default"""
print("\n๐ GANTI SERVER REGION")
print("-" * 60)
print("Server yang tersedia:")
for i, server in enumerate(self.servers, 1):
marker = "โ" if server == self.default_server else " "
print(f" [{marker}] {i}. {server}")
choice = input(f"\nPilih server (1-{len(self.servers)}): ").strip()
try:
index = int(choice) - 1
if 0 <= index < len(self.servers):
self.default_server = self.servers[index]
print(f"โ
Server berhasil diubah ke: {self.default_server}")
else:
print("โ Pilihan tidak valid!")
except ValueError:
print("โ Masukkan angka yang valid!")
def run(self):
"""Menjalankan CLI"""
self.print_header()
print(f"๐ Current Server: {self.default_server}")
while True:
self.print_menu()
choice = input("Pilih menu (1-5): ").strip()
if choice == "1":
self.get_player_stats()
elif choice == "2":
self.get_player_profile()
elif choice == "3":
self.search_account()
elif choice == "4":
self.change_server()
elif choice == "5":
print("\n๐ Terima kasih telah menggunakan FreeFire API CLI!")
print("="*60 + "\n")
sys.exit(0)
else:
print("โ Pilihan tidak valid! Silakan pilih 1-5.")
input("\n๐ Tekan ENTER untuk melanjutkan...")
if __name__ == "__main__":
try:
cli = FreeFire_CLI()
cli.run()
except KeyboardInterrupt:
print("\n\n๐ Program dihentikan. Terima kasih!")
sys.exit(0)
except Exception as e:
print(f"\nโ Error tidak terduga: {str(e)}")
sys.exit(1)