#include "EventHandlerSetScopeSequences.h" #include "Generic/GenericStringPropertySequence.h" #include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.h" #include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h" #include "Parsing/Menu/Matcher/MenuExpressionMatchers.h" #include "Parsing/Menu/Matcher/MenuMatcherFactory.h" #include "Parsing/Menu/Matcher/MenuMatcherScriptInt.h" #include "Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h" #include #include #include using namespace menu; namespace { enum class ExpectedScriptToken { NUMERIC, INT, TEXT }; class ScriptMatcherFactory final : public MenuMatcherFactory { public: explicit ScriptMatcherFactory(const IMatcherForLabelSupplier* labelSupplier) : MenuMatcherFactory(labelSupplier) { } [[nodiscard]] MatcherFactoryWrapper ScriptStrictNumeric() const { return And({ MatcherFactoryWrapper(std::make_unique()) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { const auto& firstToken = tokens[0].get(); if (firstToken.m_type == SimpleParserValueType::CHARACTER) { const auto& secondToken = tokens[1].get(); if (secondToken.m_type == SimpleParserValueType::INTEGER) return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(-secondToken.IntegerValue()))); std::ostringstream ss; ss << std::noshowpoint << -firstToken.FloatingPointValue(); return SimpleParserValue::String(firstToken.GetPos(), new std::string(ss.str())); } if (firstToken.m_type == SimpleParserValueType::INTEGER) return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); if (firstToken.m_type == SimpleParserValueType::FLOATING_POINT) { std::ostringstream ss; ss << std::noshowpoint << firstToken.FloatingPointValue(); return SimpleParserValue::String(firstToken.GetPos(), new std::string(ss.str())); } return SimpleParserValue::String(firstToken.GetPos(), new std::string(firstToken.StringValue())); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptNumeric() const { return Or({ ScriptStrictNumeric(), Or({ Type(SimpleParserValueType::CHARACTER), Type(SimpleParserValueType::STRING), Type(SimpleParserValueType::IDENTIFIER), }) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::NUMERIC)); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptStrictInt() const { return And({ MatcherFactoryWrapper(std::make_unique()) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { const auto& firstToken = tokens[0].get(); if (firstToken.m_type == SimpleParserValueType::CHARACTER) return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(-tokens[1].get().IntegerValue()))); if (firstToken.m_type == SimpleParserValueType::INTEGER) return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); return SimpleParserValue::String(firstToken.GetPos(), new std::string(firstToken.StringValue())); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptChar(const char c) const { return Or({ Char(c), Or({ Type(SimpleParserValueType::INTEGER), Type(SimpleParserValueType::FLOATING_POINT), Type(SimpleParserValueType::STRING), Type(SimpleParserValueType::IDENTIFIER), }) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::INT)); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptInt() const { return Or({ ScriptStrictInt(), Or({ Type(SimpleParserValueType::CHARACTER), Type(SimpleParserValueType::FLOATING_POINT), Type(SimpleParserValueType::STRING), Type(SimpleParserValueType::IDENTIFIER), }) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::INT)); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptText() const { return Or({ Type(SimpleParserValueType::STRING), Type(SimpleParserValueType::IDENTIFIER), Or({ Type(SimpleParserValueType::CHARACTER), Type(SimpleParserValueType::FLOATING_POINT), Type(SimpleParserValueType::INTEGER), }) .Transform( [](const token_list_t& tokens) -> SimpleParserValue { return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::TEXT)); }), }); } [[nodiscard]] MatcherFactoryWrapper ScriptKeyword(std::string keyword) const { return KeywordIgnoreCase(std::move(keyword)); } [[nodiscard]] MatcherFactoryWrapper ScriptColor() const { return And({ ScriptStrictNumeric(), Optional(ScriptStrictNumeric()), Optional(ScriptStrictNumeric()), Optional(ScriptStrictNumeric()), }); } [[nodiscard]] MatcherFactoryWrapper ScriptLocalVarIntOrLiteral() const { return Or({ And({ ScriptKeyword("localVarInt"), Char('('), ScriptText(), Char(')'), }), ScriptStrictInt(), }); } [[nodiscard]] MatcherFactoryWrapper ScriptLocalVarBoolOrLiteral() const { return Or({ And({ ScriptKeyword("localVarBool"), Char('('), ScriptText(), Char(')'), }), ScriptStrictInt(), }); } }; class SequenceCloseBlock final : public MenuFileParser::sequence_t { public: SequenceCloseBlock() { const MenuMatcherFactory create(this); AddMatchers({ create.Char('}'), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { auto remainingScript = state->m_current_script.str(); if (!remainingScript.empty()) state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(std::move(remainingScript))); state->m_current_script.str(std::string()); bool conditionWasAutoSkip; do { conditionWasAutoSkip = false; if (!state->m_condition_stack.empty()) { conditionWasAutoSkip = state->m_condition_stack.top().m_auto_skip; state->m_condition_stack.pop(); if (!state->m_condition_stack.empty()) { const auto& newConditionState = state->m_condition_stack.top(); if (newConditionState.m_in_condition_elements) state->m_current_nested_event_handler_set = newConditionState.m_condition->m_condition_elements.get(); else state->m_current_nested_event_handler_set = newConditionState.m_condition->m_else_elements.get(); } else state->m_current_nested_event_handler_set = state->m_current_event_handler_set; } else { state->m_current_event_handler_set = nullptr; state->m_current_nested_event_handler_set = nullptr; } } while (conditionWasAutoSkip); } }; class SequenceSkipEmptyStatements final : public MenuFileParser::sequence_t { public: SequenceSkipEmptyStatements() { const MenuMatcherFactory create(this); AddMatchers({ create.Char(';'), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { if (!state->m_current_script_statement_terminated) { state->m_current_script << "; "; state->m_current_script_statement_terminated = true; } } }; class SequenceSkipScriptToken final : public MenuFileParser::sequence_t { static constexpr auto CAPTURE_SCRIPT_TOKEN = 1; public: SequenceSkipScriptToken() { const ScriptMatcherFactory create(this); AddMatchers({ create .Or({ create.ScriptStrictNumeric(), create.String(), create.Identifier(), create.Type(SimpleParserValueType::CHARACTER), }) .Capture(CAPTURE_SCRIPT_TOKEN), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { const auto& capture = result.NextCapture(CAPTURE_SCRIPT_TOKEN); switch (capture.m_type) { case SimpleParserValueType::STRING: state->m_current_script << "\"" << capture.StringValue() << "\" "; break; case SimpleParserValueType::IDENTIFIER: state->m_current_script << "\"" << capture.IdentifierValue() << "\" "; break; case SimpleParserValueType::INTEGER: state->m_current_script << "\"" << capture.IntegerValue() << "\" "; break; case SimpleParserValueType::CHARACTER: state->m_current_script << capture.CharacterValue() << " "; break; case SimpleParserValueType::FLOATING_POINT: state->m_current_script << "\"" << capture.FloatingPointValue() << "\" "; break; default: throw ParsingException(capture.GetPos(), "Invalid script token type for skipping"); } state->m_current_script_statement_terminated = false; } }; class SequenceGenericScriptStatement : public MenuFileParser::sequence_t { protected: static constexpr auto CAPTURE_SCRIPT_TOKEN = 1; SequenceGenericScriptStatement() = default; public: explicit SequenceGenericScriptStatement(std::initializer_list>>> matchers) { const MenuMatcherFactory create(this); AddMatchers({ create.And(matchers).Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } static std::unique_ptr Create(std::initializer_list>>> matchers) { return std::make_unique(matchers); } private: static std::string ScriptTokenTypeToString(int tokenType) { switch (static_cast(tokenType)) { case ExpectedScriptToken::INT: return "INT"; case ExpectedScriptToken::NUMERIC: return "NUMERIC"; case ExpectedScriptToken::TEXT: return "TEXT"; default: return "UNKNOWN"; } } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { while (result.HasNextCapture(CAPTURE_SCRIPT_TOKEN)) { const auto& capture = result.NextCapture(CAPTURE_SCRIPT_TOKEN); if (capture.m_type == SimpleParserValueType::IDENTIFIER) { state->m_current_script << "\"" << capture.IdentifierValue() << "\" "; } else if (capture.m_type == SimpleParserValueType::STRING) { state->m_current_script << "\"" << capture.StringValue() << "\" "; } else if (capture.m_type == SimpleParserValueType::CHARACTER) { state->m_current_script << capture.CharacterValue() << " "; } else if (capture.m_type == SimpleParserValueType::INTEGER) { std::ostringstream ss; ss << "Invalid script token. Expected " << ScriptTokenTypeToString(capture.IntegerValue()) << "."; throw ParsingException(capture.GetPos(), ss.str()); } else throw ParsingException(capture.GetPos(), "Invalid script capture"); } state->m_current_script << "; "; } }; class SequenceUiScriptStatement final : public SequenceGenericScriptStatement { public: explicit SequenceUiScriptStatement(std::initializer_list>>> matchers) : SequenceGenericScriptStatement() { const ScriptMatcherFactory create(this); AddMatchers({ create .And({ create.ScriptKeyword("uiScript"), create.And(matchers), }) .Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } static std::unique_ptr Create(std::initializer_list>>> matchers) { return std::make_unique(matchers); } }; class AbstractSequenceWithPlayerData : public SequenceGenericScriptStatement { protected: static constexpr auto LABEL_PLAYER_DATA_PATH_ELEMENT = 1; static std::unique_ptr PlayerDataPathMatchers(const ScriptMatcherFactory& create) { return create.Or({ create.ScriptKeyword("false"), create.ScriptKeyword("true"), create.And({ create.Or({ create.ScriptKeyword("localvarstring"), create.ScriptKeyword("localvarint"), create.ScriptKeyword("localvarfloat"), create.ScriptKeyword("localvarbool"), }), create.ScriptChar('('), create.ScriptText(), create.ScriptChar(')'), }), create.ScriptStrictInt(), create.ScriptText(), }); } }; class SequenceSetPlayerData final : public AbstractSequenceWithPlayerData { public: explicit SequenceSetPlayerData() { const ScriptMatcherFactory create(this); AddLabeledMatchers(PlayerDataPathMatchers(create), LABEL_PLAYER_DATA_PATH_ELEMENT); AddMatchers({ create .And({ create.ScriptKeyword("setPlayerData"), create.ScriptChar('('), create.Label(LABEL_PLAYER_DATA_PATH_ELEMENT), create.Loop(create.And({ create.ScriptChar(','), create.Label(LABEL_PLAYER_DATA_PATH_ELEMENT), })), create.ScriptChar(')'), }) .Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } }; class SequenceSetPlayerDataSplitscreen final : public AbstractSequenceWithPlayerData { public: explicit SequenceSetPlayerDataSplitscreen() { const ScriptMatcherFactory create(this); AddLabeledMatchers(PlayerDataPathMatchers(create), LABEL_PLAYER_DATA_PATH_ELEMENT); AddMatchers({ create .And({ create.ScriptKeyword("setPlayerDataSplitscreen"), create.ScriptChar('('), create.ScriptInt(), create.ScriptChar(','), create.Label(LABEL_PLAYER_DATA_PATH_ELEMENT), create.Loop(create.And({ create.ScriptChar(','), create.Label(LABEL_PLAYER_DATA_PATH_ELEMENT), })), create.ScriptChar(')'), }) .Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } }; class SequenceLerp final : public SequenceGenericScriptStatement { public: explicit SequenceLerp() { const ScriptMatcherFactory create(this); AddMatchers({ create .And({ create.ScriptKeyword("lerp"), create.Or({ create.ScriptKeyword("scale"), create.ScriptKeyword("alpha"), create.ScriptKeyword("x"), create.ScriptKeyword("y"), }), create.ScriptKeyword("from"), create.ScriptNumeric(), create.ScriptKeyword("to"), create.ScriptNumeric(), create.ScriptKeyword("over"), create.ScriptNumeric(), }) .Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } }; class SequenceSetLocalVar final : public MenuFileParser::sequence_t { static constexpr auto TAG_BOOL = static_cast(SetLocalVarType::BOOL); static constexpr auto TAG_INT = static_cast(SetLocalVarType::INT); static constexpr auto TAG_FLOAT = static_cast(SetLocalVarType::FLOAT); static constexpr auto TAG_STRING = static_cast(SetLocalVarType::STRING); static constexpr auto CAPTURE_VAR_NAME = 1; public: SequenceSetLocalVar() { const ScriptMatcherFactory create(this); const MenuExpressionMatchers expressionMatchers; AddLabeledMatchers(expressionMatchers.Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION); AddMatchers({ create.Or({ create.ScriptKeyword("setLocalVarBool").Tag(TAG_BOOL), create.ScriptKeyword("setLocalVarInt").Tag(TAG_INT), create.ScriptKeyword("setLocalVarFloat").Tag(TAG_FLOAT), create.ScriptKeyword("setLocalVarString").Tag(TAG_STRING), }), create.ScriptText().Capture(CAPTURE_VAR_NAME), create.Or({ create.And({ create.Label(MenuExpressionMatchers::LABEL_EXPRESSION), create.Optional(create.Char(';')), }), // The game seems to accept setLocalVar expressions without value as setting the var to the default value // This only applies to the menu parser though and not to the script parser so we need to separately parse this create.Char(';'), }), }); } private: static std::string ScriptKeywordForType(const SetLocalVarType type) { switch (type) { case SetLocalVarType::BOOL: return "setLocalVarBool"; case SetLocalVarType::INT: return "setLocalVarInt"; case SetLocalVarType::FLOAT: return "setLocalVarFloat"; case SetLocalVarType::STRING: return "setLocalVarString"; default: return "unknown"; } } static void EmitStaticValue(MenuFileParserState* state, const SimpleExpressionValue& value) { switch (value.m_type) { case SimpleExpressionValue::Type::DOUBLE: state->m_current_script << value.m_double_value; break; case SimpleExpressionValue::Type::INT: state->m_current_script << value.m_int_value; break; case SimpleExpressionValue::Type::STRING: state->m_current_script << *value.m_string_value; break; } } static void CheckStaticValueType(const TokenPos& pos, const SetLocalVarType type, const SimpleExpressionValue& staticValue) { switch (type) { case SetLocalVarType::BOOL: if (staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be BOOL"); break; case SetLocalVarType::INT: if (staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be INT"); break; case SetLocalVarType::FLOAT: if (staticValue.m_type != SimpleExpressionValue::Type::DOUBLE && staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be FLOAT"); break; case SetLocalVarType::STRING: default: break; } } static void EmitStaticSetLocalVar(MenuFileParserState* state, const TokenPos& pos, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) { state->m_current_script << "\"" << ScriptKeywordForType(type) << "\" \"" << varName << "\" \""; const auto staticValue = expression->EvaluateStatic(); CheckStaticValueType(pos, type, staticValue); EmitStaticValue(state, staticValue); state->m_current_script << "\" ; "; } static void EmitDynamicSetLocalVar(MenuFileParserState* state, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) { auto remainingScript = state->m_current_script.str(); if (!remainingScript.empty()) state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(std::move(remainingScript))); state->m_current_script.str(std::string()); state->m_current_nested_event_handler_set->m_elements.emplace_back( std::make_unique(type, varName, std::move(expression))); } static std::unique_ptr DefaultExpressionForType(const SetLocalVarType type) { switch (type) { case SetLocalVarType::INT: case SetLocalVarType::BOOL: return std::make_unique(0); case SetLocalVarType::FLOAT: return std::make_unique(0.0); case SetLocalVarType::STRING: return std::make_unique(std::string()); default: assert(false); return nullptr; } } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { const MenuExpressionMatchers expressionMatchers(state); const auto typeTag = static_cast(result.NextTag()); const auto& varNameToken = result.NextCapture(CAPTURE_VAR_NAME); const auto& varName = MenuMatcherFactory::TokenTextValue(varNameToken); auto expression = expressionMatchers.ProcessExpression(result); if (expression) { if (expression->IsStatic()) EmitStaticSetLocalVar(state, varNameToken.GetPos(), typeTag, varName, std::move(expression)); else EmitDynamicSetLocalVar(state, typeTag, varName, std::move(expression)); } else EmitStaticSetLocalVar(state, varNameToken.GetPos(), typeTag, varName, DefaultExpressionForType(typeTag)); } }; class SequenceIf final : public MenuFileParser::sequence_t { static constexpr auto CAPTURE_KEYWORD = 1; public: SequenceIf() { const ScriptMatcherFactory create(this); const MenuExpressionMatchers expressionMatchers; AddLabeledMatchers(expressionMatchers.Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION); AddMatchers({ create.Keyword("if").Capture(CAPTURE_KEYWORD), create.Char('('), create.Label(MenuExpressionMatchers::LABEL_EXPRESSION), create.Char(')'), create.Char('{'), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { const MenuExpressionMatchers expressionMatchers(state); auto expression = expressionMatchers.ProcessExpression(result); if (!expression) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Could not parse expression"); auto remainingScript = state->m_current_script.str(); if (!remainingScript.empty()) state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(std::move(remainingScript))); state->m_current_script.str(std::string()); auto newCondition = std::make_unique(std::move(expression), std::make_unique(), nullptr); auto* newConditionPtr = newCondition.get(); state->m_current_nested_event_handler_set->m_elements.emplace_back(std::move(newCondition)); state->m_condition_stack.emplace(newConditionPtr); state->m_current_nested_event_handler_set = newConditionPtr->m_condition_elements.get(); } }; class SequenceElseIf final : public MenuFileParser::sequence_t { static constexpr auto CAPTURE_KEYWORD = 1; public: SequenceElseIf() { const ScriptMatcherFactory create(this); const MenuExpressionMatchers expressionMatchers; AddLabeledMatchers(expressionMatchers.Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION); AddMatchers({ create.Char('}'), create.Keyword("elseif").Capture(CAPTURE_KEYWORD), create.Char('('), create.Label(MenuExpressionMatchers::LABEL_EXPRESSION), create.Char(')'), create.Char('{'), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { const MenuExpressionMatchers expressionMatchers(state); auto expression = expressionMatchers.ProcessExpression(result); if (!expression) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Could not parse expression"); if (state->m_condition_stack.empty()) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Not in an if statement"); auto remainingScript = state->m_current_script.str(); if (!remainingScript.empty()) state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(std::move(remainingScript))); state->m_current_script.str(std::string()); auto& currentCondition = state->m_condition_stack.top(); assert(currentCondition.m_in_condition_elements == (currentCondition.m_condition->m_else_elements == nullptr)); if (!currentCondition.m_in_condition_elements) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Cannot specify elseif after else"); currentCondition.m_in_condition_elements = false; auto newCondition = std::make_unique(std::move(expression), std::make_unique(), nullptr); auto* newConditionPtr = newCondition.get(); currentCondition.m_condition->m_else_elements = std::make_unique(); currentCondition.m_condition->m_else_elements->m_elements.emplace_back(std::move(newCondition)); state->m_condition_stack.emplace(newConditionPtr, true); state->m_current_nested_event_handler_set = newConditionPtr->m_condition_elements.get(); } }; class SequenceElse final : public MenuFileParser::sequence_t { static constexpr auto CAPTURE_KEYWORD = 1; public: SequenceElse() { const ScriptMatcherFactory create(this); const MenuExpressionMatchers expressionMatchers; AddMatchers({ create.Char('}'), create.Keyword("else").Capture(CAPTURE_KEYWORD), create.Char('{'), }); } protected: void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override { if (state->m_condition_stack.empty()) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Not in an if statement"); auto& currentCondition = state->m_condition_stack.top(); assert(currentCondition.m_in_condition_elements == (currentCondition.m_condition->m_else_elements == nullptr)); if (!currentCondition.m_in_condition_elements) throw ParsingException(result.NextCapture(CAPTURE_KEYWORD).GetPos(), "Cannot specify second else block"); auto remainingScript = state->m_current_script.str(); if (!remainingScript.empty()) state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(std::move(remainingScript))); state->m_current_script.str(std::string()); currentCondition.m_in_condition_elements = false; currentCondition.m_condition->m_else_elements = std::make_unique(); state->m_current_nested_event_handler_set = currentCondition.m_condition->m_else_elements.get(); } }; class SequenceOnlineVault final : public SequenceGenericScriptStatement { static constexpr auto LABEL_OPEN = 1; static constexpr auto LABEL_PARADIGM = 2; static constexpr auto LABEL_PLATFORM = 3; static constexpr auto LABEL_FILE_CATEGORY = 4; public: explicit SequenceOnlineVault() { const ScriptMatcherFactory create(this); AddLabeledMatchers(create.Or({ create.ScriptKeyword("Browse"), create.ScriptKeyword("Load"), create.ScriptKeyword("Save"), create.ScriptKeyword("Copy"), }), LABEL_PARADIGM); AddLabeledMatchers(create.Or({ create.ScriptKeyword("Fb"), create.ScriptKeyword("Elite"), create.ScriptKeyword("Live"), }), LABEL_PLATFORM); AddLabeledMatchers(create.Or({ create.ScriptKeyword("All"), create.ScriptKeyword("Film"), create.ScriptKeyword("Clip"), create.ScriptKeyword("Screenshot"), create.ScriptKeyword("Avi"), create.ScriptKeyword("Cgm"), create.ScriptKeyword("Rcu"), }), LABEL_FILE_CATEGORY); AddLabeledMatchers(create.And({ create.ScriptKeyword("open"), create.Label(LABEL_PARADIGM), create.Optional(create.Label(LABEL_PLATFORM)), create.Optional(create.Label(LABEL_FILE_CATEGORY)), create.ScriptText(), }), LABEL_OPEN); AddMatchers({ create .And({ create.ScriptKeyword("uiScript"), create.ScriptKeyword("OnlineVault"), create.Or({ create.Label(LABEL_OPEN), create.ScriptKeyword("Pop"), create.ScriptKeyword("CloseAll"), create.ScriptKeyword("Load"), create.ScriptKeyword("LoadAndRenderMovie"), create.ScriptKeyword("TrySave"), create.ScriptKeyword("Save"), create.ScriptKeyword("Rename"), create.ScriptKeyword("Delete"), create.ScriptKeyword("Abort"), create.ScriptKeyword("FacebookUploadPhoto"), create.ScriptKeyword("FacebookUploadVideo"), }), }) .Capture(CAPTURE_SCRIPT_TOKEN), create.Optional(create.Char(';')), }); } }; } // namespace EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector>& allSequences, std::vector& scopeSequences) : AbstractScopeSequenceHolder(allSequences, scopeSequences) { } void EventHandlerSetScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const { AddSequence(std::make_unique()); // IW3 and T4 store event handlers as opaque script strings rather than structured handlers. if (featureLevel == FeatureLevel::IW3 || featureLevel == FeatureLevel::T4) { AddSequence(std::make_unique()); AddSequence(std::make_unique()); return; } // If else and stuff // Creating factory with no label supplier. Cannot use labels with it. const ScriptMatcherFactory create(nullptr); if (!permissive) { AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("fadeIn"), create.ScriptText(), })); // fadeIn AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("fadeOut"), create.ScriptText(), })); // fadeOut AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("show"), create.ScriptText(), })); // show AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("hide"), create.ScriptText(), })); // hide AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("showMenu"), create.ScriptText(), })); // showMenu AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("hideMenu"), create.ScriptText(), })); // hideMenu AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setColor"), create.Or({ create.ScriptKeyword("backColor"), create.ScriptKeyword("foreColor"), create.ScriptKeyword("borderColor"), }), create.ScriptColor(), })); // setColor ("backColor" | "foreColor" | "borderColor") [] [] [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("open"), create.ScriptText(), })); // open AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("close"), create.ScriptText(), })); // close ("self" | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("escape"), create.ScriptText(), })); // escape ("self" | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("closeForAllPlayers"), create.ScriptText(), })); // closeForAllPlayers AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("ingameOpen"), create.ScriptText(), })); // ingameOpen AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("ingameClose"), create.ScriptText(), })); // ingameClose AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setBackground"), create.ScriptText(), })); // setBackground AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setItemColor"), create.ScriptText(), create.Or({ create.ScriptKeyword("backColor"), create.ScriptKeyword("foreColor"), create.ScriptKeyword("borderColor"), create.ScriptKeyword("disableColor"), }), create.ScriptColor(), })); // setItemColor (backColor | foreColor | borderColor | disableColor) [] [] [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("focusFirst"), })); // setFocus game specific AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setFocusByDvar"), create.ScriptText(), })); // setFocusByDvar // setDvar game specific AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("exec"), create.ScriptText(), })); // exec AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execNow"), create.ScriptText(), })); // execNow AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execOnDvarStringValue"), create.ScriptText(), create.ScriptText(), create.ScriptText(), })); // execOnDvarStringValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execOnDvarIntValue"), create.ScriptText(), create.ScriptInt(), create.ScriptText(), })); // execOnDvarIntValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execOnDvarFloatValue"), create.ScriptText(), create.ScriptNumeric(), create.ScriptText(), })); // execOnDvarFloatValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execNowOnDvarStringValue"), create.ScriptText(), create.ScriptText(), create.ScriptText(), })); // execNowOnDvarStringValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execNowOnDvarIntValue"), create.ScriptText(), create.ScriptInt(), create.ScriptText(), })); // execNowOnDvarIntValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execNowOnDvarFloatValue"), create.ScriptText(), create.ScriptNumeric(), create.ScriptText(), })); // execNowOnDvarFloatValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("play"), create.ScriptText(), })); // play // scriptMenuResponse game specific AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("scriptMenuRespondOnDvarStringValue"), create.ScriptText(), create.ScriptText(), create.ScriptText(), })); // scriptMenuRespondOnDvarStringValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("scriptMenuRespondOnDvarIntValue"), create.ScriptText(), create.ScriptInt(), create.ScriptText(), })); // scriptMenuRespondOnDvarIntValue AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("scriptMenuRespondOnDvarFloatValue"), create.ScriptText(), create.ScriptNumeric(), create.ScriptText(), })); // scriptMenuRespondOnDvarFloatValue AddSequence(std::make_unique()); AddSequence(std::make_unique()); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("resetStatsConfirm"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("resetStatsCancel"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setGameMode"), create.ScriptText(), })); // setGameMode // feederTop / feederBottom game specific AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("showGamerCard"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("openForGameType"), create.ScriptText(), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("closeForGameType"), create.ScriptText(), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("kickPlayer"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("getKickPlayerQuestion"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("partyUpdateMissingMapPackDvar"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("togglePlayerMute"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("resolveError"), })); AddSequence(std::make_unique()); // UiScripts AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("StartServer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("loadArenas"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("loadGameInfo"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("clearError"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("Quit"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("Controls"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("Leave"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("closeingame"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("update"), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("startSingleplayer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("startMultiplayer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("getLanguage"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("verifyLanguage"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("updateLanguage"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("mutePlayer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("openMenuOnDvar"), create.ScriptText(), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("openMenuOnDvarNot"), create.ScriptText(), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("closeMenuOnDvar"), create.ScriptText(), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("closeMenuOnDvarNot"), create.ScriptText(), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("setRecommended"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("clearLoadErrorsSummary"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("clearClientMatchData"), })); if (featureLevel == FeatureLevel::IW4) { AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setFocus"), create.ScriptText(), })); // setFocus AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setDvar"), create.ScriptText(), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), })); // setDvar AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("scriptMenuResponse"), create.ScriptText(), })); // scriptMenuResponse AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("updateMail"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("openMail"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("deleteMail"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("doMailLottery"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederTop"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederBottom"), })); // statClearPerkNew // TODO // statSetUsingTable // TODO // statClearBitMask // TODO // IW4x UiScripts AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("LoadMods"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RunMod"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ClearMods"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("security_increase_cancel"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("mod_download_cancel"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("LoadFriends"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("JoinFriend"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("downloadDLC"), create.ScriptInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("checkFirstLaunch"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("visitWebsite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("visitWiki"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("visitDiscord"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("updateui_mousePitch"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ServerStatus"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("UpdateFilter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RefreshFilter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RefreshServers"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("JoinServer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ServerSort"), create.ScriptInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("CreateListFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("CreateFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("CreateCurrentServerFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("DeleteFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("nextStartupMessage"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("UpdateClasses"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("loadDemos"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("launchDemo"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("deleteDemo"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ApplyMap"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ApplyInitialMap"), })); } if (featureLevel == FeatureLevel::IW5) { AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("forceClose"), create.ScriptText(), })); // forceClose ("self" | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setFocus"), create.Or({ create.And({ create.ScriptKeyword("localVarString"), create.Char('('), create.ScriptText(), create.Char(')'), }), create.ScriptText(), }), })); // setFocus ((localVarString '(' ')') | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setDvar"), create.ScriptText(), create.Or({ create.And({ create.ScriptKeyword("localVarString"), create.Char('('), create.ScriptText(), create.Char(')'), }), create.ScriptStrictNumeric(), create.ScriptText(), }), })); // setDvar ((localVarString '(' ')') | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execFirstClient"), create.ScriptText(), })); // execFirstClient AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execKeyPress"), create.Or({ create.ScriptStrictNumeric(), create.ScriptText(), }), })); // execKeyPress AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("scriptMenuResponse"), create.Or({ create.And({ create.Or({ create.ScriptKeyword("localVarInt"), create.ScriptKeyword("localVarFloat"), create.ScriptKeyword("localVarBool"), create.ScriptKeyword("localVarString"), }), create.Char('('), create.ScriptText(), create.Char(')'), }), create.ScriptStrictInt(), create.ScriptText(), }), })); // scriptMenuResponse (((localVarInt | localVarFloat | localVarBool | localVarString) '(' ')') | ) AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("deleteEliteCacFile"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("integrateEliteCacFile"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setMatchRulesData"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("loadMatchRulesDataFromPlayer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveMatchRulesDataToPlayer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("loadMatchRulesDataFromHistory"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("loadMatchRulesDataDefaults"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setUsingMatchRulesData"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveMatchRulesDedicatedServer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("loadMatchRulesDedicatedServer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("onlineVaultEditMetadata"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("includeInMapRotation"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("useCustomMapRotation"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("useIntermissionTimer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("stopIntermissionTimer"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederTop"), create.Optional(create.Text()), })); // feederTop [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederBottom"), create.Optional(create.Text()), })); // feederBottom [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederPageUp"), create.Optional(create.Text()), })); // feederPageUp [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("feederPageDown"), create.Optional(create.Text()), })); // feederPageDown [] AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("showCoopGamerCard"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("showSplitscreenGamerCard"), })); // unknown parameters AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("reportPlayerOffensive"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("reportPlayerExploiting"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("reportPlayerCheating"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("reportPlayerBoosting"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardIcon"), create.Char('('), create.ScriptLocalVarIntOrLiteral(), create.Char(')'), })); // setCardIcon '(' ((localVarInt '(' ')') | ) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardTitle"), create.Char('('), create.ScriptLocalVarIntOrLiteral(), create.Char(')'), })); // setCardTitle '(' ((localVarInt '(' ')') | ) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardIconNew"), create.Char('('), create.ScriptLocalVarIntOrLiteral(), create.Char(','), create.Or({ create.ScriptLocalVarIntOrLiteral(), // This is wrong and the game does not even understand it. But because it's not a number it evaluates to 0... // The game's menus do it and i don't want to fix it everywhere create.ScriptKeyword("false"), }), create.Char(')'), })); // setCardIconNew '(' ((localVarInt '(' ')') | ) ',' ((localVarInt '(' ')') | ) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardTitleNew"), create.Char('('), create.ScriptLocalVarIntOrLiteral(), create.Char(','), create.Or({ create.ScriptLocalVarIntOrLiteral(), // This is a hack (see setCardIconNew for details) create.ScriptKeyword("false"), }), create.Char(')'), })); // setCardTitleNew '(' ((localVarInt '(' ')') | ) ',' ((localVarInt '(' ')') | ) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardIconSplitScreen"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardTitleSplitScreen"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardIconNewSplitScreen"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setCardTitleNewSplitScreen"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("purchasePrestigeTitle"), create.Char('('), create.ScriptText(), create.Char(')'), })); // purchasePrestigeTitle '(' ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setProfileItemNew"), create.Char('('), create.ScriptText(), create.Char(','), create.ScriptLocalVarIntOrLiteral(), create.Char(')'), })); // setProfileItemNew '(' <item name> ',' (0|1|(localVarInt '(' <var name> ')')) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setProfileItemNewSplitScreen"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("storePopupXuid"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("getHostMigrateQuestion"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("makeHost"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveGameHide"), })); // saveGameHide <item name> AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveGameShow"), })); // saveGameShow <item name> AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveGameSetLocalBool"), create.ScriptText(), })); // saveGameSetLocalBool <var name> AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("saveDelay"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("writeSave"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setSaveExecOnSuccess"), create.ScriptText(), })); // setSaveExecOnSuccess <command> AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("nextLevel"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("disablePause"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("enablePause"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("runCompletionResolve"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("clearCompletionResolve"), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("execWithResolve"), create.ScriptText(), })); AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("playMenuVideo"), create.Char('('), create.ScriptText(), create.Char(','), create.ScriptLocalVarIntOrLiteral(), create.Char(','), create.ScriptLocalVarBoolOrLiteral(), create.Char(')'), })); // playMenuVideo '(' <video name> ',' ((localVarInt '(' <var name> ')') | <offset>) ',' ((localVarBool '(' <var name> ')') | // <maybe_looping_bool>) ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setBackgroundVideo"), create.Char('('), create.ScriptText(), create.Char(')'), })); // setBackgroundVideo '(' <video name or empty string> ')' AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("clearEntitlementNew"), create.ScriptText(), })); // clearEntitlementNew <entitlement name> AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setPastTitleRank"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("setPastTitlePrestige"), })); // unknown AddSequence(SequenceGenericScriptStatement::Create({ create.ScriptKeyword("anticheat_bancheck"), create.ScriptStrictNumeric(), })); // anticheat_bancheck <num> // UiScripts AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("LoadSaveGames"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("LoadGame"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SaveGame"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ForceSave"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("DelSaveGame"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SaveGameSort"), create.ScriptStrictInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("playerStart"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("saveComplete"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("saveRevert"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("resetvscroll"), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RefreshLeaderboards"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ViewGamerCard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("OpenLeaderboard"), create.ScriptText(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("OpenLeaderboardExt"), create.ScriptText(), create.Optional(create.Text()), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ClearLeaderboard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendStoreXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendClearXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendInvite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendJoin"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendGamerCard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendReportOffensive"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendReportExploiter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendReportCheater"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FriendReportBooster"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerStoreXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerClearXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerGamerCard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerFriendRequest"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerShowGroups"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerJoin"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerInvite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerReportOffensive"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerReportExploiter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerReportCheater"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RecentPlayerReportBooster"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookStoreXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookClearXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookGamerCard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookFriendRequest"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookPageRight"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookPageLeft"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookJoin"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookInvite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookReportOffensive"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookReportExploiter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookReportCheater"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("FacebookReportBooster"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanStoreXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanClearXUID"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanGamerCard"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanFriendRequest"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanJoin"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanInvite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanReportOffensive"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanReportExploiter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanReportCheater"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("EliteClanReportBooster"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("coopPlayerShowGroups"), create.ScriptStrictInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("simulateKeyPress"), create.ScriptStrictInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("commerceShowStore"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("voteTypeMap"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("voteMap"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("voteGame"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RefreshServers"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("RefreshFilter"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("closeJoin"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("StopRefresh"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("TrimRecipeName"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ResetRecipeList"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SelectServer"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("ShowCurrentServerTooltip"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("voteTempBan"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("addFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("deleteFavorite"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("PlayDemo"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SwitchSegmentTransition"), create.ScriptStrictInt(), create.ScriptStrictInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("PreviewSegment"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("MoveSegment"), create.ScriptStrictInt(), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("DeleteSegment"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SetFocusOnSegmentButton"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("PopulateLocalDemoFileInformation"), })); AddSequence(std::make_unique<SequenceOnlineVault>()); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("Playlist"), create.Or({ create.And({ create.ScriptKeyword("Open"), create.ScriptStrictInt(), }), create.ScriptKeyword("DoAction"), create.ScriptKeyword("Close"), create.ScriptKeyword("CloseAll"), }), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("UpdateArenas"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("SortChallengesTop"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("xlaunchelitesearch"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("xlaunchelitelaunch"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("xlaunchelitestore"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("LobbyShowGroups"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("addPlayerProfiles"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("createPlayerProfile"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("deletePlayerProfile"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("loadPlayerProfile"), })); AddSequence(SequenceUiScriptStatement::Create({ create.ScriptKeyword("selectActivePlayerProfile"), })); } } AddSequence(std::make_unique<SequenceSetLocalVar>()); AddSequence(std::make_unique<SequenceIf>()); AddSequence(std::make_unique<SequenceElseIf>()); AddSequence(std::make_unique<SequenceElse>()); AddSequence(std::make_unique<SequenceCloseBlock>()); if (permissive) { AddSequence(std::make_unique<SequenceSkipScriptToken>()); } }