예제 #1
0
        public void RefreshCommand(ChatRoom room) // sends status updates to all members of room
        {
            if (!IsCommandRoom(room.Kind))
            {
                Debug.Assert(false);
                return;
            }

            // remember connection status from before
            // nodes we arent connected to do try connect
            // if socket already active send status request

            OpLink localLink = Trust.LocalTrust.GetLink(room.ProjectID);

            if (localLink == null)
            {
                return;
            }

            OpLink uplink = localLink.GetHigher(true);

            // updates room's member list

            if (room.Kind == RoomKind.Command_High)
            {
                room.Members = new ThreadedList <ulong>();

                if (uplink != null)
                {
                    if (localLink.LoopRoot != null)
                    {
                        uplink      = localLink.LoopRoot;
                        room.Host   = uplink.UserID; // use loop id cause 0 is reserved for no root
                        room.IsLoop = true;
                    }
                    else
                    {
                        room.Host   = uplink.UserID;
                        room.IsLoop = false;
                        room.AddMember(room.Host);
                    }

                    foreach (OpLink downlink in uplink.GetLowers(true))
                    {
                        room.AddMember(downlink.UserID);
                    }
                }
            }

            else if (room.Kind == RoomKind.Command_Low)
            {
                room.Members = new ThreadedList <ulong>();

                room.Host = Core.UserID;
                room.AddMember(room.Host);

                foreach (OpLink downlink in localLink.GetLowers(true))
                {
                    room.AddMember(downlink.UserID);
                }
            }

            else if (room.Kind == RoomKind.Live_High)
            {
                // find highest thats online and make that the host,

                // if host changes, clear members

                // higher should send live lowers which members are conneted to it so everyone can sync up
                // location update should trigger a refresh of the live rooms
            }

            else if (room.Kind == RoomKind.Live_Low)
            {
                // just add self, dont remove members
            }


            // update dispaly that members has been refreshed
            Core.RunInGuiThread(room.MembersUpdate);
        }
예제 #2
0
        void ReceiveInvite(ChatInvite invite, RudpSession session)
        {
            // if in global im, only allow if on buddies list
            if (Core.User.Settings.GlobalIM)
            {
                if (!Core.Buddies.BuddyList.SafeContainsKey(session.UserID))
                {
                    return;
                }
            }

            if (Core.Buddies.IgnoreList.SafeContainsKey(session.UserID))
            {
                return;
            }

            bool showInvite = false;

            ChatRoom room;

            if (!RoomMap.TryGetValue(invite.RoomID, out room))
            {
                RoomKind kind = invite.SignedInvite != null ? RoomKind.Secret : RoomKind.Private;
                room        = new ChatRoom(kind, invite.RoomID, invite.Title);
                room.RoomID = invite.RoomID;
                room.Kind   = kind;
                room.AddMember(session.UserID);

                if (invite.Host != null)
                {
                    room.Host = Utilities.KeytoID(invite.Host);
                    Core.IndexKey(room.Host, ref invite.Host);
                }

                RoomMap.SafeAdd(room.RoomID, room);

                showInvite = true;
            }

            // private room
            if (room.Kind == RoomKind.Secret)
            {
                if (!Core.KeyMap.ContainsKey(room.Host))
                {
                    return;
                }

                byte[] hostKey = Core.KeyMap[room.Host];


                // if this is host sending us our verification
                if (session.UserID == room.Host)
                {
                    // check that host signed our public key with his private
                    if (!Utilities.CheckSignedData(hostKey, Core.KeyMap[Core.UserID], invite.SignedInvite))
                    {
                        return;
                    }

                    if (!room.Invites.ContainsKey(Core.UserID)) // would fail if a node's dupe on network sends invite back to itself
                    {
                        room.Invites.Add(Core.UserID, new Tuple <ChatInvite, List <ushort> >(invite, new List <ushort>()));
                    }
                }

                // else this is node in room sending us proof of being invited
                else
                {
                    if (!Core.KeyMap.ContainsKey(session.UserID))
                    {
                        return; // key should def be in map, it was added when session was made to sender
                    }
                    // check that host signed remote's key with host's private
                    if (!Utilities.CheckSignedData(hostKey, Core.KeyMap[session.UserID], invite.SignedInvite))
                    {
                        return;
                    }
                }

                // if not verified yet, add them and send back our own verification
                if (!room.Verified.ContainsKey(session.UserID))
                {
                    room.Verified[session.UserID] = true;

                    if (room.Active)
                    {
                        SendInviteProof(room, session); // someone sends us their proof, we send it back in return
                        SendStatus(session);            // send status here because now it will include private rooms
                    }
                }
            }

            if (Trust != null && !Trust.TrustMap.SafeContainsKey(session.UserID))
            {
                Trust.Research(session.UserID, 0, false);
            }

            if (showInvite)
            {
                Core.RunInGuiThread(NewInvite, session.UserID, room);
            }
        }