# Arma2NET

## Recommended Posts

Arma2NET 2.2

Arma2NET is a wrapper used for communicating between managed code and SQF code used in the game Arma 2, adding significant functionality to SQF scripting.

Arma2NET gives you the ability to use the .NET Framework from Arma 2. It is designed to be an alternative for those who don't want to use C or C++ with callExtension or Java and the JVM.

There is a wide range of language implementations that target the Common Language Runtime, so you can use C#, Python, VB.NET, F#, Ruby code and more, directly from Arma 2.

A list of languages that you can use can be found here.

Features

- Call managed functions and manipulate the return value from SQF.

- Check the status of long-running managed functions from SQF using callbacks.

- Convert SQF literals (lists, strings, numbers etc) to .NET objects and back.

- Extend the functionality of Arma2NET by writing plugins written in any language that compiles to .NET bytecode, such as C#, F# or VB.NET.

Included plugins

- BaseFunctions

- CommandLine (get command line used to start Arma 2)

- DateTime (get system time/UTC time)

More plugins

- IronPython code executor/evaluator. Run .py script files and more from your system.

- IronRuby

Requirements

To use Arma2NET you must be running Arma 2 version 1.62 or later, and .NET Framework 4 Client Profile (Download it from http://www.microsoft.com/download/en/details.aspx?id=24872).

Documentation

Getting started with Arma2NET: https://bitbucket.org/Scott_NZ/arma2net/wiki/Getting_started

Introductory tutorial: https://bitbucket.org/Scott_NZ/arma2net/wiki/Tutorial

Dev-Heaven: https://dev-heaven.net/projects/a2n

Please create a ticket for bugs/features at https://dev-heaven.net/projects/a2n/issues or https://bitbucket.org/Scott_NZ/arma2net/issues

Example

C#:

using Arma2Net.AddInProxy;

namespace MyPlugin
{
{
public string Hello()
{
return "Hello world!";
}
}
}


SQF:

_result = call compile ("Arma2Net.Unmanaged" callExtension "MyPlugin [Hello]");
hint _result;


Changelog

Arma2NET 2.2 (23 Aug 2012):

- Arma2NET will now gracefully handle appdomain errors, adding partial support for .NET 4.5 and Windows 8 as a result.

- Added support for the Mono runtime as an alternative to .NET entirely.

- Improved logging functionality.

Arma2NET 2.1.1 (7 Aug 2012):

- Fixed an issue with Utils.FileVersion and Utils.Version throwing a FileNotFoundException.

- Improved the behaviour of the plugin system, and added a new Reload command.

- Improved the responsiveness of Arma2NET Explorer.

Arma2NET 2.1 (28 Jul 2012):

- Fixed a non-fatal error sometimes caused when retrieving the list of loaded addins.

- Improved the appearance of Arma2NET Explorer, and added a "Run History" feature.

- Improved the log files - addin details are now in a nice table.

- Added XML documentation file for use with IntelliSense, to make addin development easier.

Arma2NET 2.0 (22 Jul 2012):

- Performance boost, including an improvement in startup time.

- Removed sandboxing because people just override it with -arma2netdev anyway, defeating the purpose of having it.

- Plugins can now be updated and reloaded at runtime with the new custom plugin system. This should also work with .NET 4.5 RC.

- Removed scripting system for now because of issues with resolving external references.

- Removed Settings.yaml and files and folders which are no longer needed.

- Fixed culture issues - Format.ObjectAsSqf was not using the invariant culture properly.

- PythonPlugin now targets IronPython 2.7.3, from 2.7.2.

- These are breaking changes - all plugins will need to retarget Arma2NET.

Arma2NET 1.13 (17 Jul 2012):

- Explorer was wrongly displaying an error box when an evaluator result returned null.

- Improved the accessibility of Explorer - added the ability to cycle through the command history using the up/down arrow keys, and the command history is now persistent.

- Format class fixes - fixed some issues with TrySqfAsString.

- Improved stability and crash prevention - Arma2NET will no longer die if Settings.yaml can't be loaded or if NLog.dll.nlog can't be loaded.

Arma2NET 1.12 (11 Jul 2012):

- Some public API changes and design improvements. The old API is now deprecated.

- Added code inclusion support to the scripting system, and environment variables are now expanded in //reference.

- Functions and IsFunction behaviour improved.

- Arma2NET Explorer Evaluator tab now emulates Arma2Net.Unmanaged.dll.

- Arma2NET Explorer Evaluator tab results are now selectable and copyable.

Arma2NET 1.11.1 (26 Jun 2012):

- Fixed issue where script files were being read wrongly.

- Renamed #r directive to //reference so that files can compile normally.

Arma2NET 1.11 (25 Jun 2012):

- Added a scripting system, allowing C# code to be modified at runtime. Errors and warnings are stored in the Arma2NET log.

- Overhauled the Arma2Net.Managed.Expressions namespace.

- Format.SqfAsDouble now uses an invariant culture to improve portability.

Arma2NET 1.10 (6 Jun 2012):

- Settings.yaml is now created by the installer.

- Log configuration file option added to Settings.yaml.

- Arma2NET evaluator added to Arma2NET Explorer, providing the ability to test code without needing to start the game.

- Fixed an issue where Arma2NetMethodAddIn methods with UnformattedResultAttribute were sometimes causing a NullReferenceException.

- "<NULL-object>" from the game is now treated as null by Arma2NET.

- Improved error messages for plugins using Arma2NetMethodAddIn.

Arma2NET 1.9 (21 May 2012):

- New alternative function call syntax, e.g. ["DateTime", ["now", "HH:mm:ss"]]

- Arma2NetMethodAddIn now optionally formats results as SQF.

- New YAML settings file that can be used to configure Arma2NET.

- The list of plugins to automatically activate on Arma2NET startup can now be configured through YAML.

- The Arma2NET plugin whitelist can now be configured through YAML.

- Added the ability to play a beep sound when Arma2NET is activated. This can be configured through YAML.

- Sharpened text in Arma2NetExplorer.

- Dropped installer banner images to reduce file size.

- Improved return result logic further from version 1.8.

- UtilitiesPlugin and WeatherPlugin dropped from Arma2NET and are now auxiliary plugins.

- Dropped FunctionArgumentsInvalidException in favour of the standard .NET exceptions.

- Error messages vastly improved.

Arma2NET 1.8 (9 May 2012):

- Added a utility application which can be used to explore addins.

- New function 'VersionOfAddIn' which will return the version of the specified addin.

- Logging directory moved to AppData/Local/Arma2NET by suggestion.

- Improved PythonPlugin to use the standard library and user-provided .py files. See the wiki for more details.

- Fixed a minor logic error in returning the result back to Arma 2.

- Fixed an issue where SQF arrays inside other SQF arrays weren't being converted properly.

- Fixed an issue where the 'Functions' function wasn't actually returning a list of functions.

Arma2NET 1.7.1 (1 May 2012):

- Fixed bug where all auto-activated plugins were ignoring Developer mode.

Arma2NET 1.7 (30 Apr 2012):

- New function CompareVersion to compare versions, e.g. is version 1.7.0.0 higher than 1.6.0.0?

- Improved the plugin activation/deactivation system, where only one plugin is activated as needed.

- Overhauled SQF/object formatting.

- Fixed a couple of bugs related to sandboxed plugins.

- Internal code and design improvements.

Arma2NET 1.6 (21 Apr 2012):

- Arma2NET consolidated into a single modfolder, improving portability and allowing Arma2NET to be used with Arma 2 1.61 stable. arma2oa.exe.config and arma2oaserver.exe.config removed.

Arma2NET 1.5 (19 Apr 2012):

- Arma2NET log now displays the correct version.

- Arma2NET will now return its version if an empty string is passed to it via callExtension.

- New Bridge.GetDeveloperMode() and Bridge.GetVersion() methods.

- Installer now checks for an installation of the .NET 4 Client Profile before continuing.

- Arma2NetMethodAddIn now throws the correct exception if matching parameters can't be found.

- Added arma2oaserver.exe.config for use with servers.

Arma2NET 1.4 (10 Apr 2012):

- New command-line parameter "-arma2netdev" can be used to disable sandboxing for development purposes.

- Arma2NET Logs are now stored with the main ArmA 2 logs, in the AppData\Local\ArmA 2 OA\Arma2NET Logs folder.

- Improved input checking for DateTimePlugin and WeatherPlugin.

- Internal Arma2NET improvements.

Arma2NET 1.3 (30 Mar 2012):

- Small string formatting changes.

- Finalised the Arma2NET API.

- Plugins can now have code execute when they are deactivated.

- Logs are now archived into a Logs folder after they reach a day old. Logs are stored for 7 days. This behaviour can be changed by editing NLog.config. Some minor logging performance improvements.

Arma2NET 1.2 (14 Mar 2012):

- Added the ability to cancel long-running functions.

- Added the ability to start the CLR without calling an Arma2NET function at the same time, to allow the CLR to be started during mission loading etc.

- Added the ability to reactivate plugins, so missions for example will be able to start cleanly, without interference from the previous mission.

- Added a SQF code/expression generator.

- SQF arrays are now represented as a ReadOnlyCollection rather than a List.

Arma2NET 1.1 (2 Mar 2012):

- Arma2NET now runs foreign/untrusted plugins in a sandboxed environment.

- PythonPlugin now runs all Python code in a sandboxed environment.

- String manipulation functions have been added.

- The plugin-writing API has been simplified.

Arma2NET 1.0 (18 Feb 2012):

- Initial release

Edited by Scott_NZ
Version 2.2

##### Share on other sites

Awesome, thanks a bunch!

##### Share on other sites

Interesting! So could this be used to do something like have a dedicated map interface, or integrate with working gauges in the vehicles (like Flight Sim)?

##### Share on other sites

This sounds really interesting. Pity I just tinker with code instead of writing fresh stuff !

Hopefully all you coding gurus can use it.

##### Share on other sites

Excellent effort, presentation and iniatitive Scott :bounce3:

Hopefully some skilled coders will jump onto the bandwagon. :)

##### Share on other sites

very nice, thanks for sharing it with us

##### Share on other sites

BRAVO Scott!! BRAVO!!

##### Share on other sites
Interesting! So could this be used to do something like have a dedicated map interface, or integrate with working gauges in the vehicles (like Flight Sim)?

Yeah, you could create an Arma2NET plugin with a GUI and a map of the terrain on a second monitor using WPF. Arma 2 would simply call the plugin's function with the map data and the data would be plotted on the second monitor.

##### Share on other sites

Could this be used to interface with Thrustmaster Cougar MFD's? That would be really sweet. Then I could finally use this old second monitor!

##### Share on other sites

If the MFDs have an interface an Arma2NET plugin could connect to, it could marshal data back and forth between Arma 2 and the MFDs. Arma2NET/callExtension are very powerful but are hindered by the fact you can only send/receive text data at the moment. That said, I haven't tried anything of this nature yet so the only real way to know is to try it...

##### Share on other sites
Python (dynamically execute Python code)

verry intresting.

this looks like something i will have a look at :D

good job..

##### Share on other sites
Arma2NET/callExtension are very powerful but are hindered by the fact you can only send/receive text data at the moment.

Perhaps XML would be the way to go? :D

I actually started writing an XML reader/writer in SQF a while back. You can get the current version (+ example code in mission format) here, though only the XML writer currently works. I never got around to writing the reader, as it was only a fun project anyway.

(Note that I've comitted at least one "no no" in my code by creating local logics with createVehicleLocal. My bad.)

At least in the few tests I ran this generates valid XML, though I guess outputting certain characters that need to be escaped in XML (&, <, > etc.) would screw it up. Easily fixable though.

##### Share on other sites

What about JSON as opposed to XML. Seems to use less bytes for the same data, and is suitable for serialization/deserialization when machines and software need to speak to eachother.

While YAML would be my preferred markup language if humans need to be involved in reading/editing the data, better readable, and easier to write again than XML.

##### Share on other sites

I've been thinking about different ways to send/receive data, currently it sends data back (if Format.ObjectAsSqf is called) in a SQF-like fashion, e.g. [] for arrays, "" for strings etc, to be used with the call/compile SQF functions. So you're currently able to do things like:

call compile format ["brisbaneWeather = %1;", "Arma2Net.Unmanaged" callExtension "Brisbane, Australia"];

and get back a SQF array describing the weather. YAML or JSON (already using JSON in the SydneyWeather plugin, could use that as a starting point or something) seem like the best choices for more complex data but we'd need an addon to make sense of the data. Unfortunately I'm not all that experienced with SQF :P

##### Share on other sites

Wow this looks amazing, gonna have to read some of the documentation you have provided.

Great work!

##### Share on other sites

The one real advantage this can have over plain callextension dlls, is if the code it loads doesn't have to be trusted. (Then you just have to trust the loader.) Is this something it actually does?

Well, plus there's less chance for a (noob :P ) programmer to fail at lowlevel issues.

I made a lua extension myself, and it works great. There are security issues to deal with though, which kinda keeps it from being useful as anything more than alternate syntax (and probably faster processing) - since extensions are all client side.

Edited by MaHuJa_

##### Share on other sites

Arma2NET uses MEF (Managed Extensibility Framework) to load plugins. Currently it will load all plugins, regardless of what they do. I've been thinking about introducing sandboxing for the next version, to make plugins run with "Internet" trust or something.

##### Share on other sites

Release frontpaged on the Armaholic homepage.

##### Share on other sites

I have been working on object formatting over the past few days and have committed the following additions. These additions should make it into the next release of Arma2NET unless there's something really broken etc.

The new Format.SqfAsObject<TResult, TException> method automatically throws a TException if the result was not convertible to TResult.

So previously you had to write the following:

public string Run(string args)
{
string blah = Format.SqfAsObject(args) as string;
if (blah != null)
{
use blah, return from method
}
throw new FunctionArgumentsInvalidException();
}


Now all you need is:

public string Run(string args)
{
string blah = Format.SqfAsObject<string, FunctionArgumentsInvalidException>(args);
use blah, return from method
}


Unhappy with the current Format.SqfAsObject method with its low level of verbosity (everything is either a string or a list until you parse it yourself using int.Parse etc), I have added a SyntaxVerbosity overload. Format.SqfAsObject as it is currently will trip up with commas used in arguments because commas are used to separate arguments. This limitation can be overcome by specifying SyntaxVerbosity.Verbose. SyntaxVerbosity.Simple will use the simpler syntax which is the default. By specifying Verbose, strings are required to be quoted by using ' or "". Verbose also parses numbers and booleans from SQF etc into their respective types.

The above code then becomes:

string blah = Format.SqfAsObject<string, FunctionArgumentsInvalidException>(args, SyntaxVerbosity.Verbose);

Using the new addition with some new Str functions I've also committed:

hint ("Arma2Net.Unmanaged" callExtension "Str ['split', 'hello,world', [',']]")

Hints ["hello", "world"] to the player

hint ("Arma2Net.Unmanaged" callExtension "Str ['replace', 'hello world', 'hello', 'goodbye']")

Hints "goodbye world" to the player

Using the Dict function which provides hashtable functionality:

_blah = ("Arma2Net.Unmanaged" callExtension "Dict ['add', 'The answer to life, the universe, and everything', 42]");
hint ("Arma2Net.Unmanaged" callExtension "Dict ['get', 'The answer to life, the universe, and everything']");


Hints 42 to the player

##### Share on other sites

Arma2NET has been updated to version 1.1 with the following changes:

- Arma2NET now runs foreign/untrusted plugins in a sandboxed environment.

- PythonPlugin now runs all Python code in a sandboxed environment.

- String manipulation functions have been added.

- The plugin-writing API has been simplified.

- Arma2NET will now verify plugins when they are loaded and will run them in sandboxed environment if needed. Recognised plugins will run with full trust. Unrecognised/unsigned plugins will run in a sandboxed environment. The PythonPlugin will also run all Python code in a sandbox. "ExecPythonString open('C:/blah.txt')" will throw a System.Security.SecurityException.

Verification involves comparing the public key token of the assembly with Arma2NET's public key token, and also checking whether the assembly has been modified since it was signed. Users wishing to compile Arma2NET will need to generate their own key file, which can be done using Visual Studio or sn.exe (Strong Name Tool).

Unfortunately the whole security thing has required me to switch frameworks and therefore plugins/existing code has had to be ported over.

- A "Str" function has been added to UtilitiesPlugin, providing string manipulation functionality. Thanks to ThomasSkyldahl for contributing to this area of the project.

hint ("arma2net.unmanaged" callExtension "str ['split', 'Hello-world', ['-']]")

Hints ["Hello", "world"] to the player

hint ("arma2net.unmanaged" callExtension "str ['insert', 'Hello', 2, 'a']")

Hints "Heallo" to the player

A list of subfunctions can be found here: https://bitbucket.org/Scott_NZ/arma2net/wiki/Plugins/UtilitiesPlugin#!utilitiesplugin

If you'd like to do a clean installation, delete the ArmA 2\@Arma2NET and ArmA 2\Expansion\beta\@Arma2NET folders first. Then merge the folder inside the ZIP archive with your ArmA 2 folder.

If you used the installer to install Arma2NET 1.0, it should upgrade your installation to 1.1 if 1.0 is already installed.

##### Share on other sites

Excellent job Scott and team :bounce3:

##### Share on other sites

With a delay, sorry :o

Updated version frontpaged on the Armaholic homepage.

Great work!

##### Share on other sites

I have written up a tutorial for writing/using your own custom plugins which should smooth out the learning curve a bit. https://bitbucket.org/Scott_NZ/arma2net/wiki/Tutorial#!tutorial

##### Share on other sites

Arma2NET has been updated to version 1.2 with the following changes:

- Added the ability to cancel long-running functions.

- Added the ability to start the CLR without calling an Arma2NET function at the same time, to allow the CLR to be started during mission loading etc.

- Added the ability to reactivate plugins, so missions for example will be able to start cleanly, without interference from the previous mission.

- Added a SQF code/expression generator.

- SQF arrays are now represented as a ReadOnlyCollection rather than a List.

These are breaking changes so any plugins written for 1.1 will need a recompile.