Raid Selector

Платное Raid Selector 4.9.122

JSON:
# RaidSelector Plugin - Complete Configuration Guide
**Version:** 4.9.0
**Last Updated:** November 15, 2025
---
## Table of Contents
1. [Overview](#overview)
2. [Installation](#installation)
3. [Configuration File](#configuration-file)
4. [Basic Settings](#basic-settings)
5. [Permission System](#permission-system)
6. [Color Customization](#color-customization)
7. [Base Configuration](#base-configuration)
8. [Multi-Currency Support](#multi-currency-support)
9. [Localization System](#localization-system)
10. [Image Support](#image-support)
11. [ServerPanel Integration](#serverpanel-integration)
12. [Commands](#commands)
13. [Troubleshooting](#troubleshooting)
14. [Examples](#examples)
---
## Overview
RaidSelector is a user-friendly raid base purchasing system for Rust servers running Oxide or Carbon frameworks. It provides players with an intuitive UI to browse, select, and purchase raidable bases using in-game currency.
### Key Features
- **Point-and-Click Interface** - No complicated commands needed
- **Multi-Difficulty System** - Easy, Medium, Hard, Expert, and Nightmare modes
- **Permission-Based Access** - Fine-grained control over who can access what
- **Multi-Currency Support** - Works with Economics and ServerRewards plugins
- **Multilingual Support** - Full localization system with external JSON language files
- **Image Preview** - Display base thumbnails via ImageLibrary or ImageDatabase
- **Color Customization** - 24+ customizable UI colors
- **ServerPanel Integration** - Works standalone or integrated with ServerPanel UI
- **Cross-Platform** - Works on both Oxide and Carbon servers
- **Memory Optimized** - GC-aware design with object pooling for optimal performance
### Dependencies
**Required:**
- RaidableBases plugin (and its dependencies)
**Optional:**
- Economics plugin (for currency system)
- ServerRewards plugin (for reward points system)
- ImageLibrary plugin (Oxide - for image previews)
- ImageDatabase (Carbon - for image previews)
---
## Installation
### Step 1: Install Prerequisites
Ensure RaidableBases plugin is installed and configured on your server.
### Step 2: Install RaidSelector
1. Download `RaidSelector.cs`
2. Place in `oxide/plugins/` (Oxide) or `carbon/plugins/` (Carbon)
3. Restart server or reload plugin:
   ```
   o.reload RaidSelector
   ```
### Step 3: Configure Permissions
Grant basic access to players:
```bash
o.grant group default raidselector.can.use
```
### Step 4: Verify Installation
1. Check server console for successful plugin load
2. Test in-game with `/rs` command
3. Verify configuration file created at `oxide/config/RaidSelector.json`
---
## Configuration File
The configuration file is automatically created at:
```
oxide/config/RaidSelector.json
```
### Default Configuration Structure
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": true,
  "Colors": { ... },
  "DifficultyPermissions": { ... },
  "BuyButtonPermissions": { ... },
  "ServerPanelConfig": { ... },
  "Bases": { ... }
}
```
---
## Basic Settings
### ChatCommand
**Type:** `string`
**Default:** `"rs"`
**Description:** The command players type to open the UI
**Example:**
```json
"ChatCommand": "rs"
```
Players type `/rs` in chat to open the interface.
**Alternative Values:**
```json
"ChatCommand": "raids"     // Players type /raids
"ChatCommand": "buyraid"   // Players type /buyraid
"ChatCommand": "rb"        // Players type /rb
```
### RequiresOxidePermission
**Type:** `boolean`
**Default:** `false`
**Description:** Whether players need the `raidselector.can.use` permission to open UI
**Example:**
```json
"RequiresOxidePermission": true
```
**Values:**
- `true` - Only players with `raidselector.can.use` permission can access
- `false` - All players can open the UI (individual features still respect permissions)
### Debug
**Type:** `boolean`
**Default:** `true`
**Description:** Enable debug logging for troubleshooting
**Example:**
```json
"Debug": false
```
**When to Enable:**
- Troubleshooting issues
- Development and testing
- When reporting bugs
**When to Disable:**
- Production servers (reduces console spam)
- After confirming everything works
---
## Permission System
RaidSelector includes 9 permissions for fine-grained access control.
### Admin Permission
**Permission:** `raidselector.admin`
**Purpose:** Grants admin-level access to management commands
**Required For:**
- `/rsinitlang` command (language template generation)
- Future admin features
**Grant to admins:**
```bash
o.grant group admin raidselector.admin
o.grant user AdminName raidselector.admin
```
### UI Access Permission
**Permission:** `raidselector.can.use`
**Purpose:** Controls who can open the UI
**Applies When:** `RequiresOxidePermission` is `true`
**Grant to all players:**
```bash
o.grant group default raidselector.can.use
```
**Grant to specific player:**
```bash
o.grant user PlayerName raidselector.can.use
o.grant user 76561198012345678 raidselector.can.use
```
### Difficulty Permissions
Control access to specific difficulty levels. Buttons automatically hide when players lack permission.
**Permissions:**
- `raidselector.difficulty.easy`
- `raidselector.difficulty.medium`
- `raidselector.difficulty.hard`
- `raidselector.difficulty.expert`
- `raidselector.difficulty.nightmare`
**Configuration:**
```json
"DifficultyPermissions": {
  "Easy": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": false
  },
  "Expert": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": true
  }
}
```
**Settings:**
#### DifficultyActivate
**Type:** `boolean`
**Default:** `true`
**Description:** Whether this difficulty level is available at all
- `true` - Difficulty exists in UI (respects permission settings)
- `false` - Difficulty is completely hidden from everyone
#### RequiresDifficultyPermission
**Type:** `boolean`
**Default:** `false`
**Description:** Whether players need permission for this difficulty
- `true` - Players need `raidselector.difficulty.[name]` permission
- `false` - All players can access (if `DifficultyActivate` is true)
**Example Configurations:**
**Public Easy/Medium, VIP Hard/Expert:**
```json
"DifficultyPermissions": {
  "Easy": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": false
  },
  "Medium": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": false
  },
  "Hard": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": true
  },
  "Expert": {
    "DifficultyActivate": true,
    "RequiresDifficultyPermission": true
  }
}
```
Then grant VIP permissions:
```bash
o.grant group vip raidselector.difficulty.hard
o.grant group vip raidselector.difficulty.expert
```
### Purchase Permissions
Control who can purchase raids. Purchase buttons hide when players lack permission.
**Permissions:**
- `raidselector.buyraidspecific` - Purchase specific selected bases
- `raidselector.buyraidrandom` - Purchase random bases from difficulty
**Configuration:**
```json
"BuyButtonPermissions": {
  "RequiresBuyRandomPermission": true,
  "RequiresBuySpecificPermission": true
}
```
**Settings:**
#### RequiresBuyRandomPermission
**Type:** `boolean`
**Default:** `false`
**Description:** Require permission to use "Random" button
- `true` - Players need `raidselector.buyraidrandom` permission
- `false` - All players can purchase random bases
#### RequiresBuySpecificPermission
**Type:** `boolean`
**Default:** `false`
**Description:** Require permission to purchase specific bases
- `true` - Players need `raidselector.buyraidspecific` permission
- `false` - All players can purchase specific bases
**Example Configurations:**
**Everyone Browses, VIPs Purchase:**
```json
"BuyButtonPermissions": {
  "RequiresBuyRandomPermission": true,
  "RequiresBuySpecificPermission": true
}
```
```bash
o.grant group default raidselector.can.use
o.grant group vip raidselector.buyraidspecific
o.grant group vip raidselector.buyraidrandom
```
### Complete Permission Examples
#### Scenario 1: Public Easy Raids, Premium Hard Raids
**Goal:** Everyone can browse and buy Easy raids, VIPs can access Hard/Expert.
**Configuration:**
```json
{
  "RequiresOxidePermission": false,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Expert": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": false,
    "RequiresBuySpecificPermission": false
  }
}
```
**Permissions:**
```bash
o.grant group vip raidselector.difficulty.hard
o.grant group vip raidselector.difficulty.expert
```
#### Scenario 2: Browse Free, Purchase Requires VIP
**Goal:** Everyone can view all raids, only VIPs can purchase.
**Configuration:**
```json
{
  "RequiresOxidePermission": false,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": true,
    "RequiresBuySpecificPermission": true
  }
}
```
**Permissions:**
```bash
o.grant group vip raidselector.buyraidspecific
o.grant group vip raidselector.buyraidrandom
```
#### Scenario 3: Tiered Access
**Goal:** Progressive difficulty access based on player rank.
**Configuration:**
```json
{
  "RequiresOxidePermission": true,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Expert": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": false,
    "RequiresBuySpecificPermission": false
  }
}
```
**Permissions:**
```bash
# Bronze tier - Easy only
o.grant group bronze raidselector.can.use
o.grant group bronze raidselector.difficulty.easy
# Silver tier - Easy + Medium
o.grant group silver raidselector.can.use
o.grant group silver raidselector.difficulty.easy
o.grant group silver raidselector.difficulty.medium
# Gold tier - All except Nightmare
o.grant group gold raidselector.can.use
o.grant group gold raidselector.difficulty.easy
o.grant group gold raidselector.difficulty.medium
o.grant group gold raidselector.difficulty.hard
o.grant group gold raidselector.difficulty.expert
```
---
## Color Customization
RaidSelector supports 24 customizable colors using RGBA format.
### Color Format
**Format:** `"R G B A"` where each value is `0.0` to `1.0`
**Examples:**
```json
"TitleBarText": "1 1 1 1"           // White (full opacity)
"ModalBackground": "0.05 0.1 0.2 0.98"  // Dark blue (98% opacity)
"XButtonBackground": "0.8 0.2 0.2 0.9"  // Red (90% opacity)
```
### Color Reference
**Common Colors:**
```
White:       "1 1 1 1"
Black:       "0 0 0 1"
Red:         "1 0 0 1"
Green:       "0 1 0 1"
Blue:        "0 0 1 1"
Yellow:      "1 1 0 1"
Cyan:        "0 1 1 1"
Magenta:     "1 0 1 1"
Gray:        "0.5 0.5 0.5 1"
Transparent: "0 0 0 0"
```
### Main Window Colors
```json
"Colors": {
  "ModalBackground": "0.05 0.1 0.2 0.98",
  "TitleBarBackground": "0.1 0.2 0.4 1.0",
  "TitleBarText": "1 1 1 1",
  "XButtonBackground": "0.8 0.2 0.2 0.9",
  "XButtonText": "1 1 1 1"
}
```
**Settings:**
- **ModalBackground** - Main window background
- **TitleBarBackground** - Title bar background
- **TitleBarText** - Title text color
- **XButtonBackground** - Close button background
- **XButtonText** - Close button text color
### Left Panel Colors (Difficulty Selection)
```json
"LeftPanelBackground": "0.05 0.1 0.25 0.95",
"DifficultyButtonActiveBackground": "0.2 0.5 0.9 1.0",
"DifficultyButtonInactiveBackground": "0.1 0.3 0.7 0.8",
"DifficultyButtonText": "1 1 1 1",
"CloseButtonBackground": "0.8 0.2 0.2 0.9",
"CloseButtonText": "1 1 1 1"
```
**Settings:**
- **LeftPanelBackground** - Left panel background
- **DifficultyButtonActiveBackground** - Selected difficulty button
- **DifficultyButtonInactiveBackground** - Unselected difficulty buttons
- **DifficultyButtonText** - Difficulty button text
- **CloseButtonBackground** - Bottom close button background
- **CloseButtonText** - Bottom close button text
### Middle Panel Colors (Base Selection)
```json
"MiddlePanelBackground": "0.08 0.15 0.3 0.95",
"BasePanelActiveBackground": "0.15 0.45 0.85 1.0",
"BasePanelInactiveBackground": "0.1 0.3 0.7 0.8",
"BasePanelNameText": "1 1 1 1",
"BasePanelDescText": "0.9 0.9 0.9 1",
"RandomButtonBackground": "0.2 0.6 0.2 0.9"
```
**Settings:**
- **MiddlePanelBackground** - Middle panel background
- **BasePanelActiveBackground** - Selected base background
- **BasePanelInactiveBackground** - Unselected base backgrounds
- **BasePanelNameText** - Base name text color
- **BasePanelDescText** - Base description text color
- **RandomButtonBackground** - "Random" button background
### Right Panel Colors (Base Details)
```json
"RightPanelBackground": "0.05 0.12 0.25 0.95",
"RightPanelDescText": "0.9 0.9 0.9 1",
"PurchaseButtonBackground": "0.2 0.6 0.2 0.9",
"PurchaseButtonText": "1 1 1 1"
```
**Settings:**
- **RightPanelBackground** - Right panel background
- **RightPanelDescText** - Description text color
- **PurchaseButtonBackground** - Purchase button background
- **PurchaseButtonText** - Purchase button text color
### Scrollbar Colors
```json
"ScrollbarHandleColor": "0.6 0.6 0.6 0.8",
"ScrollbarHighlightColor": "0.6 0.6 0.6 0.8",
"ScrollbarPressedColor": "0.6 0.6 0.6 0.8",
"ScrollbarTrackColor": "0.2 0.2 0.2 0.3"
```
**Settings:**
- **ScrollbarHandleColor** - Scrollbar handle (draggable part)
- **ScrollbarHighlightColor** - Scrollbar when highlighted
- **ScrollbarPressedColor** - Scrollbar when pressed
- **ScrollbarTrackColor** - Scrollbar track background
### Color Theme Examples
#### Dark Theme (Default)
```json
"Colors": {
  "ModalBackground": "0.05 0.1 0.2 0.98",
  "TitleBarBackground": "0.1 0.2 0.4 1.0",
  "LeftPanelBackground": "0.05 0.1 0.25 0.95",
  "MiddlePanelBackground": "0.08 0.15 0.3 0.95",
  "RightPanelBackground": "0.05 0.12 0.25 0.95"
}
```
#### Light Theme
```json
"Colors": {
  "ModalBackground": "0.9 0.9 0.9 0.98",
  "TitleBarBackground": "0.8 0.8 0.85 1.0",
  "TitleBarText": "0.1 0.1 0.1 1",
  "LeftPanelBackground": "0.85 0.85 0.9 0.95",
  "MiddlePanelBackground": "0.88 0.88 0.92 0.95",
  "RightPanelBackground": "0.85 0.85 0.9 0.95",
  "BasePanelNameText": "0.1 0.1 0.1 1",
  "RightPanelDescText": "0.2 0.2 0.2 1"
}
```
#### Military Green Theme
```json
"Colors": {
  "ModalBackground": "0.1 0.15 0.1 0.98",
  "TitleBarBackground": "0.15 0.25 0.15 1.0",
  "LeftPanelBackground": "0.12 0.2 0.12 0.95",
  "DifficultyButtonActiveBackground": "0.3 0.5 0.3 1.0",
  "DifficultyButtonInactiveBackground": "0.2 0.35 0.2 0.8",
  "PurchaseButtonBackground": "0.25 0.45 0.25 0.9"
}
```
---
## Base Configuration
Configure custom display information for specific bases.
### Base Structure
```json
"Bases": {
  "BaseName": {
    "DisplayName": "Friendly Name",
    "Description": "Base description text",
    "Credit": "Builder name",
    "ImageUrl": "https://i.imgur.com/example.png",
    "NotBuyable": false
  }
}
```
### Base Settings
#### DisplayName
**Type:** `string`
**Default:** Base filename
**Description:** Friendly name shown in UI
**Example:**
```json
"DisplayName": "Coastal Compound"
```
#### Description
**Type:** `string`
**Default:** Empty
**Description:** Text shown in right panel when base is selected
**Example:**
```json
"Description": "A challenging coastal raid base with multiple loot rooms and traps."
```
#### Credit
**Type:** `string`
**Default:** Empty
**Description:** Base builder credit (shown in description)
**Example:**
```json
"Credit": "Built by AdminName"
```
#### ImageUrl
**Type:** `string`
**Default:** Empty (uses default Rust logo)
**Description:** Direct URL to base preview image
**Example:**
```json
"ImageUrl": "https://i.imgur.com/abc123.png"
```
**Supported Image Hosts:**
- imgur.com (recommended)
- i.gyazo.com
- prnt.sc
- Any direct image URL
**Image Requirements:**
- Direct image URL (must end in .png, .jpg, etc.)
- Publicly accessible
- Recommended size: 512x512 or similar
- Formats: PNG, JPG, JPEG
#### NotBuyable
**Type:** `boolean`
**Default:** `false`
**Description:** Hide base from purchase options (admin/testing use)
**Example:**
```json
"NotBuyable": true
```
### Complete Base Example
```json
"Bases": {
  "coastal_compound_hard": {
    "DisplayName": "Coastal Compound",
    "Description": "A challenging multi-story raid base located on the coast. Features multiple loot rooms, autoturrets, and flame traps. Recommended for experienced raiders with a full team.",
    "Credit": "Built by ServerAdmin",
    "ImageUrl": "https://i.imgur.com/coastal123.png",
    "NotBuyable": false
  },
  "mountain_fortress_expert": {
    "DisplayName": "Mountain Fortress",
    "Description": "An expert-level mountain fortress with heavy defenses. Expect Bradley APCs, autoturrets, and complex raid pathing. Bring explosives and a large team.",
    "Credit": "Community Builder Contest Winner",
    "ImageUrl": "https://i.imgur.com/mountain456.png",
    "NotBuyable": false
  },
  "test_base_internal": {
    "DisplayName": "Test Base",
    "Description": "Internal testing only",
    "Credit": "",
    "ImageUrl": "",
    "NotBuyable": true
  }
}
```
### Automatic Base Detection
RaidSelector automatically detects bases from RaidableBases configuration and adds missing entries with default values:
**Auto-Generated Entry:**
```json
"new_base_name": {
  "DisplayName": "new_base_name",
  "Description": "",
  "Credit": "",
  "ImageUrl": "",
  "NotBuyable": false
}
```
You can then customize these auto-generated entries as needed.
---
## Multi-Currency Support
RaidSelector supports multiple payment systems simultaneously.
### Supported Plugins
- **Economics** - Traditional server economy (dollars/coins)
- **ServerRewards** - Reward Points (RP) system
### How It Works
1. Costs are configured in **RaidableBases** settings files (not RaidSelector)
2. RaidSelector automatically detects installed payment plugins
3. Displays combined costs in UI
4. Charges players using appropriate plugin(s)
### Cost Configuration
**In RaidableBases Settings Files:**
```json
{
  "Easy": {
    "Economics": 500.0,
    "ServerRewards": 100
  },
  "Hard": {
    "Economics": 5000.0,
    "ServerRewards": 1000
  }
}
```
### Cost Display Formats
**Economics Only:**
```
Easy ($500)
Medium ($1,500)
Hard ($5,000)
```
**ServerRewards Only:**
```
Easy (100 RP)
Medium (300 RP)
Hard (1,000 RP)
```
**Both Currencies:**
```
Easy ($500 + 100 RP)
Medium ($1,500 + 300 RP)
Hard ($5,000 + 1,000 RP)
```
**Free Raids:**
```
Easy
Medium
Hard
```
### Payment Validation
- Checks player balance before purchase
- Shows clear error messages if insufficient funds
- Charges both currencies atomically (all or nothing)
- Refunds if raid spawn fails
### Setup Instructions
1. Install Economics and/or ServerRewards plugins
2. Configure costs in RaidableBases settings
3. RaidSelector automatically detects and uses available payment methods
4. No additional configuration needed in RaidSelector.json
---
## Localization System
RaidSelector includes a comprehensive localization system using Oxide's external JSON language files. All UI text, error messages, and dynamic content (difficulty names, base names, descriptions) can be translated.
### Language File Location
Language files are stored in:
```
oxide/lang/<language>/RaidSelector.json
```
**Example locations:**
- English: `oxide/lang/en/RaidSelector.json`
- Spanish: `oxide/lang/es/RaidSelector.json`
- French: `oxide/lang/fr/RaidSelector.json`
- German: `oxide/lang/de/RaidSelector.json`
### Supported Language Codes
Use standard ISO 639-1 language codes:
- `en` - English
- `es` - Spanish
- `fr` - French
- `de` - German
- `ru` - Russian
- `pt` - Portuguese
- `it` - Italian
- `zh` - Chinese
- `ja` - Japanese
- `ko` - Korean
### Automatic Language File Generation
RaidSelector automatically generates language template files on plugin load with:
- All static UI text keys
- Dynamic difficulty name keys
- Dynamic base name and description keys
- Empty values for translation
**Default English file is created automatically** with all keys and English translations.
### Translation Categories
#### Static UI Text
Fixed UI elements that don't change:
```json
{
  "ui.title": "Buy a Raid Base",
  "ui.close": "Close",
  "ui.button.close": "Close",
  "ui.button.buy": "Buy",
  "ui.button.random": "Random",
  "ui.label.select_mode": "Select Mode",
  "ui.label.select_base": "Select Base",
  "ui.label.base_details": "Base Details",
  "ui.label.cost": "Cost",
  "ui.label.difficulty": "Difficulty"
}
```
#### Error Messages
User-facing error messages:
```json
{
  "error.no_ui_permission": "You don't have permission to use Raid Selector.",
  "error.no_difficulty_access": "You don't have permission to access any raid difficulties.",
  "error.no_buy_specific": "You don't have permission to purchase specific raids.",
  "error.no_buy_random": "You don't have permission to purchase random raids.",
  "error.ui_error": "Error opening UI. Check server logs for details.",
  "error.raid_type_error": "Error: Could not determine raid type for '{0}'."
}
```
#### Format Strings
Messages with placeholders:
```json
{
  "format.credit": "Created by: {0}"
}
```
#### Dynamic Difficulty Names
Automatically generated for each configured difficulty:
```json
{
  "difficulty.Easy": "Easy",
  "difficulty.Medium": "Medium",
  "difficulty.Hard": "Hard",
  "difficulty.Expert": "Expert",
  "difficulty.Nightmare": "Nightmare"
}
```
#### Dynamic Base Content
Automatically generated for each base in RaidableBases:
```json
{
  "base.name.coastal_compound": "Coastal Compound",
  "base.desc.coastal_compound": "A challenging coastal raid base with multiple loot rooms and traps.",
  "base.name.mountain_fortress": "Mountain Fortress",
  "base.desc.mountain_fortress": "An expert-level mountain fortress with heavy defenses."
}
```
### Creating Translations
#### Method 1: Server Admin Manual Translation
1. Plugin automatically creates `oxide/lang/en/RaidSelector.json` with all keys
2. Copy English file to your language:
   ```bash
   cp oxide/lang/en/RaidSelector.json oxide/lang/es/RaidSelector.json
   ```
3. Edit the new file and translate values (keep keys unchanged)
4. Reload plugin: `o.reload RaidSelector`
**Example Spanish Translation:**
```json
{
  "ui.title": "Comprar Base de Asalto",
  "ui.close": "Cerrar",
  "ui.button.buy": "Comprar",
  "ui.button.random": "Aleatorio",
  "ui.label.select_mode": "Seleccionar Modo",
  "difficulty.Easy": "Fácil",
  "difficulty.Medium": "Medio",
  "difficulty.Hard": "Difícil",
  "base.name.coastal_compound": "Complejo Costero"
}
```
#### Method 2: Community Translation
1. Export English template from your server
2. Share with translators (preserve JSON structure)
3. Validate translated JSON: `jq . RaidSelector.json`
4. Upload to `oxide/lang/<language>/` directory
5. Reload plugin
### Player Language Selection
Players' languages are automatically detected from:
1. Steam client language settings (preferred)
2. Server default language (fallback)
**No player commands needed** - translation is automatic based on Steam settings.
### Translation Best Practices
**Do Translate:**
- All text visible to players
- Error messages
- Button labels
- Difficulty names
- Base names and descriptions
**Don't Translate:**
- JSON keys (left side of key:value pairs)
- Format placeholder markers ({0}, {1}, etc.)
- Technical terms in keys (ui., error., base., etc.)
**Keep Format Markers:**
```json
// Correct
"format.credit": "Créé par: {0}"
// Wrong - removes placeholder
"format.credit": "Créé par:"
```
### Updating Translations
When new bases are added to RaidableBases:
1. Reload RaidSelector plugin
2. Plugin automatically adds new keys to all language files
3. Translate new empty keys
4. Reload plugin again
**Existing translations are preserved** - only new keys are added.
### Fallback Behavior
If translation missing or empty:
1. Falls back to English translation
2. If English missing, uses original key/value from configuration
3. Never shows translation keys to players
### Validation
Check language file syntax:
```bash
jq . oxide/lang/es/RaidSelector.json
```
If valid, output is formatted JSON. If invalid, error message shows problem.
### Example Complete Translation File
**Spanish (es/RaidSelector.json):**
```json
{
  "ui.title": "Comprar Base de Asalto",
  "ui.close": "Cerrar",
  "ui.button.close": "Cerrar",
  "ui.button.buy": "Comprar",
  "ui.button.random": "Aleatorio",
  "ui.label.select_mode": "Seleccionar Modo",
  "ui.label.select_base": "Seleccionar Base",
  "ui.label.base_details": "Detalles de la Base",
  "ui.label.cost": "Costo",
  "ui.label.difficulty": "Dificultad",
  "error.no_ui_permission": "No tienes permiso para usar Raid Selector.",
  "error.no_difficulty_access": "No tienes permiso para acceder a ninguna dificultad de asalto.",
  "error.no_buy_specific": "No tienes permiso para comprar asaltos específicos.",
  "error.no_buy_random": "No tienes permiso para comprar asaltos aleatorios.",
  "format.credit": "Creado por: {0}",
  "difficulty.Easy": "Fácil",
  "difficulty.Medium": "Medio",
  "difficulty.Hard": "Difícil",
  "difficulty.Expert": "Experto",
  "difficulty.Nightmare": "Pesadilla",
  "base.name.coastal_compound": "Complejo Costero",
  "base.desc.coastal_compound": "Una base de asalto costera desafiante con múltiples salas de botín y trampas.",
  "base.name.mountain_fortress": "Fortaleza de Montaña",
  "base.desc.mountain_fortress": "Una fortaleza de montaña de nivel experto con defensas pesadas."
}
```
### Troubleshooting Translations
**Translations not showing:**
1. Check language code matches Steam client language
2. Verify JSON syntax is valid
3. Check file is in correct location: `oxide/lang/<code>/RaidSelector.json`
4. Reload plugin after editing: `o.reload RaidSelector`
5. Check console for JSON parsing errors
**Partial translations:**
1. Missing keys fall back to English automatically
2. Add missing keys from English template
3. Empty values fall back to English/config values
**Format strings not working:**
1. Ensure {0}, {1} placeholders are preserved exactly
2. Order matters - {0} is first parameter, {1} is second
3. Don't remove or modify placeholder syntax
---
## Image Support
Display preview images for raid bases using image provider plugins.
### Supported Plugins
**Oxide Servers:**
- ImageLibrary plugin
**Carbon Servers:**
- ImageDatabase (built-in)
### Setup Instructions
#### For Oxide Servers
1. Install ImageLibrary plugin
2. Add `ImageUrl` to base configurations
3. Plugin automatically downloads and caches images on first load
#### For Carbon Servers
1. Ensure ImageDatabase is enabled
2. Add `ImageUrl` to base configurations
3. Plugin automatically downloads and caches images
### Image Configuration
Add to base configuration:
```json
"Bases": {
  "your_base_name": {
    "DisplayName": "Your Base Name",
    "Description": "Base description",
    "ImageUrl": "https://i.imgur.com/yourimage.png",
    "NotBuyable": false
  }
}
```
### Image Best Practices
**Image URLs:**
- Use direct image URLs (not gallery pages)
- Test URLs in browser first
- Prefer HTTPS over HTTP
**Image Hosting:**
- imgur.com (recommended - reliable and fast)
- i.gyazo.com
- Direct server URLs
**Image Specifications:**
- Format: PNG, JPG, JPEG
- Recommended size: 512x512 pixels
- File size: Keep under 2MB for fast loading
- Aspect ratio: Square or 16:9 works best
**Fallback Behavior:**
- If image fails to load: Shows default Rust logo
- If ImageUrl empty: Shows default Rust logo
- If no image plugin: Shows default Rust logo
### Troubleshooting Images
**Images Not Showing:**
1. Check console for image loading errors
2. Verify ImageLibrary/ImageDatabase is installed
3. Test image URL in web browser
4. Check image URL is direct link (ends in .png, .jpg, etc.)
5. Try different image host (imgur recommended)
**Slow Loading:**
1. Check image file size (reduce if over 2MB)
2. Verify server internet connection
3. Use CDN-hosted images when possible
---
## ServerPanel Integration
RaidSelector can be integrated with the ServerPanel plugin to provide unified menu access alongside standalone operation.
### Overview
**ServerPanel** is a popular UI framework that consolidates multiple plugin interfaces into a single unified menu system. RaidSelector supports dual-mode operation:
- **Standalone Mode** - Traditional `/rs` command opens full modal UI
- **ServerPanel Mode** - Access via ServerPanel's category system (embedded UI)
### Benefits
**For Players:**
- Single command (`/info`) to access all server features
- Consistent navigation across plugins
- Professional unified interface
- Still works if ServerPanel not installed
**For Server Owners:**
- Professional appearance with centralized menu
- Better player experience and retention
- Easier onboarding for new players
- No breaking changes to existing setup
### Configuration Settings
Add ServerPanel integration settings to your configuration:
```json
"ServerPanelConfig": {
  "EnableIntegration": true,
  "ServerPanelOnly": false,
  "EnableHeaderFields": false
}
```
#### EnableIntegration
**Type:** `boolean`
**Default:** `true`
**Description:** Enable ServerPanel integration features
**Values:**
- `true` - Plugin registers with ServerPanel if available
- `false` - Standalone mode only (ignore ServerPanel)
**Example:**
```json
"EnableIntegration": true
```
#### ServerPanelOnly
**Type:** `boolean`
**Default:** `false`
**Description:** Disable standalone mode, only allow ServerPanel access
**Values:**
- `true` - Disable `/rs` command, only accessible via ServerPanel
- `false` - Both modes available (recommended)
**Example:**
```json
"ServerPanelOnly": false
```
**Use Cases:**
- `true` - Force all players to use unified ServerPanel menu
- `false` - Allow choice between `/rs` or ServerPanel
#### EnableHeaderFields
**Type:** `boolean`
**Default:** `false`
**Description:** Enable dynamic header fields in ServerPanel (future feature)
**Values:**
- `true` - Display raid statistics in ServerPanel header
- `false` - No header fields
**Example:**
```json
"EnableHeaderFields": false
```
**Note:** This is a future enhancement for displaying dynamic data like available raids count in the ServerPanel header.
### ServerPanel Category Configuration
To add RaidSelector to ServerPanel, edit the ServerPanel configuration file:
**File Location:**
```
oxide/data/ServerPanel/Categories.json
```
**⚠️ Important:** Always backup before editing:
```bash
cd oxide/data/ServerPanel
cp Categories.json Categories.json.backup
```
**Add this category to the `"Categories"` array:**
```json
{
  "categoryID": 1239323938,
  "Category Image": "https://i.imgur.com/YourImage.png",
  "Category Title": "RAID SELECTOR",
  "Category Sub-Title": "Browse and purchase raid bases",
  "Commands": [
    "raidselector",
    "rs"
  ],
  "Description": "Access the raid base selection interface. Choose from available difficulties and browse raid bases you can purchase.",
  "Type (Plugin/UI)": "Plugin",
  "Plugin Name": "RaidSelector",
  "Plugin Hook": "API_OpenPlugin",
  "UI_Name": "",
  "Permission": "",
  "Image Library Names": ""
}
```
**Key Fields:**
- **categoryID** - Unique identifier (use any large unique number like 1239323938)
- **Type (Plugin/UI)** - Must be `"Plugin"` for plugin-based categories
- **Plugin Name** - Must exactly match `"RaidSelector"`
- **Plugin Hook** - Must be `"API_OpenPlugin"` (ServerPanel API method)
- **Commands** - Optional chat commands that open this category
- **Permission** - Leave empty for public access, or set to `"raidselector.use"` for restricted access
### Reload Plugins
After editing ServerPanel configuration, reload both plugins:
```bash
# Via RCON
rcon "o.reload ServerPanel"
rcon "o.reload RaidSelector"
# Or via F1 console (in-game as admin)
o.reload ServerPanel
o.reload RaidSelector
```
### Verify Integration
Check server logs to confirm successful registration:
```bash
tail -50 oxide/logs/oxide_*.txt | grep -E "RaidSelector|ServerPanel"
```
**Expected log output:**
```
[RaidSelector] Registered with ServerPanel ✅
[RaidSelector] ServerPanel category ID: 1239323938 ✅
```
### Testing
**ServerPanel Mode:**
1. Join your Rust server
2. Type `/info` (or your ServerPanel command)
3. Look for the **RAID SELECTOR** category button
4. Click to open RaidSelector within ServerPanel
5. Navigate and purchase raids normally
**Standalone Mode:**
1. Type `/rs` (or your configured chat command)
2. Traditional modal UI opens
3. Verify all functionality works
### UI Differences Between Modes
**Standalone Mode Features:**
- Full modal window with backdrop
- Title bar with plugin name
- Close button (X) in title bar
- Close buttons in each panel
- Positioned in center of screen
**ServerPanel Mode Features:**
- Embedded in ServerPanel content area
- No title bar (ServerPanel provides navigation)
- No close buttons (use ServerPanel back button)
- Fills entire content area
- ServerPanel handles category switching
**Identical Functionality:**
- Three-column layout (difficulty, bases, details)
- All permissions work the same
- Payment processing identical
- Base selection and purchase logic unchanged
### Troubleshooting ServerPanel Integration
**Category doesn't appear in ServerPanel:**
1. Verify JSON syntax is valid:
   ```bash
   jq . oxide/data/ServerPanel/Categories.json
   ```
2. Ensure `categoryID` is unique (not used by other categories)
3. Check `"Plugin Name"` exactly matches `"RaidSelector"`
4. Reload both plugins (ServerPanel first, then RaidSelector)
5. Check logs for registration messages
**UI doesn't render when clicking category:**
1. Check server logs for errors during `API_OpenPlugin` call
2. Verify RaidSelector registered successfully (check logs)
3. Ensure ServerPanel version is 1.3.8 or later
4. Try reloading RaidSelector after ServerPanel loads
5. Verify `EnableIntegration` is `true` in config
**Both modes not working:**
1. If `ServerPanelOnly: true`, standalone mode (`/rs`) is disabled by design
2. Check `EnableIntegration` setting
3. Verify ServerPanel plugin is installed and loaded
4. Check permissions for both access methods
5. Review console for error messages
**Permission issues with ServerPanel:**
1. ServerPanel category `"Permission"` field applies first
2. RaidSelector's own permissions apply second
3. Leave ServerPanel permission empty for public access
4. Or set to `"raidselector.use"` and grant to users:
   ```bash
   o.grant group default raidselector.use
   ```
### Configuration Examples
#### Example 1: Dual-Mode Operation (Recommended)
Allow both ServerPanel and standalone access:
```json
"ChatCommand": "rs",
"RequiresOxidePermission": false,
"ServerPanelConfig": {
  "EnableIntegration": true,
  "ServerPanelOnly": false,
  "EnableHeaderFields": false
}
```
**Result:**
- Players can type `/info` → click RAID SELECTOR category
- Players can also type `/rs` for traditional UI
- Maximum flexibility
#### Example 2: ServerPanel-Only Mode
Force all access through ServerPanel:
```json
"ChatCommand": "rs",
"RequiresOxidePermission": false,
"ServerPanelConfig": {
  "EnableIntegration": true,
  "ServerPanelOnly": true,
  "EnableHeaderFields": false
}
```
**Result:**
- `/rs` command disabled
- Only accessible via ServerPanel `/info` menu
- Unified menu experience only
#### Example 3: Standalone Only (No ServerPanel)
Disable ServerPanel integration:
```json
"ChatCommand": "rs",
"RequiresOxidePermission": false,
"ServerPanelConfig": {
  "EnableIntegration": false,
  "ServerPanelOnly": false,
  "EnableHeaderFields": false
}
```
**Result:**
- `/rs` command works
- Plugin ignores ServerPanel even if installed
- Traditional standalone operation only
### Related Documentation
- **Integration Design:** `docs/design/SERVERPANEL_INTEGRATION_DESIGN.md`
- **Implementation Summary:** `docs/SERVERPANEL_INTEGRATION_SUMMARY.md`
- **Category Example:** `docs/ServerPanelCategoryExample.json`
---
## Commands
### Player Commands
**Open UI:**
```
/rs
```
Opens the RaidSelector interface (customizable via `ChatCommand` setting).
### Admin Commands
**Initialize Language Template:**
```bash
/rsinitlang <language>
rsinitlang <language>
```
Creates or updates a language template file with all translation keys. Preserves existing translations and adds new keys.
**Examples:**
```bash
/rsinitlang es         # Create/update Spanish template
/rsinitlang fr         # Create/update French template
/rsinitlang de         # Create/update German template
rsinitlang ru          # Console version for Russian
```
**Requirements:**
- Admin permission: `raidselector.admin`
- Generates file at: `oxide/lang/<language>/RaidSelector.json`
- Preserves existing translations
- Adds new keys with empty values for translation
- Reports preserved and added key counts
**Reload Plugin:**
```bash
o.reload RaidSelector
```
Reloads the plugin and configuration. Also regenerates language templates.
**Check User Permissions:**
```bash
o.show user PlayerName
o.show user 76561198012345678
```
Shows all permissions granted to a player.
### Permission Commands
**Grant Permission:**
```bash
o.grant group <groupname> <permission>
o.grant user <username> <permission>
o.grant user <steamid> <permission>
```
**Examples:**
```bash
o.grant group default raidselector.can.use
o.grant group vip raidselector.difficulty.expert
o.grant user JohnDoe raidselector.buyraidspecific
o.grant user 76561198012345678 raidselector.buyraidrandom
```
**Revoke Permission:**
```bash
o.revoke group <groupname> <permission>
o.revoke user <username> <permission>
o.revoke user <steamid> <permission>
```
**Examples:**
```bash
o.revoke group default raidselector.buyraidspecific
o.revoke user JohnDoe raidselector.difficulty.expert
```
---
## Troubleshooting
### Plugin Won't Load
**Symptoms:** Plugin doesn't appear in `o.plugins` list
**Solutions:**
1. Check console for error messages
2. Verify RaidableBases is installed
3. Ensure no syntax errors in configuration file
4. Try `o.reload RaidSelector`
5. Check file permissions (Linux servers)
### UI Won't Open
**Symptoms:** `/rs` command does nothing
**Solutions:**
1. Check if player has `raidselector.can.use` permission (if required)
2. Verify `ChatCommand` setting matches command used
3. Check console for errors
4. Try reloading plugin
5. Ensure player is fully loaded into server
### Permission Issues
**Symptoms:** Players can't access features they should be able to
**Solutions:**
1. Verify permissions with `o.show user <player>`
2. Check `DifficultyPermissions` settings
3. Check `BuyButtonPermissions` settings
4. Ensure `RequiresOxidePermission` is set correctly
5. Try `o.reload RaidSelector` after permission changes
### Payment Issues
**Symptoms:** Raids not charging players or purchases failing
**Solutions:**
1. Verify Economics/ServerRewards plugins installed
2. Check costs are configured in RaidableBases settings
3. Verify player has sufficient funds
4. Check console for payment errors
5. Ensure RaidableBases payment settings enabled
### Image Issues
**Symptoms:** Images not displaying in UI
**Solutions:**
1. Check ImageLibrary (Oxide) or ImageDatabase (Carbon) is installed
2. Verify image URLs are direct links
3. Test image URLs in web browser
4. Check console for image loading errors
5. Ensure images are publicly accessible
6. Try different image host (imgur recommended)
### Performance Issues
**Symptoms:** UI lag or slow responses
**Solutions:**
1. Check server performance and resources
2. Verify RaidableBases isn't overloaded
3. Reduce number of custom bases if excessive
4. Check for console errors or warnings
5. Ensure latest plugin version installed
### Localization Issues
**Symptoms:** Translations not showing or wrong language displayed
**Solutions:**
1. Check language file exists at `oxide/lang/<code>/RaidSelector.json`
2. Verify JSON syntax is valid: `jq . oxide/lang/<code>/RaidSelector.json`
3. Check player's Steam client language settings
4. Reload plugin after editing language files: `o.reload RaidSelector`
5. Use `/rsinitlang <code>` to regenerate language template
6. Check console for JSON parsing errors
7. Verify translation keys match exactly (case-sensitive)
**Symptoms:** New bases/difficulties not translated
**Solutions:**
1. Reload plugin to generate new keys automatically
2. Check language file for newly added empty keys
3. Translate new keys and reload plugin again
4. Use `/rsinitlang <code>` to update template file
---
## Examples
### Example 1: Basic Public Server
**Goal:** Everyone can use the plugin, all difficulties available, no restrictions.
**Configuration:**
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": false,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": false,
    "RequiresBuySpecificPermission": false
  },
  "Bases": {}
}
```
**Permissions:** None required
### Example 2: VIP Premium Features
**Goal:** All players can browse, only VIPs can purchase and access Expert/Nightmare.
**Configuration:**
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": false,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Expert": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Nightmare": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": true,
    "RequiresBuySpecificPermission": true
  },
  "Bases": {}
}
```
**Permissions:**
```bash
o.grant group vip raidselector.difficulty.expert
o.grant group vip raidselector.difficulty.nightmare
o.grant group vip raidselector.buyraidspecific
o.grant group vip raidselector.buyraidrandom
```
### Example 3: Progressive Difficulty Access
**Goal:** Players unlock difficulties as they rank up.
**Configuration:**
```json
{
  "ChatCommand": "raids",
  "RequiresOxidePermission": true,
  "Debug": false,
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Expert": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": false,
    "RequiresBuySpecificPermission": false
  },
  "Bases": {}
}
```
**Permissions:**
```bash
# Rank 1 - Easy only
o.grant group rank1 raidselector.can.use
o.grant group rank1 raidselector.difficulty.easy
# Rank 2 - Easy + Medium
o.grant group rank2 raidselector.can.use
o.grant group rank2 raidselector.difficulty.easy
o.grant group rank2 raidselector.difficulty.medium
# Rank 3 - Easy + Medium + Hard
o.grant group rank3 raidselector.can.use
o.grant group rank3 raidselector.difficulty.easy
o.grant group rank3 raidselector.difficulty.medium
o.grant group rank3 raidselector.difficulty.hard
# Rank 4 - All difficulties
o.grant group rank4 raidselector.can.use
o.grant group rank4 raidselector.difficulty.easy
o.grant group rank4 raidselector.difficulty.medium
o.grant group rank4 raidselector.difficulty.hard
o.grant group rank4 raidselector.difficulty.expert
```
### Example 4: Custom Base Configuration
**Goal:** Add custom display information and images for bases.
**Configuration:**
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": false,
  "DifficultyPermissions": { ... },
  "BuyButtonPermissions": { ... },
  "Bases": {
    "coastal_fortress": {
      "DisplayName": "Coastal Fortress",
      "Description": "A heavily fortified coastal base with multiple loot rooms. Features autoturrets, flame traps, and a helipad. Recommended team size: 4-6 players. Bring rockets and C4.",
      "Credit": "Built by AdminTeam",
      "ImageUrl": "https://i.imgur.com/coastal123.png",
      "NotBuyable": false
    },
    "desert_compound": {
      "DisplayName": "Desert Compound",
      "Description": "A sprawling desert compound with external defenses. Watch for land mines and automated defenses. Best approached from the north side.",
      "Credit": "Community Build Contest Winner",
      "ImageUrl": "https://i.imgur.com/desert456.png",
      "NotBuyable": false
    },
    "test_base": {
      "DisplayName": "Test Base",
      "Description": "Internal testing",
      "Credit": "",
      "ImageUrl": "",
      "NotBuyable": true
    }
  }
}
```
### Example 5: Custom Color Theme
**Goal:** Create a military green theme.
**Configuration:**
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": false,
  "Colors": {
    "ModalBackground": "0.1 0.15 0.1 0.98",
    "TitleBarBackground": "0.15 0.25 0.15 1.0",
    "TitleBarText": "0.9 0.95 0.9 1",
    "XButtonBackground": "0.6 0.2 0.2 0.9",
    "XButtonText": "1 1 1 1",
    "LeftPanelBackground": "0.12 0.2 0.12 0.95",
    "DifficultyButtonActiveBackground": "0.3 0.5 0.3 1.0",
    "DifficultyButtonInactiveBackground": "0.2 0.35 0.2 0.8",
    "DifficultyButtonText": "0.9 0.95 0.9 1",
    "CloseButtonBackground": "0.6 0.2 0.2 0.9",
    "CloseButtonText": "1 1 1 1",
    "MiddlePanelBackground": "0.12 0.18 0.12 0.95",
    "BasePanelActiveBackground": "0.25 0.45 0.25 1.0",
    "BasePanelInactiveBackground": "0.18 0.32 0.18 0.8",
    "BasePanelNameText": "0.9 0.95 0.9 1",
    "BasePanelDescText": "0.8 0.85 0.8 1",
    "RandomButtonBackground": "0.25 0.45 0.25 0.9",
    "RightPanelBackground": "0.1 0.18 0.1 0.95",
    "RightPanelDescText": "0.8 0.85 0.8 1",
    "PurchaseButtonBackground": "0.3 0.5 0.3 0.9",
    "PurchaseButtonText": "0.9 0.95 0.9 1",
    "ScrollbarHandleColor": "0.4 0.5 0.4 0.8",
    "ScrollbarHighlightColor": "0.45 0.55 0.45 0.8",
    "ScrollbarPressedColor": "0.35 0.48 0.35 0.8",
    "ScrollbarTrackColor": "0.15 0.2 0.15 0.3"
  },
  "DifficultyPermissions": { ... },
  "BuyButtonPermissions": { ... },
  "ServerPanelConfig": { ... },
  "Bases": {}
}
```
### Example 6: ServerPanel Integration with Multilingual Support
**Goal:** Full-featured server with ServerPanel integration and localization.
**Configuration:**
```json
{
  "ChatCommand": "rs",
  "RequiresOxidePermission": false,
  "Debug": false,
  "Colors": { ... },
  "DifficultyPermissions": {
    "Easy": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Medium": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": false
    },
    "Hard": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    },
    "Expert": {
      "DifficultyActivate": true,
      "RequiresDifficultyPermission": true
    }
  },
  "BuyButtonPermissions": {
    "RequiresBuyRandomPermission": false,
    "RequiresBuySpecificPermission": false
  },
  "ServerPanelConfig": {
    "EnableIntegration": true,
    "ServerPanelOnly": false,
    "EnableHeaderFields": false
  },
  "Bases": {
    "coastal_fortress": {
      "DisplayName": "Coastal Fortress",
      "Description": "A heavily fortified coastal base.",
      "Credit": "AdminTeam",
      "ImageUrl": "https://i.imgur.com/example.png",
      "NotBuyable": false
    }
  }
}
```
**Setup Steps:**
1. Configure ServerPanel category (see ServerPanel Integration section)
2. Grant permissions:
   ```bash
   o.grant group vip raidselector.difficulty.hard
   o.grant group vip raidselector.difficulty.expert
   o.grant group admin raidselector.admin
   ```
3. Generate language templates:
   ```bash
   /rsinitlang en   # English (default)
   /rsinitlang es   # Spanish
   /rsinitlang fr   # French
   ```
4. Edit language files in `oxide/lang/<code>/RaidSelector.json`
5. Reload plugin: `o.reload RaidSelector`
**Features:**
- Accessible via `/info` (ServerPanel) or `/rs` (standalone)
- VIPs can access Hard/Expert difficulties
- Automatic language detection from player's Steam settings
- Custom base information with images
- Admin can manage language templates
---
## Support & Resources
**Documentation:**
- `docs/README.md` - Documentation index
- `docs/changelogs/CHANGELOG_USER.md` - User changelog
- `docs/design/` - Feature design documents
- `docs/development/` - Developer guides
**Version Information:**
- Current Version: 4.9.0
- Release Date: November 15, 2025
- Framework Support: Oxide & Carbon
- Localization: Full multilingual support via external JSON files
**Plugin Dependencies:**
- RaidableBases (required)
- Economics (optional - for currency system)
- ServerRewards (optional - for reward points)
- ImageLibrary (optional - Oxide image support)
- ImageDatabase (optional - Carbon image support)
- ServerPanel (optional - for unified menu integration)
---
*This documentation is maintained by the RaidSelector development team. For technical development information, see the PCM Tools Guide in `docs/development/`.*