Skip to content
RustPluginGenerator

OnCardSwipe

OnCardSwipe is called when a player swipes a keycard on a CardReader, before the card is matched against the reader's access level and before the door or device is powered.

Signature
object OnCardSwipe(CardReader cardReader, Keycard keycard, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
cardReaderCardReaderThe CardReader entity that was swiped. Use its position or owner for logging and access control.
keycardKeycardThe Keycard entity read from the swipe message. Its amount tracks remaining uses and its access level is keycard.accessLevel (0-3).
playerBasePlayerThe BasePlayer who performed the swipe. Check permissions, team, or block access here.

Return value

Returning a non-null value stops the original method, so the reader does not validate the keycard and does not trigger its output. Returning null (or nothing) lets the game continue with its normal access-level check and power output.

How it works

Fires inside CardReader.ServerCardSwiped after the swipe message has been validated and the swipe sound effect has been played. The hook runs before the game compares the keycard against the reader and before any power output is triggered, so it is the correct place to grant or deny access. cardReader is the entity, keycard is the Keycard entity (check keycard.accessLevel for its tier and keycard.GetItem() for its item), and player is the swiping player. Because the game passes the keycard entity, a null keycard never reaches your hook — the method returns early when the entity lookup fails. Declaring cardReader as CardReader (not a base type) is required for the hook to fire at all. Note the card has already been charged one use or the swipe effect played by the time you see it; the access check itself has not run yet.

Example plugin: Grant keycard access to team members without a matching card

TeamCardAccess.cs
using System.Linq;
using System;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("TeamCardAccess", "RustPluginGenerator", "1.0.0")]
    [Description("Lets players on the reader owner's team bypass keycard access checks.")]
    public class TeamCardAccess : RustPlugin
    {
        private const string PermUse = "teamcardaccess.use";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Grant team members access")]
            public bool GrantTeammates { get; set; } = true;

            [JsonProperty("Required permission")]
            public bool RequirePermission { get; set; } = true;
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
        }

        private object OnCardSwipe(CardReader cardReader, Keycard keycard, BasePlayer player)
        {
            if (cardReader == null || player == null || keycard == null) return null;
            if (!config.GrantTeammates) return null;
            if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse)) return null;

            ulong ownerId = cardReader.OwnerID;
            if (ownerId == 0UL) return null;

            BasePlayer owner = BasePlayer.FindByID(ownerId);
            if (owner == null) return null;

            ulong ownerTeam = owner.currentTeam;
            if (ownerTeam == 0UL) return null;

            if (player.currentTeam != ownerTeam) return null;
            if (player.userID == ownerId) return null;

            var team = RelationshipManager.ServerInstance.FindTeam(ownerTeam);
            if (team == null || !team.members.Contains(player.userID)) return null;

            return true;
        }
    }
}

The plugin lets anyone on the same team as the card reader's owner pass its swipe check, even when their card level is too low. In OnCardSwipe it resolves the owner with cardReader.OwnerID, finds that player's team via RelationshipManager.ServerInstance.FindTeam, and checks whether the swiper is in team.members. Access is also gated behind a permission so only players with teamcardaccess.use get the bypass. When both conditions pass, the hook returns true to short-circuit the game's access comparison and power the door or turret. A config toggle lets admins disable the feature without unloading the plugin.

Common use cases

  • Team-based bypass

    Let teammates open keycard doors even with the wrong card tier by checking currentTeam against the reader's owner team and returning non-null.

  • Card use limits

    Track swipes per player per reader and return non-null to deny access once a configurable limit is hit, effectively acting as a rate limiter.

  • Audit and notifications

    Log every swipe with the player, card level, and reader position, or notify admins in chat when a non-authorized player tries a high-tier reader.

Pitfalls

  • Returning false still blocks

    Any non-null return, including false, stops the original path. If you only want to observe a swipe, return null explicitly or fall through without a return value.

  • Card is charged before the hook

    The swipe effect and message handling run before the hook is called, so denying access does not refund the card use. Do not assume a returned value prevents cost.

  • OwnerID is not always a player

    Doors owned by deployables or spawned without a player may report 0. Guard against a missing team or the lookup returns null and the bypass check throws.

Build a plugin with OnCardSwipe

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Team-based bypass using the OnCardSwipe hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnCardSwipe

Generate