public void Join(uint hostId, bool directP2P)
        {
            var            encrypted      = Filter.Config.EnableP2PEncryptedMessaging;
            EncryptContext encryptContext = null;

            if (encrypted)
            {
                encryptContext = new EncryptContext(Filter.Config.EncryptedMessageKeyLength);
            }

            var remotePeer = new ServerRemotePeer(this, hostId, directP2P, encryptContext);

            if (!_members.TryAdd(hostId, remotePeer))
            {
                throw new ProudException($"Member {hostId} is already in P2PGroup {HostId}");
            }

            var session = _filter.SessionLookupByHostId.GetValueOrDefault(hostId);

            if (session != null)
            {
                session.P2PGroup = this;

                if (encrypted)
                {
                    session.Send(new P2PGroup_MemberJoinMessage(HostId, hostId, 0, encryptContext.RC4.Key, directP2P));
                }
                else
                {
                    session.Send(new P2PGroup_MemberJoin_UnencryptedMessage(HostId, hostId, 0, directP2P));
                }
            }

            foreach (var member in _members.Values.Where(member => member.HostId != hostId).Cast <ServerRemotePeer>())
            {
                var memberSession = _filter.SessionLookupByHostId.GetValueOrDefault(member.HostId);

                var stateA = new P2PConnectionState(member);
                var stateB = new P2PConnectionState(remotePeer);

                remotePeer.ConnectionStates[member.HostId] = stateA;
                member.ConnectionStates[remotePeer.HostId] = stateB;
                if (encrypted)
                {
                    memberSession?.Send(new P2PGroup_MemberJoinMessage(HostId, hostId, stateB.EventId, encryptContext.RC4.Key, directP2P));
                    session?.Send(new P2PGroup_MemberJoinMessage(HostId, member.HostId, stateA.EventId, member.EncryptContext.RC4.Key, directP2P));
                }
                else
                {
                    memberSession?.Send(new P2PGroup_MemberJoin_UnencryptedMessage(HostId, hostId, stateB.EventId, directP2P));
                    session?.Send(new P2PGroup_MemberJoin_UnencryptedMessage(HostId, member.HostId, stateA.EventId, directP2P));
                }
            }
        }
 public P2PConnectionState(ServerRemotePeer remotePeer)
 {
     RemotePeer = remotePeer;
     EventId    = (uint)Guid.NewGuid().GetHashCode();
 }