Skip to content

Write your own armaOS application

y0014984 edited this page Jul 25, 2023 · 19 revisions

Creating your armaOS application

If you add a file to a computer via the addFile module, you will be able to flag that file as code. Now you can set the file input to something like this. This example takes a user text input and uses the Arma 3 hint command to display a notification with that custom text.

You can stop every running, active program or command by pressing CTRL+C

params["_computer", "_options", "_commandName"];
[_computer, "input: "] call AE3_armaos_fnc_shell_stdout;
output = [_computer] call AE3_armaos_fnc_shell_stdin; hint output;

Eden Editor showing addFile module with code example

In Arma you can execute the file like in this screenshot.

armaOS stdin and stdout example

Adding a parser of options and arguments (getOpts)

Using of the armaOS options and arguments parser, called getOpts, it completely optional. You can always parse the options and arguments by yourself. The _options of your command function is an array of strings containing all options and arguments and anything else. It is created via _commandString splitString " ". The first element is always the command name itself and is stored in _commandName. The rest is stored in the _options array of strings.

Defining options

First of all you need to define an settings array for the allowed options, See example. Each inner array defines one option.

index config value description required
0 var name this is the name of the returned variable that stores the value, should start with _ for private variables yes
1 short the short option, like l, only single characters are allowed; can be set to "" if only long option is used; don't put - at the beginning yes
2 long the long option, like long, only multiple characters are allowed; can be set to "" if only short option is used; don't put -- at the beginning yes
3 type see list below yes
4 default should be set to something, if the opt/arg is not required, so it can be initialized with default value; otherwise set to ""
5 required true or false yes
6 help a string describing the opt/arg; used for help yes
7 allowed values mandatory only if a select-type is used, like stringSelect or numberSelect no

Types

opt/arg type description
bool if set then it's true else it's false
string everything after the = sign as string
number everything after the = converted to a number with parseNumber
stringSelect like "string" but needs to be out of predefined list, see index 7 of opt/arg config
numberSelect like "number" but needs to be out of predefined list, see index 7 of opt/arg config
file like "string", only for organizational purposes
folder like "string", only for organizational purposes
fileExist like "string", but also checked if this file exists (no check if it's file or folder)
fileNonExist like "string", but also checked if this file does not exists (no check if it's file or folder)
folderExist like "string", but also checked if this folder exists (no check if it's file or folder)
folderNonExist like "string", but also checked if this folder exists (no check if it's file or folder)

Example

private _commandOpts =
[
   ["_longOutput", "l", "long", "bool", false, false, "prints long output format, containing permissions and owner"],
   ["_humanReadable", "h", "human-readable", "bool", false, false, "converts bytes into kbytes, Mbytes and so on"],
   ["_width", "w", "width", "number", 5, false, "sets the width of ..."],
   ["_comment", "c", "comment", "string", "", false, "prints things you want to say"],
   ["_mode", "m", "mode", "stringSelect", "", true, "sets the mode", ["encode", "decode"]],
   ["_algorithm", "a", "algorithm", "stringSelect", "", true, "sets the algorithm", ["caesar"]],
   ["_delay", "", "delay", "numberSelect", "1", false, "sets the delay in seconds", [1, 3, 5]],
   ["_experimental1", "x", "", "bool", false, false, "example for an option with only short version"],
   ["_experimental2", "", "exp", "bool", false, false, "example for an option with only long version"],
   ["_file1", "", "file1", "file", "/var/obj1", false, "sets a file"],
   ["_folder1", "", "folder1", "folder", "/var/", false, "sets a folder"],
   ["_inFile", "i", "input", "fileExist", "", true, "sets the input file"],
   ["_outFile", "o", "output", "fileNonExist", "", true, "sets the output file"],
   ["_inFolder", "s", "source", "folderExist", "", true, "sets the source folder"],
   ["_outFolder", "d", "destination", "folderNonExist", "", true, "sets the destination folder"]
];

Defining Syntax

Next you need to define the syntax. The syntax is checked and used to display the allowed syntax variants when using the -h/--help option. Syntax is also defined in an array containing syntax variants. Each syntax variant contains the following elements:

  1. "command" (mandatory) : the command itself; simply use the settings from the example; there is no need to modify that
  2. "options" (optional) : if set, the syntax shows that there are options available to use
  3. "anything" (optional) : if set, this syntax element stands for something else, that is needed, like a string, filepath, ip address etc. You can have multiple of these

The third element is the "required" flag: If you set the "required" flag to false, the element is eclosed in brackets [] to indicate, that it is optional. If set to true, the syntax check expects to find 1 element. The fourth element is the "unlimited" flag: If you set the "unlimited" flag to true, three dots ... will be appended to the element, to indicate, that you can use multiple of these elements in your command. If set to true, the syntax check expects to find 0 or more elements. If "required" is set to true, the syntax check expects 1 or more elements.

Example

private _commandSyntax =
[
   [
      ["command", "test", true, false],
      ["options", "OPTION", false, false],
      ["path", "PATH", true, false]	
   ],
   [
      ["command", "test", true, false],
      ["options", "OPTION", false, false],
      ["path", "PATH1", true, false],
      ["path", "PATH2", true, false]
   ],
   [
      ["command", "test", true, false],
      ["options", "OPTION", false, false],
      ["path", "PATH", true, true]
   ]
];

Parsing options and arguments

Now you only need to combine the command name with the two settings arrays and give these settings to the getOpts function, see example. By processing the results directly via the params command, all needed private variables are initialized. Also there are two additional variables called _ae3OptsSuccess and _ae3OptsThings. _ae3OptsSuccess is true if everything went well while parsing the options and arguments. It becomes false if, for example, a required option is missing. _ae3OptsThings is an array of all elements after the options block. This is what you need to process yourself.

Example

private _commandSettings = [_commandName, _commandOpts, _commandSyntax];

[] params ([_computer, _options, _commandSettings] call AE3_armaos_fnc_shell_getOpts);

if (_ae3OptsSuccess) then
{
   {
      private _somethingString = format ["Something %1: %2", _forEachIndex, _x];
      [_computer, _somethingString] call AE3_armaos_fnc_shell_stdout;
   } forEach _ae3OptsThings;
};

Examples

You will find some useful examples on my Discord in the Channel #ae3-code-examples