caganirmak/SteamBot
0
1# Gerekli kütüphaneleri içe aktarıyoruz2import os3import re4import requests5import streamlit as st6from bs4 import BeautifulSoup7from dotenv import load_dotenv8import google.generativeai as genai 9 10# -------------------------------------------------------11# .env dosyasındaki ortam değişkenlerini yüklüyorum.12# -------------------------------------------------------13load_dotenv()14 15#Google API anahtarı ve Gemini modelini kullanıyorum16GEMINI_API_KEY = os.getenv("GOOGLE_API_KEY")17# 'gemini-1.5-flash' kullanıyoruz.18GEMINI_MODEL = os.getenv("GEMINI_MODEL", "gemini-2.5-flash-lite") 19 20# Sisteme verceğim promptu yazıyorum.21SYSTEM_PROMPT = (22""" Sen bir oyun performans asistanısın. Genel kurallar:23Her zaman nazik, kibar ve kısa-öz cevaplar ver.24Uydurma yapma. Emin olmadığın verileri açıkça “varsayım” olarak belirt.25Önce kullanıcıyla normal sohbet isterse kısa ve doğal cevap ver; bu durumda oyunla ilgili sorular sorma.26Veri Kaynağın ve Görevin (Çok Önemli!):271. Senin (Gemini) Steam API'sine veya internete doğrudan erişimin YOKTUR. Web kazıma (web scraping) yapamazsın.282. Kullanıcı bir Steam App ID veya URL'i mesajına eklediğinde, seni çalıştıran uygulama (kod), o oyunun güncel minimum ve önerilen sistem gereksinimlerini Steam API'sinden çeker.293. Bu resmi veriler, sana "--- ANALİZ İÇİN EK BİLGİ (Steam API'den Alındı): ---" başlığı altında, kullanıcının mesajıyla birlikte sunulacaktır.304. Senin görevin, tahmin yaparken KESİNLİKLE bu sana sunulan "ANALİZ İÇİN EK BİLGİ" bloğundaki verileri kullanmaktır. Bu veriler senin birincil gerçeğindir.315. Eğer sana bu "ANALİZ İÇİN EK BİLGİ" bloğu sunulmadıysa (kullanıcı henüz oyun linki/ID'si vermediyse), tahmin yapma ve eksik bilgileri (özellikle oyunun Steam linkini) iste.32Bilgi Toplama (mutlaka alınması gerekenler):33FPS tahmini yapmadan önce KESİNLİKLE şu dört bilgiyi al:341. CPU (tam model adı, ör. "Intel i7-9700K")352. GPU (tam model adı, ör. "RTX 3070")363. RAM (GB cinsinden, ör. "16 GB")374. Oyun (Kullanıcıdan Steam App ID veya Steam mağaza URL'i isteyerek. Bu bilgi gelince kod sana "ANALİZ İÇİN EK BİLGİ" bloğunu sağlayacak.)38Eğer bu bilgiler eksikse tahmin yapma. Eksik bilgileri nazikçe sırayla sor.39Tahmin Mantığı ve Çıktı Formatı:401. Öncelikle kaç FPS alacağını tek satırda söyle (örneğin: "Tahmini: 45–60 FPS (1080p, Medium)").412. Kısa analiz: Sana sunulan Steam verilerine dayanarak hangi bileşenin sınırlayıcı olduğunu (bottleneck) ve çözünürlük/ayarlara göre nasıl değişeceğini 1-3 cümlede açıkla.423. Varsayımlar: Tahmini hangi varsayımlara dayandırdığını kısa maddeler halinde yaz (ör. sürücü güncel, ray tracing kapalı).434. Güven puanı: Tahmine ilişkin basit bir güven seviyesi ver (Yüksek/Orta/Düşük) ve nedenini tek cümlede belirt (örn: "Güven: Yüksek - Çünkü Steam'den alınan resmi verilere göre analiz yapıyorum.").445. Öneri (opsiyonel): Eğer performans düşükse pratik öneriler sun.45Format Örneği (asistanın çıktı şablonu):46Tahmini: <numara veya aralık> FPS (çözünürlük, grafik ön ayarı)47Kısa analiz: <1–3 cümle, Steam verilerine göre>48Varsayımlar: - <madde>49Güven: <Yüksek/Orta/Düşük> — <kısa neden>50Öneri: - <1–2 kısa öneri> (isteğe bağlı detay)51"""52)53 54# -------------------------------------------------------55# Google Gemini Yapılandırması ve Client56# -------------------------------------------------------57@st.cache_resource58def configure_gemini():59 """60 Google Gemini API'sini yapılandırır.61 """62 if not GEMINI_API_KEY: #gemini api key none durumlarında ise63 st.error("GOOGLE_API_KEY bulunamadı. Lütfen .env dosyanıza ekleyin.")64 st.stop() 65 try:66 genai.configure(api_key=GEMINI_API_KEY)67 except Exception as e:68 st.error(f"Google Gemini yapılandırılamadı: {e}")69 st.stop()70 71def gemini_generate_reply(history):72 """73 Gemini modelini kullanarak sohbet geçmişine dayalı bir yanıt üretir.74 Streamlit'in session_state formatını Gemini'nin beklediği formata dönüştürür.75 """76 # Streamlit'in 'st.session_state' içinde tutmuş olduğu mesaj geçmişini Google apisinin kabul etmiş olduğu formata dönüştürüyoruz.77 gemini_history = []78 for msg in history:79 role = "model" if msg["role"] == "assistant" else "user"80 gemini_history.append({"role": role, "parts": [msg["content"]]})81 82 # Son mesajı geçmişten çıkarıyoruz çünkü onu ayrıca göndereceğiz.83 last_message = gemini_history.pop()84 85 try:86 # Modeli sistem talimatıyla başlatıyoruz.87 model = genai.GenerativeModel(88 model_name=GEMINI_MODEL,89 system_instruction=SYSTEM_PROMPT90 91 )92 93 # Sohbeti geçmişle başlatıp yeni mesajı gönderiyoruz.94 chat_session = model.start_chat(history=gemini_history) # mesaj geçmişiyle birlikte gönderilir.95 response = chat_session.send_message(last_message["parts"]) # Son mesajı geçmişten çıkartmıştık onu burada ayrıca gönderiyoruz.96 97 return response.text98 99 except Exception as e:100 st.error(f"Gemini API hatası: {e}")101 return "Üzgünüm, bir hata oluştu ve yanıt üretemedim."102 103 104# -------------------------------------------------------105# Steam Gereksinimleri Yardımcıları106# -------------------------------------------------------107@st.cache_data(ttl=3600) # Steam verisini 1 saatliğine önbelleğe al108def fetch_steam_requirements(app_id: str) -> dict:109 url = f"https://store.steampowered.com/api/appdetails?appids={app_id}&cc=us&l=en"110 try:111 resp = requests.get(url, timeout=10)112 resp.raise_for_status()113 data = resp.json()114 node = data.get(str(app_id), {})115 if node.get("success") and "data" in node:116 pc_reqs = dict(node["data"].get("pc_requirements", {}) or {})117 pc_reqs["name"] = node["data"].get("name", "")118 return pc_reqs119 except Exception as e:120 st.error(f"Steam API hatası: {e}")121 return {}122 123def parse_requirements(html_text: str) -> str:124 if not html_text:125 return ""126 # BeautifulSoup kullanarak HTML'i temiz metne dönüştür127 soup = BeautifulSoup(html_text, "html.parser")128 # Daha temiz bir çıktı için listeleri ve paragrafları düzgünce ayır129 text = soup.get_text(separator="\n").strip()130 # Birden fazla boş satırı tek satıra indir131 return re.sub(r'\n\s*\n', '\n', text)132 133 134def extract_app_id(text: str):135 if not text:136 return None137 s = text.strip()138 if s.isdigit():139 return s140 # Steam URL'lerinden App ID'yi bulan regex141 m = re.search(r"/app/(\d+)", s)142 return m.group(1) if m else None143 144# -------------------------------------------------------145# Streamlit Uygulaması146# -------------------------------------------------------147def main():148 st.set_page_config(page_title="🎮 SteamBot", layout="centered")149 st.title("🤖 SteamBot")150 st.caption("Steam verisi ve Gemini AI ile FPS tahmini yapalım!") 151 152 153 configure_gemini() # geminiyi konuşmaya hazır hale getirdim.154 155 # Sohbeti direkt olarak başlatan bir chatbot tasarladım.156 if "messages" not in st.session_state:157 st.session_state.messages = [158 {"role": "assistant", "content": "Selam! Hangi oyunun FPS analizini yapmamı istersin? (Steam URL'i veya App ID belirtebilirsin)"}159 ]160 161 # Sohbet geçmişini ekranda gösterir162 for msg in st.session_state.messages:163 with st.chat_message(msg["role"]):164 st.markdown(msg["content"])165 166 # Kullanıcıdan yeni giriş al167 if user_input := st.chat_input("Mesajınızı yazın..."):168 st.session_state.messages.append({"role": "user", "content": user_input})169 with st.chat_message("user"):170 st.markdown(user_input)171 172 #Steam Veri Çekme ve Zenginleştirme173 steam_context_str = None174 app_id = extract_app_id(user_input)175 176 # Eğer kullanıcı mesajı bir App ID veya Steam URL'i içeriyorsa177 if app_id:178 with st.spinner(f"Steam'den App ID {app_id} için gereksinimler alınıyor..."):179 reqs = fetch_steam_requirements(app_id)180 if reqs:181 # Oyun adını ve gereksinimleri hazırla182 game_name = reqs.get("name", "")183 min_reqs = parse_requirements(reqs.get("minimum", ""))184 rec_reqs = parse_requirements(reqs.get("recommended", ""))185 186 if min_reqs or rec_reqs:187 # Gemini'ye göndermek için bir "bağlam" metni oluştur188 steam_context_str = f"""189 ---190 ANALİZ İÇİN EK BİLGİ (Steam API'den Alındı):191 Oyun App ID: {app_id}192 Oyun Adı: {game_name or 'Belirtilmemiş'}193 194 Minimum Gereksinimler:195 {min_reqs if min_reqs else 'Belirtilmemiş'}196 197 Önerilen Gereksinimler:198 {rec_reqs if rec_reqs else 'Belirtilmemiş'}199 ---200 Lütfen FPS tahminini bu resmi verilere ve kullanıcının sistemine göre yap.201 """202 203 # Gemini'ye göndereceğimiz sohbet geçmişini hazırlıyoruz204 history_for_gemini = list(st.session_state.messages)205 206 if steam_context_str:207 # Eğer Steam'den veri çektiysek, bu veriyi son kullanıcı mesajına ekliyoruz.208 # Böylece Gemini, kullanıcının sorusunu bu ek bağlamla birlikte analiz eder.209 last_user_message = history_for_gemini.pop()210 augmented_content = f"""211 {steam_context_str}212 213 ---214 Kullanıcının Orijinal Mesajı:215 {last_user_message['content']}216 """217 history_for_gemini.append({"role": "user", "content": augmented_content})218 219 220 #Gemini'den yanıt al221 with st.chat_message("assistant"):222 spinner_text = f"Gemini düşünüyor... ({GEMINI_MODEL})"223 if app_id and steam_context_str:224 spinner_text = f"Steam verisi analiz ediliyor... ({GEMINI_MODEL})"225 226 with st.spinner(spinner_text):227 # Gemini'ye sohbet geçmişini gönder228 reply = gemini_generate_reply(history_for_gemini) 229 230 st.markdown(reply)231 232 # Gelen yanıtı sohbet geçmişinde kalır.233 st.session_state.messages.append({"role": "assistant", "content": reply})234 235 236if __name__ == "__main__":237 238 main()