Siv3D / OpenSiv3D

C++20 framework for creative coding 🎮🎨🎹 / Cross-platform support (Windows, macOS, Linux, and the Web)
https://siv3d.github.io/
MIT License
1.02k stars 140 forks source link

Photon のルーム名に使える文字の調査 #1236

Open Reputeless opened 5 months ago

Reputeless commented 5 months ago
Raclamusi commented 3 months ago

日本語や韓国語を使うと、どこかのタイミングでその文字数と同じだけ末尾にヌル文字が入るようです。 createRoom(U"日本語", 3) でルームを作成した時、 getCurrentRoomName() == U"日本語\0\0\0"_sgetRoomNameList()[0] == U"日本語\0\0\0\0\0\0"_s でした。 また、 createRoom() に限らず、 connect()sendEvent() でも同様の問題が発生しました。 文字列の処理において共通して発生する問題のようです。

しかし、 ASCII 限定というわけでもなさそうで、絵文字や 𠮷 などではうまくいきました。 UTF-8 の文字コード1つでは表せないが、 UTF-16 の文字コード1つで表せるような文字について、この問題が発生しそうです。

Raclamusi commented 3 months ago

Linux ではこの問題は発生しませんでした。 やはり、 wchar_t が UTF-16 であることに関係してそうです。

Raclamusi commented 2 months ago

応急処置として、問題が発生する文字を問題が発生しない文字に置換することで、ユーザ名やルーム名、送信するテキストに日本語を使えるようになります。

namespace detail
{
    [[nodiscard]]
    static String ToString(const ExitGames::Common::JString& s)
    {
        auto t = Unicode::FromWstring(std::wstring_view{ s.cstr(), s.length() });
    # if SIV3D_PLATFORM(WINDOWS)

        for (auto& c : t)
        {
            // 置換された文字を元に戻す
            if ((c & 0xffff0000) == 0x00100000)
            {
                c &= 0x0000ffff;
            }
        }

    # endif
        return t;
    }

    [[nodiscard]]
    static ExitGames::Common::JString ToJString(const StringView s)
    {
    # if SIV3D_PLATFORM(WINDOWS)

        String t{ s };
        for (auto& c : t)
        {
            // 問題が発生する文字を置換する
            if ((0x0100 <= c) && (c <= 0xffff))
            {
                c |= 0x00100000;
            }
        }
        const auto ws = Unicode::ToWstring(t);

    # else

        const auto ws = Unicode::ToWstring(s);

    # endif
        return ExitGames::Common::JString{ ws.c_str(), static_cast<unsigned int>(ws.length()) };
    }
}
comefrombottom commented 2 months ago

新しいMultiplayer_Photonの方でこのやり方をそのまま採用しようと思います。