Dosya Tabanlı Depolama
Giriş
Veri Depolama (Data Storage), verilerin harita değişiklikleri ve sunucu yeniden başlatmaları boyunca kalıcı olmasını istediğimizde kullandığımız yöntemdir.
Garry's Mod'da veri depolamanın birden çok yolu vardır. Bu eğitimde, Dosya Tabanlı Depolama'yı (File Based Storage) ele alacağız.
Veri işleme kuralları
Herhangi bir veriyi işlerken uymamız gereken bazı kurallar vardır:
Asla istemci tarafından işlenmiş verilere güvenmeyin. Tüm verileri sunucuda yedekli tutun, çünkü verilerin orijinal olduğundan emin olmanın tek yolu budur. Diyelim ki istemcilerin paralarını takip etmelerine izin vermeye başladık; sonuna birkaç sıfır eklemelerini ne engelleyebilir ki?
Daima istemcinin manipüle edemeyeceği bir kimlik bilgisi kullanın. Bir istemcinin çıkış yaptığında canını kaydetmek isteseydik ve kimlik olarak Steam adlarını kullansaydık, bir sonraki girişlerinden önce bunu değiştirmelerini ne engelleyebilir? Hiçbir şey. Bu yüzden Player:SteamID gibi, istemci tarafından asla değiştirilemeyecek kimlik bilgileri kullanmalıyız.
Fark etmediyseniz, burada kapsayıcı bir tema var: İstemciye asla güvenme.
Ne yazık ki, Garry's Mod sunucuları öngörülebilir değildir - uyarı vermeden kolayca çökebilir veya aşırı yüklenebilirler. Bu nedenle, veriyi kaybetmemek için mümkün olduğunca çabuk işlemelisiniz. Oyuncunun oynarken kazandığı jeton sayısını kaydetmek için oyundan ayrılmasını beklemeyin, çünkü sunucu o zamandan önce ölümcül bir çökme yaşayabilir. Ayrıca, verileri GM:ShutDown hook'u sırasında kaydetmemelisiniz, çünkü bazı oyuncular geçersiz hale geleceği ve değerli jeton sayılarının kaybolacağı için veri kaydetmeye başlamak için çok geç olabilir. Ancak, bunu okuyor olabilirsiniz ve verilerinizin en son anda kaydedilmesi gerektiğini veya her değiştirildiğinde kaydedilecek kadar önemli olmadığını düşünebilirsiniz - bu durumda, GM:ShutDown hook'unu riski size ait olmak üzere kullanabilirsiniz!
Hakkında
Metin dosyaları, veri depolamanın basit bir yoludur. Dosya Tabanlı Depolama, yalnızca file kütüphanesine dayandığı ve oldukça basit olduğu için herhangi bir harici modül gerektirmez. Bu nedenlerden dolayı, yeni başlayanlar için önerilen yöntemdir.
Tabloları depolama - util.TableToJSON
Bu, belki de Color veya Vector gibi veri türlerini dönüştürürken yaşanan hayal kırıklığını önleyecek, yeni başlayanlar için en kolay yöntemdir, bu yüzden önce bu yöntemle başlayacağız.
Tabloları metin dizisine (string) dönüştürme
Bir metin dosyası temel olarak bir karakter dizisidir. Bu, tüm verilerimizi bir karakter dizisine dönüştürmemiz gerektiği anlamına gelir...
util.TableToJSON, bir Lua tablosunu JSON formatına dönüştürecek bir fonksiyondur. JSON, (Lua tabloları gibi) belirli verileri metin olarak temsil etmek için popüler bir formattır; bu metin bir dosyaya kaydedilebilir ve daha sonra aynı veriye geri dönüştürülebilir.
util.TableToJSON'ı nasıl kullanabileceğimize dair bir örnek:
Çıktı:
Color, Angle ve Vector yapılarının nasıl ayırt edilebilir metin yapılarına dönüştürüldüğüne dikkat edin. Bu benzersiz formatlar, tersine çevirme fonksiyonu olan util.JSONToTable'ın formatları orijinal veri yapılarına geri dönüştürmesine olanak tanır.
Dosyayı okurken gerçekleşmesi gereken tersine çevirme sürecini görebilmemiz için biraz daha kod yazalım.
Çıktı:
Gördüğünüz gibi, JSON metni tekrar bir tablo formatına dönüştürüldü. Ayrıca, converted.pos ile isvector ve converted.rot ile isangle kullanarak veri türlerinin orijinal formatlarına döndüğünü kontrol edebiliriz, bu da bize onların tekrar bir Vector ve Angle'a dönüştürüldüğünü söyler. Ne yazık ki, converted.col'u IsColor'a geçirmek, onun doğru bir şekilde Color yapısına dönüştürülmediğini gösterir. Neyse ki, daha sonra onu normale döndürmek için kod yazabiliriz.
JSON verisini kaydetme
Artık bir tabloyu depolanabilir bir formata nasıl dönüştüreceğimizi ve depolanan formatı normal bir Lua tablosuna nasıl geri çevireceğimizi öğrendiğimize göre, şimdi dosyaları nasıl okuyup/yazacağımızı ve JSON verisini nasıl kaydedeceğimizi öğrenebiliriz.
İster inanın ister inanmayın, veriyi bir dosyaya kaydetmek yalnızca tek bir fonksiyon gerektirir: file.Write. Dokümantasyona baktığımızda yalnızca iki şeye ihtiyacı olduğunu öğreniyoruz:
- Bir dosya adı
- Kaydedilecek veri
Öyleyse devam edelim ve storeOwnerData tablosunu
storedata.jsonadlı bir dosyaya kaydetmeyi tamamlamak için biraz kod yazalım:
İşte bu kadar, dosya kaydedildi!
Dosyayı kendi gözlerinizle görmek isterseniz, garrysmod/data klasörüne gidebilirsiniz; dosyanın adı "storedata.json" olacaktır.
Dosyalardan JSON verisini okuma ve tekrar tabloya dönüştürme
JSON verisini okumak da, anahtar fonksiyonun tek bir argüman alan file.Read olmasıyla aynı derecede kolaydır... Dosya Adı. Burada ayrıca renk verisi içeren tabloyu da bir Color yapısına dönüştüreceğiz:
storeOwnerData değişkeni artık tüm verileri içeriyor ve col değeri artık bir Color!
Tablolar dışındaki veri türlerini yazma
Yukarıdaki yöntem tabloları depolamak için mükemmeldir, peki ya sadece bir sayı veya metin (string) depolamak istersek?
Bu senaryoda özellikle farklı olan bir şey yok, sadece artık util fonksiyonlarına ihtiyacımız yok:
Metni (string) kaydetme
Metni (string) yükleme
Hiç de o kadar zor değil, değil mi?
Dosya tabanlı depolamaya alternatifler
Diyelim ki bir oyuncunun para miktarını takip etmemiz gerekiyor. O zaman, oyuncu her ayrıldığında veya para miktarı güncellendiğinde dosyaya kaydetmemiz gerekir ve bu nedenle, 1.000 satırlık (hatta daha fazla!) bir dosyanın okunması, değiştirilmesi ve ardından tamamen yeni verilerle üzerine yazılması gerekecektir. Bu yavaştır ve bir dosyada verisi depolanan oyuncu sayısı arttıkça çok daha yavaş hale gelecektir.
Bu nedenle, bir alternatife ihtiyacımız var.
Belki de Garry's Mod'da büyük miktarda veri depolamanın en verimli yöntemi SQL'dir. Ne yazık ki, SQL'i öğrenmek dosya tabanlı depolama kadar kolay değildir, ancak öğrenmeye karar verirseniz kesinlikle buna değer.
Tüm sunucular · GmodTR Launcher · Rehber · GMod Wiki · GmodTR nedir? · Sunucu ekle · Discord