İçeriğe geç

Metin2 serverinfo.py: Client'ı Sunucuya Bağlama

Hazırlayan: Metin2VIP Editörleri Yayın: 7 dk okuma

Kısaca: serverinfo.py, istemcinin root paketinde duran ve giriş ekranının sunucu adını, adresini, auth portunu ve kanal portlarını okuduğu Python dosyasıdır. Adres IP de olabilir alan adı da; auth portu auth sunucusunun, kanal portları ise o kanaldaki bir çekirdeğin CONFIG dosyasındaki PORT değeriyle aynı olmalıdır. Dosya root paketinde olduğu için değişiklikten sonra root paketi yeniden oluşturulur.
İçindekiler
  1. serverinfo.py'de neler yazar?
  2. Alanlar ne anlama geliyor?
    1. IP mi alan adı mı?
  3. Girişte hangi bağlantılar kurulur?
    1. Karakter seçince bağlantı kopuyorsa
  4. Kanal durumu nasıl gelir?
  5. Client ve sunucu sürümü eşleşmeli
  6. Bağlanamıyorum: belirtiye göre neden
  7. Hangi portlar dışarıya açık olmalı?

serverinfo.py, istemcinin root paketinde duran ve giriş ekranının sunucu adını, adresini, auth portunu ve kanal portlarını okuduğu Python dosyasıdır. Adres IP de olabilir alan adı da. Auth portu auth sunucusunun, kanal portları ise o kanaldaki bir oyun çekirdeğinin CONFIG dosyasındaki PORT değeriyle birebir aynı olmalıdır.

Dosya root paketinin içinde olduğu için değiştirdikten sonra root paketini yeniden oluşturmak gerekir; paket biçimi Metin2 pack dosyaları yazısında. Aşağıdaki anlatım bu dosyayı, giriş ekranının kodunu ve istemci ile sunucunun ağ kaynak kodunu esas alır.

serverinfo.py'de neler yazar?

Kaynakla gelen istemcideki dosyanın yapısı aşağıdaki gibidir. Adres yerine örnek bir alan adı konuldu, geri kalanı aynıdır:

import app
import localeInfo
app.ServerName = None

SRV1 = {
	"name":"SunucuAdi",
	"host":"oyun.example.com",
	"auth1":30001,
	"ch1":30003,
	"ch2":30009,
	"ch3":30015,
	"ch4":30021,
}

STATE_NONE = "|cFFdadada" + localeInfo.CHANNEL_STATUS_OFFLINE

STATE_DICT = {
	0 : "|cFFffffff" + localeInfo.CHANNEL_STATUS_OFFLINE,
	1 : "|cFF00ff00" + localeInfo.CHANNEL_STATUS_RECOMMENDED,
	2 : "|cFFffc000" + localeInfo.CHANNEL_STATUS_BUSY,
	3 : "|cFFff0000" + localeInfo.CHANNEL_STATUS_FULL,
}

SERVER1_CHANNEL_DICT = {
	1:{"key":11,"name":"CH1","ip":SRV1["host"],"tcp_port":SRV1["ch1"],"udp_port":SRV1["ch1"],"state":STATE_NONE,},
	2:{"key":12,"name":"CH2","ip":SRV1["host"],"tcp_port":SRV1["ch2"],"udp_port":SRV1["ch2"],"state":STATE_NONE,},
	3:{"key":13,"name":"CH3","ip":SRV1["host"],"tcp_port":SRV1["ch3"],"udp_port":SRV1["ch3"],"state":STATE_NONE,},
	4:{"key":14,"name":"CH4","ip":SRV1["host"],"tcp_port":SRV1["ch4"],"udp_port":SRV1["ch4"],"state":STATE_NONE,},
}

REGION_AUTH_SERVER_DICT = {
	0 : {
		1 : { "ip":SRV1["host"], "port":SRV1["auth1"], },
	}
}

REGION_DICT = {
	0 : {
		1 : { "name" :SRV1["name"], "channel" : SERVER1_CHANNEL_DICT, },
	},
}

MARKADDR_DICT = {
	10 : { "ip" : SRV1["host"], "tcp_port" : SRV1["ch1"], "mark" : "10.tga", "symbol_path" : "10", },
}

Kanal portları arasındaki 6'lık aralık, her kanalda üç çekirdek çalıştıran ve her çekirdeğe iki port (PORT ve P2P_PORT) ayıran bir düzene uyar. Kaynakla gelen sunucu dosyalarında 1. kanalın çekirdekleri 30003, 30005 ve 30007 portlarını, P2P için bir fazlasını kullanıyor. Kendi sunucunda bu sayılar farklıysa serverinfo.py de ona göre yazılır.

Alanlar ne anlama geliyor?

Alan Anlamı Sunucudaki karşılığı
name Sunucu listesinde görünen ad Yok, yalnız görüntü
host Sunucunun adresi, IP ya da alan adı Oyuncuların ulaştığı adres
auth1 Auth sunucusunun portu auth klasöründeki CONFIG'in PORT değeri
ch1 ... ch4 Her kanalın giriş portu O kanaldaki bir çekirdeğin CONFIG PORT değeri
key bölge × 1000 + sunucu × 10 + kanal (11 = 0. bölge, 1. sunucu, 1. kanal) Yok
tcp_port, udp_port Kanalın portu; udp_port kanal durumu eşlemesinde kullanılır Çekirdeğin PORT değeri
state Kanal durumu yazısı; istemci kendisi doldurur Yok
REGION_AUTH_SERVER_DICT Auth adresi ve portu auth CONFIG'i
REGION_DICT Sunucu listesi ve her sunucunun kanal sözlüğü Yok
MARKADDR_DICT Lonca işareti sunucusu Bu istemcide okunmuyor

Bu istemcinin giriş ekranı kanal düğmelerinde doğrudan SRV1 sözlüğünü kullanır: adresi host, auth portunu auth1, kanal portunu chN alanından alır. Kanal sözlüğündeki ip ve udp_port alanları yalnız kanal durumunu sorarken okunur. MARKADDR_DICT tanımlıdır ama hiçbir yerde kullanılmaz; lonca işaretleri host adresi ve CH1 portu üzerinden indirilir. Düğme sayısı giriş ekranının kodunda dört olarak sabittir, bu yüzden beşinci bir kanal için serverinfo.py'ye satır eklemek yetmez; giriş ekranının betiği ve arayüz düzeni de değişmelidir.

IP mi alan adı mı?

İstemci, adres rakamla başlamıyorsa onu alan adı sayar ve çözümler. Bu yüzden host alanına alan adı yazmak, sunucu taşındığında istemciyi yeniden dağıtmadan adresi değiştirmeyi sağlar. Auth, kanal, kanal durumu ve lonca işareti bağlantıları bu adresle kurulur. Karakter seçildikten sonraki bağlantı ise sunucunun bildirdiği sayısal adrese yapılır; o adresin doğru olması sunucu tarafının işidir.

Girişte hangi bağlantılar kurulur?

  1. Oyuncu bir kanal düğmesine bastığında istemci kanalın adresini ve portunu, auth adresini ve portunu hafızaya alır.
  2. Kullanıcı adı ve parola girilince istemci auth portuna bağlanır. Bu istemcide constInfo.KEEP_ACCOUNT_CONNETION_ENABLE = 1 olduğu için giriş her zaman auth üzerinden yapılır.
  3. Auth ile el sıkışılır, saat eşitlenir, iki taraf şifreleme anahtarında anlaşır; ardından kullanıcı adı ve parola şifreli olarak gönderilir.
  4. Giriş başarılıysa auth bir giriş anahtarı (login key) döner. Şifreli paket kullanan sunucularda paket anahtarları da bu anda gelir. Auth bağlantısı kapatılır.
  5. İstemci kanal portuna bağlanır ve giriş anahtarıyla oturum açar. Karakter listesi gelir; listede her karakter için o karakterin haritasını çalıştıran çekirdeğin adresi ve portu da yazar.
  6. Oyuncu karakter seçince istemci bu adrese yeniden bağlanır ve oyuna girer.

Karakter seçince bağlantı kopuyorsa

Oyun çekirdeği oyunculara bildireceği adresi açılışta makinenin ağ kartlarından bulur. 192.168 ve 10 ile başlayan adresleri iç ağ adresi sayar. Makinede genel bir adres bulamazsa bu kaynakta açık olan bir ayar yüzünden iç ağ adresini kullanır. Bu durumda dışarıdaki oyuncular auth'a ve kanala bağlanabilir ama karakter seçince sunucunun bildirdiği iç adrese ulaşamaz ve bağlantı kopar.

Çözüm CONFIG dosyasındadır. BIND_IP çekirdeğin adresini elle verir; çekirdek soketlerini de bu adrese açtığı için adres makinenin kendisine ait olmalıdır. Makine NAT arkasındaysa PROXY_IP kullanılır: soketlere dokunmaz, yalnız oyunculara karakter listesinde ve ışınlanmalarda bildirilen adresi değiştirir. İki ayarın ayrıntısı CONFIG ayarları yazısında.

Kanal durumu nasıl gelir?

Giriş ekranı kanal durumlarını tek bir sorguyla ister. İstemci listedeki ilk kanalın (pratikte CH1) adresine ve portuna TCP ile bağlanır, tek baytlık bir istek yollar. Çekirdek isteği veritabanı çekirdeğine (db) iletir; db, kendisine bağlı bütün çekirdeklerin port ve durum listesini döner. İstemci listedeki her kaydı, udp_port değeri o porta eşit olan kanala yazar.

Her çekirdek durumunu açılışta ve sonra 5 dakikada bir db'ye bildirir. Durum şöyle hesaplanır:

Değer Giriş ekranında Koşul
0 Bilinmeyen (beyaz) Çekirdek yeni oyuncu kabul etmiyor (CONFIG'de shutdowned ya da kapanma geri sayımı)
1 Tavsiye edilen (yeşil) Aşağıdakilerin hiçbiri değil
2 Kalabalık (turuncu) Oyuncu sayısı kalabalık eşiğini aşıyor
3 Dolu (kırmızı) Oyuncu sayısı dolu eşiğini aşıyor

Eşikler kodda dolu için 500, kalabalık için 10'dur. Çekirdeğin klasöründeki state_user_count dosyası iki sayıyla ("dolu kalabalık") bu değerleri değiştirir; GM /reload u komutuyla dosya yeniden okunur. Sayılan oyuncu, çekirdeğin kendi oyuncuları ile P2P üzerinden gördüğü oyuncuların toplamıdır.

Bu işleyişin üç pratik sonucu var:

  • udp_port adına rağmen bağlantı TCP'dir. Değer çekirdeğin PORT değeri olmalıdır, ayrı bir UDP portu açılmaz.
  • İlk kanalın çekirdeği kapalıysa hiçbir kanalın durumu gelmez. Bütün kanallar "Bilinmeyen" kalır, diğer kanallar açık olsa bile.
  • Durum gecikmeli değişir. Kalabalıklaşan bir kanal en geç 5 dakika sonra "Kalabalık" görünür.

Client ve sunucu sürümü eşleşmeli

İstemci ile sunucunun birbirini anlaması üç katmanda denetlenir.

Sürüm metni. İstemci yükleme ekranında sunucuya sabit bir metin yollar (1215955205). Sunucu bu metni CONFIG'deki CHECK_VERSION_VALUE değeriyle karşılaştırır; varsayılan değer aynı metindir ve denetim CHECK_VERSION_SERVER ile açılıp kapanır, varsayılanı açıktır. Uymazsa oyuncu oyuna girer girmez "İstemci versionunuz hatalı. Lütfen normal sürümü yükleyin." mesajıyla atılır. İstemci kaynağındaki Version.h dosyasındaki sürüm numarası bu denetime katılmaz, yalnız exe'nin dosya sürümüdür. Sabit bir metin karşılaştırıldığı için bu denetim bir güvenlik önlemi değil, uyumluluk kontrolüdür.

Paket yapısı. İki tarafın paket tanımları aynı olmalıdır. Örnek: ENABLE_PLAYER_PER_ACCOUNT5 sunucuda hesap başına karakter sayısını 5 yapar, istemcide de karakter listesi paketini 5 kişilik okur. Biri açık biri kapalıysa paket boyları tutmaz ve okunan veri kayar. Böyle bir uyumsuzlukta istemci çoğu zaman syserr.txt'ye "Unknown packet header" yazıp kapanır; sunucu tarafında tanımadığı bir başlık gelirse syserr'e "UNKNOWN HEADER" yazıp bağlantıyı keser. Paket şifrelemesini belirleyen _IMPROVED_PACKET_ENCRYPTION_ bayrağı da iki tarafta birlikte tanımlı olmalıdır. Bayrakların nerede durduğu Metin2 source derleme yazısında.

Veri. İstemcinin item_proto ve mob_proto kopyaları sunucudaki verilerle aynı kaynaktan üretilmelidir; aksi hâlde eşya adları ve ipuçları sunucunun uyguladığından farklı görünür. Şifreli paket kullanılıyorsa sunucudaki anahtar dosyaları istemcideki paketlerle aynı paketleme işinden çıkmalıdır.

Bağlanamıyorum: belirtiye göre neden

Ekrandaki mesaj ya da belirti Olası neden
"Sunucuya bağlanırken hata" Auth'a ulaşılamıyor: host yanlış, auth1 auth CONFIG'indeki PORT ile aynı değil, auth çalışmıyor ya da port güvenlik duvarında kapalı.
"Hesap ismi veya şifre yanlış." Sunucu NOID ya da WRONGPWD döndü.
"Hesabın zaten bağlı." Hesap başka bir oturumda açık (ALREADY).
"Sunucu henüz açılmadı." Çekirdek yeni oyuncu kabul etmiyor (SHUTDOWN): CONFIG'de shutdowned var ya da kapanma geri sayımı başladı.
"Çok fazla kullanıcı bağlı olduğu için bağlanamazsınız." Oyuncu sayısı CONFIG'deki USER_LIMIT değerine ulaştı (varsayılan 32768).
Giriş başarılı, karakter seçince kopma Sunucunun bildirdiği adres dışarıdan erişilemiyor ya da karakterin haritasını çalıştıran çekirdek kapalı.
Bütün kanallar "Bilinmeyen" İlk kanalın çekirdeği kapalı ya da udp_port değerleri çekirdek portlarıyla tutmuyor.
Giriş ya da yükleme sırasında istemci kapanıyor, syserr'de "Unknown packet header" İstemci ile sunucunun paket tanımları farklı; iki taraf farklı özellik bayraklarıyla derlenmiş.
Oyuna girince "İstemci versionunuz hatalı" Sürüm metni ile CHECK_VERSION_VALUE farklı.

Oyuncunun kendi bilgisayarından kaynaklanan sorunlar için istemci hataları yazısına bakılabilir.

Hangi portlar dışarıya açık olmalı?

Oyuncunun ulaşması gereken portlar yalnız auth'un PORT değeri ve kanal çekirdeklerinin PORT değerleridir. Kanal durumu ve lonca işaretleri de kanal portu üzerinden geçer.

Sık sorulan sorular

serverinfo.py'ye IP yerine alan adı yazılabilir mi?
Evet. İstemci rakamla başlamayan adresi alan adı sayar ve çözümler. Auth, kanal, kanal durumu ve lonca işareti bağlantıları bu adresle kurulur; karakter seçildikten sonraki bağlantı ise sunucunun bildirdiği adrese yapılır.
Kanal portu sunucudaki hangi değerdir?
O kanaldaki bir oyun çekirdeğinin CONFIG dosyasındaki PORT değeridir. P2P_PORT ya da DB_PORT yazılmaz. Karakter seçilince sunucu oyuncuyu zaten haritanın bulunduğu çekirdeğe yönlendirir.
Kanallar giriş ekranında neden hep Bilinmeyen görünüyor?
Durum bilgisi listedeki ilk kanalın adresinden istenir. O çekirdek kapalıysa ya da kanalların udp_port değeri çekirdeğin PORT değeriyle tutmuyorsa hiçbir kanalın durumu gelmez.
Girişte sorun yok ama karakter seçince bağlantı kopuyor, neden?
Karakter seçilince istemci, sunucunun o karakterin haritası için bildirdiği adrese bağlanır. Sunucu kendini iç ağ adresiyle tanıtıyorsa dışarıdaki oyuncular bu adrese ulaşamaz; CONFIG'de BIND_IP ya da PROXY_IP ile doğru adres verilmelidir.

İlgili sayfalar

Kategori: Server Kurma Client (İstemci) istemci geliştirici kanal port serverinfo

Bu sayfadaki bilgiler Metin2'nin sunucu yazılımındaki hesaplamalara ve standart oyun dosyalarına dayanır. Oyun dosyalarını değiştiren sunucularda değerler farklı olabilir. İçerikleri nasıl hazırlıyoruz?

Bu sayfa işine yaradı mı?

Giriş yap, oy ver ya da sayfayı kaydet. Okumak için üyelik gerekmez. WhatsApp X'te paylaş
Yanlış ya da eksik bir bilgi mi gördün? Bildir
Neyin yanlış olduğunu, doğrusunun ne olduğunu ve bunu nereden bildiğini yaz. Mesajın editörlere gider; yazı, kontrol edildikten sonra düzeltilir.
Yalnız editör görür.

Tartışma

Kurallar

Henüz yorum yok. Bu konuda bir deneyimin ya da sorun varsa ilk yorumu sen yaz.

Giriş yap ya da kayıt ol, sonra yorum yaz. Metin2VIP üyeliği hiçbir oyun sunucusunun hesabı değildir.