コード例 #1
0
ファイル: TwitterCommand.cs プロジェクト: phawxby/Twitterizer
        /// <summary>
        /// Parses the rate limit headers.
        /// </summary>
        /// <param name="responseHeaders">The headers of the web response.</param>
        /// <returns>An object that contains the rate-limiting info contained in the response headers</returns>
        private static RateLimiting ParseRateLimitHeaders(WebHeaderCollection responseHeaders)
        {
            RateLimiting rateLimiting = new RateLimiting();

            if (responseHeaders.AllKeys.Contains("X-RateLimit-Limit"))
            {
                rateLimiting.Total = int.Parse(responseHeaders["X-RateLimit-Limit"], CultureInfo.InvariantCulture);
            }

            if (responseHeaders.AllKeys.Contains("X-RateLimit-Remaining"))
            {
                rateLimiting.Remaining = int.Parse(responseHeaders["X-RateLimit-Remaining"], CultureInfo.InvariantCulture);
            }

            if (!string.IsNullOrEmpty(responseHeaders["X-RateLimit-Reset"]))
            {
                rateLimiting.ResetDate = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
                                                              .AddSeconds(double.Parse(responseHeaders["X-RateLimit-Reset"], CultureInfo.InvariantCulture)), DateTimeKind.Utc);
            }
            else if (!string.IsNullOrEmpty(responseHeaders["Retry-After"]))
            {
                rateLimiting.ResetDate = DateTime.UtcNow.AddSeconds(Convert.ToInt32(responseHeaders["Retry-After"]));
            }

            return(rateLimiting);
        }
コード例 #2
0
        internal static CommandResult ShowRateLimitDetails()
        {
            if (!IsInitiated)
            {
                return(CommandResult.NotInitiated);
            }

            var v = new VerifyCredentialsOptions();

            v.UseSSL = true;

            var Response = TwitterAccount.VerifyCredentials(Tokens, v);

            if (Response.Result == RequestResult.Success)
            {
                TwitterUser  acc    = Response.ResponseObject;
                RateLimiting status = Response.RateLimiting;

                Form.AppendLineToOutput("Screenname     : " + acc.ScreenName);
                Form.AppendLineToOutput("Hourly limit   : " + status.Total);
                Form.AppendLineToOutput("Remaining hits : " + status.Remaining);
                Form.AppendLineToOutput("Reset time     : " + status.ResetDate.ToLocalTime() + " (" + DateTime.Now.ToUniversalTime().Subtract(status.ResetDate).Duration().TotalMinutes + " mins left)");

                return(CommandResult.Success);
            }
            else
            {
                HandleTwitterizerError <TwitterUser>(Response);
                return(CommandResult.Failure);
            }
        }
コード例 #3
0
 private void StartDialogDebounced(object sender, EventArgs args)
 {
     RateLimiting.Debounce(nameof(StartDialogDebounced), 1000, () => {
         var tile = Game1.currentLocation?.currentEvent?.getActorByName("Lewis")?.getTileLocation();
         if (tile != null)
         {
             Vector2 mousePosition = tile.Value.ConvertTileToMouseCoords();
             var mouseState        = new MouseState(Convert.ToInt32(mousePosition.X), Convert.ToInt32(mousePosition.Y), 0, ButtonState.Released, ButtonState.Released, ButtonState.Pressed, ButtonState.Released, ButtonState.Released);
             Game1.setMousePosition(new Point(Convert.ToInt32(mousePosition.X), Convert.ToInt32(mousePosition.Y)));
             Game1.pressActionButton(new KeyboardState(), mouseState, new GamePadState());
             ViewportChanged -= StartDialogDebounced;
         }
     });
 }
コード例 #4
0
        /// <summary>
        /// Parses the rate limit headers.
        /// </summary>
        /// <param name="responseHeaders">The headers of the web response.</param>
        /// <returns>An object that contains the rate-limiting info contained in the response headers</returns>
        private static RateLimiting ParseRateLimitHeaders(HttpResponseHeaders responseHeaders)
        {
            RateLimiting rateLimiting = new RateLimiting();

            if (responseHeaders.Contains("X-RateLimit-Limit"))
            {
                rateLimiting.Total = int.Parse(responseHeaders.GetValues("X-RateLimit-Limit").First(), CultureInfo.InvariantCulture);
            }

            if (responseHeaders.Contains("X-RateLimit-Remaining"))
            {
                rateLimiting.Remaining = int.Parse(responseHeaders.GetValues("X-RateLimit-Remaining").First(), CultureInfo.InvariantCulture);
            }

            if (responseHeaders.Contains("X-RateLimit-Reset"))
            {
                rateLimiting.ResetDate = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
                                                              .AddSeconds(double.Parse(responseHeaders.GetValues("X-RateLimit-Reset").First(), CultureInfo.InvariantCulture)), DateTimeKind.Utc);
            }
            return(rateLimiting);
        }
コード例 #5
0
ファイル: TwitterCommand.cs プロジェクト: phawxby/Twitterizer
        /// <summary>
        /// Sets the status code.
        /// </summary>
        /// <param name="twitterResponse">The twitter response.</param>
        /// <param name="statusCode">The status code.</param>
        /// <param name="rateLimiting">The rate limiting.</param>
        private static void SetStatusCode(TwitterResponse <T> twitterResponse, HttpStatusCode statusCode, RateLimiting rateLimiting)
        {
            switch (statusCode)
            {
            case HttpStatusCode.OK:
                twitterResponse.Result = RequestResult.Success;
                break;

            case HttpStatusCode.BadRequest:
                twitterResponse.Result = (rateLimiting != null && rateLimiting.Remaining == 0) ? RequestResult.RateLimited : RequestResult.BadRequest;
                break;

            case (HttpStatusCode)420:     //Rate Limited from Search/Trends API
                twitterResponse.Result = RequestResult.RateLimited;
                break;

            case HttpStatusCode.Unauthorized:
                twitterResponse.Result = RequestResult.Unauthorized;
                break;

            case HttpStatusCode.NotFound:
                twitterResponse.Result = RequestResult.FileNotFound;
                break;

            case HttpStatusCode.ProxyAuthenticationRequired:
                twitterResponse.Result = RequestResult.ProxyAuthenticationRequired;
                break;

            case HttpStatusCode.RequestTimeout:
                twitterResponse.Result = RequestResult.TwitterIsOverloaded;
                break;

            case HttpStatusCode.Forbidden:
                twitterResponse.Result = RequestResult.Unauthorized;
                break;

            default:
                twitterResponse.Result = RequestResult.Unknown;
                break;
            }
        }
コード例 #6
0
        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <returns>The results of the command.</returns>
        public async Task <TwitterResponse <T> > ExecuteCommand()
        {
            TwitterResponse <T> twitterResponse = new TwitterResponse <T>();

            if (this.OptionalProperties.UseSSL)
            {
                this.Uri = new Uri(this.Uri.AbsoluteUri.Replace("http://", "https://"));
            }

            // Loop through all of the custom attributes assigned to the command class
            foreach (CustomAttributeData attribute in System.Reflection.IntrospectionExtensions.GetTypeInfo(this.GetType()).CustomAttributes)
            {
                if (attribute.AttributeType == typeof(AuthorizedCommandAttribute))
                {
                    if (this.Tokens == null)
                    {
                        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Tokens are required for the \"{0}\" command.", this.GetType()));
                    }

                    if (string.IsNullOrEmpty(this.Tokens.ConsumerKey) ||
                        string.IsNullOrEmpty(this.Tokens.ConsumerSecret) ||
                        string.IsNullOrEmpty(this.Tokens.AccessToken) ||
                        string.IsNullOrEmpty(this.Tokens.AccessTokenSecret))
                    {
                        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Token values cannot be null when executing the \"{0}\" command.", this.GetType()));
                    }
                }
                else if (attribute.AttributeType == typeof(RateLimitedAttribute))
                {
                    //Get the rate limiting status
                    if ((await Account.RateLimitStatusAsync(this.Tokens)).ResponseObject.RemainingHits == 0)
                    {
                        throw new TwitterizerException("You are being rate limited.");
                    }
                }
            }

            // Prepare the query parameters
            Dictionary <string, object> queryParameters = new Dictionary <string, object>();

            foreach (KeyValuePair <string, object> item in this.RequestParameters)
            {
                queryParameters.Add(item.Key, item.Value);
            }

            // Declare the variable to be returned
            twitterResponse.ResponseObject = default(T);
            twitterResponse.RequestUrl     = this.Uri.AbsoluteUri;
            RateLimiting        rateLimiting = null;
            AccessLevel         accessLevel;
            string              responseData = null;
            HttpResponseMessage response     = null;

            try
            {
                WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens)
                {
                    Multipart = this.Multipart
                };

                foreach (var item in queryParameters)
                {
                    requestBuilder.Parameters.Add(item.Key, item.Value);
                }

                try
                {
                    response = await requestBuilder.ExecuteRequestAsync();
                }
                catch
                {
                    ;
                }

                if (response == null)
                {
                    twitterResponse.Result = RequestResult.Unknown;
                    return(twitterResponse);
                }

                responseData = await response.Content.ReadAsStringAsync(); // ConversionUtility.ReadStream(await response.Content.ReadAsStreamAsync());

                twitterResponse.Content = responseData;                    // Encoding.UTF8.GetString(responseData, 0, responseData.Length);

                twitterResponse.RequestUrl = requestBuilder.RequestUri.AbsoluteUri;

                // Parse the rate limiting HTTP Headers
                rateLimiting = ParseRateLimitHeaders(response.Headers);

                // Parse Access Level
                accessLevel = ParseAccessLevel(response.Headers);

                // Lookup the status code and set the status accordingly
                SetStatusCode(twitterResponse, response.StatusCode, rateLimiting);

                twitterResponse.RateLimiting = rateLimiting;
                twitterResponse.AccessLevel  = accessLevel;

                response.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException wex)
            {
                // Lookup the status code and set the status accordingly
                SetStatusCode(twitterResponse, response.StatusCode, rateLimiting);

                twitterResponse.ErrorMessage = wex.Message;

                // Try to read the error message, if there is one.
                try
                {
                    TwitterErrorDetails errorDetails = SerializationHelper <TwitterErrorDetails> .Deserialize(responseData);

                    twitterResponse.ErrorMessage = errorDetails.ErrorMessage;
                }
                catch (Exception)
                {
                    // Occasionally, Twitter responds with XML error data even though we asked for json.
                    // This is that scenario. We will deal with it by doing nothing. It's up to the developer to deal with it.
                }

                return(twitterResponse);
            }

            try
            {
                twitterResponse.ResponseObject = SerializationHelper <T> .Deserialize(responseData, this.DeserializationHandler);
            }
            catch (Newtonsoft.Json.JsonReaderException)
            {
                twitterResponse.ErrorMessage = "Unable to parse JSON";
                twitterResponse.Result       = RequestResult.Unknown;
                return(twitterResponse);
            }
            catch (Newtonsoft.Json.JsonSerializationException jse)
            {
                twitterResponse.ErrorMessage = String.Format("Unable to parse JSON: {0}", jse.Message);
                twitterResponse.Result       = RequestResult.Unknown;
                return(twitterResponse);
            }

            // Pass the current oauth tokens into the new object, so method calls from there will keep the authentication.
            twitterResponse.Tokens = this.Tokens;

            return(twitterResponse);
        }
コード例 #7
0
        //todo: factor out this logic from main and add wentToFestival to mod state
        //TODO: add trace log
        public void AFKHostingRoutine()
        {
            //TODO: need to cancel waiting for player dialog if other players have quit
            //should be able to ignore events and cutscenes since that should be handled by Context.PlayerCanMove
            //TODO: cancel cutscenens when they occur
            //TODO: move player outside house in morning to trigger any cutscenes that might occur

            //TODO: pause game if no players are online
#if DEBUG
            if (!(IsThisPlayerFree && Context.IsMultiplayer))
            {
                return;
            }
#else
            if (!(IsThisPlayerFree && RemotePlayersAreOnline && Context.IsMultiplayer))
            {
                return;
            }
#endif
            //teleport player to festival when its ready if they have not been yet
            if (IsFestivalDay && IsFestivalReady && !IsThisPlayerAtFestival && !State.WentToTodaysFestival)
            {
                var festivalLocation = WhereIsFestival();
                if (festivalLocation != Location.None)
                {
                    void DebouncedTeleportToNPC(object sender, EventArgs args)
                    {
                        RateLimiting.Debounce(nameof(DebouncedTeleportToNPC), 1000, () =>
                        {
                            ViewportChanged -= DebouncedTeleportToNPC;
                            var testDialog   = new NPCDialogAutomater("Lewis", true, Monitor, Helper,
                                                                      new DialogAction[] {
                                new DialogAction {
                                    DialogActionType = DialogActionType.Start
                                },
                                new DialogAction {
                                    DialogActionType = DialogActionType.Next
                                },
                                new DialogAction {
                                    DialogActionType = DialogActionType.Next
                                },
                                new DialogAction {
                                    DialogActionType = DialogActionType.Start
                                },
                                new DialogAction {
                                    DialogActionType = DialogActionType.Answer,
                                    AnswerIndex      = 0
                                }
                            });

                            ViewportChanged += DebouncedRunActions;
                            testDialog.TeleportToNPC();

                            void DebouncedRunActions(object s, EventArgs e)
                            {
                                RateLimiting.Debounce(nameof(DebouncedRunActions), 1000, () =>
                                {
                                    ViewportChanged -= DebouncedRunActions;
                                    testDialog.RunActions();
                                });
                            }
                        });
                    }

                    ViewportChanged += DebouncedTeleportToNPC;
                    TeleportThisPlayer(festivalLocation, 0, 0);
                    return;
                }
            }

            //should not have to handle where player is waiting for other players to enter festival
            //as that should be taken care of by StardewAPI.IsThisPlayerFree
            if (IsFestivalDay && IsThisPlayerAtFestival && !State.WentToTodaysFestival)
            {
                //var tile = Game1.currentLocation?.currentEvent?.getActorByName("Lewis")?.getTileLocation();
                //if (!tile.HasValue) return;
                //Game1.player.setTileLocation(new Vector2(tile.Value.X, tile.Value.Y+1));

                State.With(s => s.WentToTodaysFestival, true);
                //Game1.player.team.SetLocalReady("festivalEnd", true);
                //Game1.activeClickableMenu = (IClickableMenu)new ReadyCheckDialog("festivalEnd", true, new ConfirmationDialog.behavior(Game1.currentLocation.currentEvent.forceEndFestival), (ConfirmationDialog.behavior)null);
            }

            //this should run once to trigger the festival leave waiting screen which should teleport to farm
            //(or just start here if there is no festival) then it will run again to move player to bed if they are not in it
            //and one more time to trigger wait for sleep
            //TODO: test how this is affected by time change when festival ends
            if (!IsFestivalDay || (IsFestivalDay && !IsThisPlayerAtFestival && State.WentToTodaysFestival))
            {
                //TODO: this doesnt work when at a festival, tries to tele repeatedly but nothing happens
                //test if this waits until the teleport is finished
                if (!IsThisPlayerInBed)
                {
                    TeleportThisPlayerToBed();
                }
                else
                {
                    StartSleepForThisPlayer(Helper);
                }
            }

            //reset festival status on next day
            //TODO: will this work for night market?
            if (!IsFestivalDay && State.WentToTodaysFestival)
            {
                State.With(s => s.WentToTodaysFestival, false);
            }

            //if (Game1.activeClickableMenu is DialogueBox dialogueBox)
            //{
            //    var isQuestion = Helper.Reflection.GetField<bool>(dialogueBox, "isQuestion").GetValue();
            //    if(isQuestion)
            //    {
            //        //TODO: auto answer questions based on a json event/dialog/person configuration file
            //        return;
            //    }
            //    CloseDialogOrMenu();
            //}
        }
コード例 #8
0
 public RateLimitingMiddleware(RequestDelegate next, IMemoryCache cache, IOptions <RateLimiting> options)
 {
     _next   = next;
     _cache  = cache;
     _config = options.Value;
 }