Developing OpenSim Addins

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
Line 53: Line 53:
 
             if (cnf == null)
 
             if (cnf == null)
 
                 return;
 
                 return;
 
+
 
             string configDirectory = cnf.GetString("ConfigDirectory", ".");
 
             string configDirectory = cnf.GetString("ConfigDirectory", ".");
 
+
 
             string configFile = Path.Combine(configDirectory, "AddinExample.ini");
 
             string configFile = Path.Combine(configDirectory, "AddinExample.ini");
 
             if (!File.Exists(configFile))
 
             if (!File.Exists(configFile))
 
             {
 
             {
 
                 // We need to copy the one that comes in the package
 
                 // We need to copy the one that comes in the package
 
 
                 if (!Directory.Exists(configDirectory))
 
                 if (!Directory.Exists(configDirectory))
 
                     Directory.CreateDirectory(configDirectory);
 
                     Directory.CreateDirectory(configDirectory);
 
+
 
                 string embeddedConfig = Path.Combine(AssemblyDirectory, "AddinExample.ini");
 
                 string embeddedConfig = Path.Combine(AssemblyDirectory, "AddinExample.ini");
 
                 File.Copy(embeddedConfig, configFile);
 
                 File.Copy(embeddedConfig, configFile);
Line 69: Line 68:
 
                 throw new Exception("AddinExample addin must be configured prior to running");
 
                 throw new Exception("AddinExample addin must be configured prior to running");
 
             }
 
             }
 
+
 
             if (File.Exists(configFile))
 
             if (File.Exists(configFile))
 
             {
 
             {

Revision as of 14:21, 2 January 2015

This page explains how to develop, package and distribute OpenSimulator region module addins. It is written for developers who wish to provide additional functionality beyond what comes in the core distribution of OpenSim. These instructions pertain to region modules that run at the simulators. It is assumed that you are already familiar with the basics of developing region modules.

If you are looking for using and installing 3rd-party addins, please see this other page.

Contents

The Final Package

An addin example can be found at https://github.com/diva/diva-distribution/tree/master/addon-modules/02AddinExample. This is a very simple example that extends the simulator with the capability of presenting a web form to a user asking for first and last name, and storing the form data in a Comma Separated Value (CSV) file. The Web form will be available at http://yoursim/diva/addinexample. The final addin package contains:

  • the region module dll (Diva.AddinExample.dll)
  • an external dll (CsvHelper.dll)
  • an .ini file (AddinExample.ini)
  • an html file (AddinExample.html)

These are all the files we need for OpenSim users to run the addin in their installations.

Addin Directives

As usual, the region module should be annotated as an OpenSim Region Module:

    [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AddinsExampleModule")]
    public class AddinExampleModule : ISharedRegionModule
    {
      ...
    }

Additionally, the assembly that contains the region module should contain the following directives:

[assembly: Addin("Diva.AddinExample", OpenSim.VersionInfo.VersionNumber + ".1")]
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDescription("Example of how to create OpenSim Addins")]
[assembly: AddinAuthor("Diva Canto")]

[assembly: ImportAddinAssembly("CsvHelper.dll")]
[assembly: ImportAddinFile("AddinExample.ini")]
[assembly: ImportAddinFile("AddinExample.html")]

The first directive [assembly: Addin("Diva.AddinExample", OpenSim.VersionInfo.VersionNumber + ".1")] establishes the public name of your addin: this is what users will see. Pay special attention to the version number. While you can use any version number you want, it is strongly advised that you tie your addin's version number with the OpenSim version against which you are compiling your code. The reason for this is simple: .NET is very picky about binary compatibility, therefore you should inform your users about which version of OpenSim this addin is compatible with. The most direct way of passing that information along is to add it to your addin's version number. In this case, we're using the first few digits to denote OpenSim's version number and the last digit to denote this addin's own version. If we were to evolve this addin in between OpenSim releases, that last digit would increase to 2, while the first few digits would remain the same.

The second directive [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] establishes the dependency with the concrete OpenSim dll that this addin extends. All region module addins extend OpenSim.Region.Framework. Again, the version number there should be the current OpenSim version number, because that is the dll that you are compiling your code against.

The third and fourth directives give a description and authorship information for your addin.

The last three directives include additional files in the package. In particular, [assembly: ImportAddinAssembly("CsvHelper.dll")] is very important, and has two purposes: (1) it includes that dll in the package and (2) it informs the user's runtime that when our addin is loaded into memory, that dll should also be loaded.

Configuration

A very important part of the process has to do with configuration of your addin. Rather than forcing users to manually edit their OpenSin.ini files and add the configuration section pertaining to your addin, we encourage the use of modular configurations. In modular configurations, your components are responsible for reading their own configuration files.

Take a look at how this is done in the AddinExample module: https://github.com/diva/diva-distribution/blob/master/addon-modules/02AddinExample/AddinExampleModule.cs

In the Initialise method, before the meat of that method, we call LoadConfiguration(...), which is declared further down. Here it is:

       private void LoadConfiguration(IConfigSource config)
       {
           IConfig cnf = config.Configs["Startup"];
           if (cnf == null)
               return;

           string configDirectory = cnf.GetString("ConfigDirectory", ".");

           string configFile = Path.Combine(configDirectory, "AddinExample.ini");
           if (!File.Exists(configFile))
           {
               // We need to copy the one that comes in the package
               if (!Directory.Exists(configDirectory))
                   Directory.CreateDirectory(configDirectory);

               string embeddedConfig = Path.Combine(AssemblyDirectory, "AddinExample.ini");
               File.Copy(embeddedConfig, configFile);
               m_log.ErrorFormat("[Diva.AddinExample]: PLEASE EDIT {0} BEFORE RUNNING THIS ADDIN", configFile);
               throw new Exception("AddinExample addin must be configured prior to running");
           }

           if (File.Exists(configFile))
           {
               // Merge 
               config.Merge(new IniConfigSource(configFile));
           }
           else
               m_log.WarnFormat("[Diva.AddinExample]: Config file {0} not found", configFile);
       }


Packaging the Addin

Compile your code as usual, and make sure that all the files that are to be included are all in the same directory. In our example, that is ensured by the following directives in prebuild.xml:

 <Files>
   <Match pattern="*.cs" recurse="true"/>
   <Match pattern="*.ini" buildAction="Copy" destination="../../bin/" />
   <Match pattern="*.html" buildAction="Copy" destination="../../bin/" />
   <Match pattern="*.dll" recurse="true" buildAction="Copy" destination="../../bin/" />
 </Files>

According to these directives, all necessary files end up in a bin folder two levels above.

To package the files, we use the mautil command line tool that comes in OpenSim bin.

 $ /path/to/mautil.exe pack bin/Diva.AddinExample.dll

This creates a file called Diva.AddinExample_osversion.1.mpack. This is the addin package that will be distributed and installed at the user's sites.

Distributing Your Addins

In order to make your addins available to others, you need to create your own addin repository and host it in some web server.

To create the repository, create a folder somewhere and place all of your addin packages (.mpack) in it. Then:

 $ /path/to/mautil.exe rep-build /path/to/repo/folder

This will create additional index files with the right entries. All you need to do next is to upload the entire contents of this folder onto a Web server. For example, http://metaverseink.com/repo/ shows the index.html of this repo that shows all available addins.

Finally, you need to let users know about the URL of your repository, so they can add it to their registries and install addins from your repository. You can add your repo here.

Personal tools
General
About This Wiki