コード例 #1
0
ファイル: Matchmake.cs プロジェクト: arxdsilva/nakama-docs
    void OnApplicationQuit()
    {
        // If no matchmaking active just disconnect.
        if (_matchmakeTicket == null)
        {
            // Lets gracefully disconnect from the server.
            _client.Disconnect();
            return;
        }

        // If matchmaking active stop matchmaking then disconnect.
        var message = NMatchmakeRemoveMessage.Default(_matchmakeTicket);

        _client.Send(message, (bool done) => {
            // The user is now removed from the matchmaker pool.
            Debug.Log("Matchmaking stopped.");

            // Lets gracefully disconnect from the server.
            _client.Disconnect();
        }, (INError error) => {
            Debug.LogErrorFormat("Send error: code '{1}' with '{0}'.", error.Message, error.Code);

            // Lets gracefully disconnect from the server.
            _client.Disconnect();
        });
    }
コード例 #2
0
    public void LeaveRoom()
    {
        client = NakamaData.Singleton.Client;
        ManualResetEvent leaveEvent = new ManualResetEvent(false);

        var message = new NTopicJoinMessage.Builder().TopicRoom(Encoding.UTF8.GetBytes(currentRoom)).Build();

        client.Send(message, (INTopic topic) =>
        {
            client.Send(NTopicLeaveMessage.Default(topic.Topic), (bool complete) =>
            {
                leaveEvent.Set();
            }, (INError err) => {
                Debug.Log("Failed to complete leaving of room : " + err);
                leaveEvent.Set();
            });
        }, (INError err) =>
        {
            Debug.Log("Failed to leave room : " + err);
            leaveEvent.Set();
        });

        leaveEvent.WaitOne(1000, false);
        chatText.Clear();
        currentChatUsers.Clear();
        //chatUsersJoinedID.Clear();
        currentRoom = "";

        UnRegisterOnTopicMessagePresence();
    }
コード例 #3
0
 public void Player2GetSelf()
 {
     client2.Send(NSelfFetchMessage.Default(), (INSelf result) => {
         Debug.LogFormat("Player 2 handle: '{0}'.", result.Handle);
         idPlayer2 = result.Id;
         JoinTopicPlayer2Enable = true;
     }, (INError error) =>
     {
         Debug.LogErrorFormat("Could not retrieve player 2 self: '{0}'.", error.Message);
     });
 }
コード例 #4
0
    //Called when "Join Match" is clicked in the Match List Panel
    public void JoinMatch()
    {
        Debug.Log("Joining the match: " + matchName);
        RegisterOnMatchData();

        ManualResetEvent joinEvent = new ManualResetEvent(false);

        matchID = matchNameMatchGuid[matchName].ToByteArray();
        string opponentName = matchGuidMatchSettings[matchNameMatchGuid[matchName]].matchCreator;
        string maxHealth    = matchGuidMatchSettings[matchNameMatchGuid[matchName]].maxHealth;

        client = NakamaData.Singleton.Client;
        client.Send(NMatchJoinMessage.Default(matchID), (INMatch match) =>
        {
            joinEvent.Set();
        }, (INError err) =>
        {
            Debug.Log("Failed to Join match. Error: " + err);
            joinEvent.Set();
        });

        joinEvent.WaitOne(1000, false);
        SendMatchInfoToMatchRoom("remove", 0);
        SendMessages.Singleton.LeaveRoom();
        SendMessages.Singleton.JoinRoom(matchName);
        GameManager.Singleton.StartNewGamePlay(matchName, Convert.ToInt32(maxHealth), opponentName);
        matchListPanel.gameObject.SetActive(false);
    }
コード例 #5
0
ファイル: UserChat.cs プロジェクト: truonglvx/nakama-unity
    public void Player1JoinTopic()
    {
        NTopicJoinMessage topicJoin = new NTopicJoinMessage.Builder().TopicDirectMessage(session2.Id).Build();

        client1.Send(topicJoin, (INResultSet <INTopic> topics) => {
            foreach (var presence in topics.Results[0].Presences)
            {
                Debug.LogFormat("Presence initial state received by Player 1: User handle '{0}' is in the topic.", presence.Handle);
            }
            topicPlayer1           = topics.Results[0].Topic;
            JoinTopicPlayer1Enable = false;
            JoinTopicPlayer2Enable = true;
        }, (INError error) => {
            Debug.LogErrorFormat("Player 1 could not join topic: '{0}'.", error.Message);
        });
    }
コード例 #6
0
    public void SendChatMessage()
    {
        client         = NakamaData.Singleton.Client;
        clientUserName = NakamaData.Singleton.ClientUserName;

        if (chatInputBox.text == "")
        {
            return;
        }
        Debug.LogWarning("Sending a message");
        ManualResetEvent sendMessage = new ManualResetEvent(false);

        chatInputText     = chatInputBox.text;
        chatInputBox.text = "";
        string chatMessage           = "{\"messageText\": \"[" + clientUserName + " " + DateTime.Now.ToString("HH:mm:ss") + "] " + chatInputText + "\"}";
        NTopicMessageSendMessage msg = NTopicMessageSendMessage.Default(currentTopic, Encoding.UTF8.GetBytes(chatMessage));

        client.Send(msg, (INTopicMessageAck ack) =>
        {
            Debug.Log("Message being sent");
            sendMessage.Set();
        }, (INError error) =>
        {
            Debug.LogErrorFormat("Player could not send message: '{0}'.", error.Message);
        });

        sendMessage.WaitOne(1000, false);
    }
コード例 #7
0
    private void SendMatchInfoToMatchRoom(string addRemove, int maxHealth)
    {
        client = NakamaData.Singleton.Client;
        ManualResetEvent sendMessage  = new ManualResetEvent(false);
        Guid             matchID_Guid = new Guid(matchID);

        //Debug.LogWarning("Encoding.UTF8.GetString(matchID): " + Encoding.UTF8.GetString(matchID));
        //Guid test = new Guid(matchID);

        string chatMessage = "{\"addRemove\":\"" + addRemove + "\",\"matchName\":\"" + matchName + "\",\"userName\":\"" + NakamaData.Singleton.ClientUserName + "\",\"matchIDGUID\":\"" + matchID_Guid.ToString() + "\",\"matchMaxHealth\":\"" + maxHealth + "\"}";
        //Debug.LogWarning("DEBUG:::: chatJson.matchIDGUID: " + test + " chatJson.matchIDGUID..ToByteArray(): " + test.ToByteArray() + " Encoding.UTF8.GetString(matchID)" + Encoding.UTF8.GetString(matchID));
        //Debug.LogWarning("DEBUG:::: Encoding.UTF8.GetString(test.ToByteArray()): " + Encoding.UTF8.GetString(test.ToByteArray()) + " Encoding.UTF8.GetString(matchID)" + Encoding.UTF8.GetString(matchID));
        NTopicMessageSendMessage msg = NTopicMessageSendMessage.Default(matchListTopic, Encoding.UTF8.GetBytes(chatMessage));

        client.Send(msg, (INTopicMessageAck ack) =>
        {
            Debug.Log("Match Room Data being sent: " + chatMessage);
            sendMessage.Set();
        }, (INError error) =>
        {
            Debug.LogErrorFormat("Player could not send message: '{0}'.", error.Message);
        });

        sendMessage.WaitOne(1000, false);
    }
コード例 #8
0
ファイル: MatchTest.cs プロジェクト: ahmadnaser/nakama-unity
        public void CreateMatch()
        {
            ManualResetEvent evt   = new ManualResetEvent(false);
            INError          error = null;

            client1.Send(NMatchCreateMessage.Default(), (INMatch match) =>
            {
                evt.Set();
            }, (INError err) =>
            {
                error = err;
                evt.Set();
            });

            evt.WaitOne(5000, false);
            Assert.IsNull(error);
        }
コード例 #9
0
ファイル: FriendTest.cs プロジェクト: truonglvx/nakama-unity
        public void AddFriend()
        {
            ManualResetEvent evt = new ManualResetEvent(false);
            var committed        = false;

            var message = NFriendAddMessage.ById(FriendUserId);

            client.Send(message, (bool completed) => {
                committed = completed;
                evt.Set();
            }, _ => {
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.IsTrue(committed);
        }
コード例 #10
0
        // +++ public functions +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public void CreateMatch()
        {
            var createMatchMessage = NMatchCreateMessage.Default();

            _client.Send(
                createMatchMessage,
                (INMatch match) => { if (OnMatchCreated != null)
                                     {
                                         OnMatchCreated(match);
                                     }
                },
                (INError error) => { if (OnMatchCreated != null)
                                     {
                                         OnMatchCreated(null);
                                     }
                }
                );
        }
コード例 #11
0
    //Create Match Button Pressed
    public void CreateandJoinMatch()
    {
        if (createdMatchNameInput.text.Length < 10 || createdMatchNameInput.text.Length > 30)
        {
            createMatchPanelErrorText.text = "Invalid match name! Must be between 10 and 30 characters. Currently only " + createdMatchNameInput.text.Length + " characters.";
            return;
        }

        Debug.Log("Creating a Match!!  Name: " + createdMatchNameInput.text);

        matchName = createdMatchNameInput.text;

        RegisterOnMatchData();

        client = NakamaData.Singleton.Client;
        ManualResetEvent createEvent = new ManualResetEvent(false);

        client.Send(NMatchCreateMessage.Default(), (INMatch match) =>
        {
            matchID     = match.Id;
            matchValues = match;
            client.Send(NMatchJoinMessage.Default(match.Id), (INMatch match2) =>
            {
                createEvent.Set();
            }, (INError err) =>
            {
                Debug.Log("Failed to Join created match. Error: " + err);
                createEvent.Set();
            });
        }, (INError err) =>
        {
            Debug.Log("Failed to create a match. Error: " + err);
            createEvent.Set();
        });

        createEvent.WaitOne(5000, false);
        createMatchPanel.gameObject.SetActive(false);
        SendMatchInfoToMatchRoom("add", Convert.ToInt32(maxHealthSlider.value));
        PlayerPrefs.SetString("MatchCreated", new Guid(matchID).ToString());
        SendMessages.Singleton.LeaveRoom();
        SendMessages.Singleton.JoinRoom(matchName);
        GameManager.Singleton.StartNewGamePlay(createdMatchNameInput.text, Convert.ToInt32(maxHealthSlider.value));
    }
コード例 #12
0
    private void FetchClientInfo()
    {
        ManualResetEvent nakamaEvent = new ManualResetEvent(false);
        INError          error       = null;

        client.Send(NSelfFetchMessage.Default(), (INSelf result) => {
            clientID = result.Id;
            nakamaEvent.Set();
        }, (INError err) =>
        {
            error = err;
            Debug.LogErrorFormat("Could not retrieve client self: '{0}'.", error.Message);
            nakamaEvent.Set();
        });

        nakamaEvent.WaitOne(1000, false);
        NakamaData.Singleton.ClientID = clientID;
        Debug.Log("FetchClientInfo():: ClientID: " + clientID);
    }
コード例 #13
0
        public void LeaderboardsList()
        {
            ManualResetEvent            evt = new ManualResetEvent(false);
            INResultSet <INLeaderboard> res = null;

            var message = new NLeaderboardsListMessage.Builder().Add(LeaderboardIdName).Build();

            client.Send(message, (INResultSet <INLeaderboard> results) =>
            {
                res = results;
                evt.Set();
            }, _ => {
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.IsNotNull(res);
            Assert.IsNotEmpty(res.Results);
            Assert.AreEqual(res.Results[0].Id, LeaderboardId);
            Assert.GreaterOrEqual(res.Results[0].Count, 0);
        }
コード例 #14
0
        public void ApplePurchaseTest()
        {
            ManualResetEvent evt   = new ManualResetEvent(false);
            INPurchaseRecord res   = null;
            INError          error = null;

            var message = NPurchaseValidateMessage.Apple("product_id", "base64_receipt_data");

            client.Send(message, (INPurchaseRecord record) =>
            {
                res = record;
                evt.Set();
            }, (INError e) => {
                error = e;
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.IsNull(error);
            Assert.IsNotNull(res);
        }
コード例 #15
0
ファイル: TopicTest.cs プロジェクト: ahmadnaser/nakama-unity
        public void PresenceUpdateJoinTopic()
        {
            INError error = null;

            ManualResetEvent evt1 = new ManualResetEvent(false);

            byte[] room    = Encoding.UTF8.GetBytes("test-room");
            var    message = new NTopicJoinMessage.Builder().TopicRoom(room).Build();

            client1.Send(message, (INTopic topic) =>
            {
                evt1.Set();
            }, (INError err) =>
            {
                error = err;
                evt1.Set();
            });
            evt1.WaitOne(5000, false);
            Assert.IsNull(error);

            byte[]           joinUserId = null;
            ManualResetEvent evt2       = new ManualResetEvent(false);

            client1.OnTopicPresence += (object source, NTopicPresenceEventArgs args) =>
            {
                joinUserId = args.TopicPresence.Join[0].UserId;
                evt2.Set();
            };
            client2.Send(new NTopicJoinMessage.Builder().TopicRoom(room).Build(), (INTopic topic) =>
            {
                // No action.
            }, (INError err) =>
            {
                error = err;
                evt2.Set();
            });
            evt2.WaitOne(5000, false);
            Assert.IsNull(error);
            Assert.AreEqual(joinUserId, userId2);
        }
コード例 #16
0
        public void FetchUser()
        {
            ManualResetEvent evt  = new ManualResetEvent(false);
            INSelf           self = null;

            var message = NSelfFetchMessage.Default();

            client.Send(message, (INSelf result) => {
                self = result;
                evt.Set();
            }, _ => {
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.NotNull(self);
            Assert.NotNull(self.Id);
        }
コード例 #17
0
    /// <summary>
    /// opCodes:
    /// 0 Joined
    /// 1 Player 1 turn
    /// 2 Player 2 turn
    /// 3 Card Drawn(by whoever sent this)
    /// 4 Attack(by whoever sent this)
    /// 5 current turn
    /// </summary>
    public void SendMatchData(int opCode, string dataString)
    {
        Debug.Log("Sending Match Data:: opCode: " + opCode + " datastring: " + dataString);
        byte[] data    = Encoding.ASCII.GetBytes(dataString);
        var    message = NMatchDataSendMessage.Default(matchID, opCode, data);

        client.Send(message, (bool complete) =>
        {
            Debug.Log("Successfully sent data to match.");
        }, (INError error) => {
            Debug.LogErrorFormat("Could not send data to match: '{0}'.", error.Message);
        });
    }
コード例 #18
0
ファイル: TopicTest.cs プロジェクト: truonglvx/nakama-unity
        public void PresenceUpdateJoinTopic()
        {
            INError error = null;

            ManualResetEvent evt1 = new ManualResetEvent(false);
            string           room = "test-room";
            var message           = new NTopicJoinMessage.Builder().TopicRoom(room).Build();

            client1.Send(message, (INResultSet <INTopic> topics) =>
            {
                evt1.Set();
            }, (INError err) =>
            {
                error = err;
                evt1.Set();
            });
            evt1.WaitOne(5000, false);
            Assert.IsNull(error);

            string           joinUserId = null;
            ManualResetEvent evt2       = new ManualResetEvent(false);

            client1.OnTopicPresence = (INTopicPresence presence) =>
            {
                joinUserId = presence.Join[0].UserId;
                evt2.Set();
            };
            client2.Send(new NTopicJoinMessage.Builder().TopicRoom(room).Build(), (INResultSet <INTopic> topic) =>
            {
                // No action.
            }, (INError err) =>
            {
                error = err;
                evt2.Set();
            });
            evt2.WaitOne(5000, false);
            Assert.IsNull(error);
            Assert.AreEqual(joinUserId, userId2);
        }
コード例 #19
0
        public void SendNotificationsRpc()
        {
            ManualResetEvent evt = new ManualResetEvent(false);
            INError          err = null;

            var message = new NRuntimeRpcMessage.Builder("notification_send").Build();

            client.OnNotification = (INNotification notification) =>
            {
                Assert.IsTrue(notification.CreatedAt > 0);
                evt.Set();
            };

            client.Send(message, (INRuntimeRpc result) =>
            {
            }, (INError e) => {
                err = e;
                evt.Set();
            });

            evt.WaitOne(2000, false);
            Assert.IsNull(err);
        }
コード例 #20
0
    /// <summary>
    /// The following is used to create a Match List. Hopefully Nakama releases the version that does this for us! Yay!
    /// TODO: Fix this once that release comes out
    /// Methods::::
    /// SendMatchInfoToMatchRoom(), JoinMatchRoom(),
    /// </summary>
    ///
    public void JoinMatchRoom()
    {
        client = NakamaData.Singleton.Client;
        ManualResetEvent joinEvent = new ManualResetEvent(false);
        var message = new NTopicJoinMessage.Builder().TopicRoom(Encoding.UTF8.GetBytes("match-list")).Build();

        client.Send(message, (INTopic topic) =>
        {
            matchListTopic = topic.Topic;
            joinEvent.Set();
        }, (INError err) =>
        {
            Debug.Log("Failed to join room : " + err);
            joinEvent.Set();
        });

        joinEvent.WaitOne(1000, false);
        RegisterMatchListRoom();
    }
コード例 #21
0
    // Update is called once per frame
    void Update()
    {
        if (isLocal)
        {
            // get input
            var input = Input.GetAxis("Vertical");

            // move
            transform.Translate(Vector3.up * Time.deltaTime * input * speed, Space.World);

            // push position
            List <float> data    = new List <float>().AddVector(transform.position);
            var          message = NMatchDataSendMessage.Default(matchId, 1, data.Serialize());
            client.Send(message, (bool done) => { Debug.Log("done"); }, (INError error) => Debug.LogError(error.Message));
        }
        else
        {
            transform.position = networkPosition;
        }
    }
コード例 #22
0
    public void QuitMatch()
    {
        Debug.LogWarning("Quitting Match");
        ManualResetEvent quitEvent = new ManualResetEvent(false);

        client = NakamaData.Singleton.Client;
        client.Send(NMatchLeaveMessage.Default(matchID), (bool complete) =>
        {
            Debug.LogWarning("Successfully Quit Match");
        }, (INError err) =>
        {
            Debug.LogWarning("Could not quit match. Error: " + err);
            quitEvent.Set();
        });
        quitEvent.WaitOne(1000, false);
        SendMatchInfoToMatchRoom("remove", 0);
        UnRegisterOnMatchData();
        SendMessages.Singleton.LeaveRoom();
        SendMessages.Singleton.JoinRoom("default-room");
        GameManager.Singleton.QuitCurrentGameMatch(NakamaData.Singleton.ClientUserName + " left the match");
    }
コード例 #23
0
    //Used to get the username from userID
    private string FetchUserFullName(byte[] userID)
    {
        ManualResetEvent fetchEvent = new ManualResetEvent(false);

        string fullNameValue = "";
        var    message       = NUsersFetchMessage.Default(userID);

        client.Send(message, (INResultSet <INUser> results) => {
            //Debug.LogFormat("Fetched {0} users.", results.Results.Count);
            foreach (INUser user in results.Results)
            {
                fullNameValue = user.Fullname;
            }
            fetchEvent.Set();
        }, (INError error) =>
        {
            Debug.LogErrorFormat("Could not retrieve users: '{0}'.", error.Message);
            fetchEvent.Set();
        });
        fetchEvent.WaitOne(1000, false);
        return(fullNameValue);
    }
コード例 #24
0
ファイル: RuntimeTest.cs プロジェクト: truonglvx/nakama-unity
        public void RpcLoopback()
        {
            ManualResetEvent evt = new ManualResetEvent(false);
            INRuntimeRpc     rpc = null;

            string payload = "payload-data";
            var    message = new NRuntimeRpcMessage.Builder("loopback").Payload(payload).Build();

            client.Send(message, (INRuntimeRpc result) =>
            {
                rpc = result;
                evt.Set();
            }, _ =>
            {
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.NotNull(rpc);
            Assert.AreEqual("loopback", rpc.Id);
            Assert.AreEqual(payload, rpc.Payload);
        }
コード例 #25
0
    //Will join a room for the client, and update that room's userlist for all clients
    public void JoinRoom(string roomName)
    {
        client = NakamaData.Singleton.Client;
        ManualResetEvent joinEvent = new ManualResetEvent(false);

        currentRoom = roomName;
        var message = new NTopicJoinMessage.Builder().TopicRoom(Encoding.UTF8.GetBytes(roomName)).Build();

        client.Send(message, (INTopic topic) =>
        {
            chatText.Add("Successfully joined the room '" + roomName + "'. There are currently " + topic.Presences.Count + " Users");
            Debug.Log("Successfully Joined Room");
            userList     = topic.Presences;
            currentTopic = topic.Topic;
            joinEvent.Set();
        }, (INError err) =>
        {
            Debug.Log("Failed to join room : " + err);
            joinEvent.Set();
        });

        joinEvent.WaitOne(1000, false);

        //Create the user list to display
        foreach (var userInList in userList)
        {
            if (!chatUsersJoinedID.Contains(userInList.UserId))
            {
                chatUsersJoinedID.Add(userInList.UserId);
            }
        }

        Debug.Log("JoinRoom::  ::chatUsersJoinedID.count: " + chatUsersJoinedID.Count);

        UserListChange = true;   //Run update to update UserList
        RegisterOnTopicMessagePresence();
    }
コード例 #26
0
        public void MatchmakeAdd()
        {
            ManualResetEvent   evt   = new ManualResetEvent(false);
            INError            error = null;
            INMatchmakeMatched res   = null;

            client1.OnMatchmakeMatched = (INMatchmakeMatched matched) =>
            {
                res = matched;
                evt.Set();
            };

            client1.Send(NMatchmakeAddMessage.Default(2), (INMatchmakeTicket ticket1) =>
            {
            }, (INError err) =>
            {
                error = err;
            });

            evt.WaitOne(2000, false);
            Assert.IsNull(error);
            Assert.IsNull(res);
        }
コード例 #27
0
        public void WriteStorageInvalidIfMatch()
        {
            ManualResetEvent           evt = new ManualResetEvent(false);
            INResultSet <INStorageKey> res = null;

            var message = new NStorageWriteMessage.Builder()
                          .Write(Bucket, Collection, Record, StorageValue, InvalidVersion)
                          .Build();

            client.Send(message, (INResultSet <INStorageKey> results) =>
            {
                res = results;
                evt.Set();
            }, _ => {
                evt.Set();
            });

            evt.WaitOne(1000, false);
            Assert.IsNotNull(res);
            Assert.IsNotEmpty(res.Results);
            Assert.AreEqual(res.Results[0].Bucket, Bucket);
            Assert.AreEqual(res.Results[0].Collection, Collection);
            Assert.AreEqual(res.Results[0].Record, Record);
        }
コード例 #28
0
ファイル: TopicTest.cs プロジェクト: truonglvx/nakama-unity
        public void JoinTopic()
        {
            ManualResetEvent evt   = new ManualResetEvent(false);
            INError          error = null;

            var message = new NTopicJoinMessage.Builder().TopicRoom("test-room").Build();

            client1.Send(message, (INResultSet <INTopic> topics) =>
            {
                evt.Set();
            }, (INError err) =>
            {
                error = err;
                evt.Set();
            });

            evt.WaitOne(5000, false);
            Assert.IsNull(error);
        }
コード例 #29
0
    void FetchSelf()
    {
        var message = NSelfFetchMessage.Default();

        client.Send(message, OnFetchSelf, OnError);
    }
コード例 #30
0
    public void StartMatchMaking(Action onMatchMakeSucceeded, Action onMatchMakeFailed)
    {
        INMatchmakeTicket      matchmake         = null;
        IList <INUserPresence> matchParticipants = null;

        // Look for a match for two participants. Yourself and one more.
        var message = NMatchmakeAddMessage.Default(numMatchParticipants);

        _client.Send(message, (INMatchmakeTicket result) => {
            Debug.Log("Added user to matchmaker pool.");

            var cancelTicket = result.Ticket;
            Debug.LogFormat("The cancellation code {0}", cancelTicket);
        }, (INError err) => {
            Debug.LogErrorFormat("Error: code '{0}' with '{1}'.", err.Code, err.Message);
        });

        _client.OnMatchmakeMatched = (INMatchmakeMatched matched) => {
            // a match token is used to join the match.
            Debug.LogFormat("Match token: '{0}'", matched.Token);

            matchParticipants = matched.Presence;
            // a list of users who've been matched as opponents.
            foreach (var presence in matched.Presence)
            {
                Debug.LogFormat("User id: '{0}'.", presence.UserId);
                Debug.LogFormat("User handle: '{0}'.", presence.Handle);
            }

            // list of all match properties
            foreach (var userProperty in matched.UserProperties)
            {
                foreach (KeyValuePair <string, object> entry in userProperty.Properties)
                {
                    Debug.LogFormat("Property '{0}' for user '{1}' has value '{2}'.", entry.Key, userProperty.Id, entry.Value);
                }

                foreach (KeyValuePair <string, INMatchmakeFilter> entry in userProperty.Filters)
                {
                    Debug.LogFormat("Filter '{0}' for user '{1}' has value '{2}'.", entry.Key, userProperty.Id, entry.Value.ToString());
                }
            }

            var jm = NMatchJoinMessage.Default(matched.Token);
            _client.Send(jm, (INResultSet <INMatch> matches) => {
                Debug.Log("Successfully joined match.");
                _match             = matches.Results[0];
                _matchParticipants = matchParticipants;
//				foreach(Action a in OnMatchJoinedActions) {
//					a();
//				}

                foreach (INMatch match in matches.Results)
                {
                    Debug.LogFormat("Match id: {0} Presence", match.Id);

                    foreach (INUserPresence presence in match.Presence)
                    {
                        Debug.LogFormat("User handle: {0} id {1}.", presence.Handle, presence.UserId);
                    }
                }

                Enqueue(() => {
                    onMatchJoined(_match);
                });
            }, (INError error) => {
                Debug.LogErrorFormat("Error: code '{0}' with '{1}'.", error.Code, error.Message);
            });

            // TODO callback to UI
            onMatchMakeSucceeded();
        };
    }