BannedItems

  • community
  • anti-cheat
  • by limon
  • Takaro v0.0.24
  • all
Version
View export JSON

Banned Items Module: Tiered Item Restriction System

Manage which items players can possess based on permission tiers, with configurable warnings and punishments for violations.

Key Features:

Tiered Items Configuration

  • Permission-Based Item Control: Restrict items based on player permission tiers. Players need the ALLOW_ITEMS_TIER permission with a count value equal to or greater than an item's required tier to possess it.
  • Item Tier System: Assign different restriction levels to items - higher tier numbers indicate more restricted items that require higher permission levels.
  • Global Immunity: Grant certain roles complete immunity to all item restrictions with the BANNED_ITEMS_IMMUNITY permission.

Permission Role Configuration

  • Configurable Enforcement:
    • Set the number of warnings before punishment
    • Choose punishment type: warn only, kick, or ban
    • Configure ban duration and customized messages

Warning Configuration

  • Automated Inventory Scanning: The module automatically scans player inventories and detects unauthorized items based on permission tiers.
  • Discord Integration: Receive detailed notifications in Discord when violations occur, including player information, tier level, and unauthorized items.

Discord Notification

  • In-Game Notifications: Players receive clear warnings about unauthorized items with information about how many warnings they have before facing punishment.
  • Server-Wide Announcements: When players are kicked or banned for violations, an announcement is made to all players.

Kick Message

How the Permission Tier System Works:

  1. Assign Tiers to Items: Configure which items are restricted and what permission tier is required to possess them.
  2. Set Role Permissions: Give player roles the ALLOW_ITEMS_TIER permission with a count value representing their tier level.
  3. Automatic Enforcement: Players can only possess items with a required tier that is equal to or lower than their permission tier.

Role Permission Count

Example Usage:

  • Set powerful weapons to tier 3, requiring a higher permission level
  • Set basic resources to tier 1, allowing most players to have them
  • Grant VIP players tier 2 access, giving them more item options than regular players
  • Assign tier 99 to completely ban items for everyone except those with immunity

Perfect For:

  • Servers with tiered player ranks (VIP, donor, etc.)
  • PvP servers wanting to balance gameplay by restricting higher-tier equipment
  • Roleplaying servers with progression-based item access
  • Any server wanting to prevent certain items from being used/exploited

Configuration 8

Settings you fill in when installing the module on a server.

SettingTypeDefaultDescription
bannedItemsWithPermissions required Tiered Items array List of items that require a specific tier permission to possess. Players need ALLOW_ITEMS_TIER permission with a count equal to or greater than the required tier to possess these items. Players with BANNED_ITEMS_IMMUNITY can possess any items regardless of tier.
warningsBeforePunishment required Warnings Before Punishment number 1 Number of warnings a player receives before punishment is applied
punishmentType required Punishment Type string "kick" What happens when a player has unauthorized items too many times
banDuration Ban Duration number 86400000 How long a player is banned for (if ban is selected)
kickMessage Kick Message string "You were kicked for possessing unauthorized items: {items}" Message to display when a player is kicked (use {items} to list all unauthorized items)
discordChannelId Discord Channel ID string "" Discord channel ID where notifications about players with banned items will be sent. Leave empty to disable Discord notifications.
banMessage Ban Message string "You were banned for possessing unauthorized items: {items}" Message to display when a player is banned (use {items} to list all unauthorized items)
warningMessage Warning Message string "The following items are not allowed with your permission level: {items}. Please dispose of them immediately." Message to display when warning a player (use {items} to list all unauthorized items)
Raw config schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "bannedItemsWithPermissions": {
      "x-component": "item",
      "type": "array",
      "title": "Tiered Items",
      "description": "List of items that require a specific tier permission to possess. Players need ALLOW_ITEMS_TIER permission with a count equal to or greater than the required tier to possess these items. Players with BANNED_ITEMS_IMMUNITY can possess any items regardless of tier.",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "title": "Tiered Item",
        "properties": {
          "item": {
            "type": "string",
            "title": "Item"
          },
          "tier": {
            "type": "number",
            "title": "Required Tier",
            "description": "The permission tier required to possess this item. Higher numbers indicate more restricted items.",
            "minimum": 1,
            "default": 1
          }
        },
        "required": [
          "item",
          "tier"
        ]
      }
    },
    "warningsBeforePunishment": {
      "title": "Warnings Before Punishment",
      "type": "number",
      "description": "Number of warnings a player receives before punishment is applied",
      "default": 1,
      "minimum": 1
    },
    "punishmentType": {
      "title": "Punishment Type",
      "type": "string",
      "enum": [
        "none",
        "kick",
        "ban"
      ],
      "default": "kick",
      "description": "What happens when a player has unauthorized items too many times"
    },
    "banDuration": {
      "title": "Ban Duration",
      "x-component": "duration",
      "type": "number",
      "description": "How long a player is banned for (if ban is selected)",
      "default": 86400000,
      "minimum": 0
    },
    "kickMessage": {
      "title": "Kick Message",
      "type": "string",
      "description": "Message to display when a player is kicked (use {items} to list all unauthorized items)",
      "default": "You were kicked for possessing unauthorized items: {items}"
    },
    "discordChannelId": {
      "title": "Discord Channel ID",
      "type": "string",
      "description": "Discord channel ID where notifications about players with banned items will be sent. Leave empty to disable Discord notifications.",
      "default": ""
    },
    "banMessage": {
      "title": "Ban Message",
      "type": "string",
      "description": "Message to display when a player is banned (use {items} to list all unauthorized items)",
      "default": "You were banned for possessing unauthorized items: {items}"
    },
    "warningMessage": {
      "title": "Warning Message",
      "type": "string",
      "description": "Message to display when warning a player (use {items} to list all unauthorized items)",
      "default": "The following items are not allowed with your permission level: {items}. Please dispose of them immediately."
    }
  },
  "required": [
    "bannedItemsWithPermissions",
    "warningsBeforePunishment",
    "punishmentType"
  ],
  "additionalProperties": false
}
Raw UI schema
{
  "bannedItemsWithPermissions": {
    "items": {
      "item": {
        "ui:widget": "item"
      }
    }
  },
  "banDuration": {
    "ui:widget": "duration"
  }
}

Cron jobs 1

Work the module runs on a schedule.

  • bannedItems

    Cron job source
    import { takaro, data, checkPermission } from '@takaro/helpers';
    
    async function main() {
        const { module: mod, gameServerId } = data;
        const {
            bannedItemsWithPermissions,
            warningsBeforePunishment,
            punishmentType,
            banDuration,
            kickMessage,
            banMessage,
            warningMessage,
            warningExpirationHours = 24, // Default to 24 hours if not specified
            discordChannelId // New discord channel ID field
        } = data.module.userConfig;
    
        // Get all online players
        const playersResponse = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({
            filters: {
                gameServerId: [gameServerId],
                online: [true]
            }
        });
    
        // No players online, exit early
        if (!playersResponse.data.data.length) {
            return;
        }
    
        // Get all banned items in one query
        const itemIds = bannedItemsWithPermissions.map(entry => entry.item);
    
        // If no banned items configured, exit early
        if (!itemIds.length) {
            return;
        }
    
        const itemResponse = await takaro.item.itemControllerSearch({
            filters: {
                id: itemIds,
                gameserverId: [gameServerId]
            }
        });
    
        // Create lookup Maps for banned items with their tier requirements
        const bannedItemsMap = new Map();
    
        // Process each banned item and link it with its tier requirement
        for (const item of itemResponse.data.data) {
            // Find the config entry for this item to get its tier
            const configEntry = bannedItemsWithPermissions.find(entry => entry.item === item.id);
            if (configEntry && configEntry.tier) {
                // Store only by EXACT code for more precise matching
                bannedItemsMap.set(item.code, {
                    item,
                    requiredTier: parseInt(configEntry.tier, 10)
                });
            }
        }
    
        // If no valid banned items mapped, exit early
        if (!bannedItemsMap.size) {
            return;
        }
    
        // Get server information for Discord notifications
        const serverInfo = (await takaro.gameserver.gameServerControllerGetOne(gameServerId)).data.data;
    
        // Process each player
        for (const player of playersResponse.data.data) {
            // Skip if player has no inventory
            if (!player.inventory || !player.inventory.length) {
                continue;
            }
    
            // Check if player has global immunity
            const pog = (await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(
                gameServerId, player.player.id)).data.data;
            const hasGlobalImmunity = checkPermission(pog, 'BANNED_ITEMS_IMMUNITY');
    
            if (hasGlobalImmunity) {
                continue; // Skip this player entirely
            }
    
            // Get player's item tier permission
            const tierPermission = checkPermission(pog, 'ALLOW_ITEMS_TIER');
            const playerTier = tierPermission ? tierPermission.count || 0 : 0;
    
            // Find all unauthorized items this player has
            let unauthorizedItems = [];
    
            // Check each item in player's inventory
            for (const invItem of player.inventory) {
                // Only match by exact code
                const bannedItemData = bannedItemsMap.get(invItem.code);
    
                if (!bannedItemData) {
                    // Not a banned item
                    continue;
                }
    
                // Check if player's tier is high enough
                if (playerTier < bannedItemData.requiredTier) {
                    unauthorizedItems.push({
                        item: invItem,
                        requiredTier: bannedItemData.requiredTier
                    });
                }
            }
    
            // If no unauthorized items, continue to next player
            if (unauthorizedItems.length === 0) {
                continue;
            }
    
            // Get current warnings
            const existingVariable = await takaro.variable.variableControllerSearch({
                filters: {
                    playerId: [player.player.id],
                    gameServerId: [gameServerId],
                    moduleId: [mod.moduleId],
                    key: ['banned_items_warning'],
                },
            });
    
            let currentWarnings = existingVariable.data.data[0]
                ? parseInt(existingVariable.data.data[0].value, 10)
                : 0;
    
            currentWarnings++;
    
            // Create a different message format for player vs discord
    
            // For players - simple item names without tier info
            const playerItemsList = unauthorizedItems.map(item => item.item.name).join(", ");
    
            // For Discord - detailed item names with tier requirements
            const discordItemsList = unauthorizedItems.map(item =>
                `${item.item.name} (requires Tier ${item.requiredTier})`
            ).join(", ");
    
            // Calculate expiration date (default to 24 hours from now)
            const now = new Date();
            const expiresAt = new Date(now.getTime() + (warningExpirationHours * 60 * 60 * 1000));
    
            // Send Discord notification if channel ID is provided
            if (discordChannelId && discordChannelId.trim() !== '') {
                // For 7 Days to Die, we need to use the steamId from the player profile
                // instead of the gameId which has a different format
    
                // We'll need to check if we can get the proper Steam ID
                // This might require fetching the player profile from Takaro first
    
                // Try to get steamId from player object if available
                const steamId = player.player.steamId || "76561199524039401"; // Fallback to the known steamId if needed
    
                // Create a detailed message for Discord with cleaner Markdown formatting
                let discordMessage = `🚨 **Banned Item Alert: ${player.player.name}**\n` +
                    `**Player**: [${player.player.name}](https://steamcommunity.com/profiles/${steamId})\n` +
                    `**Game ID**: ${player.gameId}\n` +
                    `**Server**: ${serverInfo.name}\n` +
                    `**Player Tier**: ${playerTier}\n` +
                    `**Warning**: ${currentWarnings}/${warningsBeforePunishment}\n` +
                    `**Action**: ${currentWarnings >= warningsBeforePunishment ?
                        (punishmentType === 'none' ? 'Warning Only' : punishmentType) :
                        'Warning'}\n` +
                    `**Banned Items**: ${discordItemsList}\n` +
                    `**Links**: [Steam](https://steamcommunity.com/profiles/${steamId}) | [Takaro](https://dashboard.takaro.io/player/${player.player.id}/info)`;
                // Send to Discord with the correct function
                try {
                    await takaro.discord.discordControllerSendMessage(discordChannelId, {
                        message: discordMessage
                    });
                } catch (error) {
                    // Log error but continue execution
                    console.error(`Failed to send Discord notification: ${error.message}`);
                }
            }
    
            // Handle punishment if warnings exceeded
            if (currentWarnings >= warningsBeforePunishment && punishmentType !== 'none') {
                if (punishmentType === 'kick') {
                    await takaro.gameserver.gameServerControllerKickPlayer(gameServerId, player.player.id, {
                        reason: `Unauthorized items: ${playerItemsList}`
                    });
    
                    // Announce to all players that someone was kicked
                    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
                        message: `${player.player.name} has been kicked for having unauthorized items: ${playerItemsList}`
                    });
                } else if (punishmentType === 'ban') {
                    const banExpiresAt = new Date(now.getTime() + banDuration);
                    await takaro.player.banControllerCreate({
                        gameServerId,
                        playerId: player.player.id,
                        until: banExpiresAt,
                        reason: `Unauthorized items: ${playerItemsList}`
                    });
    
                    // Announce to all players that someone was banned
                    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
                        message: `${player.player.name} has been banned for having unauthorized items: ${playerItemsList}`
                    });
                }
    
                // Reset warnings after punishment
                if (existingVariable.data.data.length) {
                    await takaro.variable.variableControllerDelete(existingVariable.data.data[0].id);
                }
            } else {
                // Handle warning - SIMPLIFIED for player
                let message = `The following items are not allowed with your permission level: ${playerItemsList}. Please dispose of them immediately.`;
    
                if (punishmentType !== 'none') {
                    message += ` Warning ${currentWarnings} of ${warningsBeforePunishment} before ${punishmentType}`;
                }
    
                // No expiration time details for player
    
                // Send warning message PRIVATELY to the specific player only
                await takaro.gameserver.gameServerControllerSendMessage(
                    gameServerId,
                    {
                        message,
                        opts: {
                            recipient: {
                                gameId: player.gameId
                            }
                        }
                    }
                );
    
                // Update warning count with expiration time
                if (existingVariable.data.data.length) {
                    await takaro.variable.variableControllerUpdate(existingVariable.data.data[0].id, {
                        value: currentWarnings.toString(),
                        expiresAt: expiresAt
                    });
                } else {
                    await takaro.variable.variableControllerCreate({
                        playerId: player.player.id,
                        gameServerId: gameServerId,
                        moduleId: mod.moduleId,
                        key: 'banned_items_warning',
                        value: currentWarnings.toString(),
                        expiresAt: expiresAt
                    });
                }
            }
        }
    }
    
    await main();

Permissions 2

Roles you can grant to decide who may use what.

  • Banned Items Immunity

    Players with this permission are immune to all item bans regardless of item permissions

  • Allow Items for TIer

    Allow player to possess tier items. the count connected to the item will allow it for that role