Example #1
0
    public override void Exicute(TheScript managerScript)
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            managerScript.SetState(connections[0]);
        }

        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            managerScript.SetState(connections[1]);
        }

        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            managerScript.SetState(connections[2]);
        }
    }
Example #2
0
        //Helper to update storage list
        private void UpdateStorageList(string name, string status, int step, TheScript script, TheThing context, bool replay)
        {
            ScriptSnapshot existingSnapshot = null;

            // No longer adding a new entry on replay because the list is now used to disable script/steps etc.
            existingSnapshot = MyScriptTableStorage.MyMirrorCache.GetEntryByFunc(snapshot => snapshot.ScriptName == name && snapshot.ScriptStep == step);
            var stepName = step > 0 && step <= script?.Steps.Length ? script?.Steps[step - 1]?.GetName() ?? "" : "";

            if (existingSnapshot == null)
            {
                var newSnapshot = new ScriptSnapshot
                {
                    ScriptName    = name,
                    ScriptStatus  = status,
                    StepName      = stepName,
                    ScriptStep    = step,
                    ContextScript = script,
                    FileName      = script?.FileName,
                    ScriptRaw     = script?.ScriptRaw,
                    Context       = context,
                    LastUpdate    = DateTimeOffset.Now,
                };
                MyScriptTableStorage.AddAnItem(newSnapshot);
            }
            else
            {
                existingSnapshot.ScriptName    = name;
                existingSnapshot.ScriptStatus  = status;
                existingSnapshot.StepName      = stepName;
                existingSnapshot.ScriptStep    = step;
                existingSnapshot.ContextScript = script;
                existingSnapshot.FileName      = script?.FileName;
                existingSnapshot.ScriptRaw     = script?.ScriptRaw;
                existingSnapshot.Context       = context;
                existingSnapshot.LastUpdate    = DateTimeOffset.Now;
                MyScriptTableStorage.UpdateItem(existingSnapshot);
            }
        }
Example #3
0
    // Update is called once per frame
    void Update()
    {
        if (theScript == goodEnding ||
            theScript == badEnding ||
            theScript == sadEnding ||
            theScript == creepyEnding)
        {
            if (currentLine > 2 && finishedTyping && Input.GetKeyDown(KeyCode.Return))
            {
                TransitionHandler.me.go = true;
            }
        }

        if (currentLine == theScript.script.Count && !done)
        {
            overrideline     = "";
            finishedTyping   = false;
            done             = true;
            currentLine      = 0;
            currentCharacter = 0;

            float good   = 0;
            float sad    = 0;
            float creepy = 0;
            for (int i = 0; i < stats.Count; i++)
            {
                if (stats[i].name == "Good")
                {
                    good += stats[i].value;
                }
                if (stats[i].name == "Sad")
                {
                    sad += stats[i].value;
                }
                if (stats[i].name == "Creepy")
                {
                    creepy += stats[i].value;
                }
            }
            if (good > sad + creepy)
            {
                theScript = goodEnding;
            }
            else if (sad > good + creepy)
            {
                theScript = sadEnding;
            }
            else if (creepy > good + sad)
            {
                theScript = creepyEnding;
            }
            else if (good <= 0)
            {
                theScript = badEnding;
            }
            else
            {
                theScript = badEnding;
            }
        }

        // Type character by character until you're done
        if (!finishedTyping)
        {
            if (currentCharacter % meowFrequency == 0)
            {
                MeowBox.me.Meow();
            }
            currentCharacter++;

            if (overrideline == "")
            {
                dialogText.text = theScript.script[currentLine].line.Substring(0, currentCharacter);

                if (dialogText.text.Equals(theScript.script[currentLine].line))
                {
                    finishedTyping = true;
                }
            }
            else
            {
                dialogText.text = overrideline.Substring(0, currentCharacter);
                if (dialogText.text.Equals(overrideline))
                {
                    finishedTyping = true;
                }
            }
        }
        else
        {
            if (overrideline == "")
            {
                dialogText.text = theScript.script[currentLine].line;
                if (theScript.script[currentLine].isQuestion && answerBox.GetBool("Visible") == false)
                {
                    selection = 0;
                    answerBox.SetBool("Visible", true);
                }
            }
            else
            {
                dialogText.text = overrideline;
            }
        }

        // Show the answer box if the line is a question
        if (theScript.script[currentLine].isQuestion)
        {
            string answers = "";
            for (int i = 0; i < theScript.script[currentLine].answers.Length; i++)
            {
                answers += "<color=#";
                answers += i == selection ? selectedColor : unselectedColor;
                answers += ">•" + theScript.script[currentLine].answers[i].text + "</color>\r\n";
            }
            answerText.text = answers;
        }

        // Key inputs
        // Next line on enter press
        if (Input.GetKeyDown(KeyCode.Return))
        {
            if (currentLine < theScript.script.Count)
            {
                Next();
            }
        }
        // Up and down
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            selection++;
        }
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            selection--;
        }

        if (selection < 0)
        {
            selection = theScript.script[currentLine].answers.Length - 1;
        }
        if (selection >= theScript.script[currentLine].answers.Length)
        {
            selection = 0;
        }
    }
Example #4
0
 public virtual void Exicute(TheScript manageScript)
 {
 }
Example #5
0
        private async Task RunScriptAsync(TheScript script, TheThing variables, int stepNumber = 1, bool replay = false)
        {
            TheThing variablesSnapshot;

            try
            {
                for (; stepNumber <= script.Steps.Length; stepNumber++)
                {
                    //Clone thing before step occurs
                    variablesSnapshot = new TheThing();
                    variables.CloneThingAndPropertyMetaData(variablesSnapshot, true);

                    var step = script.Steps[stepNumber - 1];

                    var existingSnapshot = MyScriptTableStorage.MyMirrorCache.GetEntryByFunc(snapshot => snapshot.ScriptName == script.Name && snapshot.ScriptStep == stepNumber);
                    if (existingSnapshot?.Disabled == true)
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step because it was disabled", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                            { "Script", script.Name },
                            { "Step", stepNumber },
                            { "Message", step.Message.MessageName },
                            { "Target", step.Message.Target },
                        })));

                        UpdateStorageList(script.Name, "Disabled", stepNumber, script, variablesSnapshot, replay);
                        continue;
                    }

                    if (step.Condition != null)
                    {
                        var condition = TheCommonUtils.GenerateFinalStr(step.Condition, variables);
                        if (
                            (condition == "" || condition.ToLowerInvariant() == "false" || condition.Trim() == "0") ||
                            (condition.StartsWith("!") && condition.Length >= 1 && (condition.Substring(1).ToLowerInvariant() == "true") || condition.Substring(1).Trim() == "1"))
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step due to condition not met", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                { "Script", script.Name },
                                { "Step", stepNumber },
                                { "Message", step.Message.MessageName },
                                { "Target", step.Message.Target },
                                { "Condition", step.Condition },
                                { "ConditionEvaluated", condition },
                            })));

                            UpdateStorageList(script.Name, "Condition Not Met", stepNumber, script, variablesSnapshot, replay);

                            continue;
                        }
                    }
                    var messageType = TheCommonUtils.GenerateFinalStr(step.Message.MessageName, variables);
                    var txtPayload  = TheCommonUtils.GenerateFinalStr(step.Message.Parameters?.ToString(), variables);
                    {
                        var txtPayload2 = txtPayload?.Replace("\"\\\"", "");
                        var txtPayload3 = txtPayload2?.Replace("\\\"\"", "");
                        txtPayload = txtPayload3;
                    }

                    // TODO Need a simpler and more flexible way to specify thing address in the script JSON
                    var target = step.Message.Target;
                    if (target == null)
                    {
                        if (txtPayload.Contains("EngineName"))
                        {
                            var    payloadDict        = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(txtPayload);
                            object engineNameInferred = null;
                            if (payloadDict?.TryGetValue("EngineName", out engineNameInferred) == true && !string.IsNullOrEmpty(engineNameInferred?.ToString()))
                            {
                                target = new TheMessageAddress {
                                    EngineName = engineNameInferred.ToString()
                                };
                            }
                        }
                    }
                    if (target.EngineName.StartsWith("%") || target.EngineName.StartsWith("{"))
                    {
                        target.EngineName = TheCommonUtils.GenerateFinalStr(target.EngineName, variables);
                        // TODO Clean this up: support a serialized TheMessageAddress in the engine name, so that an output variable can be fed into a method invocation
                        try
                        {
                            var newTarget = TheCommonUtils.DeserializeJSONStringToObject <TheMessageAddress>(target.EngineName);
                            if (newTarget != null)
                            {
                                target = newTarget;
                            }
                        }
                        catch
                        {
                            // parsing error: ignore, will result in other errors downstream
                        }
                    }

                    await TheThingRegistry.WaitForInitializeAsync(target);

                    bool bDoRetry;
                    int  remainingRetryCount = step.RetryCount ?? 0;
                    do
                    {
                        existingSnapshot = MyScriptTableStorage.MyMirrorCache.GetEntryByFunc(snapshot => snapshot.ScriptName == script.Name && snapshot.ScriptStep == stepNumber);
                        if (existingSnapshot?.Disabled == true)
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step because it was disabled", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                { "Script", script.Name },
                                { "Step", stepNumber },
                                { "Message", step.Message.MessageName },
                                { "Target", step.Message.Target },
                            })));

                            UpdateStorageList(script.Name, "Disabled", stepNumber, script, variablesSnapshot, replay);
                            break;
                        }

                        bDoRetry = false;
                        var response = await TheCommRequestResponse.PublishRequestAsync(MyBaseThing, target, messageType, new TimeSpan(0, 0, 0, 0, step.Message.timeout), null, txtPayload, null);

                        if (!string.IsNullOrEmpty(response?.PLS))
                        {
                            var outputs = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(response.PLS);
                            if (outputs != null)
                            {
                                if (step.Message.outputs != null)
                                {
                                    foreach (var output in step.Message.outputs)
                                    {
                                        if (output.Key == "*")
                                        {
                                            variables.SetProperty(output.Value, response.PLS);
                                        }
                                        else if (outputs.TryGetValue(output.Key, out var outputValue))
                                        {
                                            variables.SetProperty(output.Value, outputValue);
                                            if (output.Value.Contains("Error") && !string.IsNullOrEmpty(TheCommonUtils.CStr(outputValue)))
                                            {
                                                TheBaseAssets.MySYSLOG.WriteToLog(175004, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step: output reported error", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                                    { "Script", script.Name },
                                                    { "Step", stepNumber },
                                                    { "Message", messageType },
                                                    { "Target", target },
                                                    { "PLS", txtPayload },
                                                    { "Response", response },
                                                    { "ResponsePLS", response?.PLS },
                                                })));

                                                UpdateStorageList(script.Name, $"Error {outputValue} in output", stepNumber, script, variablesSnapshot, replay);

                                                if (remainingRetryCount < 0 || remainingRetryCount > 0)
                                                {
                                                    remainingRetryCount--;
                                                    bDoRetry = true;
                                                }
                                                string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none";
                                                MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: output '{output.Value}' reported error {outputValue}. Retries remaining: {retriesRemaining}");
                                            }
                                        }
                                        else
                                        {
                                            // TODO provide access to sub-elements in the JSON
                                            //var outputParts = output.Key.Split('/');
                                            //dynamic currentNode = outputs;
                                            //foreach (var outputPart in outputParts)
                                            //{
                                            //    if (currentNode.TryGetValue(outputPart, out var nextNode))
                                            //    {
                                            //        currentNode = nextNode;
                                            //    }
                                            //}
                                        }
                                    }
                                }
                                TheBaseAssets.MySYSLOG.WriteToLog(175003, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                    { "Script", script.Name },
                                    { "Step", stepNumber },
                                    { "Message", messageType },
                                    { "Target", target },
                                    { "PLS", txtPayload },
                                    { "ResponsePLS", response.PLS },
                                })));

                                UpdateStorageList(script.Name, "Finished", stepNumber, script, variablesSnapshot, replay);
                            }
                            else
                            {
                                TheBaseAssets.MySYSLOG.WriteToLog(175004, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step: no outputs found in response", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                    { "Script", script.Name },
                                    { "Step", stepNumber },
                                    { "Message", messageType },
                                    { "Target", target },
                                    { "PLS", txtPayload },
                                    { "Response", response },
                                    { "ResponsePLS", response?.PLS },
                                })));

                                UpdateStorageList(script.Name, "Error: No Output", stepNumber, script, variablesSnapshot, replay);

                                if (step.DontRetryOnEmptyResponse != true && (remainingRetryCount < 0 || remainingRetryCount > 0))
                                {
                                    remainingRetryCount--;
                                    bDoRetry = true;
                                }
                                string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none";
                                MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: no outputs found in response. Retries remaining: {retriesRemaining}");
                            }
                        }
                        else
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(175005, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error Script step: timeout", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                                { "Script", script.Name },
                                { "Step", stepNumber },
                                { "Message", messageType },
                                { "Target", target },
                                { "PLS", txtPayload },
                                { "Response", response },
                            })));

                            UpdateStorageList(script.Name, "Error: Timeout", stepNumber, script, variablesSnapshot, replay);

                            //Retries infinitely unless count is specified
                            if (remainingRetryCount < 0 || remainingRetryCount > 0)
                            {
                                remainingRetryCount--;
                                bDoRetry = true;
                            }
                            string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none";
                            MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: timeout. Retries remaining: {retriesRemaining}");
                        }
                        if (bDoRetry)
                        {
                            await TheCommonUtils.TaskDelayOneEye(30000, 100).ConfigureAwait(false);
                        }
                    } while (bDoRetry && TheBaseAssets.MasterSwitch);
                }
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(175006, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> {
                    { "Script", script.Name },
                    { "Exception", e.Message },
                })));
                MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}': {e.Message}");
                //Save variables instead of snapshot in case of error
                UpdateStorageList(script.Name, $"Error: {e.Message}", stepNumber, script, variables, replay);
            }
        }
Example #6
0
#pragma warning restore CS0649

        private async void RunScriptsAsync(object _)
        {
            try
            {
                MyBaseThing.SetStatus(4, "Running scripts.");
                var variables = new TheThing(); // Using this as a property bag to hold variables that can be shared across the scripts -> Maybe use the script thing itself for this? Keeps an audit trail of the state of the script...

                var scriptDir      = TheCommonUtils.cdeFixupFileName(@"ClientBin\scripts");
                var scriptFiles    = Directory.EnumerateFiles(scriptDir, "*.cdescript").ToList();
                var scriptsRun     = new List <string>();
                var pendingScripts = new List <string>();
                var scriptsToRun   = new List <TheScript>();
                int pendingScriptCount;
                pendingScriptCount = pendingScripts.Count;
                foreach (var scriptFile in scriptFiles)
                {
                    try
                    {
                        TheScript script = LoadScript(scriptFile);
                        scriptsToRun.Add(script);
                    }
                    catch (Exception e)
                    {
                        string scriptName = scriptFile;
                        try
                        {
                            scriptName = Path.GetFileNameWithoutExtension(scriptFile);
                        }
                        catch { }
                        UpdateStorageList(scriptFile, $"Failed to read: {e.Message}", -1, null, null, false);
                        TheBaseAssets.MySYSLOG.WriteToLog(175000, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error reading cde script file", eMsgLevel.l1_Error, e.ToString()));
                    }
                }
                foreach (var dependentScript in scriptsToRun.Where(script => script.DependsOn != null && script.DependsOn.Length > 0).ToList())
                {
                    foreach (var dependencyName in dependentScript.DependsOn)
                    {
                        var dependencyScriptIndex = scriptsToRun.FindIndex(script => script.Name == dependencyName);
                        if (dependencyScriptIndex < 0)
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(175007, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Unable to run script with dependencies", eMsgLevel.l1_Error, $"Dependent: '{dependentScript.Name}'. Dependency not found: '{dependencyName}'"));
                        }
                        else
                        {
                            var dependentScriptIndex = scriptsToRun.IndexOf(dependentScript);
                            if (dependentScriptIndex >= 0 && dependencyScriptIndex > dependentScriptIndex)
                            {
                                scriptsToRun.Insert(dependencyScriptIndex + 1, dependentScript);
                                scriptsToRun.RemoveAt(dependentScriptIndex);
                            }
                        }
                    }
                }

                // This assumes RunScriptsAsync is only called from Init() (= on gate restart)
                foreach (var oldScript in MyScriptTableStorage.TheValues)
                {
                    if (oldScript.ScriptStatus == "Not found")
                    {
                        MyScriptTableStorage.RemoveAnItem(oldScript, null);
                    }
                    else
                    {
                        oldScript.ScriptStatus = "Not found";
                    }
                }

                foreach (var script in scriptsToRun)
                {
                    int stepNumber = 1;
                    foreach (var step in script.Steps ?? new TheScriptStep[0])
                    {
                        UpdateStorageList(script.Name, "Pending", stepNumber, script, null, false);
                        stepNumber++;
                    }
                }

                int index       = 0;
                var scriptTasks = new List <Task>();
                foreach (var script in scriptsToRun)
                {
                    Task task = null;
                    if (script.DependsOn?.Length > 0)
                    {
                        if (index > 1)
                        {
                            task = scriptTasks[index - 1].ContinueWith(t => RunScriptAsync(script, variables));
                        }
                    }
                    if (task == null)
                    {
                        task = RunScriptAsync(script, variables);
                    }
                    scriptTasks.Add(task);
                    scriptsRun.Add(script.Name);
                }
                await TheCommonUtils.TaskWhenAll(scriptTasks);

                if (MyBaseThing.StatusLevel == 4)
                {
                    if (scriptTasks?.Count > 0)
                    {
                        MyBaseThing.SetStatus(1, $"All {scriptTasks?.Count} scripts applied.");
                    }
                    else
                    {
                        MyBaseThing.SetStatus(1, "No scripts found.");
                    }
                    TheBaseAssets.MySYSLOG.WriteToLog(175001, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, "Scripts applied", eMsgLevel.l3_ImportantMessage, $"Number of scripts: {scriptTasks?.Count}"));
                }
            }
            catch (DirectoryNotFoundException)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(175001, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, "Error finding or running script files", eMsgLevel.l3_ImportantMessage, "Script directory not found"));
                MyBaseThing.SetStatus(1, "No script directory found.");
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(175001, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error finding or running script files", eMsgLevel.l1_Error, e.ToString()));
                MyBaseThing.SetStatus(3, $"Error while finding or running cdescript files: {e.Message}");
            }
        }