// Cihaz Merkezi: üretici için sade, kart ızgaralı cihaz ekranı. // Karta tıklanınca o cihazın kendi sayfası açılır (sekme yok): durum, bilgi, // engelle / izin ver, kilitle, komut. Ağ işleri lisans_yonetim_http.cpp'de. #include #include #include #include #include #include #include #include "lisans_yonetim.hpp" #include "fiko/core/gunluk.hpp" #include "fiko/ui/bilesen.hpp" #include "fiko/ui/bilesen_ek.hpp" #include "fiko/ui/tema.hpp" #include "imgui.h" namespace fiko { namespace { struct MerkezDurum { std::vector cihazlar; std::map adlar; // kimlik -> takma ad std::string secili; // seçili cihazın kimliği (boş = ızgara) char arama[64] = ""; bool bilinmeyenGizle = false; char token[128] = ""; // yönetici token (yalnız bellekte) char komutMesaj[160] = ""; int komutSecim = 0; std::string durumMetni; float sonYenile = -99.0f; bool ilk = true; }; MerkezDurum g_m; bool bilinmeyenMi(const CihazOzet& c) { return c.bilgisayar.empty() || c.bilgisayar == "(bilinmiyor)"; } std::string adiBul(const CihazOzet& c) { const auto it = g_m.adlar.find(c.cihazKimlik); if (it != g_m.adlar.end() && !it->second.empty()) return it->second; return bilinmeyenMi(c) ? std::string("(adsız)") : c.bilgisayar; } struct DurumGorunum { ImVec4 renk; const char* etiket; }; DurumGorunum durumOf(const CihazOzet& c) { const ImVec4 kirmizi(0.93f, 0.27f, 0.27f, 1.0f); const ImVec4 gri(0.55f, 0.55f, 0.58f, 1.0f); const ImVec4 yesil(0.30f, 0.80f, 0.45f, 1.0f); const ImVec4 turuncu(0.96f, 0.66f, 0.20f, 1.0f); if (c.engelli || c.kilitli) return {kirmizi, "engelli"}; if (!c.cevrimici) return {gri, "çevrimdışı"}; if (c.uretici == "1") return {yesil, "üretici"}; if (c.seri.empty()) return {turuncu, "lisanssız"}; return {yesil, "bağlı"}; } bool gorunur(const CihazOzet& c) { if (g_m.bilinmeyenGizle && bilinmeyenMi(c)) return false; if (g_m.arama[0] == '\0') return true; std::string hay = adiBul(c) + " " + c.seri + " " + c.musteri + " " + c.ip; std::string ara = g_m.arama; auto kucuk = [](std::string s) { for (char& ch : s) ch = (char)std::tolower((unsigned char)ch); return s; }; return kucuk(hay).find(kucuk(ara)) != std::string::npos; } // Cihaz listesini ve engel durumlarını tazele (oturum açıksa). void verileriTazele() { if (!yonetimDurumu().oturumAcik) { g_m.durumMetni = "Önce Lisans Yönetimi panelinden oturum açın."; return; } std::string hata; std::vector liste; if (!yonetimCihazlariYenile(liste, hata)) { g_m.durumMetni = hata; return; } if (g_m.token[0] != '\0') { std::vector engelliler; std::string ehata; if (yonetimEngelliKimlikleri(g_m.token, engelliler, ehata)) { for (CihazOzet& c : liste) c.engelli = std::find(engelliler.begin(), engelliler.end(), c.cihazKimlik) != engelliler.end(); } } std::map adlar; std::string ahata; if (yonetimCihazAdlariOku(adlar, ahata)) g_m.adlar = adlar; g_m.cihazlar = liste; g_m.durumMetni.clear(); } const CihazOzet* seciliCihaz() { for (const CihazOzet& c : g_m.cihazlar) if (c.cihazKimlik == g_m.secili) return &c; return nullptr; } void ustCubuk() { ImGui::SetNextItemWidth(200.0f); ImGui::InputTextWithHint("##merkez_ara", "ara", g_m.arama, sizeof g_m.arama); ImGui::SameLine(); ImGui::Checkbox("Bilinmeyenleri gizle", &g_m.bilinmeyenGizle); ImGui::SameLine(); if (ImGui::Button("Yenile")) verileriTazele(); ImGui::SameLine(); ImGui::SetNextItemWidth(150.0f); ImGui::InputTextWithHint("##merkez_token", "yönetici token", g_m.token, sizeof g_m.token, ImGuiInputTextFlags_Password); int cevrimici = 0; for (const CihazOzet& c : g_m.cihazlar) if (c.cevrimici) ++cevrimici; ImGui::SameLine(); ImGui::TextDisabled("%d cihaz · %d çevrimiçi", (int)g_m.cihazlar.size(), cevrimici); if (!g_m.durumMetni.empty()) ImGui::TextColored(ImVec4(0.96f, 0.66f, 0.20f, 1.0f), "%s", g_m.durumMetni.c_str()); } void izgara() { const float kartG = 210.0f; const float kartY = 64.0f; const float bosluk = 6.0f; const int sutun = std::max(1, (int)((ImGui::GetContentRegionAvail().x + bosluk) / (kartG + bosluk))); int i = 0; for (const CihazOzet& c : g_m.cihazlar) { if (!gorunur(c)) continue; if (i % sutun != 0) ImGui::SameLine(0.0f, bosluk); ImGui::PushID(c.cihazKimlik.c_str()); ImGui::BeginChild("kart", ImVec2(kartG, kartY), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); const DurumGorunum d = durumOf(c); ImGui::TextColored(d.renk, "●"); ImGui::SameLine(); ImGui::TextUnformatted(adiBul(c).c_str()); ImGui::TextDisabled("%s", c.seri.empty() ? "seri yok" : c.seri.c_str()); ImGui::TextDisabled("%s · %s", d.etiket, c.ip.c_str()); const bool tiklandi = ImGui::IsWindowHovered() && ImGui::IsMouseClicked(0); ImGui::EndChild(); ImGui::PopID(); if (tiklandi) { g_m.secili = c.cihazKimlik; g_m.komutMesaj[0] = '\0'; } ++i; } if (i == 0) ImGui::TextDisabled("Gösterilecek cihaz yok."); } void bilgiSatiri(const char* ad, const std::string& deger) { ImGui::TextDisabled("%s", ad); ImGui::NextColumn(); ImGui::TextUnformatted(deger.empty() ? "-" : deger.c_str()); ImGui::NextColumn(); } void detay(CihazOzet c) { if (ImGui::Button("← Cihazlar")) { g_m.secili.clear(); return; } ImGui::SameLine(); ImGui::TextUnformatted(adiBul(c).c_str()); ImGui::SameLine(); const DurumGorunum d = durumOf(c); ImGui::TextColored(d.renk, "%s", d.etiket); ImGui::Separator(); ImGui::Columns(4, "bilgi", false); ImGui::SetColumnWidth(0, 110.0f); ImGui::SetColumnWidth(1, 220.0f); ImGui::SetColumnWidth(2, 110.0f); ImGui::SetColumnWidth(3, 220.0f); bilgiSatiri("Seri", c.seri); bilgiSatiri("Müşteri", c.musteri); bilgiSatiri("IP", c.ip); bilgiSatiri("Son görülme", c.sonBaglanma); bilgiSatiri("Sürüm", c.surum); bilgiSatiri("Bilgisayar", c.bilgisayar); ImGui::Columns(1); ImGui::Separator(); // Eylemler: engel, kilit if (ImGui::Button(c.engelli ? "İzin ver" : "Engelle", ImVec2(110, 0))) { std::string hata; if (g_m.token[0] == '\0') { ui::toastGoster("Önce yönetici token girin", ui::ToastTip::Hata, 5.0f); } else if (yonetimEngelDegistir(c, !c.engelli, g_m.token, hata)) { ui::toastGoster(c.engelli ? "İzin verildi" : "Engellendi", ui::ToastTip::Basari, 4.0f); verileriTazele(); } else { ui::toastGoster(hata.c_str(), ui::ToastTip::Hata, 7.0f); } } ImGui::SameLine(); if (ImGui::Button(c.kilitli ? "Kilidi aç" : "Kilitle", ImVec2(110, 0))) { std::string hata; if (yonetimKilitle(c, !c.kilitli, "", hata)) { ui::toastGoster(c.kilitli ? "Kilit açma gönderildi" : "Kilit gönderildi", ui::ToastTip::Basari, 4.0f); verileriTazele(); } else { ui::toastGoster(hata.c_str(), ui::ToastTip::Hata, 7.0f); } } // Komut: beyaz listeden seç, mesaj yaz, gönder ImGui::Spacing(); const std::vector& liste = yonetimBeyazListe(); if (!liste.empty()) { if (g_m.komutSecim < 0 || g_m.komutSecim >= (int)liste.size()) g_m.komutSecim = 0; ImGui::SetNextItemWidth(260.0f); if (ImGui::BeginCombo("##komut", liste[(size_t)g_m.komutSecim].c_str())) { for (int k = 0; k < (int)liste.size(); ++k) { const bool secili = (k == g_m.komutSecim); if (ImGui::Selectable(liste[(size_t)k].c_str(), secili)) g_m.komutSecim = k; } ImGui::EndCombo(); } ImGui::SameLine(); ImGui::SetNextItemWidth(260.0f); ImGui::InputTextWithHint("##komutmesaj", "mesaj (ops.)", g_m.komutMesaj, sizeof g_m.komutMesaj); ImGui::SameLine(); if (ImGui::Button("Gönder", ImVec2(90, 0))) { std::string hata; if (yonetimKomutGonder(c, liste[(size_t)g_m.komutSecim], g_m.komutMesaj, hata)) { ui::toastGoster("Komut gönderildi", ui::ToastTip::Basari, 4.0f); } else { ui::toastGoster(hata.c_str(), ui::ToastTip::Hata, 7.0f); } } } // Bu cihazın son komut cevapları ImGui::Spacing(); ImGui::TextDisabled("Son komutlar"); int gosterilen = 0; const std::vector& cevaplar = yonetimCevaplari(); for (auto it = cevaplar.rbegin(); it != cevaplar.rend() && gosterilen < 5; ++it) { if (it->cihazKimlik != c.cihazKimlik) continue; const ImVec4 renk = it->beklemede ? ImVec4(0.6f, 0.6f, 0.6f, 1.0f) : it->basarili ? ImVec4(0.30f, 0.80f, 0.45f, 1.0f) : ImVec4(0.93f, 0.27f, 0.27f, 1.0f); ImGui::TextColored(renk, "%s", it->komutKodu.c_str()); ImGui::SameLine(); ImGui::TextDisabled("%s", it->mesaj.c_str()); ++gosterilen; } if (gosterilen == 0) ImGui::TextDisabled("Henüz komut yok."); } } // namespace void cihazMerkeziCiz(UygulamaBaglam& b, bool& acik) { (void)b; if (!acik) return; ImGui::SetNextWindowSize(ImVec2(960.0f, 620.0f), ImGuiCond_FirstUseEver); if (!ImGui::Begin("🛰 Cihaz Merkezi###cihaz_merkezi", &acik)) { ImGui::End(); return; } // Sık tekrarlanan yenileme (3 sn); ilk açılışta hemen. const float simdi = (float)ImGui::GetTime(); if (g_m.ilk || simdi - g_m.sonYenile > 3.0f) { g_m.ilk = false; g_m.sonYenile = simdi; verileriTazele(); } ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 5.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 8.0f)); if (const CihazOzet* c = seciliCihaz()) { detay(*c); } else { ustCubuk(); ImGui::Separator(); izgara(); } ImGui::PopStyleVar(2); ImGui::End(); } } // namespace fiko