Package: ducklingscript
Welcome to DucklingScript, a language that compiles into Rubber Ducky Scripting Language 1.0! DucklingScript is the best language to use for BadUSB on the Flipper Zero. Although this is the main idea, there are many other applications as well!Table of ContentsPlease note that not all sections are listed, but mainly the most important headers are.Why DucklingScriptLanguage BasicsInstallationDucklingScript: Crash CourseProject CreationSimple CommandsCommand GroupingDollar Sign OperatorBlock CommandsVariables and FunctionsFlow ControlIf StatementsFor LoopsWhile LoopsMulti-File ProjectsDebugging CommandsExpression EvaluationCommand Line InterfaceCommandsNewCompileHelpAllVersionGlobal ConfigContributingFuture PlansWhy DucklingScript?There are many key points to using DucklingScript. Here are some of those now.Type SafetyBecause DucklingScript has to go through a compilation process, it means DucklingScript can validate your script will work on your hardware. It will tell you that there is an error, and it will tell you exactly where. For example, CTRL requires one character. DucklingScript will validate that this is true.Flow ControlRubber Ducky Scripting Language 1.0 and even the Flipper's implementation don't add any kind of flow control. e.g. if statements, while/for loops, etc. DucklingScript gives you those capabilities, and more!Syntactical SpeedNormal Rubber Ducky Scripting 1.0 doesn't give much room for speed, and oftentimes leads you to repeating yourself in code. Not only does DucklingScript add commands to improve this, it also makes small syntactical changes. Such as:Rubber Ducky 1.0STRINGLN Hello,
STRINGLN world,
STRINGLN it is I!DucklingScriptSTRINGLN 
    Hello,
    world,
    it is I!Forward CompatibilityIf you use a command that does not exist in Rubber Ducky 1.0, DucklingScript will simply warn you that this is the case (these warnings can even be supressed using a flag on compilation, or editing the config file). However, it does not stop you from doing so. This allows you to use future commands!Language BasicsFirst off, DucklingScript allows for all syntax ofRubber Ducky Scripting Language 1.0, as well as theFlipper Zero's BadUsb ducky extension.⚠️ Note For Flipper Compatibility ⚠️If you are not using a device that can parse flipper commands, then you cannot use them. Please make sure to disable flipper commands if this is the case through the config file.InstallationDucklingScript has been test on:Windows 11MacOS VenturaUbuntu Jammy (Linux)Step OneMake sure to have Python 3.11 or higher installed.There are many places on the internet that will
explain how to download Python, but if
you are on Windows, I recommend goinghere.From here, you can either use pipx or pip to
install DucklingScript; I highly recommend
using pipx, because it handles putting the
scripts onPATHfor you.With pipx (recommended)Step TwoInstall Pipx:python3.11-mpipinstallpipx
python3.11-mpipxensurepath⚠️It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.This command should run flawlessly:pipx--versionStep ThreeTo install on any of the major operating systems, simply run:pipxinstallducklingscriptStep FourYou now have a few options on how to run the command. This way works in most circumstances:duckling--helpWithout pipxStep TwoTo install on any of the major operating systems, simply run:pip3.11installducklingscript⚠️It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.Step ThreeYou now have a few options on how to run the command. This way works in most circumstances:duckling--helpHowever, if the script is not put onPATH, then it might be best to do it this way:pip-mducklingscript--helpDucklingScript: "Crash Course"First, make sure to check theLanguage Basics, and look through the documentation there to learn Rubber Ducky 1.0 and the Flipper commands.Project CreationTo create a new project, you can use thenewcommand. Simply give the name for your project, and optionally a directory:ducklingnewexample-proj⚠️You don't have to make a project; you can simply make a txt file and compile it if you wishAfter making the project, go into the folder and you will see aconfig.yamland amain.txt.
Any time your run the project, any of your global config settings will be overrided by the config inside the project.To compile your project, simply run this command in the terminal while in your project:ducklingcompilemain.txtWhen compiling any file in the root directory of your project, the config file will automatically be used.DucklingScript files use the.txtfile extension. This will be important for when we import external files later.Simple CommandsSimple commands can be characterized by a command that is a command and no argument, or a command with arguments, and no trailing code blocks. All Rubber Ducky 1.0 and Flipper Commands are Simple Commands.However, in DucklingScript they have extended syntax.Command GroupingUsing indentation, you don't have to repeat yourself. You can simply make an indentation after the command, and write all arguments for the command. This may seem a bit confusing, so here's an example:DucklingScriptSTRING 
    Hello World!
    I enjoy DucklingScript!Compiles into:STRINGHelloWorld!
STRINGIenjoyDucklingScript!This is a powerful feature, allowing you to type out everything you need all at once, instead of repeatedly typingSTRING.However, if you start using indents inside of those indents, you might encounter an error. You may need these extra indents if you are for example having your injection device write code. In that case, simply use three quotation marks like so:STRINGLN
    """
    print("Starting Hacking Software...")
    for i in range(10):
        print(f"Hacking your pc in {i} second(s)")
        if i < 4:
            print("This is your final warning!")
    """Dollar Sign OperatorAll simple commands that don't alreadyevaluatetheir arguments can use the dollar sign operator. This turns the argument into an expression that will evaluated.This allows you to write mathematical expressions, or use variables; you can read more of thathere.⚠️When using the dollar sign operator, all strings are required to be incased in quotations like this:"Hello World"ExamplesDucklingScript:$CTRL 1+1Compiled:CTRL2DucklingScript:$STRING "Hello " + "world!"Compiled:STRINGHelloworld!This becomes more relevant and more important when we introduce variables.Block CommandsAll Block commands will be commands that require an argument, and then a code block after. As of writing, all block commands are added by DucklingScript.ExamplesDucklingScriptREM Command with arg
REPEAT 10
    REM Command's code block
    STRING foo
    STRING bar*More info onREPEAThere.Variables and FunctionsVariablesA variable can be understood as a sort of "drawer" that has a label, and contains some form of data of a specific type (either a string, number, or a boolean). Read more about data types and expression evaluationhere.VAR counter 0
REM a variable named "counter" now equals 0VAR switch TRUE
REM a variable named "switch" is now TRUE
REM (Make sure that TRUE is in all caps)FunctionsFunctions allow you to run the same piece of code as many times as you want, where ever you want, plus the ability to control the variables inside.To make a function, use the command named eitherFUNCorFUNCTION. After that, give the name, then following the name include all variable names separated by a comma.To run a function, use theRUNcommand, followed by the name of the function to run, and then the value for all variables separated by comma in order as they were declared on function creation.DucklingScriptFUNC hello
    STRING Hello World!

RUN hello
STRING In the middle
RUN helloCompiledSTRING Hello World!
STRING In the middle
STRING Hello World!DucklingScriptFUNC hello phrase,number
    $STRING "The number given was: "+number
    $STRING phrase

RUN hello "Foo/Bar",10CompiledSTRING The number given was: 10
STRING Foo/BarIt is also possible to leave a function early if you wish. Using theRETURNcommand, you can exit a function early.DucklingScriptFUNC hello 
    STRING Hello!
    RETURN
    REM This does not run.
    STRING Goodbye!

RUN helloCompiledSTRING Hello!⚠️The return command can also be used outside of a function to exit out of your program earlyFlow ControlThese are commands that manage how your injection is ran. These are conditionals and loops.Conditional StatementsConditional Statements allow you to run code, only if a certain condition is met. In DucklingScript, we use the commandsIF,ELIF, andELSEto evaluate conditionals.ELIFcan only come after anIF, andELSEcan only come after anELIForIF. If anyIForELIFare true, then all subsequentELIFs andELSEs are ignored. After that, you can create a newIFstatement by using theIFcommand once again.ExamplesDucklingScriptVAR a 10

REM if a is equal to 10
IF a == 10
    REM this code is ran
    STRINGLN Hello World

REM if a is not equal to 10
ELSE 
    STRINGLN Hello World Not Found :/CompiledSTRINGLN Hello WorldDucklingScriptVAR a 10

IF a > 10
    STRING a is greater than 10
ELIF a < 10
    STRING a is less than 10
ELSE
    STRING a is 10CompiledSTRING a is 10For LoopsRubber Ducky 1.0 actually includes a sort of "for" loop already. To do this, writeREPEAT(DucklingScript also acceptsFOR, and it does the same things) directly after the command you want to repeat.Please note that although possible in DucklingScript, DucklingScript does not support the ability to check if you have compiled code BEFORE the repeat statement, and therefore cannot fix any syntax issues in doing so.⚠️Please note that there is a limit to for loops; for loops will eventually error if they run too many times. This can be avoided however by using inner for loops, but that is not recommended.DucklingScript/Rubber Ducky 1.0STRINGLN Hello World!
REPEAT 4End ResultSTRINGLN Hello World!
STRINGLN Hello World!
STRINGLN Hello World!
STRINGLN Hello World!This is great, but unfortunately this will only work for one line of code. DucklingScript resolves this by including added syntax using indentation!DucklingScriptREPEAT 3
    STRING Not only can I repeat...
    STRING ...but so can I!CompiledSTRING Not only can I repeat...
STRING ...but so can I!
STRING Not only can I repeat...
STRING ...but so can I!
STRING Not only can I repeat...
STRING ...but so can I!Not only that, but DucklingScript also includes the ability to count the amount of repeats that have occurred in a variable!Please note that the first iteration is considered to be0.The syntax for this is:<variable name>, <iteration count>.DucklingScriptREPEAT i,3
    $STRING "this is iteration number "+i+"!"CompiledSTRING this is iteration number 0!
STRING this is iteration number 1!
STRING this is iteration number 2!While LoopsWhile loops are loops that continue to loop whilst a condition is true.⚠️Please note that there is a limit to while loops; while loops will eventually error if they run too many times.DucklingScriptVAR a 10
WHILE a!=15
    VAR a a+1
    $STRING aCompiledSTRING 11
STRING 12
STRING 13
STRING 14
STRING 15DucklingScriptVAR a ""
WHILE a!="eee":
    VAR a a+"e"
    $STRING aCompiledSTRING e
STRING ee
STRING eeeJust like the for loop, the while loop also allows you to implement a variable that stores the number of iterations completed.DucklingScriptVAR a ""
WHILE count,a!="eee"
    VAR a a+"e"
    $STRING a + " [iteration: "+count+"]"CompiledSTRING e [iteration: 0]
STRING ee [iteration: 1]
STRING eee [iteration: 2]Loop ControlsDucklingScript offers to additional commands to assist with loop usage. These two commands help extend the usage of both kinds of loops.BREAKLOOPBREAKLOOP/BREAK_LOOPallows you tobreak outof a loop. This is especially useful if under a certain circumstance you need to leave a loop early.DucklingScriptREPEAT i,10
    $STRING "iteration "+i
    IF i==2
        BREAKLOOPCompiledSTRING iteration 0
STRING iteration 1
STRING iteration 2As you can see, we left the while loop early becauseiwas equal to two.CONTINUELOOPCONTINUELOOP/CONTINUE_LOOP/CONTINUEallows you tocontinuethrough the loop.DucklingScriptREPEAT i,5
    IF i==3
        CONTINUELOOP
    $STRING "I like the number "+i+"!"CompiledSTRING I like the number 0!
STRING I like the number 1!
STRING I like the number 2!
STRING I like the number 4!As you can see, the number 3 is missing from the compiled, becauseCONTINUEcontinued the loop, ignoring the resulting code after it.Multi-File ProjectsDuckingScript supports multi-file projects using theSTART,STARTENV,STARTCODEcommands.AllSTARTcommands start with the same general syntax, and they allow you to compile the code from another file into the output file. For this to work however, make sure to use the.txtextension on all files.To start another file, simply use theSTARTcommand, and for the argument put the file name. As long as both files are in the same folder, this will work flawlessly.File StructureProject
|-main.txt
|-startme.txtDucklingScript - startme.txtSTRING "startme" says hello!DucklingScript - main.txtSTART startme
STRING ran startme file.CompiledSTRING "startme" says hello!
STRING ran startme file.This is great and all, but would if you want to access a file that is inside a folder? Or maybe the file is one level up. In this case comes the dot operator. To go inside a folder, give the name of the folder, then put a dot after. After that dot put the name of the file.Similarly, if you want to go a level up, put a dot at the very beginning of the argument.File StructureProject
|-above.txt
|-middle
  |-main.txt
  |-below
    |-below.txtDucklingScript - above.txtSTRING Hello from above!DucklingScript - below.txtSTRING Hello from below!DucklingScript - main.txtREM Using the dot operator at the beginning, we can go up a folder
REM Using the dot operator in the middle allows use to go into a folder
START
    .above
    below.belowCompiledSTRING Hello from above!
STRING Hello from below!Debugging CommandsBecause DucklingScript ramps up the complexity of your programs, discovering exactly what is happening might become difficult. This is why DucklingScript adds more commands for debugging!First isPRINT, which allows you to send text to the console when you ocmpile your injection.DucklingScriptPRINT Hello World!Console output--> Captured STD:OUT
example.txt - 1 > Hello World!
---The next one isNOTEXIST/NOT_EXIST, which allows you to raise an error if the given variable exists.DucklingScriptVAR a "hello world"
NOTEXIST aConsole Output---
In file 'X:\test.txt', on line 2
> NOTEXIST a
GeneralError: 'a' does exist.
---The next up is the opposite ofNOTEXIST, which isEXIST. This raises an error if the given variable doesn't exist.DucklingScriptEXIST aConsole Output---
In file 'X:\test.txt', on line 1
> EXIST a
GeneralError: 'a' does not exist.
---Finally, we havePASS, which allows you to fill in the block space for a block command without actually doing anything. Although a comment works too,PASSis cleaner, and allows you to find what hasn't been completed yet in a language specific way.DucklingScriptFUNC a
    PASSExpression EvaluationDucklingScript allows mathematical/logical/conditional expressions. Assuming you already have a basic understanding of 'normal' programming, you should understandmostof this already.Data TypesA string is a data type containing characters. It must be wrapped in quotation marks."Hello World"A number is a data type containing, well, a number100A boolean is either a TRUE or FALSE value. When using these keywords in DucklingScript, make sure to keep them as all caps.TRUE
FALSEMathematicsDucklingScript will follow the rules of PEMDAS (please note that addition/subtraction, and multiplication/division are evaluated left to right. However, multiplation/division is evaluated before addition/subtraction).Please note floor division and modulus share the same precedence as multiplication/division.Here are all of the operators that DucklingScript accepts:Exponents:10^2Result is 100Addition/subtraction5+5
5-5Result is 10, and 0Multiplication/division5*5
5/5Result is 25, and 1Floor Division3//2Result is 1 (the decimal is essentially truncated, meaning removed)Modulus5%2Result is 1 (when dividing 5 by 2, there is a remainder of 1)As well as these,strings can also be added together, and can even be added together with other data types:"Hello, I like the number "+5Result isHello, I like the number 5ConditionalsConditional operators produce a true/false statement (a boolean). Conditionals are evaluated after all mathematical statements, and all Conditionals have the same precedence, meaning they are evaluated left to right.Equal to5==2
10==10Results areFALSE, andTRUENot equal to5!=2
10!=10Results areTRUE, andFALSEGreater than5>2
10>10Results areTRUE, andFALSELesser than5<2
10<10Both result inFALSEGreater than or equal to5>=2
10>=10Both result inTRUELesser than or equal to5<=2
10<=10Results areFALSE, andTRUENot!(FALSE)
!(5!=2)
!TRUEThe results areTRUE,FALSE, and anerror⚠️Unlike other programming languages, in DucklingScript theNOToperator requires parenthesisCommand Line Interface (CLI)The command line interface is used to compile your code, and help assist you on your programming endeavors.When you need help on using the CLI, you can use--help:duckling--helpYou can also use--helpon specific commands:ducklingcompile--helpCLI CommandsNewCreates a new project. This project will include a config file, and a main file.Command:duckling new [OPTIONS] NAME [PATH]Example:duckling new example-projOutput Treeexample-proj
|- config.yaml
|- main.txtCompileThecompilecommand compiles your DucklingScript code into Rubber Ducky Language 1.0. Give the file to compile, and then give the output location.Usage:Usage: duckling compile [OPTIONS] FILENAME [OUTPUT]Options given to you through the command can also be adjusted through global config files.HelpThehelpcommand gives you details on any command you give it.Usage:duckling help [OPTIONS] COMMAND_NAMEOutput if we give itstring:duckling help stringAllTheallcommand gives all the commands in the programming language. In the future, this may include allplug-incommands as well.All commands as of November 28th, 2023:VersionGives the current version of DucklingScript.Command:duckling versionOutput as of November 28th, 2023:Ducklingscript is version 0.1.0Global Config FileUpon using the CLI in anyway, a global config is made/edited. The keys inside of the
global config should be identical to the keys that you find inside of the project
scoped config file. By editing the global config, you can change configurations for
any time you compile a project-less script.ContributingPython versin must be 3.11 or higher. From then on, I recommend
putting the python version at the end of any command involvingpythonorpip, like so:python3.11--version
pip3.11--versionBy doing this, you avoid mixing python versions.Installing PoetryThen, you will need to installpoetry. You can either
use the docs given, or you can follow the steps below.I recommend using pipx, however poetry offers many options. Find the pipx documentationhere.These steps should work on Windows.However, pipx recommends usingbrewto install
pipx on MacOS.python3.11-mpipinstallpipx
python3.11-mpipxensurepathRestart your terminal, then run:pipxinstallpoetry
poetry--versionPoetry should now work as a command.With Poetry InstalledWith poetry installed, inside of the directory
of the project, run these commands:poetryinstall
poetryshellThis will install the necessary dependencies, and take you
into the virtual environment for the project.Now, while in the virtual environment, you can run theducklingcommand!duckling--versionContribution RequirementsBefore making a pull request, please format your project
using the black command (while in the virtual environment
provided by poetry of course):Run this at the root of the project dir:black.As well as this, make sure all tests succeed:pytestIf you've read through this section throughly, write
"I've read the Contribution Requirements" in your
pull request.Future PlansDucklingScript is still not fully complete, so naturally of course there are still plans in the works.Here are the main ones:Add Plugin Support.This will allow users to use plugins made by the community; these could include macros (such as open powershell), or possibly new functionality (like a block command).Add Built-in Flipper-Connect System.This would allow a developer to compile their code directly onto the flipper, which cuts out the need to use a software such as qFlipper.Live Python Interpretation.This would run your code directly on your computer, and skip the process of compiling to Rubber Ducky Language 1.0.