public static bool ContainsMemoryAccessor(ExpressionBase expression)
        {
            var funcCall = expression as FunctionCallExpression;

            if (funcCall != null)
            {
                var func = AchievementScriptInterpreter.GetGlobalScope().GetFunction(funcCall.FunctionName.Name);
                if (func is MemoryAccessorFunction)
                {
                    return(true);
                }

                foreach (var parameter in funcCall.Parameters)
                {
                    if (ContainsMemoryAccessor(parameter))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            var leftRightExpression = expression as LeftRightExpressionBase;

            if (leftRightExpression != null)
            {
                return(ContainsMemoryAccessor(leftRightExpression.Left) || ContainsMemoryAccessor(leftRightExpression.Right));
            }

            return(false);
        }
        public void TestGetConditionString(string input, string expected)
        {
            ExpressionBase   error;
            InterpreterScope scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.Context = new TriggerBuilderContext();

            var expression = Parse(input);

            ExpressionBase processed;

            Assert.That(expression.ReplaceVariables(scope, out processed), Is.True);

            var result = TriggerBuilderContext.GetConditionString(processed, scope, out error);

            if (error != null)
            {
                Assert.That(((ParseErrorExpression)error).InnermostError.Message, Is.EqualTo(expected));
            }
            else
            {
                Assert.That(error, Is.Null);
                Assert.That(result, Is.EqualTo(expected));
            }
        }
Exemple #3
0
        private List <Requirement> Evaluate(string input, string expectedError = null)
        {
            var requirements = new List <Requirement>();
            var funcDef      = new RepeatedFunction();

            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            Assert.That(expression, Is.InstanceOf <FunctionCallExpression>());
            var funcCall = (FunctionCallExpression)expression;

            ExpressionBase error;
            var            scope   = funcCall.GetParameters(funcDef, AchievementScriptInterpreter.GetGlobalScope(), out error);
            var            context = new TriggerBuilderContext {
                Trigger = requirements
            };

            scope.Context = context;

            ExpressionBase evaluated;

            Assert.That(funcDef.ReplaceVariables(scope, out evaluated), Is.True);

            if (expectedError == null)
            {
                Assert.That(funcDef.BuildTrigger(context, scope, funcCall), Is.Null);
            }
            else
            {
                var parseError = funcDef.BuildTrigger(context, scope, funcCall);
                Assert.That(parseError, Is.Not.Null);
                Assert.That(parseError.Message, Is.EqualTo(expectedError));
            }

            return(requirements);
        }
Exemple #4
0
        public void TestSizes()
        {
            var scope = AchievementScriptInterpreter.GetGlobalScope();
            var sizes = new Dictionary <string, FieldSize>
            {
                { "byte(0x1234)", FieldSize.Byte },
                { "bit0(0x1234)", FieldSize.Bit0 },
                { "bit1(0x1234)", FieldSize.Bit1 },
                { "bit2(0x1234)", FieldSize.Bit2 },
                { "bit3(0x1234)", FieldSize.Bit3 },
                { "bit4(0x1234)", FieldSize.Bit4 },
                { "bit5(0x1234)", FieldSize.Bit5 },
                { "bit6(0x1234)", FieldSize.Bit6 },
                { "bit7(0x1234)", FieldSize.Bit7 },
                { "low4(0x1234)", FieldSize.LowNibble },
                { "high4(0x1234)", FieldSize.HighNibble },
                { "word(0x1234)", FieldSize.Word },
                { "dword(0x1234)", FieldSize.DWord },
                { "bit(0,0x1234)", FieldSize.Bit0 },
                { "bit(1,0x1234)", FieldSize.Bit1 },
                { "bit(2,0x1234)", FieldSize.Bit2 },
                { "bit(3,0x1234)", FieldSize.Bit3 },
                { "bit(4,0x1234)", FieldSize.Bit4 },
                { "bit(5,0x1234)", FieldSize.Bit5 },
                { "bit(6,0x1234)", FieldSize.Bit6 },
                { "bit(7,0x1234)", FieldSize.Bit7 },
            };

            foreach (var kvp in sizes)
            {
                var requirements = Evaluate(kvp.Key);
                Assert.That(requirements.Count, Is.EqualTo(1), kvp.Key);
                Assert.That(requirements[0].Left.Size, Is.EqualTo(kvp.Value), kvp.Key);
            }
        }
        public void TestPopulateEditorOrder()
        {
            var vmGame = new GameViewModelHarness(1234, "Title");

            var interpreter = new AchievementScriptInterpreter();

            AddGeneratedLeaderboard(interpreter, 17, "Leaderboard1");
            AddGeneratedAchievement(interpreter, 65, "Test1");
            AddGeneratedAchievement(interpreter, 68, "A Test2");
            AddGeneratedAchievement(interpreter, 61, "Test3");
            AddGeneratedRichPresence(interpreter);

            // list is sorted by the order they were generated, not by id or title
            // rich presence always appears before achievements, leaderboards always appear after
            vmGame.PopulateEditorList(interpreter);
            Assert.That(vmGame.Editors.Count(), Is.EqualTo(6));
            Assert.That(vmGame.Editors.ElementAt(0).Title, Is.EqualTo("Script"));
            Assert.That(vmGame.Editors.ElementAt(1).Title, Is.EqualTo("Rich Presence"));
            Assert.That(vmGame.Editors.ElementAt(2).Title, Is.EqualTo("Test1"));
            Assert.That(vmGame.Editors.ElementAt(3).Title, Is.EqualTo("A Test2"));
            Assert.That(vmGame.Editors.ElementAt(4).Title, Is.EqualTo("Test3"));
            Assert.That(vmGame.Editors.ElementAt(5).Title, Is.EqualTo("Leaderboard1"));

            // despite having ids, these don't get categorized as Core or Unofficial without reading from file
            Assert.That(vmGame.GeneratedAchievementCount, Is.EqualTo(3));
            Assert.That(vmGame.CoreAchievementCount, Is.EqualTo(0));
            Assert.That(vmGame.CoreAchievementPoints, Is.EqualTo(0));
            Assert.That(vmGame.UnofficialAchievementCount, Is.EqualTo(0));
            Assert.That(vmGame.UnofficialAchievementPoints, Is.EqualTo(0));
            Assert.That(vmGame.LocalAchievementCount, Is.EqualTo(0));
            Assert.That(vmGame.LocalAchievementPoints, Is.EqualTo(0));
        }
Exemple #6
0
        public void TestFunctionReference()
        {
            string input = "once(f)";

            var requirements = new List <Requirement>();
            var funcDef      = new OnceFunction();

            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            Assert.That(expression, Is.InstanceOf <FunctionCallExpression>());
            var funcCall = (FunctionCallExpression)expression;

            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.AssignVariable(new VariableExpression("f"), new FunctionReferenceExpression("f2"));

            ExpressionBase error;

            scope = funcCall.GetParameters(funcDef, scope, out error);
            var context = new TriggerBuilderContext {
                Trigger = requirements
            };

            scope.Context = context;

            ExpressionBase evaluated;

            Assert.That(funcDef.ReplaceVariables(scope, out evaluated), Is.True);
            funcCall = evaluated as FunctionCallExpression;

            var parseError = funcDef.BuildTrigger(context, scope, funcCall);

            Assert.That(parseError, Is.Not.Null);
            Assert.That(parseError.InnermostError.Message, Is.EqualTo("Function used like a variable"));
        }
Exemple #7
0
        internal void PopulateEditorList(AchievementScriptInterpreter interpreter)
        {
            var editors = new List <ViewerViewModelBase>();

            if (Script != null)
            {
                editors.Add(Script);
            }

            var selectedEditor = (SelectedEditor != null) ? SelectedEditor.Title : null;

            if (interpreter != null)
            {
                GeneratedAchievementCount = interpreter.Achievements.Count();
                editors.Capacity         += GeneratedAchievementCount;

                if (!String.IsNullOrEmpty(interpreter.RichPresence))
                {
                    var richPresenceViewModel = new RichPresenceViewModel(this, interpreter.RichPresence);
                    if (richPresenceViewModel.Lines.Any())
                    {
                        richPresenceViewModel.SourceLine = interpreter.RichPresenceLine;
                        editors.Add(richPresenceViewModel);
                    }
                }

                foreach (var achievement in interpreter.Achievements)
                {
                    var achievementViewModel = new AchievementViewModel(this);
                    achievementViewModel.Generated.Asset = achievement;
                    editors.Add(achievementViewModel);
                }

                foreach (var leaderboard in interpreter.Leaderboards)
                {
                    var leaderboardViewModel = new LeaderboardViewModel(this);
                    leaderboardViewModel.Generated.Asset = leaderboard;
                    editors.Add(leaderboardViewModel);
                }
            }
            else
            {
                GeneratedAchievementCount = 0;
            }

            if (_publishedAchievements.Count > 0 || _publishedLeaderboards.Count > 0)
            {
                MergePublished(editors);
            }

            if (_localAssets != null)
            {
                MergeLocal(editors);
            }

            UpdateTemporaryIds(editors);

            SelectedEditor = editors.FirstOrDefault(e => e.Title == selectedEditor);
            Editors        = editors;
        }
Exemple #8
0
        public void TestTriggerWhenDefinition()
        {
            var funcDef = AchievementScriptInterpreter.GetGlobalScope().GetFunction("trigger_when");

            Assert.That(funcDef, Is.Not.Null);
            Assert.That(funcDef.Name.Name, Is.EqualTo("trigger_when"));
            Assert.That(funcDef.Parameters.Count, Is.EqualTo(1));
            Assert.That(funcDef.Parameters.ElementAt(0).Name, Is.EqualTo("comparison"));
        }
        public void TestDefinition()
        {
            var def = AchievementScriptInterpreter.GetGlobalScope().GetFunction("disable_when");

            Assert.That(def, Is.Not.Null);
            Assert.That(def.Name.Name, Is.EqualTo("disable_when"));
            Assert.That(def.Parameters.Count, Is.EqualTo(2));
            Assert.That(def.Parameters.ElementAt(0).Name, Is.EqualTo("comparison"));
            Assert.That(def.Parameters.ElementAt(1).Name, Is.EqualTo("until"));
        }
        public void TestIsTrueMemoryAccessorFunction()
        {
            var expr  = new FunctionCallExpression("byte", new ExpressionBase[] { new IntegerConstantExpression(0x1234) });
            var scope = AchievementScriptInterpreter.GetGlobalScope();

            ParseErrorExpression error;

            Assert.That(expr.IsTrue(scope, out error), Is.Null);
            Assert.That(error, Is.Null);
        }
        public void TestIsTrueAlwaysFalseFunction()
        {
            var expr  = AlwaysFalseFunction.CreateAlwaysFalseFunctionCall();
            var scope = AchievementScriptInterpreter.GetGlobalScope();

            ParseErrorExpression error;

            Assert.That(expr.IsTrue(scope, out error), Is.False);
            Assert.That(error, Is.Null);
        }
Exemple #12
0
        private Achievement AddGeneratedAchievement(AchievementScriptInterpreter interpreter, int id, string name)
        {
            var achievement = new Achievement
            {
                Id          = id,
                Title       = name,
                Description = name
            };

            ((List <Achievement>)interpreter.Achievements).Add(achievement);
            return(achievement);
        }
        public void TestGetValueString(string input, string expected)
        {
            ExpressionBase   error;
            InterpreterScope scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.Context = new TriggerBuilderContext();

            var expression = Parse(input);
            var result     = TriggerBuilderContext.GetValueString(expression, scope, out error);

            Assert.That(error, Is.Null);
            Assert.That(result, Is.EqualTo(expected));
        }
        public void TestIsTrue(string input, bool?expected)
        {
            var tokenizer = Tokenizer.CreateTokenizer(input);
            var expr      = ExpressionBase.Parse(new PositionalTokenizer(tokenizer));

            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.Context = new RATools.Parser.TriggerBuilderContext();
            ParseErrorExpression error;

            Assert.That(expr.IsTrue(scope, out error), Is.EqualTo(expected));
            Assert.That(error, Is.Null);
        }
        public void TestIsTrueUserFunctionReturningBoolean()
        {
            var userFunc = Parse("function u() => always_true()");
            var expr     = new FunctionCallExpression("u", new ExpressionBase[0]);
            var scope    = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.AddFunction(userFunc);

            ParseErrorExpression error;

            Assert.That(expr.IsTrue(scope, out error), Is.True);
            Assert.That(error, Is.Null);
        }
        public void TestIsTrue(string input, bool expected)
        {
            var tokenizer  = new PositionalTokenizer(Tokenizer.CreateTokenizer(input));
            var expression = ExpressionBase.Parse(tokenizer);

            Assert.That(expression, Is.InstanceOf <ConditionalExpression>());

            ParseErrorExpression error;
            var scope  = AchievementScriptInterpreter.GetGlobalScope();
            var result = expression.IsTrue(scope, out error);

            Assert.That(error, Is.Null);
            Assert.That(result, Is.EqualTo(expected));
        }
Exemple #17
0
        private static string Evaluate(string input)
        {
            var script    = "achievement(\"title\", \"desc\", 5,\n" + input + "\n)";
            var tokenizer = Tokenizer.CreateTokenizer(script);
            var parser    = new AchievementScriptInterpreter();

            if (parser.Run(tokenizer))
            {
                var achievement = parser.Achievements.First();
                var builder     = new AchievementBuilder(achievement);
                return(builder.RequirementsDebugString);
            }

            return(parser.Error.InnermostError.Message);
        }
Exemple #18
0
        private Leaderboard AddGeneratedLeaderboard(AchievementScriptInterpreter interpreter, int id, string name)
        {
            var leaderboard = new Leaderboard
            {
                //Id = id,
                Title  = name,
                Start  = "1=1",
                Submit = "1=1",
                Cancel = "1=1",
                Value  = "1"
            };

            ((List <Leaderboard>)interpreter.Leaderboards).Add(leaderboard);
            return(leaderboard);
        }
Exemple #19
0
        private static string GetInnerErrorMessage(AchievementScriptInterpreter parser)
        {
            if (parser.Error == null)
            {
                return(null);
            }

            var err = parser.Error;

            while (err.InnerError != null)
            {
                err = err.InnerError;
            }

            return(string.Format("{0}:{1} {2}", err.Location.Start.Line, err.Location.Start.Column, err.Message));
        }
Exemple #20
0
        /// <summary>
        /// Gets the return value from calling a function.
        /// </summary>
        /// <param name="scope">The scope object containing variable values and function parameters.</param>
        /// <param name="result">[out] The new expression containing the function result.</param>
        /// <returns>
        ///   <c>true</c> if substitution was successful, <c>false</c> if something went wrong, in which case <paramref name="result" /> will likely be a <see cref="ParseErrorExpression" />.
        /// </returns>
        public virtual bool Evaluate(InterpreterScope scope, out ExpressionBase result)
        {
            var interpreter      = new AchievementScriptInterpreter();
            var interpreterScope = new InterpreterScope(scope)
            {
                Context = interpreter
            };

            if (!interpreter.Evaluate(Expressions, interpreterScope))
            {
                result = interpreter.Error;
                return(false);
            }

            result = interpreterScope.ReturnValue;
            return(true);
        }
Exemple #21
0
                  "trigger_when(byte(1) == 56) && trigger_when(byte(2) == 3) && trigger_when(byte(1) == 55 || byte(2) == 4)")]                             // and can be separated, but not nested ors
        public void TestReplaceVariables(string input, string expected)
        {
            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.Context = new TriggerBuilderContext();

            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            ExpressionBase evaluated;

            Assert.That(expression.ReplaceVariables(scope, out evaluated), Is.True);

            var builder = new StringBuilder();

            evaluated.AppendString(builder);
            Assert.That(builder.ToString(), Is.EqualTo(expected));
        }
        public void TestPushMemoryComparison()
        {
            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());
            var array = new ArrayExpression();

            scope.DefineVariable(new VariableDefinitionExpression("arr"), array);
            AddHappyFunction(scope);

            Evaluate("array_push(arr, byte(1) == 2)", scope);

            var comparison = (ComparisonExpression)array.Entries[0];

            Assert.That(comparison.Left, Is.InstanceOf <FunctionCallExpression>());
            Assert.That(((FunctionCallExpression)comparison.Left).FunctionName.Name, Is.EqualTo("byte"));
            Assert.That(comparison.Right, Is.InstanceOf <IntegerConstantExpression>());
            Assert.That(((IntegerConstantExpression)comparison.Right).Value, Is.EqualTo(2));
        }
        private RichPresenceBuilder Evaluate(string input, string expectedError = null)
        {
            var funcDef = new RichPresenceValueFunction();

            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            Assert.That(expression, Is.InstanceOf <FunctionCallExpression>());
            var funcCall = (FunctionCallExpression)expression;

            ExpressionBase error;
            var            scope   = funcCall.GetParameters(funcDef, AchievementScriptInterpreter.GetGlobalScope(), out error);
            var            context = new RichPresenceDisplayFunction.RichPresenceDisplayContext {
                RichPresence = new RichPresenceBuilder()
            };

            scope.Context = context;

            ExpressionBase evaluated;

            if (expectedError != null && expectedError.EndsWith(" format"))
            {
                Assert.That(funcDef.ReplaceVariables(scope, out evaluated), Is.False);
                var parseError = evaluated as ParseErrorExpression;
                Assert.That(parseError, Is.Not.Null);
                Assert.That(parseError.Message, Is.EqualTo(expectedError));
                return(context.RichPresence);
            }

            ExpressionBase result;

            Assert.That(funcDef.ReplaceVariables(scope, out evaluated), Is.True);
            if (expectedError == null)
            {
                Assert.That(funcDef.BuildMacro(context, scope, out result), Is.True);
                context.RichPresence.DisplayString = ((StringConstantExpression)result).Value;
            }
            else
            {
                Assert.That(funcDef.BuildMacro(context, scope, out result), Is.False);
                Assert.That(result, Is.InstanceOf <ParseErrorExpression>());
                Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo(expectedError));
            }

            return(context.RichPresence);
        }
Exemple #24
0
        public void TestExplicitCall()
        {
            // not providing a TriggerBuilderContext simulates calling the function at a global scope
            var funcDef = new MemoryAccessorFunction("byte", FieldSize.Byte);

            var input      = "byte(0x1234)";
            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            Assert.That(expression, Is.InstanceOf <FunctionCallExpression>());
            var funcCall = (FunctionCallExpression)expression;

            ExpressionBase error;
            var            scope = funcCall.GetParameters(funcDef, AchievementScriptInterpreter.GetGlobalScope(), out error);

            Assert.That(funcDef.Evaluate(scope, out error), Is.False);
            Assert.That(error, Is.InstanceOf <ParseErrorExpression>());
            Assert.That(((ParseErrorExpression)error).Message, Is.EqualTo("byte has no meaning outside of a trigger clause"));
        }
Exemple #25
0
        public void TestExplicitCall()
        {
            // not providing a RichPresenceDisplayContext simulates calling the function at a global scope
            var funcDef = new RichPresenceValueFunction();

            var input      = "rich_presence_value(\"Name\", byte(0x1234))";
            var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input)));

            Assert.That(expression, Is.InstanceOf <FunctionCallExpression>());
            var funcCall = (FunctionCallExpression)expression;

            ExpressionBase error;
            var            scope = funcCall.GetParameters(funcDef, AchievementScriptInterpreter.GetGlobalScope(), out error);

            Assert.That(funcDef.Evaluate(scope, out error), Is.False);
            Assert.That(error, Is.InstanceOf <ParseErrorExpression>());
            Assert.That(((ParseErrorExpression)error).Message, Is.EqualTo("rich_presence_value has no meaning outside of a rich_presence_display call"));
        }
Exemple #26
0
        public void TestScopedVariable()
        {
            var script = "function ItemInInventory(id) => any_of(range(0x1200, 0x1208, step=2), addr => word(addr) == id)\n" +
                         "achievement(\"title\", \"desc\", 5, ItemInInventory(17))";
            var tokenizer = Tokenizer.CreateTokenizer(script);
            var parser    = new AchievementScriptInterpreter();

            if (!parser.Run(tokenizer))
            {
                Assert.Fail(parser.ErrorMessage);
            }

            var achievement = parser.Achievements.First();
            var builder     = new AchievementBuilder(achievement);

            Assert.That(builder.RequirementsDebugString, Is.EqualTo(
                            "word(0x001200) == 17 || word(0x001202) == 17 || word(0x001204) == 17 || word(0x001206) == 17 || word(0x001208) == 17"));
        }
Exemple #27
0
        public void TestPredicateWithDefaultParameter()
        {
            var script = "function p(addr, id=17) => byte(addr) == id\n" +
                         "achievement(\"title\", \"desc\", 5, any_of([1, 2, 3], p))";
            var tokenizer = Tokenizer.CreateTokenizer(script);
            var parser    = new AchievementScriptInterpreter();

            if (!parser.Run(tokenizer))
            {
                Assert.Fail(parser.ErrorMessage);
            }

            var achievement = parser.Achievements.First();
            var builder     = new AchievementBuilder(achievement);

            Assert.That(builder.RequirementsDebugString, Is.EqualTo(
                            "byte(0x000001) == 17 || byte(0x000002) == 17 || byte(0x000003) == 17"));
        }
        public void TestReplaceVariablesMemoryAccessor()
        {
            var value = new FunctionCallExpression("byte", new[] { new IntegerConstantExpression(1) });
            var expr  = new ArrayExpression();

            expr.Entries.Add(value);

            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            ExpressionBase result;

            Assert.That(expr.ReplaceVariables(scope, out result), Is.True);

            Assert.That(result, Is.InstanceOf <ArrayExpression>());
            var arrayResult = (ArrayExpression)result;

            Assert.That(arrayResult.Entries.Count, Is.EqualTo(1));
            Assert.That(arrayResult.Entries[0].ToString(), Is.EqualTo(value.ToString()));
        }
        public void TestReplaceVariablesLogicalFunctionCall()
        {
            var functionDefinition = UserFunctionDefinitionExpression.ParseForTest("function func(i) => byte(i) == 1");

            var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) });
            var value1       = new IntegerConstantExpression(98);
            var expr         = new DictionaryExpression();

            expr.Add(functionCall, value1);

            var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope());

            scope.AddFunction(functionDefinition);

            ExpressionBase result;

            Assert.That(expr.ReplaceVariables(scope, out result), Is.False);
            Assert.That(result, Is.InstanceOf <ParseErrorExpression>());
            Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("Dictionary key must evaluate to a constant"));
        }
Exemple #30
0
        private AchievementScriptInterpreter Parse(string input, bool expectedSuccess = true)
        {
            var tokenizer = Tokenizer.CreateTokenizer(input);
            var parser    = new AchievementScriptInterpreter();

            if (expectedSuccess)
            {
                if (!parser.Run(tokenizer))
                {
                    Assert.That(parser.ErrorMessage, Is.Null);
                    Assert.Fail("AchievementScriptInterpreter.Run failed with no error message");
                }
            }
            else
            {
                Assert.That(parser.Run(tokenizer), Is.False);
                Assert.That(parser.ErrorMessage, Is.Not.Null);
            }

            return(parser);
        }