aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Metin2 Ranking Sitesi Yapımı (PHP + MySQL)

Bir Metin2 ranking sitesi, sunucunun veritabanından oyuncu ve lonca verilerini çekip ziyaretçilere sıralı tablolar halinde gösteren küçük ama etkili bir web uygulamasıdır. Oyuncuların kendi seviyelerini, lonca puanlarını ve PvP istatistiklerini görebildiği bu sayfalar; topluluğu canlı tutar, rekabeti besler ve sunucuna profesyonel bir hava katar. Bu yazıda PHP ve MySQL kullanarak sıfırdan, güvenli ve performanslı bir sıralama sayfasının nasıl kurulduğunu adım adım anlatıyorum.

Metin2 veritabanı yapısını anlamak

Metin2 sunucuları verilerini birden çok MySQL veritabanına böler: oyuncu bilgileri genellikle player veritabanında, hesaplar ise account veritabanında tutulur. Bir ranking sitesi için ilgilendiğimiz iki ana tablo şunlardır:

  • player.player — her karakterin name, level, exp, playtime, job (sınıf) ve guild_id gibi alanları burada bulunur.
  • player.guild — lonca adı (name), seviyesi (level), deneyimi (exp) ve lonca savaşı sonuçları (win, draw, loss) burada saklanır.

Önemli bir not: ranking sitesi asla oyun sunucusunun yazdığı tabloları değiştirmemeli. Sadece SELECT sorguları çalıştıran, salt-okunur bir MySQL kullanıcısı oluşturmak en güvenli yaklaşımdır.

CREATE USER 'ranking'@'localhost' IDENTIFIED BY 'guclu_bir_parola';
GRANT SELECT ON player.player TO 'ranking'@'localhost';
GRANT SELECT ON player.guild TO 'ranking'@'localhost';
FLUSH PRIVILEGES;

Güvenli veritabanı bağlantısı (PDO)

PHP'de MySQL'e bağlanmanın modern ve güvenli yolu PDO'dur. Hazır ifadeler (prepared statements) sayesinde SQL enjeksiyonuna karşı korunuruz. Bağlantıyı tek bir dosyada toplamak, ileride yönetmeyi kolaylaştırır:

<?php
// db.php
$host = '127.0.0.1';
$db   = 'player';
$user = 'ranking';
$pass = 'guclu_bir_parola';

$dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    http_response_code(500);
    exit('Veritabanına bağlanılamadı.');
}

Veritabanı parolasını kaynak koduna gömmek yerine, üretim ortamında bir .env dosyasından veya sunucu ortam değişkeninden okumak daha güvenlidir.

Oyuncu sıralamasını çekmek

En klasik Metin2 ranking sitesi tablosu, oyuncuları seviyeye ve deneyime göre sıralar. Bir karakterin tam ilerlemesini doğru sıralamak için önce level, eşitlik durumunda exp alanına bakarız:

<?php
$stmt = $pdo->prepare(
    "SELECT name, level, exp, playtime
     FROM player
     ORDER BY level DESC, exp DESC
     LIMIT :limit"
);
$stmt->bindValue(':limit', 50, PDO::PARAM_INT);
$stmt->execute();
$players = $stmt->fetchAll();

Sayfa başına 50 satır göstermek hem okunabilir hem de performanslıdır. Daha fazlasını göstereceksen sayfalama (pagination) eklemeyi düşün.

Verileri HTML tablosunda göstermek

Veritabanından gelen her metni ekrana basarken htmlspecialchars() ile kaçışlamak şarttır; aksi halde özel karakterli oyuncu adları XSS açığına yol açabilir. playtime dakika cinsinden tutulur, onu saate çevirerek daha okunabilir gösteririz:

<table>
  <thead>
    <tr><th>#</th><th>İsim</th><th>Seviye</th><th>Süre</th></tr>
  </thead>
  <tbody>
  <?php foreach ($players as $i => $p): ?>
    <tr>
      <td><?= $i + 1 ?></td>
      <td><?= htmlspecialchars($p['name']) ?></td>
      <td><?= (int) $p['level'] ?></td>
      <td><?= round($p['playtime'] / 60) ?> saat</td>
    </tr>
  <?php endforeach; ?>
  </tbody>
</table>

Lonca sıralaması ekleme

Oyuncu tablosunun yanına bir de lonca sıralaması koymak topluluk rekabetini güçlendirir. Loncaları seviyeye ve kazanılan lonca savaşlarına göre sıralayabiliriz:

<?php
$stmt = $pdo->query(
    "SELECT name, level, win, draw, loss
     FROM guild
     ORDER BY level DESC, win DESC
     LIMIT 20"
);
$guilds = $stmt->fetchAll();

Ayrıca player ve guild tablolarını guild_id üzerinden birleştirerek "en kalabalık loncalar" gibi ek tablolar da üretebilirsin.

Sayfalama ve arama eklemek

Sunucun büyüdükçe oyuncuların ilk 50 kişiyle yetinmesini istemezsin; herkes kendi sırasını merak eder. Bu yüzden sayfalama (pagination) ve basit bir isim araması, ranking sitesini çok daha kullanışlı hale getirir. Sayfa numarasını URL'den okurken yine tür dönüşümü yaparak güvenliği koruruz:

<?php
$page    = max(1, (int) ($_GET['page'] ?? 1));
$perPage = 50;
$offset  = ($page - 1) * $perPage;

$stmt = $pdo->prepare(
    "SELECT name, level, exp
     FROM player
     ORDER BY level DESC, exp DESC
     LIMIT :limit OFFSET :offset"
);
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();

İsim aramasında ise kullanıcı girdisini doğrudan sorguya koyma; hazır ifadeyle LIKE kullanarak parametre olarak bağla. Bu hem güvenlidir hem de oyuncuların kendi karakterlerini hızlıca bulmasını sağlar.

Sayfayı sunucunun temasına uydurmak

Teknik altyapı kadar görsel sunum da önemlidir. Bir ranking sayfası, sunucunun ana sitesiyle aynı renk paletini, yazı tipini ve logo dilini kullandığında profesyonel görünür. İlk üç sırayı altın/gümüş/bronz renklerle vurgulamak, lonca amblemlerini göstermek ve mobil uyumlu bir tablo tasarlamak ziyaretçi deneyimini belirgin biçimde iyileştirir. Tabloyu küçük ekranlarda yatay kaydırılabilir bir kapsayıcıya alman, taşmayı önler.

Performans ve önbellekleme

Her ziyaretçi için canlı sorgu çalıştırmak, oyuncu sayısı arttığında veritabanını yorar. Sıralamalar saniyede bir değişmediği için sonuçları kısa süreli önbelleğe almak çok mantıklıdır:

  • Sorgu sonucunu birkaç dakikalık bir dosya veya Redis önbelleğinde tut, süresi dolunca yenile.
  • Sık sıralanan alanlara (level, exp) MySQL indeksi olduğundan emin ol.
  • Ranking sitesini oyun sunucusunun çalıştığı makineden farklı bir alana koyup, sadece salt-okunur kullanıcıyla bağlan.

Sık Sorulan Sorular

Ranking sitesi oyun sunucusunu yavaşlatır mı?

Doğru yapılandırıldığında hayır. Salt-okunur bir kullanıcı, indekslenmiş sorgular ve birkaç dakikalık önbellek kullanırsan veritabanı yükü ihmal edilebilir düzeyde kalır.

Oyuncu adlarındaki Türkçe karakterler bozuk görünüyor, neden?

Genellikle karakter seti uyuşmazlığıdır. PDO bağlantısında charset=utf8mb4 kullandığından ve HTML sayfanın <meta charset="utf-8"> içerdiğinden emin ol.

Hangi alanlara göre sıralamalıyım?

En yaygın seçimler seviye + deneyim, lonca seviyesi ve PvP/kill istatistikleridir. Sunucunun türüne göre playtime veya altın gibi alanlar da ilgi çekici olabilir.

Sunucun için profesyonel bir ranking sitesi mi istiyorsun? PHP ve MySQL ile güvenli, hızlı ve sunucunun temasına uygun sıralama sayfaları tasarlayıp kurabilirim. Projeni konuşmak için benimle iletişime geç.

Bu kategorideki tüm yazılar →

Devamı için