Skip to content
This repository was archived by the owner on Sep 11, 2026. It is now read-only.

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

samp-invisibility

Per-viewer administrative invisibility for SA-MP and open.mp using Pawn.RakNet.

Author: WroxExM
Repository: github.com/WroxExM/samp-invisibility
License: MIT

Features

  • Hide administrators from normal players per viewer.
  • Allow staff at INVISIBLE_VIEW_LEVEL or higher to see invisible players.
  • Safe stream-in/stream-out synchronization and RPC_SPAWN_PLAYER filtering.
  • Optional vehicle, damage, weapon, interaction, and normal-chat restrictions.
  • Toggle cooldown, death disable, audit logging, and debug logging.
  • No timers or per-frame loops.

Installation

Include Pawn.RakNet before invisible.inc:

#include <a_samp>
#include <Pawn.RakNet>
#include "invisible.inc"

The library does not define normal server callbacks. It uses this required gamemode callback to read admin levels:

public GetInvisibleAdminLevel(playerid)
{
    return PlayerInfo[playerid][pAdmin];
}

Configuration

Define these before including the file:

#define INVISIBLE_ADMIN_LEVEL       (6)
#define INVISIBLE_VIEW_LEVEL        (6)
#define INVISIBLE_BLOCK_VEHICLES    (1)
#define INVISIBLE_BLOCK_DAMAGE      (1)
#define INVISIBLE_COOLDOWN          (3000)
#define INVISIBLE_DISABLE_ON_DEATH  (1)
#define INVISIBLE_BLOCK_NORMAL_CHAT (0)

1 enables a restriction, 0 disables it, and cooldown is in milliseconds. Optional INVISIBLE_DEBUG prints changes. Optional INVISIBLE_AUDIT_LOG(playerid, enabled) can connect your audit logger.

State and permission functions

SetPlayerInvisible(playerid, bool:toggle);
TogglePlayerInvisible(playerid);
IsPlayerInvisible(playerid);
IsInvisibleAdmin(playerid);
CanSeeInvisiblePlayer(viewerid, targetid);
CanEnableInvisible(playerid);
CheckInvisiblePermission(playerid);

TogglePlayerInvisible checks admin permission and cooldown. Call CheckInvisiblePermission after changing a player's admin level.

Lifecycle and refresh functions

RefreshInvisiblePlayer(playerid);
RefreshInvisibleViewer(viewerid);
ResetInvisiblePlayer(playerid);
OnInvisiblePlayerConnect(playerid);
OnInvisiblePlayerDisconnect(playerid);
OnInvisiblePlayerSpawn(playerid);
OnInvisiblePlayerDeath(playerid);
OnInvisiblePlayerStreamIn(playerid, forplayerid);
OnInvisiblePlayerStreamOut(playerid, forplayerid);

Call the matching lifecycle function from OnPlayerConnect, OnPlayerDisconnect, OnPlayerSpawn, OnPlayerDeath, OnPlayerStreamIn, and OnPlayerStreamOut. Refresh after admin-level, world, or interior changes.

Restriction and callback helpers

CanUseInvisibleInteraction(playerid);
CanUseInvisibleChat(playerid);
OnInvisiblePlayerText(playerid);
CanUseInvisibleVehicle(playerid);
OnInvisiblePlayerEnterVehicle(playerid, vehicleid, ispassenger);
OnInvisiblePlayerStateChange(playerid, newstate, oldstate);
CanUseInvisibleCombat(playerid);
OnInvisiblePlayerWeaponShot(playerid);
OnInvisiblePlayerGiveDamage(attackerid, damagedid);
OnInvisiblePlayerTakeDamage(playerid, issuerid);

Example callback integration:

public OnPlayerText(playerid, text[])
{
    #pragma unused text
    return OnInvisiblePlayerText(playerid);
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
    OnInvisiblePlayerStateChange(playerid, newstate, oldstate);
    return 1;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
    return OnInvisiblePlayerEnterVehicle(playerid, vehicleid, ispassenger);

Return the weapon and damage helper results from their corresponding callbacks. Combine the result if another system also uses those callback return values.

Low-level helpers

SendPlayerRemove(targetid, viewerid);
SendPlayerSpawn(targetid, viewerid);
HideInvisiblePlayer(targetid, viewerid);
ShowInvisiblePlayer(targetid, viewerid);
ShouldBlockInvisibleDamage(attackerid, damagedid);
LogInvisibleChange(playerid, bool:enabled);

Normally use lifecycle and refresh functions instead of sending packets directly.

Custom systems

Before showing labels, nametags, GPS markers, AFK indicators, tracking results, attached objects, voice streams, or custom UI, check:

if (CanSeeInvisiblePlayer(viewerid, targetid))
{
    // Show the custom player-related element.
}

Invisibility is runtime-only and resets on disconnect. Plugin-owned objects, labels, voice streams, and tracking systems need their own integration. Test with the exact client, server, and Pawn.RakNet versions used by your project.

Contributing

Issues and pull requests are welcome at the GitHub repository.

About

A lightweight and advanced player invisibility library for open.mp/SA-MP, built with Pawn.RakNet. Supports per-viewer visibility, safe streaming, staff visibility levels, and synchronization handling.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages