All required files for the C++/WASM module are located in the include folder.
Copy this folder to a known location of your choice.

Security Note: Make sure you're using the latest include/ files for enhanced security features. See the WASM Build & Security guide for important security improvements.


How It Works

Your C++/WASM code must pass a few parameters to the L3S DRM module.
This includes a DrmSucessEvent() callback function.

Only when this function is called should you allow usage of your aircraft.
How you implement this is up to you.


Setting Up Visual Studio

The DRM Module is compiled as a static .wasm module in DRMCore2.a.
You need to link this file and reference the header files in Visual Studio:

  1. Right-click the project containing the DRM integration → Properties

  2. Ensure ConfigurationAll Configurations is selected.

  3. Navigate to:

    • Configuration PropertiesVC++ Directories

      • Include Directories: Add the path to the include folder.
    • LinkerGeneral

      • Additional Library Directories: Add the path to the include folder.
    • LinkerInput

      • Additional Dependencies: Add DRMCore2.a

Click OK to apply.


Initializing DRM

At the top of your .cpp file:

#include "DRMCommon.h"
#include "DRMPublish.h"
#include "obfusheader.h"  // For string obfuscation

static DRMPublish* drmPublish;

Security Enhancement: Use the OBF(...) macro to obfuscate sensitive strings. See the WASM Build & Security guide for details.

Callback Functions

Define the following DRM event handlers:

void DrmSucessEvent(DRMSuccessResponse& response)
{
    // Called only when activation is successful.
    std::cout << "DRM Success";
}

void DrmFailEvent(DRMFailResponse& response)
{
    // Called when an error occurs during activation.
    std::cerr << "DRM FAIL";
}

void DrmTamperEvent()
{
    // Called when DRM tampering is highly likely.
    // It's recommended to immediately terminate MSFS or disable the aircraft.
    std::cerr << "DRM Tamper";
}

DRM Initialization

In your _init function, initialize the DRM as follows:

DRMInputConstants

Holds static information (see DRMCommon.h for more):

DRMInputConstants drmConstants(
    OBF("https://DUMMY_SERVER.COM/functions/v1/auth2"), // Activation URL, differs for Marketplace/Xbox and direct sales
    "DRM Demo",                // Product name
    "^[A-Za-z0-9]{10}$",       // Key regex
    OBF(".\SimObjects\Airplanes\MyCompany_CommBus_Aircraft\panel\SampleCommBus.wasm"), // WASM path
    DrmSucessEvent,
    DrmErrorEvent,
    DrmTamperEvent,
    false // Keyless (true = Marketplace/Xbox, false = Direct Sale)
);

DRMHashVerification

Used to verify the integrity of specific aircraft files.
It's recommended to verify ModuleDrmGauge.html/.js and panel.cfg.

Adding File Hashes for Verification (Optional but Highly Recommended):

To ensure the integrity of your aircraft files, you can add their hashes for verification. Here's how to obtain the correct hash values:

  1. Initially, set a placeholder hash value (e.g., "1") in your code for the file you want to verify.
  2. Enable DEBUG MODE (see the "Debug Mode" section below for instructions).
  3. Load your aircraft in Microsoft Flight Simulator
  4. Try activating the aircraft. Without the correct hashes set, you will get an error EFH01.
  5. Open the MSFS console, search for "[DRM]". The correct hash for the file will be displayed there.
  6. Update the placeholder hash in your code with this correct hash.
  7. Remember to disable DEBUG MODE once you have the correct hashes.

Important Note: At the moment, if you modify a file after obtaining its hash, you will need to repeat this process to get the new hash. We are working on a more streamlined solution for this.

You should verify, at a minimum, your primary HTML, JavaScript (e.g., ModuleDrmGauge.html, ModuleDrmGauge.js), and panel.cfg files.

Hashes are shown in the MSFS Console when debug mode is enabled. See below how to activate debug mode

DRMHashVerification ModuleDrmGaugeHtml(".\html_ui\Pages\VCockpit\Instruments\MyCompany_CommBus_Aircraft_HtmlGauge\ModuleDrmGauge.html", "hash1");
DRMHashVerification ModuleDrmGaugeJs(".\html_ui\Pages\VCockpit\Instruments\MyCompany_CommBus_Aircraft_HtmlGauge\ModuleDrmGauge.js", "hash2");
DRMHashVerification ModuleDrmGaugePanel(".\SimObjects\Airplanes\MyCompany_Wasm_Aircraft\common\panel\panel.cfg", "hash3");

std::vector<DRMHashVerification> hashesVector = {
    ModuleDrmGaugeHtml,
    ModuleDrmGaugeJs,
    ModuleDrmGaugePanel
};

DRMInputVariables

Contains version-specific variables (see DRMCommon.h): For testing, you can also pass an empty hashesVector. Not recommended for production.

DRMInputVariables drmVariables(
    "CLIENT_API_KEY_FROM_WEBSITE",  // client_api_key
    "0.1.2 BETA",         // productVersion. (optional) Only used in UI
    hashesVector
);

Debug Mode

When enabled, debug mode prints file hashes in the console if mismatched.

Do NOT enable in public releases!

#ifdef _DEBUG
    drmVariables.Debug = true;
#endif

Create drmPublish Object

Instantiate the DRM system:

if (!drmPublish)
{
    drmPublish = new DRMPublish(drmConstants, drmVariables);
}

DRM validation will begin automatically. Wait for DrmSucessEvent() before unlocking aircraft features.


IntervalUpdate()

This method should be called from your _system_update or _gauge_callback function:

dTime is the time since the last call in milliseconds.
dTime is currently unused, so you can pass 0 if you don't have a timer in your gauge.

if (drmPublish)
{
    drmPublish->IntervalUpdate(dTime);
}

This function must be called regularly.
It's very lightweight and won't affect performance.