Exemple #1
0
        /*
         * Helper that handles the HTTP request with the specified verb and URL.
         */
        async Task <IActionResult> HandleRequest(string verb, string url)
        {
            // Creating and decorating our request object.
            var request = new MagicRequest
            {
                URL     = WebUtility.UrlDecode(url),
                Verb    = verb,
                Query   = Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString()),
                Headers = Request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString()),
                Cookies = Request.Cookies.ToDictionary(x => x.Key, x => x.Value.ToString()),
                Host    = Request.Host.Value,
                Scheme  = Request.Scheme
            };

            // Notice, we only attach payload arguments to PUT, POST and PATCH requests.
            switch (verb)
            {
            case "put":
            case "post":
            case "patch":
                request.Payload = await GetPayload();

                break;

            case "get":
            case "delete":
                break;     // Request is accepted, even though we don't care about its payload.

            default:
                throw new HyperlambdaException($"Sorry, I don't know how to handle the {verb} HTTP verb");
            }

            // Executing request and transforming to an IActionResult accordingly.
            return(HandleResponse(await _executor.ExecuteAsync(request)));
        }
Exemple #2
0
    IEnumerator ThrowRequests()
    {
        yield return(new WaitForSeconds(startDelay - maxRequestInterval));

        while (requests.Count > 0 && !GameManager.gameIsOver)
        {
            yield return(new WaitForSeconds(Mathf.Lerp(minRequestInterval, maxRequestInterval, Progress)));

            //Throw a new request
            MagicRequest currentRequest = ExecuteNewRequest();

            //Tell the gamemanager which request has been thrown
            RequestsManager.Instance.AddNewRequest(currentRequest);

            if (requests.Count == 0)
            {
                //Tell the game manager that we finished asking for stuff
                RequestsManager.Instance.requestsAreOver = true;
            }

            //Wait for the anim to finish before doing anything else
            while (animIsPlaying)
            {
                yield return(null);
            }
        }
    }
Exemple #3
0
    public MagicRequest ExecuteNewRequest()
    {
        int          rand    = Random.Range(0, requests.Count);
        MagicRequest request = requests[rand];

        requests.RemoveAt(rand);


        if (request.direction != MagicRequest.Direction.Both)
        {
            anim.SetBool("Right", request.IsRight);
        }
        anim.SetInteger("SpellType", request.SpellId);
        anim.SetTrigger("Spell");
        animIsPlaying = true;

        return(request);
    }
Exemple #4
0
    private void OnValidate()
    {
        int pixelRequiered = 0;

        for (int i = 0; i < requestCount.Length; i++)
        {
            if (requestCount[i].type == MagicRequest.Type.Around)
            {
                pixelRequiered += MagicRequest.GetPixelValue(requestCount[i].type) * requestCount[i].count * 2;
            }
            else
            {
                pixelRequiered += MagicRequest.GetPixelValue(requestCount[i].type) * requestCount[i].count;
            }
        }

        Debug.Log("Pixel requiered : " + pixelRequiered);
    }
Exemple #5
0
    public void AddNewRequest(MagicRequest magicRequest)
    {
        PixelRequest pixelRequest = new PixelRequest();

        pixelRequest.name = magicRequest.type.ToString();
        pixelRequest.pixelCountRequested = magicRequest.pixelValue;
        pixelRequest.endTime             = Time.time + timePerRequest;

        switch (magicRequest.direction)
        {
        case MagicRequest.Direction.Right:
            rightRequests.Add(pixelRequest);
            onNewRequest.Invoke(pixelRequest);
            break;

        case MagicRequest.Direction.Left:
            leftRequests.Add(pixelRequest);
            onNewRequest.Invoke(pixelRequest);
            break;

        case MagicRequest.Direction.Both:
            //Add a little bit of time if its around
            pixelRequest.endTime = Time.time + timePerRequest * 1.5f;

            leftRequests.Add(pixelRequest);
            PixelRequest pixelRequest2 = new PixelRequest();
            pixelRequest2.name = pixelRequest.name;
            pixelRequest2.pixelCountRequested = pixelRequest.pixelCountRequested;
            pixelRequest2.endTime             = pixelRequest.endTime;
            rightRequests.Add(pixelRequest2);

            onNewRequest.Invoke(pixelRequest);
            onNewRequest.Invoke(pixelRequest2);

            break;
        }
    }
 public object Magic(MagicRequest request)
 {
     return new MagicResponse { InId = request.Id, OutId = request.Id++ };
 }
        /// <inheritdoc/>
        public async Task <MagicResponse> ExecuteAsync(MagicRequest request)
        {
            // Sanity checking invocation
            if (string.IsNullOrEmpty(request.URL))
            {
                return new MagicResponse {
                           Result = 404
                }
            }
            ;

            // Making sure we never resolve to anything outside of "modules/" and "system/" folder.
            if (!request.URL.StartsWith("modules/") && !request.URL.StartsWith("system/"))
            {
                return new MagicResponse {
                           Result = 401
                }
            }
            ;

            // Figuring out file to execute, and doing some basic sanity checking.
            var path = Utilities.GetEndpointFilePath(_rootResolver, request.URL, request.Verb);

            if (!await _fileService.ExistsAsync(path))
            {
                return new MagicResponse {
                           Result = 404
                }
            }
            ;

            // Creating our lambda object by loading Hyperlambda file.
            var lambda = HyperlambdaParser.Parse(await _fileService.LoadAsync(path));

            // Applying interceptors.
            lambda = await ApplyInterceptors(lambda, request.URL);

            // Attaching arguments.
            _argumentsHandler.Attach(lambda, request.Query, request.Payload);

            // Invoking method responsible for actually executing lambda object.
            return(await ExecuteAsync(lambda, request));
        }

        #region [ -- Private helper methods -- ]

        /*
         * Applies interceptors to specified Node/Lambda object.
         */
        async Task <Node> ApplyInterceptors(Node result, string url)
        {
            // Checking to see if interceptors exists recursively upwards in folder hierarchy.
            var splits = url.Split(new char [] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            // Stripping away last entity (filename) of invocation.
            var folders = splits.Take(splits.Length - 1);

            // Iterating as long as we have more entities in list of folders.
            while (true)
            {
                // Checking if "current-folder/interceptor.hl" file exists.
                var current = _rootResolver.AbsolutePath(string.Join("/", folders) + "/interceptor.hl");

                if (_fileService.Exists(current))
                {
                    result = await ApplyInterceptor(result, current);
                }

                // Checking if we're done, and at root folder, at which point we break while loop.
                if (!folders.Any())
                {
                    break; // We're done, no more interceptors!
                }
                // Traversing upwards in hierarchy to be able to nest interceptors upwards in hierarchy.
                folders = folders.Take(folders.Count() - 1);
            }

            // Returning result to caller.
            return(result);
        }

        /*
         * Applies the specified interceptor and returns the transformed Node/Lambda result.
         */
        async Task <Node> ApplyInterceptor(Node lambda, string interceptorFile)
        {
            // Getting interceptor lambda.
            var interceptNode = HyperlambdaParser.Parse(await _fileService.LoadAsync(interceptorFile));

            // Moving [.arguments] from endpoint lambda to the top of interceptor lambda if existing.
            var args = lambda
                       .Children
                       .Where(x =>
                              x.Name == ".arguments" ||
                              x.Name == ".description" ||
                              x.Name == ".type" ||
                              x.Name == "auth.ticket.verify" ||
                              x.Name.StartsWith("validators."));

            // Notice, reversing arguments nodes makes sure we apply arguments in order of appearance.
            foreach (var idx in args.Reverse().ToList())
            {
                interceptNode.Insert(0, idx); // Notice, will detach the argument from its original position!
            }

            // Moving endpoint Lambda to position before any [.interceptor] node found in interceptor lambda.
            foreach (var idxLambda in new Expression("**/.interceptor").Evaluate(interceptNode).ToList())
            {
                // Iterating through each node in current result and injecting before currently iterated [.lambda] node.
                foreach (var idx in lambda.Children)
                {
                    // This logic ensures we keep existing order without any fuzz.
                    // By cloning node we also support having multiple [.interceptor] nodes.
                    idxLambda.InsertBefore(idx.Clone());
                }

                // Removing currently iterated [.interceptor] node in interceptor lambda object.
                idxLambda.Parent.Remove(idxLambda);
            }

            // Returning interceptor Node/Lambda which is now the root of the execution Lambda object.
            return(interceptNode);
        }

        /*
         * Method responsible for actually executing lambda object after file has been loaded,
         * interceptors and arguments have been applied, and transforming result of invocation
         * to a MagicResponse.
         */
        async Task <MagicResponse> ExecuteAsync(Node lambda, MagicRequest request)
        {
            // Creating our result wrapper, wrapping whatever the endpoint wants to return to the client.
            var result   = new Node();
            var response = new MagicResponse();

            try
            {
                await _signaler.ScopeAsync("http.request", request, async() =>
                {
                    await _signaler.ScopeAsync("http.response", response, async() =>
                    {
                        await _signaler.ScopeAsync("slots.result", result, async() =>
                        {
                            await _signaler.SignalAsync("eval", lambda);
                        });
                    });
                });

                response.Content = GetReturnValue(response, result);
                return(response);
            }
            catch
            {
                if (result.Value is IDisposable disposable)
                {
                    disposable.Dispose();
                }
                if (response.Content is IDisposable disposable2 && !object.ReferenceEquals(response.Content, result.Value))
                {
                    disposable2.Dispose();
                }
                throw;
            }
        }

        /*
         * Creates a returned payload of some sort and returning to caller.
         */
        object GetReturnValue(MagicResponse httpResponse, Node lambda)
        {
            /*
             * An endpoint can return either a Node/Lambda hierarchy or a simple value.
             * First we check if endpoint returned a simple value, at which point we convert it to
             * a string. Notice, we're prioritising simple values, implying if return node has a
             * simple value, none of its children nodes will be returned.
             */
            if (lambda.Value != null)
            {
                // IDisposables (Streams e.g.) are automatically disposed by ASP.NET Core.
                if (lambda.Value is IDisposable || lambda.Value is byte[])
                {
                    return(lambda.Value);
                }

                return(lambda.Get <string>());
            }
            else if (lambda.Children.Any())
            {
                // Checking if we should return content as Hyperlambda.
                if (httpResponse.Headers.TryGetValue("Content-Type", out var val) && val == "application/x-hyperlambda")
                {
                    return(HyperlambdaGenerator.GetHyperlambda(lambda.Children));
                }

                // Defaulting to returning content as JSON by converting from Lambda to JSON.
                var convert = new Node();
                convert.AddRange(lambda.Children.ToList());
                _signaler.Signal(".lambda2json-raw", convert);
                return(convert.Value);
            }
            return(null); // No content
        }

        #endregion
    }
}