/*********************************************************
 * A plugin about accesslevels - Version 1.0             *
 *********************************************************
 *                                                       *
 * Name: plugin_rindy_who                                *
 * Author: Rinde (rinde@fiatnox.de)                      *
 * Released: 09/12/02                                    *
 *                                                       *
 *                                                       *
 * Commands:                                             *
 *                                                       *
 * admin_accesslevel [<target>]: Displays accesslevel of *
 *                               target, own accesslevel *
 *                               if no target is given   *
 *                                                       *
 * admin_who: Displays all admins connected and their    *
 *            accesslevel                                *
 *                                                       *
 * admin_stealth <0|1>: Turn stealth admin mode on for   *
 *                      yourself. Others cannot see your *
 *                      accesslevel if stealthmode is on *
 *                                                       *
 *                                                       *
 * Changelog:                                            *
 *                                                       *
 * Version 1.0                                           *
 *                                                       *
 *  -  Fixed an issue about the default_access binary    *
 *     string always being 11111111111111111             *
 *  -  Fixed an error about admin_who not showing admins *
 *  -  Added connect/disconnect reset for stealth-state  *
 *                                                       *
 * Version 0.9                                           *
 *                                                       *
 *  -  Added feature: Admins can stealth, so others      *
 *                    can't see they are admins.         *
 * Version 0.8                                           *
 *                                                       *
 *  -  Initial release                                   *
 *                                                       *
 *********************************************************/
 
/* Includes */
#include <core>
#include <console>
#include <plugin>
#include <adminlib>
 
/* Constants */
#define ACCESS_LVL ACCESS_ALL
#define ACCESS_STEALTH ACCESS_RCON
 
/* Global Variables */
new g_Version[] = "1.0";
new g_Stealth[MAX_PLAYERS] = {0,0,...};
 
/* Function Declarations */
forward AdminAccesslevel(HLCommand,HLData,HLUserName,UserIndex);
forward AdminWho(HLCommand,HLData,HLUserName,UserIndex);
forward AdminStealth(HLCommand,HLData,HLUserName,UserIndex);
forward user_accesstobin(Target[],Bin[]);
forward default_accesstobin(Bin[]);
forward Sort(Data[MAX_PLAYERS][2]);
 
/* Event Handlers */
public plugin_init() {
    plugin_registerinfo("Rinde's Accesslevel Plugin","Displaying Adminmod accesslevels",g_Version);
    plugin_registercmd("admin_accesslevel","AdminAccesslevel",ACCESS_LVL,"admin_accesslevel [<Target>]: Returns accesslevel of <target>. No target returns own accesslevel.");
    plugin_registercmd("admin_who","AdminWho",ACCESS_LVL,"admin_who: Displays all admins and their accesslevel.");
    plugin_registercmd("admin_stealth","AdminStealth",ACCESS_STEALTH,"admin_stealth <1|0>: Swith stealthmode on|off.");
    return PLUGIN_CONTINUE;
}
 
public plugin_connect(HLUserName,HLIP,UserIndex) {
    g_Stealth[UserIndex] = 0;
    return PLUGIN_CONTINUE;
}
 
public plugin_disconnect(HLUserName,UserIndex) {
    g_Stealth[UserIndex] = 0;
    return PLUGIN_CONTINUE;
}
 
/* Command Handlers */
public AdminAccesslevel(HLCommand,HLData,HLUserName,UserIndex) {
    new Data[MAX_DATA_LENGTH];
    new Target[MAX_NAME_LENGTH];
    new Text[MAX_TEXT_LENGTH];
    new Bin[MAX_NUMBER_LENGTH];
    new i;
    convert_string(HLData, Data, MAX_DATA_LENGTH);
    strstripquotes(Data);
    if(strlen(Data) == 0 && UserIndex == 0) {
        selfmessage("You can execute all commands from the serverconsole, you n00b.");
    } else {
        if(strlen(Data) == 0) {
            selfmessage("Your accesslevel is:");
            user_accesstobin("",Bin);
            selfmessage(Bin);
        } else {
            if(check_user(Data) == 1) {
                get_username(Data,Target,MAX_NAME_LENGTH);
                snprintf(Text,MAX_TEXT_LENGTH,"The accesslevel of %s is:",Target);
                selfmessage(Text);
                get_userindex(Target,i);
                if(g_Stealth[i] == 0 || access(ACCESS_STEALTH,"") == 1) {
                    user_accesstobin(Target,Bin);
                } else {
                    default_accesstobin(Bin);
                }
                selfmessage(Bin);
            } else {
                selfmessage("Unrecognized player:");
                selfmessage(Data);
            }
        }
        default_accesstobin(Bin);
        selfmessage(Bin);
        selfmessage("is the default accesslevel.");
    }
    return PLUGIN_HANDLED;
}
 
public AdminWho(HLCommand,HLData,HLUserName,UserIndex) {
    new MaxPlayers = maxplayercount();
    new Data[MAX_PLAYERS][2];
    new Text[MAX_TEXT_LENGTH];
    new Tag[MAX_PLAYERS][MAX_NUMBER_LENGTH];
    new Name[MAX_NAME_LENGTH];
    new Admins = 0;
    new default_access = getvar("default_access");
    new i,j,k;
    for(i=1;i<=MaxPlayers;i++) {
        if(playerinfo(i,Name,MAX_NAME_LENGTH) == 1) {
            Data[i][1] = 0;
            for(j=131072;j>0;j/=2) {
                if(access(j,Name) == 1) {
                    Data[i][1] += j;
                    Tag[i][k] = '1';
                } else {
                    Tag[i][k] = '0';
                }
                k++;
            }
            k = 0;
            if(Data[i][1] != default_access) {
                Data[i][0] = i;
                Admins++;
            }
        }
    }
    if(Admins > 0) {
        Sort(Data);
        selfmessage("");
        selfmessage("Admins:");
        for(i=1;i<=MaxPlayers;i++) {
            if(Data[i][0] > 0) {
                if(playerinfo(Data[i][0],Name,MAX_NAME_LENGTH) == 1  && (g_Stealth[Data[i][0]] == 0 || access(ACCESS_STEALTH,"") == 1)) {
                    snprintf(Text,MAX_TEXT_LENGTH,"%s %s",Tag[Data[i][0]],Name);
                    selfmessage(Text);
                }
            }
        }
    } else {
        selfmessage("There are no admins on the server.");
    }
    default_accesstobin(Tag[0]);
    selfmessage("");
    selfmessage("The default accesslevel is:");
    selfmessage(Tag[0]);
    return PLUGIN_HANDLED;
}
 
public AdminStealth(HLCommand,HLData,HLUserName,UserIndex) {
    new Data[MAX_DATA_LENGTH];
    new Text[MAX_TEXT_LENGTH];
    convert_string(HLData,Data,MAX_DATA_LENGTH);
    if(strlen(Data) == 0) {
        snprintf(Text,MAX_TEXT_LENGTH,"Stealth mode is ^"%i^"",g_Stealth[UserIndex]);
        selfmessage(Text);
    } else if(check_param(Data) != g_Stealth[UserIndex]) {
        g_Stealth[UserIndex] = check_param(Data);
        snprintf(Text,MAX_TEXT_LENGTH,"Stealth mode changed to ^"%i^"",g_Stealth[UserIndex]);
        selfmessage(Text);
    }
}
 
/* Support Functions */
user_accesstobin(Target[],Bin[]) {
    new i,j;
    for(i=131072;i>0;i/=2) {
        if(access(i,Target) == 1) {
            Bin[j] = '1';
        } else {
            Bin[j] = '0';
        }
        j++;
    }
}
 
default_accesstobin(Bin[]) {
    new default_access = getvar("default_access");
    new i,j;
    for(i=131072;i>0;i/=2) {
        if(i <= default_access) {
            default_access -= i;
            Bin[j] = '1';
        } else {
            Bin[j] = '0';
        }
        j++;
    }
}
 
Sort(Data[MAX_PLAYERS][2]) {
    new MaxPlayers = maxplayercount();
    new i,j,k;
    for(i=2;i<MaxPlayers;i++) {
        for(j=1;j<i;j++) {
            if(Data[i][1] > Data[j][1]) {
                Data[0] = Data[i];
                for(k=i-1;k>=j;k--) {
                    Data[k+1] = Data[k];
                }
                Data[j] = Data[0];
            }
        }
    }
}