# FiveM Projects

### Prerequisites

* A FiveM server
* SunLicense API credentials
* Your product ID and license key

### Step 1: Set Up Basic Structure

Create a new file called `license_check.lua` in your resource's server folder:

```lua
-- license_check.lua
local SunLicenseValidator = {}
SunLicenseValidator.__index = SunLicenseValidator

-- Configuration
local CONFIG = {
    API_URL = "http://localhost:8080/api/v1/validate",
    LICENSE_KEY = GetConvar("sunlicense_key", "YOUR-LICENSE-KEY"),
    PRODUCT_ID = 602,  -- Replace with your product ID
    VERSION = "1.0.0"
}
```

### Step 2: Implement the Validator Class

Add the core validation functionality:

```lua
function SunLicenseValidator.new()
    local self = setmetatable({}, SunLicenseValidator)
    self.authenticated = false
    return self
end

function SunLicenseValidator:validate()
    -- Construct the payload according to SunLicense specifications
    local payload = json.encode({
        licenseKey = CONFIG.LICENSE_KEY,
        productId = CONFIG.PRODUCT_ID,
        productVersion = CONFIG.VERSION,
        hwid = self:getHWID(),
        macAddress = "",  -- Optional field
        operatingSystem = "",  -- Optional field
        operatingSystemVersion = "",  -- Optional field
        operatingSystemArchitecture = "",  -- Optional field
        javaVersion = ""  -- Optional field
    })

    PerformHttpRequest(CONFIG.API_URL, function(errorCode, resultData, headers)
        if errorCode == 200 then
            local success, data = pcall(json.decode, resultData)
            if success and data then
                if data.status == "valid" then
                    self.authenticated = true
                    print("^2[SunLicense] License validated successfully^0")
                else
                    print("^1[SunLicense] License validation failed^0")
                    Wait(5000)
                    os.exit()
                end
            end
        else
            print("^1[SunLicense] Failed to connect to license server^0")
            Wait(5000)
            os.exit()
        end
    end, 'POST', payload, {
        ['Content-Type'] = 'application/json',
        ['Content-Length'] = #payload
    })
end

-- Generate a unique hardware identifier
function SunLicenseValidator:getHWID()
    -- You can implement your own HWID generation logic here
    -- This is a simple example that combines server information
    local serverID = GetConvar("sv_licenseIdentifier", "")
    local port = GetConvar("endpoint_port", "")
    return string.format("fivem-server-%s-%s", serverID, port)
end
```

### Step 3: Initialize the License Check

Create an initialization file (`init.lua`):

```lua
-- init.lua
local validator = SunLicenseValidator.new()

AddEventHandler('onResourceStart', function(resourceName)
    if GetCurrentResourceName() ~= resourceName then return end
    
    Wait(1000) -- Wait for server to fully initialize
    validator:validateWithRetry(3)
end)
```

### Step 4: Configure Your Resource

Update your `fxmanifest.lua`:

```lua
fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'Your Resource Description'
version '1.0.0'

server_scripts {
    'server/license_check.lua',
    'server/init.lua',
    -- Your other server scripts
}

-- Add your convar for the license key
convar_category 'Licensing' {
    "License Configuration",
    {
        { "License Key", "sunlicense_key", "CV_STRING", "Your SunLicense key" }
    }
}
```

### Best Practices

1. **License Key Security**
   * Store your license key in server.cfg
   * Never expose the key in client-side code
   * Regularly rotate keys if possible
2. **Error Handling**
   * Implement proper logging
   * Handle network timeouts
   * Provide clear error messages
3. **Validation Timing**
   * Validate on resource start
   * Implement periodic validation if needed
   * Use reasonable retry intervals

### Common Issues and Solutions

#### Network Connectivity Problems

```lua
-- Add this to your validation function
if not self:checkConnection() then
    print("^1[SunLicense] No network connection available^0")
    Wait(10000)
    return false
end
```

#### Invalid License Format

```lua
-- Add this validation check
function SunLicenseValidator:isValidLicenseFormat(key)
    -- Check for the format: XXXX-XXXX-XXXX-XXXX-XXXX
    return type(key) == "string" and key:match("^%w%w%w%w%-%w%w%w%w%-%w%w%w%w%-%w%w%w%w%-%w%w%w%w$") ~= nil
end
```

#### Failed Validation Response

```lua
-- Add this helper function
function SunLicenseValidator:handleValidationError(response)
    if response.error then
        print(string.format("^1[SunLicense] Validation error: %s^0", response.error))
        return false
    end
    return true
end
```


---

# 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.sunlicense.hapangama.com/product-integrations/fivem-projects.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.
