# Luarmor User Manual & F.A.Q

{% hint style="success" %}
You can also use this documentation below, maintained by Stefanuk. :arrow\_down\_small:

<https://luarmor.mintlify.app/introduction>

:point\_up:
{% endhint %}

## ✅Quickstart Guide✅

If you just started using Luarmor, you should read this quick start guide. It will take you only 10 minutes to understand how Luarmor works.&#x20;

### 1️⃣ Create an account:

* In order to use Luarmor, you need to create an account. And for that, you need an "invite code". Invite codes can be purchased here --> [**https://luarmor.net#prices** ](<https://luarmor.net#prices >)
* Alternatively, you can use an invite code to extend your membership for +30 extra days here    --> [**https://luarmor.net/profile**](https://luarmor.net/profile)

<div><figure><img src="/files/C5IEUXZjQE20XbXXMZn4" alt=""><figcaption><p>Step 1 - Sign Up at <a href="https://luarmor.net/signup">https://luarmor.net/signup</a></p></figcaption></figure> <figure><img src="/files/CAAlsN6xT3IVGvAqhgjb" alt=""><figcaption><p>Step 2 - Receive your login credential ('API Key')</p></figcaption></figure> <figure><img src="/files/DfLfk4NhgqETbqebE4w2" alt=""><figcaption><p>Step 3 - Log in and access the dashboard at<a href="https://luarmor.net/login"> https://luarmor.net/login</a></p></figcaption></figure></div>

### 2️⃣ Upload your script:

{% hint style="info" %}
Luarmor has a feature called **project folders.** They can contain multiple scripts, allowing you to have a **script hub** with multiple games in it.
{% endhint %}

<div><figure><img src="/files/5kOkixyMOOUhxovidber" alt=""><figcaption><p>Step 4 - Create a project at <a href="https://luarmor.net/projects">https://luarmor.net/projects</a></p></figcaption></figure> <figure><img src="/files/SG9WABt2sT32JonOZXlk" alt=""><figcaption><p>Step 5 - Enter project details</p></figcaption></figure> <figure><img src="/files/wdZCVMD07hFdjO3xDnr3" alt=""><figcaption><p>Step 6 - Upload your script to the project</p></figcaption></figure></div>

<div><figure><img src="/files/PNi5kpAts54Xh0WVRMfT" alt=""><figcaption><p>Step 7 - Enter script details. Detailed descriptions can be found below</p></figcaption></figure> <figure><img src="/files/LFF6NR21leelbiMjQKbq" alt=""><figcaption><p>Step 8 - Download the loader file. Keep in mind that loader does not change, so you don't have to re-download it every time you update your script.</p></figcaption></figure></div>

### 3️⃣ Whitelist users:

<mark style="color:green;">**If you are migrating**</mark> from another whitelist service, or your own, you can easily import your users with 2 clicks. Skip to [**this part**](#mass-whitelist-import-users) for mass whitelisting details.

{% hint style="info" %}
There are **2 ways** to whitelist someone:

* Generate an empty key at [**https://luarmor.net/users**](https://luarmor.net/users) and give it to user. Alternatively, you can mass-generate keys and put them to your sellix / shoppy as "**serials"** for automated purchases.&#x20;

<img src="/files/ZhFXqtRmWP2UxKAQ0cLo" alt="" data-size="original">![Sellix / Shoppy integration](/files/izeWe2FJx2hFNeI86fWP)

* Or run `/whitelist` command via discord bot and user will be able to click on "get script" button on control panel

&#x20;![](/files/oBqRS7rtPepDwASqm2v6)![](/files/Dgh3fXrGEsnDzhtcW0J6)

( Bot invite will be DM'ed upon purchasing a Luarmor invite code. Join our discord server to buy an invite code: [**https://discord.gg/luarmor**](https://discord.gg/luarmor) )

{% endhint %}

Once the user is whitelisted, they can execute the script by adding **`script_key = "KEY HERE";`** on top of the script. Note that keys are **linked to user's HWID** and sharing the key with someone else won't work because they will have a different HWID.&#x20;

<figure><img src="/files/jRv7zuxXlMqCp8VmYgm3" alt=""><figcaption><p>Tada! authenticated in 0.7 seconds ;D</p></figcaption></figure>

<div><figure><img src="/files/tpX7T5KMnh6sp2T3VkHL" alt=""><figcaption><p>You will get this notification to your webhook.</p></figcaption></figure> <figure><img src="/files/o5baHISqOoT3XnqSnP4E" alt=""><figcaption><p>script_key must be added on top of the script (except for FFA mode)</p></figcaption></figure></div>

### 4️⃣ Reset HWID:

In some cases, user's HWID might change on its own, when that happens, they must run **`/resethwid`** via discord bot and re-execute the script. It will automatically assign the new HWID upon execution.

<figure><img src="/files/EPAnVNOXU4QIKVESDquW" alt=""><figcaption><p>You can reset HWID like this. Users can reset their own HWIDs as well if you have the setting enabled.</p></figcaption></figure>

If you think someone might be sharing their key and using **`/resethwid`** for others, simply compare action fingerprint in the resethwid notification

<figure><img src="/files/4THpjZ9PbpzsUgYIScsq" alt=""><figcaption><p>Reset HWID notification action fingerprints. If they're *mostly* similar, it's legit. If they're fully different, there's a high chance that user is sharing his key to someone else and /resethwid'ing on their behalf.</p></figcaption></figure>

## ⚡Runtime Variables⚡

Luarmor has runtime variables that allows you to access to user details such as discord id, total executions, script name, premium, user note etc..

They can be used for a lot of things. Check out this example:

<figure><img src="/files/NczDVDmMuduclaaS6IDR" alt=""><figcaption><p>A script that utilizes runtime assigned variables.</p></figcaption></figure>

{% hint style="success" %}
You can see a full list of runtime variables here:

* **`LRM_IsUserPremium`** : if user is whitelisted or not. useful for FFA scripts, ('freemium')&#x20;
* **`LRM_LinkedDiscordID`** : linked discord id&#x20;
* **`LRM_ScriptName`** : name of the current script.&#x20;
* **`LRM_TotalExecutions`** : total executions of the user. it will be 0 by default.&#x20;
* **`LRM_SecondsLeft`** : seconds left until expiry. it will be math.huge if auth\_expire isn't set&#x20;
* **`LRM_UserNote`** : user note ('Not specified' by default)
* **LRM\_ScriptVersion**    : version of the script. Looks like "0.0.0.3" and is a string.
  {% endhint %}

## ⚙️ Discord Bot Configuration ⚙️

{% hint style="danger" %}
This documentation shows the setup for OLD BOT!. New bot looks different than this. It doesn't require a documentation to use the new bot.
{% endhint %}

You can automate everything using this discord bot. Or you can write your own bot using our [API documentation.](/docs/luarmor-api-documentation.md)&#x20;

If you're a Luarmor buyer, <mark style="color:green;">**discord bot invite will be sent to you via DM**</mark>. After inviting the bot, run **`/login`** command and link the server.

<div><figure><img src="/files/hSYGf2Qsl7akvJwfUgNW" alt=""><figcaption><p>Step 1 - Run /login [api key] command</p></figcaption></figure> <figure><img src="/files/jTBqnsaYinVIGQVpAMZe" alt=""><figcaption><p>Step 2 - Set a manager role. People with manager role can run basic management commands like /whitelist, /force-resethwid</p></figcaption></figure></div>

<div><figure><img src="/files/JWFMK7HzpRdbhqd3xxDi" alt=""><figcaption><p>Step 3 - Select a project. Once you do this, all management commands will be <br>applied to this project. </p></figcaption></figure> <figure><img src="/files/g7M5MZGgZ1TRK0AeOG75" alt=""><figcaption><p>Step 4 - Set a buyer role. This role will be automatically<br>assigned when a manager runs /whitelist [user] <br>or when a user runs /redeem [code] or /getrole</p></figcaption></figure></div>

<div><figure><img src="/files/DxNjN4FXdOm3RcBBdn6w" alt=""><figcaption><p>Step 5 - Set the script to DM to users when they run /script or a manager runs /whitelist</p></figcaption></figure> <figure><img src="/files/me8KjGTsgFiZwn13VIfO" alt=""><figcaption><p>This is what the file should be like.</p></figcaption></figure></div>

## 👑 Mass Whitelist - Import Users 👑

If you already have users with a specific role, you can easily mass whitelist every single one of them with one command.&#x20;

<div><figure><img src="/files/GPEmL6uuRKp4juW0bBfC" alt=""><figcaption><p>Your already existing users</p></figcaption></figure> <figure><img src="/files/vfR8O6BzU0qSTzPikt8A" alt=""><figcaption><p>Command syntax</p></figcaption></figure></div>

<figure><img src="/files/ARDKI1DEezuVyZu0volg" alt=""><figcaption><p>Successfully imported users</p></figcaption></figure>

{% hint style="warning" %}
"Total failed" means their discord IDs are already registered, so in order to avoid duplicated entries, it will skip them.
{% endhint %}

**Alternatively**, you can import them as a JSON file.&#x20;

<div><figure><img src="/files/ccEHpecWwywhP7IXGjRD" alt=""><figcaption><p>Step 1 - Go to <a href="https://luarmor.net/users">https://luarmor.net/users</a> and click on gear icon</p></figcaption></figure> <figure><img src="/files/GQKovcTfJ7RB2cPsImDf" alt=""><figcaption><p>Step 2 - Upload your JSON file and confirm. That's it.</p></figcaption></figure></div>

{% hint style="success" %}
Once users are imported, all they need to do is to click on the "Get Script" button and the bot will respond to them with the script + key appended on top.&#x20;
{% endhint %}

## 📜 LRM\_INIT\_SCRIPT macro

This macro can be used to run a function **before** the obfuscated code. It can be useful for displaying a "Enter a key" GUI or running AC bypasses, or anything that must be executed before authentication.

{% hint style="danger" %}
Function passed into this macro will **not** be obfuscated, and **people can view it** as if it is raw. So don't pass critical code here.
{% endhint %}

**Example usage:**

{% code lineNumbers="true" %}

```lua
LRM_INIT_SCRIPT(function()
		local UI_lib = loadstring(.....)()
	
		local Completed = false;
		local enteredKey;

		UI_lib:AddTab({ 
			Title = "Enter a key", 
			Type = "InputBox", 
			OnClick = function(key) 
				enteredKey = key;
				Completed = true; -- Let it go
			end
		});

		UI_lib:Show()

	-- Pend / Block execution until key is entered.
		while not Completed do wait() end
		script_key = enteredKey

end)
```

{% endcode %}

To display an async key UI, execution must be blocked via a loop at the end of the INIT script otherwise it will continue running and kick the user with a "no key found".

To run a "bypass" or any code that doesn't require async execution, just add your code directly, without having to block the execution.

{% hint style="warning" %}
**LIMITATIONS:**&#x20;

* You can't reference upvalues inside an INIT script, because it will get extracted out of the obfuscated code, and there will be no upvalues there. So assume that it is a completely separate context, and put every helper function / variable inside, which will be used by the init script.
* There can be only **one** init script per script, you can't use this macro **more than once** in a single script.
* Whatever function you pass, must be a constant. Do not pass a variable e.g LRM\_INIT\_SCRIPT(handlerFn)
  {% endhint %}

**This works best when combined with the key check API below**.

## 🔑 Key Check Library

{% hint style="info" %}
In most cases, you don't need to check the key yourself because Luarmor protected scripts already come with the whitelist built inside them, which will kick them if a key is invalid.

But in certain cases where you want to check a key in advance (before whitelist), so the user doesn't get kicked if it is an invalid key, you can use our key checking library.
{% endhint %}

Ideally, you would want to run this library **before** the obfuscated code (luarmor loadstring) runs. So you can implement your custom logic to handle invalid / expired keys by displaying the error message to the user without kicking or crashing the client.

Here's how to import it:

```lua
local api = loadstring(game:HttpGet("https://sdkapi-public.luarmor.net/library.lua"))()
--> Returns a table with methods that you can use.
-- You must initialize it with the script ID first.

-- Put your own script ID Below:
-- You can find it in your loadstring URL or projects tab.
api.script_id = "f42f3746fb3eb60f837d3673581c14a6"

-- make the API request:
local status = api.check_key(script_key or textLabel1.Text); -- pass 32-char user key here
print(status) --> table {code:<string>, message:<string>, data?:<table>}

-- custom logic below:
if (status.code == "KEY_VALID") then

    -- fetch basic info about the key (only if KEY_VALID)
    ui:SetBanner("Welcome. Seconds left: " .. (status.data.auth_expire - os.time()))
    ui:UpdateTitle("Total executions: ", status.data.total_executions)
    
    print("Is key from ad system? " .. status.data.note == "Ad Reward" and "YES" or "NO")
    
    script_key = script_key or textLabel1.Text; -- SET THE KEY BEFORE LOADSTRINGING.
    
    api.load_script(); -- Executes the script, based on the script_id you put above.
    -- Alternatively, you can just put the loadstring you got from luarmor website.
    -- You must specify the script_key global either way.
    return
    
elseif (status.code == "KEY_HWID_LOCKED") then
    ui:Notify("Key linked to a different HWID. Please reset it using our bot")
    return
    
elseif (status.code == "KEY_INCORRECT") then
    ui:Notify("Key is wrong or deleted!")
    return    
else
    -- fallback to anything else e.g blacklisted, key empty/too short:
    player:Kick("Key check failed:" .. status.message .. " Code: " .. status.code)
end

-- You can see a full list of possible status codes and status messages below.
```

### Possible status codes:

| "code" \<string>                                     | "message" \<string>                                                                 | Meaning:                                                                                                                            |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| <mark style="color:green;">KEY\_VALID</mark>         | The provided key is valid.                                                          | Key has no hwid assigned to it (reset state) **or** the assigned hwid matches client's hwid, and the key is not expired.            |
| <mark style="color:yellow;">KEY\_EXPIRED</mark>      | The provided key has expired.                                                       | Key is valid, hwid matches, but it has expired and can not be used.                                                                 |
| <mark style="color:red;">KEY\_BANNED</mark>          | The provided key is blacklisted.                                                    | Key is valid, hwid matches but it is blacklisted and can not be used. Blacklist reason is not exposed to the user via this library. |
| <mark style="color:orange;">KEY\_HWID\_LOCKED</mark> | The provided key has been locked to a different HWID. Reset your HWID to access it. | Key is valid, **hwid does not match** and needs to be reset via bot panel or ad page.                                               |
| <mark style="color:red;">KEY\_INCORRECT</mark>       | The provided key is incorrect / it does not exist.                                  | Key seems valid, but does not exist in the database. Could be deleted, or never generated.                                          |
| <mark style="color:red;">KEY\_INVALID</mark>         | The provided key is in an invalid format.                                           | Key is empty / too long / too short.                                                                                                |
| SCRIPT\_ID\_INCORRECT                                | The provided script ID is incorrect / it does not exist.                            | Script ID does not exist or has been deleted later.                                                                                 |
| SCRIPT\_ID\_INVALID                                  | The provided script ID is in an invalid format.                                     | Script ID is too short / too long / contains non-hexadecimal characters.                                                            |
| INVALID\_EXECUTOR                                    | HWID header contains invalid data. Executor might not be supported.                 | Executor not supported.                                                                                                             |
| SECURITY\_ERROR                                      | Request can not be validated by cloudflare                                          | Signature does not match.                                                                                                           |
| TIME\_ERROR                                          | Client time is invalid.                                                             | Request took too long to complete or os.time() is broken.                                                                           |
| UNKNOWN\_ERROR                                       | Unknown server error - contact gg/luarmor                                           | Upstream closed connection (outage or an API restart)                                                                               |

Response body will always be a JSON. In case of <mark style="color:green;">**KEY\_VALID,**</mark> an additional "data" field will be included in the table, with these fields:

<mark style="color:green;">KEY\_VALID</mark> "data" fields:

| Field Name        | Type                     | Value                                                                                                                                          |
| ----------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| auth\_expire      | number (32bit timestamp) | Expiry date of the key, could be -1 or 0 for lifetime keys.                                                                                    |
| note              | string                   | Note, can be accessed in the obfuscated script via LRM\_UserNote too. (Refer to [runtime ](#runtime-variables)[variables](#runtime-variables)) |
| total\_executions | number                   | Total executions made by this key. Could be any number.                                                                                        |

### Library Methods

You can see a full list of functions that are provided by the library.&#x20;

| method:                 | usage:                        | Meaning                                                                                                                                                                            |
| ----------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \<new index> script\_id | lib.script\_id = "PASTE ID"   | You have to assign your script ID to the table that library returns in order to check keys. Always do this first.                                                                  |
| check\_key(\<string>)   | lib.check\_key("JnX84B...Q1") | Make a call to fetch key data.                                                                                                                                                     |
| load\_script()          | lib.load\_script();           | Loadstrings the script ID that was previously assigned above. You can just use the default loadstring too. YOU MUST set the script\_key global before loadstringing or using this. |
| purge\_cache()          | lib.purge\_cache();           | Tries to delete the cached file in workspace folder that holds the last known obfuscated version of the script. You can force a purge with this.                                   |

## 🎁 Ad System (Rewards)

Refer to "[Ad System (Rewards)](/ad-system-rewards.md)" page.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.luarmor.net/luarmor-user-manual-and-f.a.q.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
