Beispiel #1
0
        async Task IrisSub()
        {
            var dic = new Dictionary <string, object>
            {
                { "seq_id", SeqId.ToString() },
                { "sub", new List <string>() },
                { "snapshot_at_ms", SnapshotAt.ToUnixTimeMiliSeconds() }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/ig_sub_iris"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
        /// <summary>
        ///     Indicate activity
        /// </summary>
        /// <param name="threadId">Thread id</param>
        /// <param name="isActive">Active status</param>
        public async Task <IResult <bool> > IndicateActivityAsync(string threadId, bool isActive)
        {
            try
            {
                var token = ExtensionHelper.GetThreadToken();

                var data = new Dictionary <string, string>
                {
                    { "action", "indicate_activity" },
                    { "item_type", "indicate_activity" },
                    { "thread_id", threadId },
                    { "client_context", token },
                    { "activity_status", isActive ? "1" : "0" },
                };
                var json          = JsonConvert.SerializeObject(data);
                var bytes         = Encoding.UTF8.GetBytes(json);
                var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    Payload   = ZlibHelper.Compress(bytes).AsBuffer(),
                    PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                    TopicName = "132"
                };
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                return(Result.Success(true));
            }
            catch (SocketException socketException)
            {
                return(Result.Fail(socketException, default(bool), ResponseType.NetworkProblem));
            }
            catch (Exception exception)
            {
                return(Result.Fail <bool>(exception));
            }
        }
Beispiel #3
0
        async Task PubSub()
        {
            var user = _instaApi.GetLoggedUser().LoggedInUser;
            var dic  = new Dictionary <string, List <string> >
            {
                { "sub",
                  new List <string>
                  {
                      SkyWalker.DirectSubscribe(user?.Pk.ToString()),
                      SkyWalker.LiveSubscribe(user?.Pk.ToString()),
                  } }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/pubsub"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
Beispiel #4
0
        async Task RealtimeSub()
        {
            var user = _instaApi.GetLoggedUser().LoggedInUser;
            var dic  = new Dictionary <string, List <string> >
            {
                { "sub",
                  new List <string>
                  {
                      GraphQLSubscriptions.GetAppPresenceSubscription(),
                GraphQLSubscriptions.GetZeroProvisionSubscription(_instaApi.GetCurrentDevice().DeviceGuid.ToString()),
                      GraphQLSubscriptions.GetDirectStatusSubscription(),
                      GraphQLSubscriptions.GetDirectTypingSubscription(user?.Pk.ToString()),
                      GraphQLSubscriptions.GetAsyncAdSubscription(user?.Pk.ToString())
                  } }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/ig_realtime_sub"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
Beispiel #5
0
        async Task SubscribeForDM()
        {
            var messageSync     = new SubscriptionRequest("/ig_message_sync", QualityOfService.AtLeastOnce);
            var sendMessageResp = new SubscriptionRequest("/ig_send_message_response", QualityOfService.AtLeastOnce);
            var subIrisResp     = new SubscriptionRequest("/ig_sub_iris_response", QualityOfService.AtLeastOnce);
            var subscribePacket = new SubscribePacket((ushort)CryptographicBuffer.GenerateRandomNumber(), messageSync, sendMessageResp, subIrisResp);

            await FbnsPacketEncoder.EncodePacket(subscribePacket, _outboundWriter);
        }
        private async Task <IResult <InstaDirectRespondPayload> > SendDirectItem(Dictionary <string, string> dic, string token = null)
        {
            try
            {
                if (string.IsNullOrEmpty(token))
                {
                    token = ExtensionHelper.GetThreadToken();
                }

                var data = new Dictionary <string, string>
                {
                    { "action", "send_item" },
                    { "client_context", token },
                };
                foreach (var item in dic)
                {
                    data.Add(item.Key, item.Value);
                }
                var json  = JsonConvert.SerializeObject(data);
                var bytes = Encoding.UTF8.GetBytes(json);

                //id: '132',
                //path: '/ig_send_message',
                var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    Payload   = ZlibHelper.Compress(bytes).AsBuffer(),
                    PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                    TopicName = "132"
                };
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                await Task.Delay(WaitForResponseDelay);

                var responseItem = Responses.GetItem(token);
                if (responseItem != null)
                {
                    Responses.Remove(responseItem);
                    return(responseItem.IsSucceed ?
                           Result.Success(ConvertersFabric.Instance.GetDirectRespondConverter(responseItem).Convert().Payload) :
                           Result.Fail(responseItem.Payload?.Message, ConvertersFabric.Instance
                                       .GetDirectRespondConverter(responseItem).Convert().Payload));
                }
                else
                {
                    return(Result.Fail <InstaDirectRespondPayload>("Couldn't get any response in the waiting time...\nMessage might sent after this period"));
                }
            }
            catch (SocketException socketException)
            {
                return(Result.Fail(socketException, default(InstaDirectRespondPayload), ResponseType.NetworkProblem));
            }
            catch (Exception exception)
            {
                return(Result.Fail <InstaDirectRespondPayload>(exception));
            }
        }
Beispiel #7
0
        public async Task StartFresh()
        {
            Log("Starting fresh");
            if (!InternetAvailable())
            {
                Log("Internet not available. Exiting.");
                return;
            }

            if (Running)
            {
                Log("realtime client is already running");
                return;
            }

            if (AppIsInBackground)
            {
                Log("Application is in background");
                return;
            }
            if (Socket != null)
            {
                Shutdown();
                await Task.Delay(350);
            }
            try
            {
                var connectPacket = new FbnsConnectPacket
                {
                    Payload = await RealtimePayload.BuildPayload(_instaApi)
                };
                Socket = new StreamSocket();
                Socket.Control.KeepAlive = true;
                Socket.Control.NoDelay   = true;
                Socket.Control.OutboundBufferSizeInBytes = 20 * 1024 * 1024;
                await Socket.ConnectAsync(new HostName(DEFAULT_HOST), "443", SocketProtectionLevel.Tls12);

                _inboundReader                    = new DataReader(Socket.InputStream);
                _outboundWriter                   = new DataWriter(Socket.OutputStream);
                _inboundReader.ByteOrder          = ByteOrder.BigEndian;
                _inboundReader.InputStreamOptions = InputStreamOptions.Partial;
                _outboundWriter.ByteOrder         = ByteOrder.BigEndian;
                _runningTokenSource               = new CancellationTokenSource();
                await FbnsPacketEncoder.EncodePacket(connectPacket, _outboundWriter);
            }
            catch (Exception e)
            {
                e.PrintInDebug();
                Restart();
                return;
            }
            StartPollingLoop();
        }
        public async Task <IResult <bool> > LikeThreadMessageAsync(string threadId, string itemId)
        {
            try
            {
                var token = /* ExtensionHelper.GetThreadToken()*/ Guid.NewGuid().ToString();
//item_type=reaction&
//reaction_type=like&
//action=send_item&
//thread_ids=[340282366841710300949128148722678938640]&
//client_context=6687326311760832960&
//_csrftoken=tmqdvmqM1YjSauVdSOpIPnbCW3d2Dxxh&
//mutation_token=6687326311760832960&
//_uuid=fe3634e6-d3ec-4f01-943e-20381fdd9e19&
//node_type=item&
//reaction_status=created&
//item_id=29414953485080962978249978855555072&
//device_id=android-35b3eb8488e1e15c
                var data = new Dictionary <string, string>
                {
                    { "action", "send_item" },
                    { "item_type", "reaction" },
                    { "reaction_type", "like" },
                    { "node_type", "item" },
                    { "reaction_status", "created" },
                    { "thread_id", threadId },
                    { "client_context", token },
                    { "item_id", itemId },
                };
                var json          = JsonConvert.SerializeObject(data);
                var bytes         = Encoding.UTF8.GetBytes(json);
                var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    Payload   = ZlibHelper.Compress(bytes).AsBuffer(),
                    PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                    TopicName = "132"
                };
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                return(Result.Success(true));
            }
            catch (SocketException socketException)
            {
                return(Result.Fail(socketException, default(bool), ResponseType.NetworkProblem));
            }
            catch (Exception exception)
            {
                return(Result.Fail <bool>(exception));
            }
        }
Beispiel #9
0
        public async Task SendPing()
        {
            try
            {
                var packet = PingReqPacket.Instance;
                await FbnsPacketEncoder.EncodePacket(packet, _outboundWriter);

                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Pinging Push server");
            }
            catch (Exception ex)
            {
                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Failed to ping Push server. Shutting down.");
                Shutdown();
            }
        }
Beispiel #10
0
        /// <summary>
        ///     Register this client on the MQTT side stating what application this client is using.
        ///     The server will then return a token for registering over Instagram API side.
        /// </summary>
        /// <param name="ctx"></param>
        private async Task RegisterMqttClient()
        {
            var message = new Dictionary <string, string>
            {
                { "pkg_name", "com.instagram.android" },
                { "appid", "567067343352427" }
            };

            var json      = JsonConvert.SerializeObject(message);
            var jsonBytes = Encoding.UTF8.GetBytes(json);

            byte[] compressed;
            using (var compressedStream = new MemoryStream(jsonBytes.Length))
            {
                using (var zlibStream =
                           new ZlibStream(compressedStream, CompressionMode.Compress, CompressionLevel.Level9, true))
                {
                    zlibStream.Write(jsonBytes, 0, jsonBytes.Length);
                }
                compressed = new byte[compressedStream.Length];
                compressedStream.Position = 0;
                compressedStream.Read(compressed, 0, compressed.Length);
            }

            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed.AsBuffer(),
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = ((byte)TopicIds.RegReq).ToString()
            };

            // Send PUBLISH packet then wait for PUBACK
            // Retry after TIMEOUT seconds
            if (!Running)
            {
                return;
            }
            try
            {
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                WaitForPubAck();
            }
            catch (ObjectDisposedException)
            {
                // pass
            }
        }
Beispiel #11
0
        public async Task SendPing()
        {
            try
            {
                var packet = PingReqPacket.Instance;
                if (!Running)
                {
                    return;
                }
                await FbnsPacketEncoder.EncodePacket(packet, _outboundWriter);

                this.Log("Pinging Push server");
            }
            catch (Exception)
            {
                this.Log("Failed to ping Push server");
            }
        }
Beispiel #12
0
        public async Task StartFresh()
        {
            this.Log("Starting fresh");
            if (!InternetAvailable())
            {
                this.Log("Internet not available. Exiting.");
                return;
            }

            if (Running)
            {
                throw new Exception("Push client is already running");
            }
            var connectPacket = new FbnsConnectPacket
            {
                Payload = await RealtimePayload.BuildPayload(_instaApi)
            };

            Socket = new StreamSocket();
            Socket.Control.KeepAlive = true;
            Socket.Control.NoDelay   = true;
            Socket.Control.OutboundBufferSizeInBytes = 10 * 1024 * 1024;
            try
            {
                await Socket.ConnectAsync(new HostName(DEFAULT_HOST), "443", SocketProtectionLevel.Tls12);

                _inboundReader                    = new DataReader(Socket.InputStream);
                _outboundWriter                   = new DataWriter(Socket.OutputStream);
                _inboundReader.ByteOrder          = ByteOrder.BigEndian;
                _inboundReader.InputStreamOptions = InputStreamOptions.Partial;
                _outboundWriter.ByteOrder         = ByteOrder.BigEndian;
                _runningTokenSource               = new CancellationTokenSource();
                await FbnsPacketEncoder.EncodePacket(connectPacket, _outboundWriter);
            }
            catch (Exception e)
            {
                DebugLogger.LogExceptionX(e);
                Restart();
                return;
            }
            StartPollingLoop();
        }
        public async Task <IResult <bool> > ReactionMessageAsync(string threadId, string itemId, string emoji)
        {
            try
            {
                //{"action":"item_ack","status_code":"404","payload":{"client_context":"6687658745131972483","message":"target item is not supported"},"status":"fail"}

                //{"action":"item_ack","status_code":"400","payload":{"client_context":"6685052289622163080","message":"unknown reaction type"},"status":"fail"}
                var token = ExtensionHelper.GetThreadToken();
                var data  = new Dictionary <string, string>
                {
                    { "action", "send_item" },
                    { "item_type", "reaction" },
                    { "reaction_type", "like" },
                    { "node_type", "item" },
                    { "reaction_status", "created" },
                    { "thread_id", threadId },
                    { "client_context", token },
                    { "item_id", itemId },
                    { "emoji", emoji },
                };
                var json          = JsonConvert.SerializeObject(data);
                var bytes         = Encoding.UTF8.GetBytes(json);
                var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    Payload   = ZlibHelper.Compress(bytes).AsBuffer(),
                    PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                    TopicName = "132"
                };
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                return(Result.Success(true));
            }
            catch (SocketException socketException)
            {
                return(Result.Fail(socketException, default(bool), ResponseType.NetworkProblem));
            }
            catch (Exception exception)
            {
                return(Result.Fail <bool>(exception));
            }
        }
Beispiel #14
0
        private async Task SendPing()
        {
            try
            {
                if (_outboundWriter == null)
                {
                    return;
                }
                var packet = PingReqPacket.Instance;
                await FbnsPacketEncoder.EncodePacket(packet, _outboundWriter);

                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Pinging realtime server");
            }
            catch (Exception)
            {
                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Failed to ping realtime server. Shutting down.");
                Shutdown();
                await Task.Delay(5000);

                Restart();
            }
        }
Beispiel #15
0
        public async Task StartFresh()
        {
            this.Log("Starting fresh");
            if (!Instagram.InternetAvailable())
            {
                this.Log("Internet not available. Exiting.");
                return;
            }

            if (Running)
            {
                throw new Exception("Push client is already running");
            }
            var connectPacket = new FbnsConnectPacket
            {
                Payload = await PayloadProcessor.BuildPayload(ConnectionData)
            };

            Socket = new StreamSocket();
            Socket.Control.KeepAlive = true;
            Socket.Control.NoDelay   = true;
            if (await RequestBackgroundAccess())
            {
                try
                {
                    Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.Wake);
                }
                catch (Exception connectedStandby)
                {
                    this.Log(connectedStandby);
                    this.Log("Connected standby not available");
                    try
                    {
                        Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.DoNotWake);
                    }
                    catch (Exception e)
                    {
                        DebugLogger.LogException(e);
                        this.Log("Failed to transfer socket completely!");
                        return;
                    }
                }
            }
            else
            {
                // if cannot get background access then there is no point of running push client
                return;
            }

            try
            {
                await Socket.ConnectAsync(new HostName(HOST_NAME), "443", SocketProtectionLevel.Tls12);

                _inboundReader                    = new DataReader(Socket.InputStream);
                _outboundWriter                   = new DataWriter(Socket.OutputStream);
                _inboundReader.ByteOrder          = ByteOrder.BigEndian;
                _inboundReader.InputStreamOptions = InputStreamOptions.Partial;
                _outboundWriter.ByteOrder         = ByteOrder.BigEndian;
                _runningTokenSource               = new CancellationTokenSource();
                await FbnsPacketEncoder.EncodePacket(connectPacket, _outboundWriter);
            }
            catch (Exception e)
            {
                DebugLogger.LogException(e);
                Restart();
                return;
            }
            StartPollingLoop();
        }
Beispiel #16
0
        private async Task OnPacketReceived(Packet msg)
        {
            if (!Running)
            {
                return;
            }
            var writer = _outboundWriter;

            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    this.Log("Received CONNACK");
                    await SubscribeForDM();
                    await RealtimeSub();
                    await PubSub();

                    if (SnapshotAt != null && SeqId <= 0)
                    {
                        await IrisSub();
                    }
                    StartKeepAliveLoop();
                    break;

                case PacketType.PUBLISH:
                    this.Log("Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(RealtimeClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), writer);
                    }


                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = await GetJsonFromThrift(payload);

                    this.Log($"MQTT json: {json}");
                    if (string.IsNullOrEmpty(json))
                    {
                        break;
                    }
                    try
                    {
                        Debug.WriteLine("");
                        Debug.WriteLine($"Unknown topic received:{msg.PacketType} :  {publishPacket.TopicName} : {json}");


                        Debug.WriteLine("");
                        Debug.WriteLine(json);
                        switch (publishPacket.TopicName)
                        {
                        case "150": break;

                        case "133":         //      /ig_send_message_response
                            try
                            {
                                Responses.AddItem(JsonConvert.DeserializeObject <InstaDirectRespondResponse>(json));
                            }
                            catch
                            {
                                try
                                {
                                    var o = JsonConvert.DeserializeObject <InstaDirectRespondV2Response>(json);
                                    Responses.AddItem(new InstaDirectRespondResponse
                                    {
                                        Action     = o.Action,
                                        Message    = o.Message,
                                        Status     = o.Status,
                                        StatusCode = o.StatusCode,
                                        Payload    = o.Payload[0]
                                    });
                                }
                                catch { }
                            }
                            break;

                        case "88":
                        {
                            var obj = JsonConvert.DeserializeObject <InstaRealtimeRespondResponse>(json);
                            if (obj?.Data?.Length > 0)
                            {
                                var typing = new List <InstaRealtimeTypingEventArgs>();
                                var dm     = new List <InstaDirectInboxItem>();
                                for (int i = 0; i < obj.Data.Length; i++)
                                {
                                    var item = obj.Data[i];
                                    if (item != null)
                                    {
                                        if (item.IsTyping)
                                        {
                                            var typingResponse = JsonConvert.DeserializeObject <InstaRealtimeTypingResponse>(item.Value);
                                            if (typingResponse != null)
                                            {
                                                try
                                                {
                                                    var tr = new InstaRealtimeTypingEventArgs
                                                    {
                                                        SenderId       = typingResponse.SenderId,
                                                        ActivityStatus = typingResponse.ActivityStatus,
                                                        RealtimeOp     = item.Op,
                                                        RealtimePath   = item.Path,
                                                        TimestampUnix  = typingResponse.Timestamp,
                                                        Timestamp      = DateTimeHelper.FromUnixTimeMiliSeconds(typingResponse.Timestamp),
                                                        Ttl            = typingResponse.Ttl
                                                    };
                                                    typing.Add(tr);
                                                }
                                                catch { }
                                            }
                                        }
                                        else if (item.IsThreadItem || item.IsThreadParticipants)
                                        {
                                            if (item.HasItemInValue)
                                            {
                                                var directItemResponse = JsonConvert.DeserializeObject <InstaDirectInboxItemResponse>(item.Value);
                                                if (directItemResponse != null)
                                                {
                                                    try
                                                    {
                                                        var dI = ConvertersFabric.Instance.GetDirectThreadItemConverter(directItemResponse).Convert();
                                                        dI.RealtimeOp   = item.Op;
                                                        dI.RealtimePath = item.Path;
                                                        dm.Add(dI);
                                                    }
                                                    catch { }
                                                }
                                            }
                                            else
                                            {
                                                var dI = new InstaDirectInboxItem
                                                {
                                                    RealtimeOp   = item.Op,
                                                    RealtimePath = item.Path,
                                                    ItemId       = item.Value
                                                };
                                                dm.Add(dI);
                                            }
                                        }
                                    }
                                }
                                if (typing.Count > 0)
                                {
                                    OnTypingChanged(typing);
                                }
                                if (dm.Count > 0)
                                {
                                    OnDirectItemChanged(dm);
                                }
                            }
                        }
                        break;
                        }
                    }
                    catch { }
                    break;

                case PacketType.PUBACK:
                    this.Log("Received PUBACK");
                    break;

                case PacketType.PINGRESP:
                    this.Log("Received PINGRESP");
                    break;

                default:
                    Debug.WriteLine($"Unknown topic received:{msg.PacketType}");
                    break;
                }
            }
            catch (Exception e)
            {
                DebugLogger.LogExceptionX(e);
            }
        }
Beispiel #17
0
        private async Task OnPacketReceived(Packet msg)
        {
            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received CONNACK");
                    ConnectionData.UpdateAuth(((FbnsConnAckPacket)msg).Authentication);
                    await RegisterMqttClient();

                    break;

                case PacketType.PUBLISH:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(PushClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), _outboundWriter);
                    }

                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = Encoding.UTF8.GetString(payload);
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + $"MQTT json: {json}");
                    switch (Enum.Parse(typeof(TopicIds), publishPacket.TopicName))
                    {
                    case TopicIds.Message:
                        var message = JsonConvert.DeserializeObject <PushReceivedEventArgs>(json);
                        message.Json     = json;
                        message.InstaApi = _instaApi;
                        MessageReceived?.Invoke(this, message);
                        break;

                    case TopicIds.RegResp:
                        await OnRegisterResponse(json);

                        StartKeepAliveLoop();
                        break;

                    default:
                        Log($"[{_instaApi.GetLoggedUser().UserName}] " + $"Unknown topic received: {publishPacket.TopicName}");
                        break;
                    }

                    break;

                case PacketType.PUBACK:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PUBACK");
                    _waitingForPubAck = false;
                    break;

                // todo: PingResp never arrives even though data was received. Decoder problem?
                case PacketType.PINGRESP:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PINGRESP");
                    break;

                default: return;
                    //throw new NotSupportedException($"Packet type {msg.PacketType} is not supported.");
                }
            }
            catch (Exception ex)
            {
                PrintException("SendPing", ex);
                Shutdown();
            }
        }
Beispiel #18
0
        public async Task StartFresh(bool withBG)
        {
            try
            {
                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Starting fresh");
                var connectPacket = new FbnsConnectPacket
                {
                    Payload = await PayloadProcessor.BuildPayload(ConnectionData)
                };

                Socket = new StreamSocket();
                Socket.Control.KeepAlive = true;
                Socket.Control.NoDelay   = true;
                if (await RequestBackgroundAccess() && !withBG)
                {
                    OnlyOnce = false;
                    if (CanRunInBG())
                    {
                        try
                        {
                            Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.Wake);
                        }
                        catch (Exception connectedStandby)
                        {
                            Log(connectedStandby);
                            Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Connected standby not available");
                            try
                            {
                                Socket.EnableTransferOwnership(_socketActivityTask.TaskId, SocketActivityConnectedStandbyAction.DoNotWake);
                            }
                            catch (Exception e)
                            {
                                Log(e);
                                Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Failed to transfer socket completely!");
                                if (RetryConnection > 3)
                                {
                                    Shutdown();
                                    await StartFresh(true);

                                    RetryConnection++;
                                    return;
                                }
                                return;
                            }
                        }
                    }
                }
                _runningTokenSource = new CancellationTokenSource();
                await Socket.ConnectAsync(new HostName(HOST_NAME), "443", SocketProtectionLevel.Tls12);

                _inboundReader                    = new DataReader(Socket.InputStream);
                _outboundWriter                   = new DataWriter(Socket.OutputStream);
                _inboundReader.ByteOrder          = ByteOrder.BigEndian;
                _inboundReader.InputStreamOptions = InputStreamOptions.Partial;
                _outboundWriter.ByteOrder         = ByteOrder.BigEndian;
                await Task.Delay(2500);

                await FbnsPacketEncoder.EncodePacket(connectPacket, _outboundWriter);

                await Task.Delay(2500);

                StartPollingLoop();
            }
            catch (Exception ex)
            {
                PrintException("StartFresh", ex);
                Shutdown();
                if (!OnlyOnce)
                {
                    OnlyOnce = true;
                    await StartFresh(true);
                }
            }
        }
Beispiel #19
0
        private async Task OnPacketReceived(Packet msg)
        {
            if (!Running)
            {
                return;
            }
            var writer = _outboundWriter;

            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    this.Log("Received CONNACK");
                    ConnectionData.UpdateAuth(((FbnsConnAckPacket)msg).Authentication);
                    await RegisterMqttClient();

                    break;

                case PacketType.PUBLISH:
                    this.Log("Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(PushClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), writer);
                    }

                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = Encoding.UTF8.GetString(payload);
                    this.Log($"MQTT json: {json}");
                    switch (Enum.Parse(typeof(TopicIds), publishPacket.TopicName))
                    {
                    case TopicIds.Message:
                        try
                        {
                            var message = JsonConvert.DeserializeObject <PushReceivedEventArgs>(json);
                            message.Json = json;
                            if (message.NotificationContent.CollapseKey == "direct_v2_message")
                            {
                                MessageReceived?.Invoke(this, message);
                            }
                        }
                        catch (Exception e)
                        {
                            // If something wrong happens here we don't need to shut down the whole push client
                            DebugLogger.LogException(e);
                        }
                        break;

                    case TopicIds.RegResp:
                        await OnRegisterResponse(json);

                        StartKeepAliveLoop();
                        break;

                    default:
                        this.Log($"Unknown topic received: {publishPacket.TopicName}");
                        break;
                    }

                    break;

                case PacketType.PUBACK:
                    this.Log("Received PUBACK");
                    _waitingForPubAck = false;
                    break;

                case PacketType.PINGRESP:
                    this.Log("Received PINGRESP");
                    break;

                default:
                    throw new NotSupportedException($"Packet type {msg.PacketType} is not supported.");
                }
            }
            catch (Exception e)
            {
                DebugLogger.LogException(e);
            }
        }