# Hate Framework Bridge

HateBridge is a central bridge system that provides framework independence for all Hate scripts. It supports ESX, QBCore, and QBox frameworks with automatic detection and unified API.

## Features

* **Automatic Framework Detection**: Automatically detects which framework is installed on the server
* **Unified API**: Provides a single API for all frameworks
* **Player Management**: Manages player data across different frameworks
* **Inventory Management**: Item adding/removing operations
* **Money Management**: Money adding/removing operations
* **Notification System**: Framework-independent notifications
* **Progress Bar**: Framework-independent progress bars
* **Callback System**: Server-client callbacks
* **Database Operations**: Helper functions for MySQL operations
* **Target System**: Unified targeting system (ox\_target, qb-target, qtarget)

## Installation

1. Copy the `hate-bridge` folder to your resources directory
2. Add this line to your `server.cfg`:

```
ensure hate-bridge
```

## Framework Support

| Framework | Status | Version Support |
| --------- | ------ | --------------- |
| ESX       | ✅      | Legacy & Final  |
| QBCore    | ✅      | All Versions    |
| QBox      | ✅      | Latest          |

## Dependencies

* `oxmysql` (required)
* `ox_lib` (optional, for enhanced features)

## Usage in Other Hate Scripts

### FXManifest Dependency

Add dependency to your `fxmanifest.lua`:

```lua
dependencies {
    'hate-bridge'
}
```

### Client Side Usage

```lua
local HateBridge = nil

-- Load HateBridge
CreateThread(function()
    while HateBridge == nil do
        HateBridge = exports['hate-bridge']:getBridge()
        Wait(100)
    end
end)

-- Usage examples
-- Get player data
local playerData = HateBridge.GetPlayerData()

-- Check if player is loaded
if HateBridge.IsPlayerLoaded() then
    print("Player is loaded")
end

-- Get player job
local job = HateBridge.GetPlayerJob()

-- Get player money
local money = HateBridge.GetPlayerMoney('money') -- or 'bank', 'black_money'

-- Show notification
HateBridge.ShowNotification('Hello World!', 'success', 5000)

-- Progress bar
HateBridge.ProgressBar('my_progressbar', 'Doing something...', 5000, false, true, {
    disableMovement = true,
    disableCarMovement = true,
    disableMouse = false,
    disableCombat = true,
}, {
    animDict = 'mini@repair',
    anim = 'fixing_a_player',
    flags = 49,
}, {}, function()
    print('Progress completed')
end, function()
    print('Progress cancelled')
end)

-- Trigger server callback
HateBridge.TriggerCallback('my_callback', function(result)
    print('Callback result:', result)
end, 'arg1', 'arg2')

-- Target system
HateBridge.AddTargetEntity(entity, {
    {
        name = 'my_option',
        icon = 'fas fa-hand',
        label = 'Interact',
        action = function()
            print('Entity targeted!')
        end,
        distance = 2.0
    }
})
```

### Server Side Usage

```lua
local HateBridge = exports['hate-bridge']:getBridgeServer()

-- Get player
local Player = HateBridge.GetPlayer(source)

-- Add money
HateBridge.AddMoney(source, 'money', 1000)

-- Remove money
HateBridge.RemoveMoney(source, 'money', 500)

-- Add item
HateBridge.AddItem(source, 'bread', 5, {quality = 100})

-- Remove item
HateBridge.RemoveItem(source, 'bread', 2)

-- Check if player has item
local hasItem = HateBridge.HasItem(source, 'bread', 3)

-- Get item count
local itemCount = HateBridge.GetItemCount(source, 'bread')

-- Create server callback
HateBridge.CreateCallback('my_callback', function(source, cb, arg1, arg2)
    cb(true)
end)

-- Database operations
HateBridge.ExecuteQuery('SELECT * FROM users WHERE identifier = ?', {identifier}, function(result)
    print('Query result:', json.encode(result))
end)
```

## Client API Reference

### Player Functions

<table><thead><tr><th width="272.6666259765625">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>GetPlayerData()</code></td><td>Get all player data</td><td>None</td><td>table</td></tr><tr><td><code>IsPlayerLoaded()</code></td><td>Check if player is loaded</td><td>None</td><td>boolean</td></tr><tr><td><code>GetPlayerJob()</code></td><td>Get player job information</td><td>None</td><td>table</td></tr><tr><td><code>GetPlayerMoney(moneyType)</code></td><td>Get player money amount</td><td>string (optional)</td><td>number</td></tr></tbody></table>

### UI Functions

<table><thead><tr><th width="312.66668701171875">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>ShowNotification(message, type, duration)</code></td><td>Show notification</td><td>string, string, number</td><td>void</td></tr><tr><td><code>ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, onFinish, onCancel)</code></td><td>Show progress bar</td><td>multiple</td><td>void</td></tr></tbody></table>

### Callback Functions

<table><thead><tr><th width="292">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>TriggerCallback(name, cb, ...)</code></td><td>Trigger server callback</td><td>string, function, ...</td><td>void</td></tr></tbody></table>

### Target System Functions

<table><thead><tr><th width="342.66668701171875">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>AddTargetEntity(entity, options)</code></td><td>Add target to entity</td><td>number, table</td><td>void</td></tr><tr><td><code>RemoveTargetEntity(entity, optionNames)</code></td><td>Remove target from entity</td><td>number, table</td><td>void</td></tr><tr><td><code>AddTargetModel(models, options)</code></td><td>Add target to models</td><td>table, table</td><td>void</td></tr><tr><td><code>RemoveTargetModel(models, optionNames)</code></td><td>Remove target from models</td><td>table, table</td><td>void</td></tr><tr><td><code>AddGlobalPed(options)</code></td><td>Add global ped target</td><td>table</td><td>void</td></tr><tr><td><code>RemoveGlobalPed(optionNames)</code></td><td>Remove global ped target</td><td>table</td><td>void</td></tr><tr><td><code>AddTargetZone(name, coords, length, width, options, targetOptions)</code></td><td>Add target zone</td><td>string, vector3, number, number, table, table</td><td>void</td></tr><tr><td><code>AddCircleZone(name, coords, radius, options, targetOptions)</code></td><td>Add circle zone</td><td>string, vector3, number, table, table</td><td>void</td></tr><tr><td><code>RemoveTargetZone(name)</code></td><td>Remove target zone</td><td>string</td><td>void</td></tr></tbody></table>

## Server API Reference

### Player Functions

<table><thead><tr><th width="347.3333740234375">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>GetPlayer(source)</code></td><td>Get player object</td><td>number</td><td>object</td></tr><tr><td><code>GetPlayerFromIdentifier(identifier)</code></td><td>Get player by identifier</td><td>string</td><td>object</td></tr><tr><td><code>GetPlayerIdentifier(source)</code></td><td>Get player identifier</td><td>number</td><td>string</td></tr><tr><td><code>GetPlayerName(source)</code></td><td>Get player name</td><td>number</td><td>string</td></tr><tr><td><code>GetPlayerCharName(source, useNickname)</code></td><td>Get character name</td><td>number, boolean</td><td>string</td></tr></tbody></table>

### Money Functions

<table><thead><tr><th width="345.3333740234375">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>AddMoney(source, moneyType, amount)</code></td><td>Add money to player</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>RemoveMoney(source, moneyType, amount)</code></td><td>Remove money from player</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>GetPlayerMoney(source, moneyType)</code></td><td>Get player money</td><td>number, string</td><td>number</td></tr><tr><td><code>HasEnoughMoney(source, moneyType, amount)</code></td><td>Check if player has enough money</td><td>number, string, number</td><td>boolean</td></tr></tbody></table>

### Inventory Functions

<table><thead><tr><th width="359.33331298828125">Function</th><th>Description</th><th>Parameters</th><th>Returns</th></tr></thead><tbody><tr><td><code>AddItem(source, itemName, amount, metadata)</code></td><td>Add item to player</td><td>number, string, number, table</td><td>boolean</td></tr><tr><td><code>RemoveItem(source, itemName, amount)</code></td><td>Remove item from player</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>GetItemCount(source, itemName)</code></td><td>Get item count</td><td>number, string</td><td>number</td></tr><tr><td><code>HasItem(source, itemName, amount)</code></td><td>Check if player has item</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>HasEnoughItem(source, itemName, amount)</code></td><td>Check if player has enough items</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>CanCarryItem(source, itemName, amount)</code></td><td>Check if player can carry item</td><td>number, string, number</td><td>boolean</td></tr><tr><td><code>GetPlayerInventory(source)</code></td><td>Get player inventory</td><td>number</td><td>table</td></tr></tbody></table>

### Job Functions

| Function                               | Description    | Parameters             | Returns |
| -------------------------------------- | -------------- | ---------------------- | ------- |
| `GetPlayerJob(source)`                 | Get player job | number                 | table   |
| `SetPlayerJob(source, jobName, grade)` | Set player job | number, string, number | boolean |

### Callback Functions

| Function                   | Description            | Parameters       | Returns |
| -------------------------- | ---------------------- | ---------------- | ------- |
| `CreateCallback(name, cb)` | Create server callback | string, function | void    |

### Database Functions

| Function                               | Description          | Parameters              | Returns |
| -------------------------------------- | -------------------- | ----------------------- | ------- |
| `ExecuteQuery(query, parameters, cb)`  | Execute MySQL query  | string, table, function | mixed   |
| `ExecuteInsert(query, parameters, cb)` | Execute MySQL insert | string, table, function | number  |
| `ExecuteUpdate(query, parameters, cb)` | Execute MySQL update | string, table, function | number  |

### Utility Functions

| Function                                            | Description                 | Parameters                     | Returns |
| --------------------------------------------------- | --------------------------- | ------------------------------ | ------- |
| `CreateUseableItem(itemName, cb)`                   | Create useable item         | string, function               | void    |
| `ShowNotification(source, message, type, duration)` | Show notification to player | number, string, string, number | void    |
| `GetItemLabel(itemName)`                            | Get item label              | string                         | string  |
| `GetItemImagePath(itemName)`                        | Get item image path         | string                         | string  |

## Shared Exports

These exports are available on both client and server:

| Export                   | Description                      | Returns |
| ------------------------ | -------------------------------- | ------- |
| `getFramework()`         | Get detected framework name      | string  |
| `getTargetSystem()`      | Get detected target system       | string  |
| `getProgressBarSystem()` | Get detected progress bar system | string  |
| `getFrameworkEvents()`   | Get framework events table       | table   |
| `getServerEvents()`      | Get server events table          | table   |

## Framework Detection

The bridge automatically detects your framework on startup:

* **ESX**: Detects `es_extended` resource
* **QBCore**: Detects `qb-core` resource
* **QBox**: Detects `qbx_core` resource

## Target System Support

Automatically detects and supports:

* `ox_target`
* `qb-target`
* `qtarget`

## Progress Bar Support

Automatically detects and supports:

* `ox_lib` (progressCircle)
* `esx_progressbar`
* `qb-progressbar`

## Events

### Client Events

| Event                               | Description                   | Parameters |
| ----------------------------------- | ----------------------------- | ---------- |
| `hate-bridge:client:playerLoaded`   | Triggered when player loads   | playerData |
| `hate-bridge:client:playerUnloaded` | Triggered when player unloads | None       |
| `hate-bridge:client:jobUpdate`      | Triggered when job updates    | jobData    |

### Server Events

| Event                              | Description                 | Parameters |
| ---------------------------------- | --------------------------- | ---------- |
| `hate-bridge:server:playerLoaded`  | Triggered when player loads | source     |
| `hate-bridge:server:playerDropped` | Triggered when player drops | source     |

## Configuration

Edit `config.lua` to customize:

```lua
Config.Debug = true -- Enable debug prints
Config.Framework = nil -- Force framework (auto-detect if nil)
```

## Example Usage in Scripts

### Complete Client Example

```lua
-- Wait for bridge to be available
local HateBridge = nil
CreateThread(function()
    while HateBridge == nil do
        HateBridge = exports['hate-bridge']:getBridge()
        Wait(100)
    end
    
    -- Now you can use HateBridge functions
    print('Bridge loaded, framework:', exports['hate-bridge']:getFramework())
end)

-- Listen for player load
RegisterNetEvent('hate-bridge:client:playerLoaded')
AddEventHandler('hate-bridge:client:playerLoaded', function(playerData)
    print('Player loaded with job:', playerData.job.name)
end)

-- Example interaction
RegisterCommand('testbridge', function()
    if not HateBridge or not HateBridge.IsPlayerLoaded() then
        return
    end
    
    local job = HateBridge.GetPlayerJob()
    local money = HateBridge.GetPlayerMoney('money')
    
    HateBridge.ShowNotification('Job: ' .. job.name .. ' | Money: $' .. money, 'info')
end)
```

### Complete Server Example

```lua
-- Get bridge on resource start
local HateBridge = exports['hate-bridge']:getBridgeServer()

-- Create a callback for client use
HateBridge.CreateCallback('myresource:getData', function(source, cb)
    local Player = HateBridge.GetPlayer(source)
    if Player then
        cb({
            name = HateBridge.GetPlayerName(source),
            job = HateBridge.GetPlayerJob(source),
            money = HateBridge.GetPlayerMoney(source, 'money')
        })
    else
        cb(false)
    end
end)

-- Listen for player load
RegisterNetEvent('hate-bridge:server:playerLoaded')
AddEventHandler('hate-bridge:server:playerLoaded', function()
    local src = source
    print('Player loaded on server:', src)
    
    -- Give welcome bonus
    HateBridge.AddMoney(src, 'money', 100)
    HateBridge.ShowNotification(src, 'Welcome bonus: $100', 'success')
end)

-- Example command
RegisterCommand('givebread', function(source, args)
    local amount = tonumber(args[1]) or 1
    
    if HateBridge.CanCarryItem(source, 'bread', amount) then
        HateBridge.AddItem(source, 'bread', amount)
        HateBridge.ShowNotification(source, 'You received ' .. amount .. ' bread', 'success')
    else
        HateBridge.ShowNotification(source, 'You cannot carry that much bread', 'error')
    end
end)
```

## Troubleshooting

### Common Issues

1. **Framework not detected**: Ensure your framework resource is started before hate-bridge
2. **Exports not working**: Make sure to add hate-bridge as a dependency in your fxmanifest.lua
3. **Player data nil**: Wait for the player to be fully loaded before accessing data

### Debug Mode

Enable debug mode in config.lua to see detection logs:

```lua
Config.Debug = true
```

### Framework Override

You can force a specific framework if auto-detection fails:

```lua
Config.Framework = 'esx' -- or 'qb', 'qbox'
```

## Migration from Framework-Specific Code

### From ESX:

```lua
-- Old ESX code
ESX.TriggerServerCallback('callback', function(result) end)
ESX.ShowNotification('message')

-- New HateBridge code  
HateBridge.TriggerCallback('callback', function(result) end)
HateBridge.ShowNotification('message', 'info')
```

### From QBCore:

```lua
-- Old QB code
QBCore.Functions.TriggerCallback('callback', function(result) end)
QBCore.Functions.Notify('message')

-- New HateBridge code
HateBridge.TriggerCallback('callback', function(result) end)  
HateBridge.ShowNotification('message', 'info')
```

## Performance Notes

* HateBridge uses minimal resources
* Framework detection happens once on startup
* No polling or continuous checks
* Event-driven architecture for optimal performance

## License

This project is licensed under the MIT License.

## Support

For support and updates, visit our community or contact the development team.

***

**Note**: This bridge is designed specifically for Hate scripts ecosystem. While it can be used with other resources, it's optimized for Hate scripts integration.

Eğer herhangi bir sorun yaşarsanız:

1. HateBridge'in düzgün yüklendiğinden emin olun
2. Debug modunu açın (`Config.Debug = true`)
3. Server console'unda hata mesajlarını kontrol edin
4. Framework'ünüzün desteklendiğinden emin olun


---

# 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://hate-development.gitbook.io/hate-development-docs/hate-framework-bridge.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.
