🚀 DUYURU: YudumSosyal Eğlence Devrimi Başlıyor! (Canlı Oyun Motoru Entegrasyonu)🎉 Yeni WebChat yayında — hemen dene!
Güncelleme

YudumSosyal Güncelleme — Tek Kişilik Oyunlar, Güvenlik Sertleştirmeleri ve Mobil Düzeltmeler

YudumSosyal'a tek kişilik oyunlar bölümü eklendi: 801 aday tarandı, güvenlik denetiminden geçen oyunlar kendi sunucumuzda barındırılıyor — reklam SDK'sı, dış istek ve takip kodu taşıyanlar reddediliyor. Ayrıca CSP başlık taşması, nöbetçi yanlış alarmı, mobil sarma kuralları ve oyun çerçevesindeki odak sorunu kapatıldı.

YudumSosyal Güncelleme — Tek Kişilik Oyunlar, Güvenlik Sertleştirmeleri ve Mobil Düzeltmeler
✍ Yudum Editör 📅 2026-08-09T15:01:39 👁 20 okunma
𝕏 f W

YudumSosyal

Platform: LinuxSürüm: YudumSosyal2.5-Beta (Go 1.26.5)
İndir

YudumSosyal, Go ve WebAssembly üzerine kurulu tek süreçli iletişim platformumuz. İlk tanıtım yazısında mimariyi anlatmıştık; bu yazı o yazının devamı: ne eklendi, ne çıkarıldı, hangi arıza nasıl kapatıldı. Teknik ayrıntı seviyesi bilerek yüksek tutuldu — neyi neden yaptığımızı kayda geçiriyoruz.

🕹 Yeni bölüm: Tek Kişilik Oyunlar

Platforma reklamsız, kurulumsuz, tarayıcıda çalışan oyunlar eklendi. Bunlar dışarıdan alınan açık kaynak HTML5 oyunları ama bizim sunucumuzda barınıyorlar — hazır bir oyun sağlayıcısının çerçevesini gömmüyoruz.

Bu tercihin sebebi teknikti. Hazır oyun API'leri (GameDistribution, GameMonetize vb.) oyunu kendi sunucularından iframe ile verir; bu da reklam SDK'sı, üçüncü taraf takip kodu, kullanıcı IP'sinin dışarı gitmesi ve içerik güvenlik politikamızı (CSP) dışarıya açmak demektir. Onun yerine oyunları indirip denetleyip kendimiz barındırıyoruz.

Kurulum hattı ve güvenlik kapısı

Her oyun, GitHub'daki sabit bir commit'ten indiriliyor (dalın ucuna bağlanmıyoruz — yarın depo değişince oyunumuz habersiz bozulmasın ya da denetlenmemiş kod gelmesin). İndirilen paket şu denetimden geçmeden kurulmuyor:

  • Dışarıya istek atan paket reddedilir — uzak script, uzak stil, uzak görsel/çerçeve, fetch/XHR ile dış adres, WebSocket.
  • Reklam SDK'sı ve analitik reddedilir — googlesyndication, doubleclick, Google Analytics, gtag, mixpanel, hotjar…
  • Uzak yazı tipi reddedilir (fonts.googleapis/gstatic).
  • Lisans süzgeci: MIT, Apache-2.0, BSD, CC0, ISC, Unlicense, Zlib alınır. GPL alınmaz — kaynak sunma yükümlülüğü doğurur.
  • .svg dosyaları atılır (yükleme yasağımız XSS içindir, aynı riski burada da sıfırlıyoruz).
  • Uyarı olarak işaretlenenler: dış bağlantı, yerel depolama, native confirm/alert kullanımı, sayfa açılır açılmaz başlayan sayaç, latin dışı arayüz (Çince/Kiril — elle çeviri ister).

Rakamla: 801 aday tarandı, 388'i güvenlik denetiminden geçti, kalite süzgecinden sonra 308 oyun kurulmaya uygun bulundu. Elenenlerin 58'i uzak script, 33'ü uzak stil, 3'ü analitik taşıdığı için reddedildi — yani bu oyunlar kurulsaydı kullanıcılarımızın IP'si üçüncü taraflara gidecekti.

Türkçeleştirme

Bu oyunlar İngilizce (bazen Çince) geliyor. Oyun başına elle çeviri ölçeklenmediği için iki katmanlı bir çözüm kuruldu:

  • Ortak sözlük — "New Game", "Score", "Game Over", "Restart" gibi yüz kadar yaygın terim bir kez yazıldı, her kurulumda tüm oyunlara otomatik uygulanıyor. Yeni oyunun çeviri maliyeti sıfır.
  • Oyuna özel yama — sözlüğün yakalayamadığı cümleler için. Yama dosyada durur ve her kurulumda yeniden uygulanır; yani oyunu kaynağından güncellediğinizde çeviri kaybolmaz.

Sözlük yalnız HTML metinlerine dokunur, JavaScript'e asla: "Score" bir değişken adı da olabilir ve kod içinde metin değiştirmek oyunu sessizce bozar. Yönetim panelinde ayrıca bir çeviri ekranı var — oyunun çevrilmemiş metinlerini kendisi çıkarıyor, karşısına Türkçesi yazılıyor.

🎲 Oyun motoru (masa oyunları)

/oyna altındaki masa oyunu motoru kendi yazdığımız katmanlı bir sistem: kural paketi → masa (koltuk/izleyici/kopma/puanlama) → kalıcılık → arayüz. İki tasarım kararı önemli:

  • Zar math/rand değil, (tohum, sayaç) çiftinden belirlenimci üretiliyor. Getirisi: sunucu yeniden başlasa bile masa kaldığı yerden devam eder ve "zar hileli" şikayeti hamle günlüğüyle objektif olarak denetlenebilir. Tohum istemciye asla gitmez.
  • Her koltuğa ayrı görüntü döndürülüyor. Tavlada gereksiz ama okeyin gizli eli buna bağlı — sonradan eklenemeyecek bir karardı.

Yeni oyun eklemek = yalnızca kural paketi yazmak. Masa, koltuk, izleyici, kopma, sıralama, rozet ve moderasyon hazır.

🔒 Güvenlik ve dayanıklılık

CSP başlığı: sessiz bir bomba

İçerik güvenlik politikamız panelden eklenen alan adlarını her yönergeye tekrar tekrar yazıyordu. Başlık boyutu (alan sayısı × yönerge sayısı) kadar büyüyor ve nginx'in 4 KB'lık tampon sınırına dayanmıştı. Yönerge listesi büyütülünce başlık taştı ve sunucu sağlıklı olmasına rağmen her istek 502 döndü — sayfalar üretiliyor, başlık öldürüyordu.

Kalıcı çözüm: stil/yazı tipi kaynakları ayrı bir ayara alındı, artık reklam alan adları style-src'ye kopyalanmıyor. Başlık 4 KB üstünden 2,7 KB'a indi. Üstüne bir de otomatik test yazıldı: CSP bütçeyi aşarsa derleme aşamasında patlıyor, canlıya çıkamıyor. nginx tamponu da emniyet olarak 16 KB'a çıkarıldı.

Nöbetçi: yanlış alarmın maliyeti

Sunucu nöbetçimiz yalnız swap yüzdesine bakıyordu. Oysa Linux, swap'a bir kez yazdığı sayfaları RAM boşalsa bile geri okumaz; baskı geçtikten sonra da swap dolu görünür. Sonuç: tek seferlik bir bellek baskısı 14 saat boyunca "sistem yavaşlıyor" alarmı ürettirdi. Yanlış alarm, gerçek sorunu maskeler.

Artık uyarı için iki koşul birlikte aranıyor: swap yüksek ve kullanılabilir bellek %15'in altında. Ayrıca nöbetçi artık ölçüm kaydı tutuyor — her turda kullanılabilir bellek, swap ve en büyük üç süreç bir günlüğe yazılıyor. Bir daha "gece ne oldu" sorusu cevapsız kalmayacak.

📱 Mobil

Trafiğin ağırlığı mobil olduğu için arayüz kuralımız netleşti: mobil asıl durumdur, masaüstü istisnadır. Somut bir örnek: yardım sayfalarındaki "içindekiler" kartları flex-wrap:nowrap ile yazılmış, sarma yalnız 640 pikselin altında açılıyordu. 15 başlıklı bir sayfada 641 pikselden geniş her ekranda kartlar tek satıra sıkışıp okunmaz hale geliyordu.

Ders şu: eleman sayısı da genişliği belirler, kırılma noktası bunu bilemez. Artık akışkan kural kullanıyoruz (flex-wrap:wrap + taban genişlik, auto-fill + minmax), satır başına sabit eleman sayısı vermiyoruz.

🎮 Oyun sayfalarında etkileşim

Oyunlar çerçeve (iframe) içinde çalışıyor — kendi CSS ve JavaScript'leri sitenin düzenini bozmasın diye. Ama ilk sürümde ne fare ne klavye çalışıyordu; ok tuşuna basınca oyun değil sayfa kayıyordu.

Sebep: odak hiçbir zaman çerçeveye geçmiyordu. Tuşlar ana belgeye gidiyor, tarayıcı da onları kaydırma komutu sayıyordu. Çözüm üç kuralda toplandı: oyun ekranda görününce odak ona verilir, oyun alanına her tıklamada geri verilir, odak oyundayken ok tuşları sayfayı kaydırmaz.

🎙 Sesli / görüntülü sohbet ve canlı yayın

Platformun en ağır teknik katmanı burası. Sohbet odalarında sesli ve görüntülü görüşme, ayrıca canlı yayın altyapısı çalışıyor — ikisi de tarayıcıdan, eklenti kurmadan.

Sesli/görüntülü sohbet: neden kendi TURN sunucumuz var

WebRTC iki kullanıcıyı doğrudan bağlamaya çalışır, ama gerçek dünyada kullanıcıların çoğu ev modeminin (NAT) arkasında. İki taraf da NAT arkasındaysa doğrudan bağlantı kurulamaz ve görüşme sessizce başarısız olur. Bunun için kendi TURN sunucumuzu (coturn) çalıştırıyoruz: doğrudan bağlantı kurulamadığında ses/görüntü trafiği sunucu üzerinden aktarılıyor. Üçüncü taraf bir TURN hizmeti kullanmıyoruz — trafik bizim sunucumuzda kalıyor.

Canlı yayın: RTMP/SRT ile alınır, WHEP ile dağıtılır

Yayın hattı MediaMTX üzerine kurulu. Yayıncı isterse doğrudan tarayıcıdan (WHIP), isterse OBS gibi bir programdan RTMP ya da SRT ile yayın açabiliyor. İzleyici tarafında WHEP kullanılıyor: yayın doğrudan tarayıcıda açılıyor, HLS'in getirdiği 10-20 saniyelik gecikme yok. Yayın açma yetkisi bizim kendi ucumuzdan doğrulanıyor (/api/yayin/izin) — yayıncı kimliği IRC hesabına bağlı.

Bu hatta çıkan üç gerçek arıza

Bu katman kolay değildi; üç arıza da sessizce bozulan cinstendi:

  • Teklif sıfır adayla gidiyordu. WebRTC'de bağlantı adayları (ICE candidate) teklif nesnesine değil localDescription'a eklenir. Kod, teklifi oluşturur oluşturmaz orijinal nesneyi gönderiyordu; sunucu hiçbir aday görmüyor, bağlantı hiç kurulmuyordu. Çözüm: yerel açıklama uygulandıktan sonra gönderim ve sonradan gelen adayların trickle ICE ile bildirilmesi.
  • "Görüntü var, ses yok." ontrack olayı iki kez tetiklenir — bir kez ses (Opus), bir kez görüntü (VP8). Kod her seferinde srcObject'i yeniden atadığı için ikinci parça birincinin yerini alıyor, ses ya da görüntüden biri kayboluyordu. Sunucuda iki parçanın da geldiği ölçümle doğrulandı; doğrusu tek bir akış tutup gelen her parçayı ona eklemek.
  • TURN adresi ayarı boş kaydedilmişti ve bağlantı "STUN host lookup" hatasıyla düşüyordu. Ayara boşluk koruması eklendi.

Yayın duyurusu tarafında da bir kusur kapatıldı: yayın başlayınca çıkan "katılmak ister misin?" penceresi giriş ekranında bekleyen kullanıcılara da görünüyordu — yoklama döngüsü çıkıştan sonra durdurulmuyordu. Artık çıkışta gerçekten duruyor, oturum kapalıyken hiç duyuru üretilmiyor.

🔎 Bulunabilirlik

  • Oyun sayfaları site haritasına eklendi — yüzlerce yeni sayfa arama motoruna görünür oldu.
  • Sayfa başlıkları ve açıklamaları şablondan üretiliyor, ham metin basılmıyor. Aranan kelimeler ("ücretsiz", "online", "oyna", "kayıt yok") ve oyunun adı artık açıklamada geçiyor.
  • VideoGame yapılandırılmış verisi eklendi; oyun sayfaları arama sonuçlarında oyun olarak tanınıyor.
  • Kategori sayfaları açıldı, her kategorinin kendi başlığı ve açıklaması var. Liste sayfasında arama, sıralama (popüler / yeni / A-Z) ve sayfalama çalışıyor.
  • Popülerlik ölçümle belirleniyor: oyunlar gerçek oynanma sayısına göre sıralanıyor, elle sıra verilmiyor.

🏷 Platform kimliği ve sürüm yönetimi

Bu güncellemeyle YudumSosyal artık kendini tanıtan bir platform: /yudumsosyal adresinde kendi sayfası var — sürümü, çalışma süresi, barındırdığı oyun sayısı ve yetenek dökümü canlı olarak orada. Sitenin altbilgisinde de "… ile çalışır" bağlantısı bulunuyor; WordPress ve Joomla'nın yaptığı gibi.

Teknoloji tespit araçlarının (Wappalyzer, BuiltWith) baktığı iki yere de imza kondu: sayfa başlığında <meta name="generator"> ve HTTP yanıtında X-Powered-By. İkisi de ayarla kapatılabiliyor — sürüm bilgisini dışarı vermek istemeyen kurulumlar için.

Sürüm artık elle yazılmıyor

Bu iş bir kusuru kapatmak için başladı: sürüm birden çok yerde elle yazılıyordu ve senkron kalmıyordu. IRC sunucusu bir sürüm bildiriyor, kullanım dışı kalmış bir dosyada aylar öncesinin sürümü duruyor, tanıtım yazısında başka bir numara yazıyordu.

Artık tek kaynak var: derleme betiği ana sürümü bir dosyadan okuyor, yapı sayacını her derlemede kendiliğinden bir artırıyor ve sonucu doğrudan çalıştırılabilir dosyaya gömüyor. IRC bildirimi, altbilgi, meta etiketi, HTTP başlığı ve platform sayfası — hepsi aynı değeri okuyor. Kodun hiçbir yerinde sürüm metni düzenlenmiyor.

🖼 Oyun kapakları: gerçek ekran görüntüleri

Tek kişilik oyunlar bölümü ilk açıldığında bütün kartlarda aynı emoji vardı — üç yüz oyun, tek görsel. Oyunların kendi favicon'larını kullanmak denendi ve yetmedi: yalnız 55'inde vardı, çoğu 16 piksellik iş görmez ikonlardı.

Çözüm, oyunun gerçek görüntüsünü almak oldu. Sunucuda başsız bir tarayıcı her oyunu tek tek açıyor, oyun çizilene kadar bekliyor ve ekran görüntüsünü kaydediyor. Bu kapaklar oyunun kendi klasöründe duruyor; oyun silindiğinde onunla birlikte gidiyor.

Yol boyunca iki şey öğrenildi. Birincisi teknik: ekran görüntüsü alırken tarayıcıya "önce çiz, sonra çek" demezseniz stilsiz, çıplak HTML yakalıyorsunuz — ilk denemede 2048 böyle çıktı. İkincisi tasarım: emoji ile kapak görseli ayrı alanlar olmalı. İkisini tek alanda tutmayı denemek kartlarda dosya yollarının düz yazı olarak görünmesine yol açtı.

Ayrıca: "açılıyor mu" testi

Kurulan 310 oyunun hepsi güvenlik denetiminden geçmişti, ama güvenli olmak çalışmak demek değil. Her oyunun giriş dosyasındaki yerel başvurular tarandı ve diskte var mı diye bakıldı: 207 oyun sağlam, 95'inde eksik dosya bulundu. Eksiklerin bir kısmının sebebi bizzat kendi kurulum hattımızdı — güvenlik gereği sildiğimiz bazı dosya türlerine (ör. vektör görseller) o oyunlar bağımlıydı. Yalnız testi geçen 207 oyun yayına alındı; kalanlar kapalı bekliyor.

Çıkarılanlar

  • Hazır oyun portalı fikri — reklam SDK'sı, dış istek ve CSP'yi açma zorunluluğu yüzünden elendi.
  • Periyodik DOM gözcüleriwebchat'te beş ayrı zamanlayıcı arayüzü sürekli tarıyordu; donma ve çökme kaynağıydı, tamamen kaldırıldı.
  • Native confirm/alert kutuları — kendi onay pencerelerimiz var; tarayıcının kutusu hem çirkin hem çevrilemiyor.
  • Eski yönetim adresi — tek yönetim kökü kaldı.

Yol haritası

Sırada dama var (gizli bilgi içermediği için motoru sınamaya ideal), ardından okey. Tek kişilik oyun havuzu genişlemeye devam edecek; kurulum hattı ve denetim kapısı hazır olduğu için yeni oyun eklemek artık sunucuya girmeyi gerektirmiyor — yönetim panelinden depo adresi ve sürüm girmek yeterli.

Oyunlara göz atın: /oyna · /oyna/tek

Bu haberi paylaş 𝕏 f W T

✨ Keşfetmeye Devam Et