public ChatRoom CreateRoom(string name, RoomKind kind) { ulong id = Utilities.RandUInt64(Core.RndGen); if (kind == RoomKind.Public) { id = ChatService.GetPublicRoomID(name); } ChatRoom room = new ChatRoom(kind, id, name); room.Active = true; room.AddMember(Core.UserID); RoomMap.SafeAdd(id, room); if (kind == RoomKind.Secret) { room.Host = Core.UserID; room.Verified[Core.UserID] = true; SendInviteRequest(room, Core.UserID); // send invite to copies of ourself that exist } Core.RunInGuiThread(Refresh); if (room.PublishRoom) { SetupPublic(room); } return(room); }
public void SendInviteRequest(ChatRoom room, ulong id) { if (Core.InvokeRequired) { Core.RunInCoreAsync(delegate() { SendInviteRequest(room, id); }); return; } room.AddMember(id); ChatInvite invite = null; // if user explicitly chooses to invite users, invalidate previous recorded attempts invite = new ChatInvite(); invite.RoomID = room.RoomID; invite.Title = room.Title; // if private room sign remote users id with our private key if (room.Kind == RoomKind.Secret) { invite.Host = Core.KeyMap[Core.UserID]; if (!Core.KeyMap.ContainsKey(id)) { return; } invite.SignedInvite = Core.User.Settings.KeyPair.SignData(Core.KeyMap[id], new SHA1CryptoServiceProvider()); room.Verified[id] = true; } room.Invites[id] = new Tuple <ChatInvite, List <ushort> >(invite, new List <ushort>()); // try to conncet to all of id's locations foreach (ClientInfo loc in Core.Locations.GetClients(id)) { Network.RudpControl.Connect(loc.Data); } // send invite to already connected locations foreach (RudpSession session in Network.RudpControl.GetActiveSessions(id)) { session.SendData(ServiceID, 0, invite); room.Invites[id].Param2.Add(session.ClientID); ProcessMessage(room, "Invite sent to " + GetNameAndLocation(session)); SendStatus(room); // so we get added as active to new room invitee creates SendWhoResponse(room, session); } }
public void JoinRoom(ChatRoom room) { if (Core.InvokeRequired) { Core.RunInCoreAsync(() => JoinRoom(room)); return; } if (IsCommandRoom(room.Kind)) { JoinCommand(room.ProjectID, room.Kind); return; } room.Active = true; room.AddMember(Core.UserID); // for private rooms, send proof of invite first if (room.Kind == RoomKind.Secret) { SendInviteProof(room); } SendStatus(room); SendWhoRequest(room); ConnectRoom(room); if (room.PublishRoom) { SetupPublic(room); } Core.RunInGuiThread(Refresh); Core.RunInGuiThread(room.MembersUpdate); }
void Search_FoundRoom(byte[] data, object arg) { ChatRoom room = arg as ChatRoom; if (!room.Active) { return; } // add locations to running transfer LocationData loc = LocationData.Decode(data); DhtClient client = new DhtClient(loc.UserID, loc.Source.ClientID); Core.Network.LightComm.Update(loc); if (!room.Members.SafeContains(client.UserID)) { room.AddMember(client.UserID); Core.Locations.Research(client.UserID); } // connect to new members ConnectRoom(room); }
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); } }