private IEnumerator GetRoomList()
            {
                if (!_entryJoined || _roomJoining || _roomJoined || GetRoomListLock)
                {
                    yield break;
                }

                GetRoomListLock = true;
                OrLog(LogLevel.Verbose, "Get rooms info");
                UnityWebRequest webRequest = UnityWebRequest.Get(BASE_URL + _serverAddress + ":" + _entryPort + "/rooms");

                webRequest.SetRequestHeader("User-Agent", UA_UNITY_CDK);
                yield return(webRequest.SendWebRequest());

                if (webRequest.isNetworkError)
                {
                    OrLogError(LogLevel.Info, webRequest.error);
                    // TODO VERSION ERROR HANDLE CALLBACK
                    yield break;
                }

                var streamReader  = new MemoryStream(webRequest.downloadHandler.data);
                var messageReader = new EndiannessBinaryReader(streamReader);

                if (webRequest.responseCode != 200)
                {
                    OrLog(LogLevel.Verbose, "post create room failed. http status code:" + webRequest.responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseCode = (ResponseCode)messageReader.ReadUInt16();
                var roomListLen  = messageReader.ReadUInt16();

                if (responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_OK_NO_ROOM)
                {
                    OrLog(LogLevel.Verbose, "no room");
                }
                else if (responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_OK)
                {
                    List <RoomInfo> list = new List <RoomInfo>();
                    for (int index = 0; index < roomListLen; index++)
                    {
                        var responseSize  = Marshal.SizeOf(typeof(RoomResponse));
                        var responseBytes = messageReader.ReadBytes(responseSize);
                        OrLog(LogLevel.VeryVerbose, "raw response:" + BitConverter.ToString(responseBytes));
                        var          ptr = Marshal.AllocCoTaskMem(responseSize);
                        var          gch = GCHandle.Alloc(responseBytes, GCHandleType.Pinned);
                        RoomResponse response;
                        try
                        {
                            response = Marshal.PtrToStructure <RoomResponse>(gch.AddrOfPinnedObject());
                            OrLog(LogLevel.Verbose, "read bytes get room Id:" + BitConverter.ToString(response.Id));
                            OrLog(LogLevel.Verbose, "read bytes get room Capacity:" + response.Capacity.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StfDealPort:" + response.StfDealPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StfSubPort:" + response.StfSubPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StlDealPort:" + response.StlDealPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StlSubPort:" + response.StlSubPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room QueuingPolicy:" + response.QueuingPolicy.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room Flags:" + response.Flags.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room NameLen:" + response.NameLen.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room FilterLen:" + response.FilterLen.ToString());
                        }
                        catch (Exception e)
                        {
                            OrLogError(LogLevel.Info, "handle error: " + e.Message);
                            OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                            OrLogError(LogLevel.Verbose, "post create room failed ");
                            gch.Free();

                            yield break;
                        }
                        gch.Free();

                        byte[] name = new byte[] { };
                        //if (0 < response.NameLen)
                        //{
                        name = messageReader.ReadBytes(256);
                        OrLog(LogLevel.Verbose, "read bytes get room Name:" + Encoding.UTF8.GetString(name).Substring(0, response.NameLen));
                        //}
                        byte[] filter;
                        //if (0 < response.FilterLen)
                        //{
                        filter = messageReader.ReadBytes(256);
                        OrLog(LogLevel.Verbose, "read bytes get room Filter:" + BitConverter.ToString(filter).Substring(0, response.FilterLen));
                        //}
                        var listenMode = messageReader.ReadByte();
                        OrLog(LogLevel.Verbose, "read bytes get room listen mode:" + listenMode);
                        messageReader.ReadBytes(3); // alignment 3bytes for 4byte alignment.
                        var ipv4Bytes = messageReader.ReadBytes(4);
                        var ipv4Addr  = new IPAddress(ipv4Bytes).ToString();
                        //var ipv4Addr = _serverAddress; // TODO ISSUE 24 provisional fix
                        OrLog(LogLevel.Verbose, "read bytes get room listen ipv4 addr:" + ipv4Addr);
                        var ipv6Bytes = messageReader.ReadBytes(16);
                        var ipv6Addr  = new IPAddress(ipv6Bytes).ToString();
                        OrLog(LogLevel.Verbose, "read bytes get room listen ipv6 addr:" + ipv6Addr);
                        var roomInfo = new RoomInfo(Encoding.UTF8.GetString(name).Substring(0, response.NameLen),
                                                    response.Id,
                                                    listenMode,
                                                    ipv4Addr,
                                                    ipv6Addr,
                                                    response.StfDealPort.ToString(),
                                                    response.StfSubPort.ToString(),
                                                    response.StlDealPort.ToString(),
                                                    response.StlSubPort.ToString(),
                                                    response.Capacity,
                                                    new RoomOptions());
                        roomInfo = new RoomInfo(response.UserCount, roomInfo);
                        list.Add(roomInfo);
                    }

                    foreach (var room in list)
                    {
                        yield return(StartCoroutine(GetRoomProperties(room)));

                        yield return(new WaitForSeconds(0.01f));
                    }

                    RoomList = list;
                    OnRoomListUpdateCall(RoomList);
                }

                GetRoomListLock = false;
            }
            private IEnumerator CreateRoom(string roomName, UInt16 maxPlayer, RoomOptions presetRoomOptions, bool ignoreExist)
            {
                createAndJoinRoomAbort = false;
                OrLog(LogLevel.Verbose, "room name: " + roomName);
                OrLog(LogLevel.Verbose, "room max player: " + maxPlayer);
                var messageBytes = new byte[sizeof(UInt16)];
                var stream       = new MemoryStream(messageBytes);
                var message      = new EndiannessBinaryWriter(stream);

                try
                {
                    message.Write(maxPlayer);
                }
                catch (Exception e)
                {
                    OrLogError(LogLevel.Info, "error: " + e.Message);
                    OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                }
                message.Close();

                UnityWebRequest webRequest = UnityWebRequest.Put(BASE_URL + _serverAddress + ":" + _entryPort + "/room/create/" + roomName, messageBytes);

                webRequest.method = "POST";
                webRequest.SetRequestHeader("User-Agent", UA_UNITY_CDK);
                webRequest.SetRequestHeader("Content-Type", "application/octet-stream");
                //webRequest.SetRequestHeader("Content-Length", messageBytes.Length.ToString()); // auto setting.
                yield return(webRequest.SendWebRequest());

                if (webRequest.isNetworkError)
                {
                    OrLogError(LogLevel.Info, webRequest.error);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, "failed polling");//TODO error handle case;
                    yield break;
                }

                var streamReader  = new MemoryStream(webRequest.downloadHandler.data);
                var messageReader = new EndiannessBinaryReader(streamReader);

                if (webRequest.responseCode != 200)
                {
                    OrLog(LogLevel.Verbose, "post create room failed. http status code:" + webRequest.responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseCode = (ResponseCode)messageReader.ReadUInt16();

                OrLog(LogLevel.Verbose, "read bytes responseCode:" + responseCode.ToString());
                messageReader.ReadUInt16();// read alignment

                if (ignoreExist && responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS)
                {
                    OrLog(LogLevel.Verbose, "ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS, but ignore ");
                }
                else if (!ignoreExist && responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS)
                {
                    createAndJoinRoomAbort = true;
                    OrLogError(LogLevel.Info, "post create room failed. http status code:" + webRequest.responseCode);
                    OrLogError(LogLevel.Info, "post create room failed. response code:" + responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }
                else if (responseCode != ResponseCode.OPENRELAY_RESPONSE_CODE_OK_ROOM_ASSGIN_AND_CREATED)
                {
                    OrLogError(LogLevel.Info, "post create room failed. http status code:" + webRequest.responseCode);
                    OrLogError(LogLevel.Info, "post create room failed. response code:" + responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseSize  = Marshal.SizeOf(typeof(RoomResponse));
                var responseBytes = messageReader.ReadBytes(responseSize);

                OrLog(LogLevel.VeryVerbose, "raw response:" + BitConverter.ToString(responseBytes));
                var          ptr = Marshal.AllocCoTaskMem(responseSize);
                var          gch = GCHandle.Alloc(responseBytes, GCHandleType.Pinned);
                RoomResponse response;

                try
                {
                    response = Marshal.PtrToStructure <RoomResponse>(gch.AddrOfPinnedObject());
                    OrLog(LogLevel.Verbose, "read bytes created room Id:" + BitConverter.ToString(response.Id));
                    OrLog(LogLevel.Verbose, "read bytes created room Capacity:" + response.Capacity.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StfDealPort:" + response.StfDealPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StfSubPort:" + response.StfSubPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StlDealPort:" + response.StlDealPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StlSubPort:" + response.StlSubPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room QueuingPolicy:" + response.QueuingPolicy.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room Flags:" + response.Flags.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room NameLen:" + response.NameLen.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room FilterLen:" + response.FilterLen.ToString());
                }
                catch (Exception e)
                {
                    OrLogError(LogLevel.Info, "handle error: " + e.Message);
                    OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                    OrLogError(LogLevel.Verbose, "post create room failed ");
                    gch.Free();

                    yield break;
                }
                gch.Free();

                //if (0 < response.NameLen)
                //{
                var name = messageReader.ReadBytes(256);

                OrLog(LogLevel.Verbose, "read bytes created room Name:" + Encoding.UTF8.GetString(name));
                //}
                //if (0 < response.FilterLen)
                //{
                var filter = messageReader.ReadBytes(256);

                OrLog(LogLevel.Verbose, "read bytes created room Filter:" + BitConverter.ToString(filter));
                //}
                var listenMode = messageReader.ReadByte();

                OrLog(LogLevel.Verbose, "read bytes get room listen mode:" + listenMode);
                messageReader.ReadBytes(3); // alignment 3bytes for 4byte alignment.
                var ipv4Bytes = messageReader.ReadBytes(4);
                var ipv4Addr  = new IPAddress(ipv4Bytes).ToString();

                //var ipv4Addr = _settings.ServerAddress; // TODO ISSUE 24 provisional fix
                OrLog(LogLevel.Verbose, "read bytes get room listen ipv4 addr:" + ipv4Addr);
                var ipv6Bytes = messageReader.ReadBytes(16);
                var ipv6Addr  = new IPAddress(ipv6Bytes).ToString();

                OrLog(LogLevel.Verbose, "read bytes get room listen ipv6 addr:" + ipv6Addr);
                _room = new RoomInfo(roomName,
                                     response.Id,
                                     listenMode,
                                     ipv4Addr,
                                     ipv6Addr,
                                     response.StfDealPort.ToString(),
                                     response.StfSubPort.ToString(),
                                     response.StlDealPort.ToString(),
                                     response.StlSubPort.ToString(),
                                     response.Capacity,
                                     presetRoomOptions
                                     );

                subscriberListener.Start();
                dealerListener.Start();

                _room = new RoomInfo(
                    dealerListener.SetProperties,
                    dealerListener.SetPropertiesListedInLobby,
                    _room);

                OnCreatedRoomCall();
                OrLog(LogLevel.Verbose, "OnCreatedRoomCall");
                OrLog(LogLevel.Verbose, "post create room end");
            }
 public RoomInfo(UInt16 playerCount, RoomInfo original)
 {
     CopyFromOriginal(original);
     PlayerCount = playerCount;
 }