Çözüldü Client UTF-8 modunda Türkçe karakterleri görüntüleyebiliyor ancak textbox'a yazamıyor

Bu konu çözüme ulaştırılmıştır. Çözüm için konuya yazılan tüm yorumları okumayı unutmayın. Eğer konudaki yorumlar sorununuzu çözmediyse yeni bir konu açabilirsiniz.
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.

Kaptan Yosun

Moderatör
Moderatör
Geliştirici
Yardımsever Üye
Mesaj
926
Çözümler
31
Beğeni
864
Puan
939
Ticaret Puanı
0
Selamlar, oyunuma çoklu dil desteği eklediğim için 1252 English codepage'i ile oyuna giren kimse 1254 Turkish codepage'i ile oyuna giren kimselerin yazdığı "üğİçö" gibi karakterleri göremiyordu. Ben de clienti bütün karakterleri destekleyen UTF-8 codepage'ine geçirdim. Oyundaki tüm yazılarda mevzubahis Türkçe karakterler doğru çalışsa da, chate yazı yazarken veya kullanıcı adı girerken yani herhangi bir textbox'a yazı yazarken bu karakterler "??" olarak gözüküyor. Herhangi bir fikriniz var mı? 65001 UTF-8 Codepage'i geri 1254 tr yaptığımda textbox'a türkçe karakterleri sorunsuz yazabiliyorum.

1254 tr
1726128795031.webp


65001 tr
1726128827566.webp


65001 tr codepage'i ile oyun içindeki Türkçe karakterler sorunsuz görüntülenebiliyor, ancak chate yazılamıyor
1726129036307.webp
 
Çözüm
Sorunu @Kaiser tespit edip çözdü.

C++:
Genişlet Daralt Kopyala
int  CIME::GetText (std::string& rstrText, bool addCodePage)

fonksiyonu kullanıcıdan text inputu alırken bilgisayarın diline göre codepage belirliyor (o da düzgün çalışıyor mu meçhul)

bunun yerine dil farketmeksizin UTF-8 codepage döndürürsek sorun düzeliyor.

C++:
Genişlet Daralt Kopyala
int  CIME::GetText (std::string& rstrText, bool addCodePage)
{
    int outCodePage = CP_UTF8; // @fix22

    int len = 0;
    char text[IMESTR_MAXLEN];

    len += WideCharToMultiByte (outCodePage, 0, m_wText, ms_curpos, text, sizeof (text)-len, NULL, NULL);
    len += WideCharToMultiByte (outCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof (text)-len, NULL, NULL);
    len += WideCharToMultiByte (outCodePage, 0, m_wText+ms_curpos...
C++:
Genişlet Daralt Kopyala
void CTextLine::SetText(const char * c_szText)

Fonksiyon gelen argümanı const char olarak işlediği için muhtemelen Türkçe karakterleri bozuyordur. Çünkü char ve const char veri tipleri Türkçe karakterleri/UTF8 doğrudan desteklemez. Yaptığın düzenlemelerden sonra bu fonksiyonun çalışma mantığı etkilenmiş olabilir.

Bunu netleştirmek için bu ve ilgili olan diğer kısımlardaki veri tiplerini std::string'e çevirmeyi deneyebilirsin.
 
C++:
Genişlet Daralt Kopyala
void CTextLine::SetText(const char * c_szText)

Fonksiyon gelen argümanı const char olarak işlediği için muhtemelen Türkçe karakterleri bozuyordur. Çünkü char ve const char veri tipleri Türkçe karakterleri/UTF8 doğrudan desteklemez. Yaptığın düzenlemelerden sonra bu fonksiyonun çalışma mantığı etkilenmiş olabilir.

Bunu netleştirmek için bu ve ilgili olan diğer kısımlardaki veri tiplerini std::string'e çevirmeyi deneyebilirsin.
Malesef düzelmedi. Bu işlemleri yaptım:

C++:
Genişlet Daralt Kopyala
Önce
void CGraphicTextInstance::SetValue (const char* c_szText, size_t len)

Sonra
void CGraphicTextInstance::SetValue (const std::string& c_szText, size_t len)
C++:
Genişlet Daralt Kopyala
Önce
    void CTextLine::SetText (const char* c_szText)
    
Sonra
    void CTextLine::SetText (const std::string& c_szText)

C++:
Genişlet Daralt Kopyala
Önce
    void CTextLine::OnSetText (const char* c_szText)

Sonra
    void CTextLine::OnSetText (const std::string& c_szText)
 
Malesef düzelmedi. Bu işlemleri yaptım:

C++:
Genişlet Daralt Kopyala
Önce
void CGraphicTextInstance::SetValue (const char* c_szText, size_t len)

Sonra
void CGraphicTextInstance::SetValue (const std::string& c_szText, size_t len)
C++:
Genişlet Daralt Kopyala
Önce
    void CTextLine::SetText (const char* c_szText)
   
Sonra
    void CTextLine::SetText (const std::string& c_szText)

C++:
Genişlet Daralt Kopyala
Önce
    void CTextLine::OnSetText (const char* c_szText)

Sonra
    void CTextLine::OnSetText (const std::string& c_szText)
O halde pythondan kaynaklı olma ihtimali yüksek gibi görünüyor. Bu fonksiyonların içine ve en üstüne TraceError("Text: %s", c_szText) şeklinde yazdırmayı dene. Ardından chate bozuk karakterli de olsa bir şey yaz ve enterla.

Eğer syserr'da chate yazdığın şey sorunsuz görünürse sorun python kaynaklıdır. Eğer syserr dosyasına da bozuk karakterli yazarsa o zaman ya herro ya merro.
 
O halde pythondan kaynaklı olma ihtimali yüksek gibi görünüyor. Bu fonksiyonların içine ve en üstüne TraceError("Text: %s", c_szText) şeklinde yazdırmayı dene. Ardından chate bozuk karakterli de olsa bir şey yaz ve enterla.

Eğer syserr'da chate yazdığın şey sorunsuz görünürse sorun python kaynaklıdır. Eğer syserr dosyasına da bozuk karakterli yazarsa o zaman ya herro ya merro.
Syserr Türkçe karakter gösteriyor
Kod:
Genişlet Daralt Kopyala
0912 17:35:50462 :: Text: dğüğüğüğüğüğişi
0912 17:35:50462 :: Text: dğüğüğüğüğüğişi
0912 17:35:50462 :: Text: dğüğüğüğüğüğişi
0912 17:35:52244 :: Text: dğüğüğüğüğüğişi
0912 17:35:52244 :: Text: dğüğüğüğüğüğişi
0912 17:35:52244 :: Text: dğüğüğüğüğüğişi
 
Sorunun sebebini buldum. Sonradan daha önce yaşadığım durum aklıma geldi. Çift kodlama sorunu yüzünden böyle oluyor.
Yani kabaca bahsetmem gerekirse: 65001 bir dil desteği sağlamaktan ziyade converter görevi görüyor.
65001'in etkin olarak çalışabilmesi için, işlenen verinin ANSI vb. olması gerek. Eğer işlenen veri UTF-8 olursa, 65001 tarafından tekrar UTF-8 kodlamasına maruz kalıyor ve çift kodlama sorunu oluşuyor.

Az önce yaptığım test sonucunda da yukarıda yazdıklarımı doğrulamış oldum:

Görsel 1: Orjinal tr kodlamalı giriş ekranı:
Ekran görüntüsü 2024-09-12 153159.webp

Buradaki "Bağlan" ve "Çıkış" kelimeleri zaten utf-8 formatında(!)
Görsel 2: 65001 kodlamalı giriş ekranı:
Ekran görüntüsü 2024-09-12 152834.webp

Burada ise bahsettiğim çift kodlama sorunu gerçekleşiyor.
Zaten utf8 olan metin, 65001 tarafından tekrar formatlanıyor ve bozuluyor.


Eğer locale_interface.txt içindeki "Bağlan" ve "Çıkış" metinlerini ANSI'ye çevirirsem, bu sefer 65001 kodlaması görevini yapıyor ve ANSI'yi UTF8'e dönüştürüyor.
ANSI karşılığı olarak .txt içindeki ilgili kısımları şu şekilde değiştirdim:
Bağlan-->BaÄŸlan
Çıkış-->Çıkış

Ve tekrar 65001 kodlamalı giriş ekranı:
Ekran görüntüsü 2024-09-12 153900.webp


Yani 65001'in sorunsuz çalışması için, işlenen metnin ANSI vb. olması gerek. Ancak o zaman UTF8'e sorunsuz formatlayabilir.
 
Sorunun sebebini buldum. Sonradan daha önce yaşadığım durum aklıma geldi. Çift kodlama sorunu yüzünden böyle oluyor.
Yani kabaca bahsetmem gerekirse: 65001 bir dil desteği sağlamaktan ziyade converter görevi görüyor.
65001'in etkin olarak çalışabilmesi için, işlenen verinin ANSI vb. olması gerek. Eğer işlenen veri UTF-8 olursa, 65001 tarafından tekrar UTF-8 kodlamasına maruz kalıyor ve çift kodlama sorunu oluşuyor.

Az önce yaptığım test sonucunda da yukarıda yazdıklarımı doğrulamış oldum:

Görsel 1: Orjinal tr kodlamalı giriş ekranı:
18870 eklentisini görüntüle
Buradaki "Bağlan" ve "Çıkış" kelimeleri zaten utf-8 formatında(!)
Görsel 2: 65001 kodlamalı giriş ekranı:
18872 eklentisini görüntüle
Burada ise bahsettiğim çift kodlama sorunu gerçekleşiyor.
Zaten utf8 olan metin, 65001 tarafından tekrar formatlanıyor ve bozuluyor.


Eğer locale_interface.txt içindeki "Bağlan" ve "Çıkış" metinlerini ANSI'ye çevirirsem, bu sefer 65001 kodlaması görevini yapıyor ve ANSI'yi UTF8'e dönüştürüyor.
ANSI karşılığı olarak .txt içindeki ilgili kısımları şu şekilde değiştirdim:
Bağlan-->BaÄŸlan
Çıkış-->Çıkış

Ve tekrar 65001 kodlamalı giriş ekranı:
18873 eklentisini görüntüle
Benim deneyimim bu şekilde değildi hocam. Codepage 65001 ile oyunu açtığımda ANSI textler "?" olarak gözüküyordu. Örneğin oyun içi yazılar bozuktu ve Locale_game.txt dosyasını Notepad++ ile UTF-8 formatına dönüştürünce yazılar düzeldi.

CP 65001 + ANSI skilldesc.txt
1726145158593.webp


CP 65001 + "Convert to UTF-8" yapılmış skilldesc.txt
1726145250109.webp
 
Sorunu @Kaiser tespit edip çözdü.

C++:
Genişlet Daralt Kopyala
int  CIME::GetText (std::string& rstrText, bool addCodePage)

fonksiyonu kullanıcıdan text inputu alırken bilgisayarın diline göre codepage belirliyor (o da düzgün çalışıyor mu meçhul)

bunun yerine dil farketmeksizin UTF-8 codepage döndürürsek sorun düzeliyor.

C++:
Genişlet Daralt Kopyala
int  CIME::GetText (std::string& rstrText, bool addCodePage)
{
    int outCodePage = CP_UTF8; // @fix22

    int len = 0;
    char text[IMESTR_MAXLEN];

    len += WideCharToMultiByte (outCodePage, 0, m_wText, ms_curpos, text, sizeof (text)-len, NULL, NULL);
    len += WideCharToMultiByte (outCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof (text)-len, NULL, NULL);
    len += WideCharToMultiByte (outCodePage, 0, m_wText+ms_curpos, ms_lastpos-ms_curpos, text+len, sizeof (text)-len, NULL, NULL);

    int i;
    for (i=0; i<len; ++i)
        if ((BYTE)text[i] > 0x7F)
        {
            break;
        }

    if (i == len)
    {
        rstrText.append (text, text+len);
    }
    else
    {
        rstrText.append (text, text+i);

        //if (addCodePage)
        //    rstrText.append(GetCodePageText());

        rstrText.append (text+i, text+len);
    }

    return rstrText.size();
}
 
Çözüm
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.
Üst