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); }
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); } }