OpenSiv3D icon indicating copy to clipboard operation
OpenSiv3D copied to clipboard

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

Open Reputeless opened this issue 1 year ago • 4 comments
trafficstars

  • reported by: https://discord.com/channels/443310697397354506/1000291580915232879/1253760169460895837

Reputeless avatar Jun 22 '24 00:06 Reputeless

日本語や韓国語を使うと、どこかのタイミングでその文字数と同じだけ末尾にヌル文字が入るようです。 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 avatar Aug 29 '24 09:08 Raclamusi

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

Raclamusi avatar Aug 30 '24 04:08 Raclamusi

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

namespace detail
{
	[[nodiscard]]
	static String ToString(const ExitGames::Common::JString& s)
	{
		auto t = Unicode::FromWstring(std::wstring_view{ s.cstr(), s.length() });
		for (auto& c : t)
		{
			// 置換された文字を元に戻す
			if ((c & 0xffff0000) == 0x00100000)
			{
				c &= 0x0000ffff;
			}
		}
		return t;
	}

	[[nodiscard]]
	static ExitGames::Common::JString ToJString(const StringView s)
	{
		String t{ s };
		for (auto& c : t)
		{
			// 問題が発生する文字を置換する
			if ((0x0100 <= c) && (c <= 0xffff))
			{
				c |= 0x00100000;
			}
		}
		const auto ws = Unicode::ToWstring(t);
		return ExitGames::Common::JString{ ws.c_str(), static_cast<unsigned int>(ws.length()) };
	}
}

編集

  • # if SIV3D_PLATFORM(WINDOWS) を削除しました。Windows-他OS間の通信も考えられるので、すべてのOSでこの変換をする必要があります。

Raclamusi avatar Sep 07 '24 10:09 Raclamusi

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

comefrombottom avatar Sep 10 '24 07:09 comefrombottom