View Single Post
DJBosma
Member
Join Date: Dec 2009
Old 03-31-2020 , 17:38   Re: is_user_admin(id) , does not check after map change
Reply With Quote #64

Quote:
Originally Posted by Bugsy View Post
I just tested it myself and I retain flags after a map change. I am not going to keep tweaking the code to make it comply with your other plugins.
I believe the whole idea of my thread was to find a plugin to comply with my server. In the beginning, I clearly stated that I worked with AmxBans, now with GM-x and only needed a resolution for this issue, which is basically the thread title. You were the one who proposed to write a plugin if I recall?

This is the plugin which handles the flags, it would be great if you can implement the veteran feature in there..

PHP Code:
#include <amxmodx>
#include <uac>
#include <grip>
#include <gmx>
#include <gmx_cache>

#pragma semicolon 1

#define LOG_ADMIN_ACTIVITY  // Just added the function, no calibrating is made
// #define LOAD_USERS_INI //Load admins from filename

#define CHANGE_NICK_HOOK 2 // 0 - amxmodx, 1 - fakemeta, 2 - reapi

#if CHANGE_NICK_HOOK == 1
#include <fakemeta>
#elseif CHANGE_NICK_HOOK == 2
#include <reapi>
#endif

#if defined LOG_ADMIN_ACTIVITY
new LogFile;
#endif

#define CHECK_NATIVE_ARGS_NUM(%1,%2,%3) \
    
if (%< %2) { \
        
log_error(AMX_ERR_NATIVE"Invalid num of arguments %d. Expected %d", %1, %2); \
        return %
3; \
    }

#define CHECK_NATIVE_PLAYER(%1,%2) \
    
if (!is_user_connected(%1)) { \
        
log_error(AMX_ERR_NATIVE"Invalid player %d", %1); \
        return %
2; \
    }

#define TIMEOUT_TASK_ID 1

const MAX_KEY_LENGTH MAX_AUTHID_LENGTH 2;

enum {
    
FWD_Loading,
    
FWD_Loaded,
    
FWD_Checking,
    
FWD_Checked,
    
FWD_Pushing,
    
FWD_Pushed,

    
FWD_LAST
};

new 
Forwards[FWD_LAST], FReturn;

enum _:LoadStatus {
    
LoadSource,
    
bool:LoadLoaded
};

new 
LoadStatusList[5][LoadStatus], LoadStatusNumPluginLoadedNum;

enum {
    
STATUS_LOADING,
    
STATUS_LOADED
};

new 
Status;

new 
bool:NeedRecheck false;

enum (+=1) {
    
MODE_DISABLE 0,
    
MODE_NORMAL,
    
MODE_KICK
}
// Mode of logging to a server
// 0 - disable logging, players won't be checked (and access won't be set)
// 1 - normal mode which obey flags set in accounts
// 2 - kick all players not on list
new Mode;

/**
* s - STEAM_ID
* i - IP
* n - NAME
* c - CASESENSITIVE
* t - CLAN TAG
*/
new SearchPriority[32];

new 
KickReason[64];
new 
PasswordField[10];

enum {
    
DefaultAccessCvar,
    
DefaultAccessFlags
}
enum (+=1) {
    
DefaultAccessPlayer 0,
    
DefaultAccessHLTV,
    
DefaultAccessBOT,
    
    
DefaultAccessLast
}

new 
DefaultAccess[DefaultAccessLast][2];

enum (<<=1) {
    
STATE_DISCONNECTED 1,
    
STATE_CONNECTING,
    
STATE_CONNECTED,
}

#define STATES_SET_ID                1
#define add_user_state(%1,%2)         set_user_flags(%1, %2, STATES_SET_ID)
#define get_user_state(%1,%2)         (get_user_flags(%1, STATES_SET_ID) & %2)
#define remove_user_state(%1,%2)     remove_user_flags(%1, %2, STATES_SET_ID)
#define clear_user_state(%1)         remove_user_flags(%1, -1, STATES_SET_ID)
#define clear_privilege() arrayset(Privilege, 0 , sizeof Privilege)
#define clear_user_privilege(%1) arrayset(UsersPrivilege[%1], 0 , sizeof UsersPrivilege[])

enum CheckResult {
    
CHECK_IGNORE,
    
CHECK_DEFAULT,
    
CHECK_SUCCESS,
    
CHECK_KICK,
};

enum _:PrivilegeStruct {
    
PrivilegeSource,
    
PrivilegeId,
    
PrivilegeAccess,
    
PrivilegeFlags,
    
PrivilegePassword[UAC_MAX_PASSWORD_LENGTH],
    
PrivilegePrefix[UAC_MAX_PREFIX_LENGTH],
    
PrivilegeExpired,
    
PrivilegeOptions
};

new 
PluginId;
new 
Trie:PrivilegesPrivilege[PrivilegeStruct];
new 
UsersPrivilege[MAX_PLAYERS 1][PrivilegeStruct];

new 
Snapshot:PrivilegesSnapshot Invalid_SnapshotPrivilegesIterate 0;

new 
bool:Loaded false;
new 
bool:GMXLoaded falsebool:UACLoading false;

enum {
    
GMX_REQ_STATUS_ERROR 0,
    
GMX_REQ_STATUS_OK 1
};

enum AUTH_TYPE {
    
AUTH_TYPE_STEAM,
    
AUTH_TYPE_STEAM_AND_PASS,
    
AUTH_TYPE_NICK_AND_PASS,
    
AUTH_TYPE_STEAM_AND_HASH,
    
AUTH_TYPE_NICK_AND_HASH
};

enum _:GroupInfo {
    
GroupId,
    
GroupTitle[UAC_GROUP_MAX_TITLE_LENGTH],
    
GroupFlags,
    
GroupPriority,
    
GroupPrefix[UAC_MAX_PREFIX_LENGTH]
}

new Array:
Groups Invalid_ArrayGroupsNumGroup[GroupInfo];

public 
plugin_init() {
    
PluginId register_plugin("[UAC] Core"UAC_VERSION_STR"GM-X Team");

    
register_concmd("dex_reloadadmins""CmdReload"ADMIN_CVAR);

#if defined _reapi_included
    
RegisterHookChain(RG_CBasePlayer_SetClientUserInfoName"CBasePlayer_SetClientUserInfoName_Post"true);
#elseif defined _fakemeta_included
    
register_forward(FM_SetClientKeyValue"SetCleintKeyValue_Post"true);
#endif
    
    
new pcvar;
    
pcvar create_cvar("dex_mode""1", .has_min=true, .min_val=0.0, .has_max=true, .max_val=2.0);
    
bind_pcvar_num(pcvarMode);
    
    
pcvar create_cvar("pmm_search_priority""sinct");
    
bind_pcvar_string(pcvarSearchPrioritycharsmax(SearchPriority));

    
pcvar create_cvar("dex_password_field""_dex");
    
bind_pcvar_string(pcvarPasswordFieldcharsmax(PasswordField));
    
    
DefaultAccess[DefaultAccessPlayer][DefaultAccessCvar] = create_cvar("dex_default_access""z");
    
DefaultAccess[DefaultAccessHLTV][DefaultAccessCvar] = create_cvar("pmm_hltv_access""a");
    
DefaultAccess[DefaultAccessBOT][DefaultAccessCvar] = create_cvar("pmm_bot_access""a");
    
    
hook_cvar_change(DefaultAccess[DefaultAccessPlayer][DefaultAccessCvar], "CvarChangeAccess");
    
hook_cvar_change(DefaultAccess[DefaultAccessHLTV][DefaultAccessCvar], "CvarChangeAccess");
    
hook_cvar_change(DefaultAccess[DefaultAccessBOT][DefaultAccessCvar], "CvarChangeAccess");

    
Privileges TrieCreate();

    
Forwards[FWD_Loading] = CreateMultiForward("UAC_Loading"ET_IGNORE);
    
Forwards[FWD_Loaded] = CreateMultiForward("UAC_Loaded"ET_IGNORE);
    
Forwards[FWD_Checking] = CreateMultiForward("UAC_Checking"ET_STOPFP_CELL);
    
Forwards[FWD_Checked] = CreateMultiForward("UAC_Checked"ET_IGNOREFP_CELLFP_CELL);
    
Forwards[FWD_Pushing] = CreateMultiForward("UAC_Pushing"ET_IGNORE);
    
Forwards[FWD_Pushed] = CreateMultiForward("UAC_Pushed"ET_IGNORE);

    
loadStart();
}

public 
plugin_cfg() {
    
Mode get_cvar_num("dex_mode");
    for (new 
0flags[32]; DefaultAccessLasti++) {
        
get_pcvar_string(DefaultAccess[i][DefaultAccessCvar], flagscharsmax(flags));
        
DefaultAccess[i][DefaultAccessFlags] = read_flags(flags);
    }
    
checkAPIVersion();
    
    
#if defined LOG_ADMIN_ACTIVITY
    
new path[128];
    
get_localinfo("amxx_logs"pathcharsmax(path));

    
add(pathcharsmax(path), "/user-access-control");
    if (!
dir_exists(path)) {
        
mkdir(path);
    }

    new 
time[16];
    
get_time("/L%Y%m%d.log"timecharsmax(time));
    
add(pathcharsmax(path), time);

    new 
map[64];
    
get_mapname(mapcharsmax(map));

    
LogFile fopen(path"at");
    if (!
LogFile) {
        
set_fail_state("Couldn't open %s for write. Check permissions."path);
    } else {
        
fprintf(LogFile"Start of log session (map %s)"map);
    }
    
#endif
    
}

public 
plugin_end() {
    
TrieDestroy(Privileges);

    for (new 
0FWD_LASTi++) {
        
DestroyForward(Forwards[i]);
    }
    
    if (
PrivilegesSnapshot != Invalid_Snapshot) {
        
TrieSnapshotDestroy(PrivilegesSnapshot);
    }
    
    
#if defined LOG_ADMIN_ACTIVITY
    
fclose(LogFile);
    
#endif
    
}

public 
CvarChangeAccess(const pcvar, const oldValue[], const newValue[]) {
    for (new 
0DefaultAccessLasti++) {
        if (
pcvar == DefaultAccess[i][DefaultAccessCvar]) {
            
DefaultAccess[i][DefaultAccessFlags] = read_flags(newValue);
            break;
        }
    }
}

public 
CmdReload(idlevel) {
    if (~
get_user_flags(id) & level) {
        
console_print(id"You have no access to that command");
        return 
PLUGIN_HANDLED;
    }

    
TrieClear(Privileges);
    
NeedRecheck true;
    
loadStart();
    return 
PLUGIN_HANDLED;
}

public 
client_connect(id) {
    if (
Status == STATUS_LOADING) {
        
NeedRecheck true;
    }
    
clear_user_state(id);
    
clear_user_privilege(id);
    
remove_user_flags(id, -1);
}

public 
client_authorized(id) {
    
add_user_state(idSTATE_CONNECTING);
    
makeUserAccess(idcheckUserFlags(id));
}

public 
client_putinserver(id) {
    if (
get_user_state(idSTATE_CONNECTING)) {
        
remove_user_state(idSTATE_CONNECTING);
    } else {
        
makeUserAccess(idcheckUserFlags(id));
    }
    
add_user_state(idSTATE_CONNECTED);
}

public 
client_disconnected(id) {
    
clear_user_state(id);
    
add_user_state(idSTATE_DISCONNECTED);
    
remove_user_flags(id, -1);
    
set_user_flags(idDefaultAccess[DefaultAccessPlayer][DefaultAccessFlags]);
}

public 
TaskLoadTimeout() {
    
loadFinish();
}

#if defined _reapi_included
public CBasePlayer_SetClientUserInfoName_Post(const id, const infobuffer[], const name[]) {
    
remove_user_flags(id, -1);
    
makeUserAccess(idcheckUserFlags(idname));
}
#elseif defined _fakemeta_included
public SetCleintKeyValue_Post(const id, const infobuffer[], const key[], const value[]) {
    if(
strcmp(key"name") == 0) {
        
remove_user_flags(id, -1);
        
makeUserAccess(idcheckUserFlags(idvalue));
    }
}
#else
public client_infochanged(id) {
    if (!
is_user_connected(id)) {
        return 
PLUGIN_CONTINUE;
    }

    new 
oldname[MAX_NAME_LENGTH], newname[MAX_NAME_LENGTH];
    
get_user_name(idoldnamecharsmax(oldname));
    
get_user_info(id"name"newnamecharsmax(newname));
    if (
strcmp(oldnamenewname) != 0) {
        
remove_user_flags(id, -1);
        
makeUserAccess(idcheckUserFlags(idnewname));
    }
    return 
PLUGIN_CONTINUE;
}
#endif

loadStart() {
    
Status STATUS_LOADING;
    
PluginLoadedNum 0;

    for (new 
0sizeof LoadStatusListi++) {
        
arrayset(LoadStatusList[i], 0sizeof LoadStatusList[]);
    }
    
LoadStatusNum 0;
    
ExecuteForward(Forwards[FWD_Loading], FReturn);
    
set_task(5.0"TaskLoadTimeout"TIMEOUT_TASK_ID);
}

loadFinish() {
    
Status STATUS_LOADED;

    if (
NeedRecheck) {
        for (new 
player 1player <= MaxClientsplayer++) {
            if (
is_user_connected(player)) {
                
makeUserAccess(playercheckUserFlags(player));
            }
        }
    }

    if (
PrivilegesSnapshot != Invalid_Snapshot) {
        
TrieSnapshotDestroy(PrivilegesSnapshot);
    }
    
PrivilegesSnapshot TrieSnapshotCreate(Privileges);

    
ExecuteForward(Forwards[FWD_Loaded], FReturn);
}

makeUserAccess(const idCheckResult:result) {
    switch (
result) {
        case 
CHECK_DEFAULT: {
            
remove_user_flags(id);
            if (
is_user_bot(id)) {
                
set_user_flags(idDefaultAccess[DefaultAccessBOT][DefaultAccessFlags]);
            } else {
                
set_user_flags(idDefaultAccess[DefaultAccessPlayer][DefaultAccessFlags]);
            }
            
        }

        case 
CHECK_SUCCESS: {
            
remove_user_flags(id);
            
set_user_flags(idPrivilege[PrivilegeAccess]);
            
UsersPrivilege[id] = Privilege;
            
printConsole(id"* Privileges set");
        }

        case 
CHECK_KICK: {
            
server_cmd("kick #%d ^"%s^""get_user_userid(id), KickReason);
        }
    }
    
ExecuteForward(Forwards[FWD_Checked], FReturnidresult);
}

CheckResult:checkUserFlags(const id, const name[] = "") {
    
ExecuteForward(Forwards[FWD_Checking], FReturnid);
    if (
FReturn == PLUGIN_HANDLED) {
        return 
CHECK_IGNORE;
    }

    if (
Mode == MODE_DISABLE) {
        return 
CHECK_IGNORE;
    }

    if (
is_user_hltv(id)) {
        
set_user_flags(idDefaultAccess[DefaultAccessHLTV][DefaultAccessFlags]);
        return 
CHECK_IGNORE;
    }
    
    if (
is_user_bot(id)) {
        return 
CHECK_DEFAULT;
    }
    
    
#define MAX_AUTH_LENGTH 32
    
new auth[MAX_AUTH_LENGTH], key[MAX_KEY_LENGTH], 0flagsCheckResult:result CHECK_DEFAULT;
    do {
        switch (
SearchPriority[i]) {
            case 
's': {
                
get_user_authid(idauthcharsmax(auth));
                
flags FLAG_AUTHID;
            }

            case 
'i': {
                
get_user_ip(idauthcharsmax(auth), 1);
                
flags FLAG_IP;
            }

            case 
'n''c': {
                if (
name[0] != EOS) {
                    
copy(authcharsmax(auth), name);
                } else {
                    
get_user_name(idauthcharsmax(auth));
                }

                if (
SearchPriority[i] == 'c') {
                    
strtolower(auth);
                    
flags FLAG_CASE_SENSITIVE;
                } else {
                    
flags 0;
                }
            }

            default: {
                
flags = -1;
            }
        }

        if (
flags == -1) {
            continue;
        }

        
makeKey(authflagskeycharsmax(key));
        if (
TrieKeyExists(Privilegeskey)) {
            
TrieGetArray(PrivilegeskeyPrivilegesizeof Privilege);
            new 
CheckResult:checked setUserAccess(id);
            if (
checked result) {
                
result checked;
            }
        }
    } while (
SearchPriority[++i] != EOS);
    if (
Mode == MODE_KICK && result == CHECK_DEFAULT) {
        
KickReason "You have no entry to the server...";
        return 
CHECK_KICK;
    }
    return 
result;
}

CheckResult:setUserAccess(const id) {
    if (
Privilege[PrivilegeFlags] & FLAG_NOPASS) {
        return 
CHECK_SUCCESS;
    } else {
        new 
password[UAC_MAX_PASSWORD_LENGTH];
        if (
Privilege[PrivilegeOptions] & UAC_OPTIONS_MD5) {
            new 
infoPass[40];
            
get_user_info(idPasswordFieldinfoPasscharsmax(infoPass));
            
hash_string(infoPassHash_Md5passwordcharsmax(password));
        } else {
            
get_user_info(idPasswordFieldpasswordcharsmax(password));
        }

        if (
strcmp(passwordPrivilege[PrivilegePassword]) == 0) {
            return 
CHECK_SUCCESS;
        } else if (
Privilege[PrivilegeFlags] & FLAG_KICK) {
            
KickReason "Invalid Password!";
            return 
CHECK_KICK;
        } else {
            return 
CHECK_DEFAULT;
        }
    }
}

makeKey(const auth[], const flagskey[], len) {
    if (
flags FLAG_AUTHID) {
        
formatex(keylen"s%s"auth);
    } else if (
flags FLAG_IP) {
        
formatex(keylen"i%s"auth);
    } else if (
flags FLAG_CASE_SENSITIVE) {
        
formatex(keylen"c%s"auth);
        
strtolower(key);
    } else {
        
formatex(keylen"n%s"auth);
    }
}

getLoadStatus(const source) {
    for (new 
0LoadStatusNumi++) {
        if (
LoadStatusList[i][LoadSource] == source) {
            return 
i;
        }
    }

    return -
1;
}

getLoadStatusCount(const bool:loaded true) {
    new 
result 0;
    for (new 
0LoadStatusNumi++) {
        if (
LoadStatusList[LoadStatusNum][LoadLoaded] == loaded) {
            
result++;
        }
    }

    return 
result;
}

printConsole(id, const msg[]) {
    
message_begin(MSG_ONESVC_PRINT, .player id);
    
write_string(msg);
    
message_end();
}

// NATIVES
public plugin_natives() {
    
register_native("UAC_Push""NativePush"0);
    
register_native("UAC_StartLoad""NativeStartLoad"0);
    
register_native("UAC_FinishLoad""NativeFinishLoad"0);
    
register_native("UAC_GetSource""NativeGetSource"0);
    
register_native("UAC_GetId""NativeGetId"0);
    
register_native("UAC_GetAccess""NativeGetAccess"0);
    
register_native("UAC_GetFlags""NativeGetFlags"0);
    
register_native("UAC_GetPassword""NativeGetPassword"0);
    
register_native("UAC_GetPrefix""NativeGetPrefix"0);
    
register_native("UAC_GetExpired""NativeGetExpired"0);
    
register_native("UAC_SetAccess""NativeSetAccess"0);
    
register_native("UAC_GetOptions""NativeGetOptions"0);
    
register_native("UAC_CheckPlayer""NativeCheckPlayer"0);
    
register_native("UAC_IterReset""NativeIterReset"0);
    
register_native("UAC_IterEnded""NativeIterEnded"0);
    
register_native("UAC_IterNext""NativeIterNext"0);
    
register_native("UAC_GetPlayerPrivilege""NativeGetPlayerPrivilege"0);
    
register_native("UAC_GetPlayerExpired""NativeGetPlayerExpired"0);
}

public 
NativeStartLoad(plugin) {
    if (
Status == STATUS_LOADED) {
        return 
0;
    }

    
LoadStatusList[LoadStatusNum][LoadSource] = plugin;
    
LoadStatusList[LoadStatusNum][LoadLoaded] = false;
    
LoadStatusNum++;
    
log_amx("Loading privileges");
    return 
1;
}

public 
NativeFinishLoad(plugin) {
    if (
Status == STATUS_LOADED) {
        return 
0;
    }

    new 
status getLoadStatus(plugin);
    if (
status == -1) {
        return 
0;
    }

    
LoadStatusList[status][LoadLoaded] = true;
    
log_amx("Loaded %d privileges"PluginLoadedNum);
    
PluginLoadedNum 0;

    if (
getLoadStatusCount(true) != LoadStatusNum) {
        return 
1;
    }

    
remove_task(TIMEOUT_TASK_ID);
    
loadFinish();
    return 
1;
}

public 
NativePush(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc80)
    
enum arg_id 1arg_autharg_passwordarg_accessarg_flagsarg_prefixarg_expiredarg_options };
    
    
clear_privilege();

    new 
auth[MAX_AUTHID_LENGTH], key[MAX_KEY_LENGTH];
    
Privilege[PrivilegeSource] = plugin;
    
Privilege[PrivilegeId] = get_param(arg_id);
    
get_string(arg_authauthcharsmax(auth));
    
get_string(arg_passwordPrivilege[PrivilegePassword], charsmax(Privilege[PrivilegePassword]));
    
Privilege[PrivilegeAccess] = get_param(arg_access);
    
Privilege[PrivilegeFlags] = get_param(arg_flags);
    
get_string(arg_prefixPrivilege[PrivilegePrefix], charsmax(Privilege[PrivilegePrefix]));
    
Privilege[PrivilegeExpired] = get_param(arg_expired);
    
Privilege[PrivilegeOptions] = get_param(arg_options);

    
makeKey(authPrivilege[PrivilegeFlags], keycharsmax(key));
    
TrieSetArray(PrivilegeskeyPrivilegesizeof Privilege);
    
PluginLoadedNum++;
    
    if (
Status == STATUS_LOADED) {
        if (
PrivilegesSnapshot != Invalid_Snapshot) {
            
TrieSnapshotDestroy(PrivilegesSnapshot);
        }
        
PrivilegesSnapshot TrieSnapshotCreate(Privileges);
    }

    return 
1;
}

public 
NativeGetSource(pluginargc) {
    return 
Privilege[PrivilegeSource];
}

public 
NativeGetId(pluginargc) {
    return 
Privilege[PrivilegeId];
}

public 
NativeGetAccess(pluginargc) {
    return 
Privilege[PrivilegeAccess];
}

public 
NativeGetFlags(pluginargc) {
    return 
Privilege[PrivilegeFlags];
}

public 
NativeGetPassword(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc20)
    
enum arg_dest 1arg_length };
    return 
set_string(arg_destPrivilege[PrivilegePassword], get_param(arg_length));
}

public 
NativeGetPrefix(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc20)
    
enum arg_dest 1arg_length };
    return 
set_string(arg_destPrivilege[PrivilegePrefix], get_param(arg_length));
}

public 
NativeGetExpired(pluginargc) {
    return 
Privilege[PrivilegeExpired];
}

public 
NativeGetOptions(pluginargc) {
    return 
Privilege[PrivilegeOptions];
}

public 
NativeSetAccess(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc10)
    
enum arg_access };
    
Privilege[PrivilegeAccess] = get_param(arg_access);
    return 
1;
}

public 
CheckResult:NativeCheckPlayer(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc1CHECK_IGNORE)
    
enum arg_player };
    new 
player get_param(arg_player);
    
CHECK_NATIVE_PLAYER(playerCHECK_IGNORE)

    
remove_user_flags(player, -1);
    new 
CheckResult:result checkUserFlags(player);
    
makeUserAccess(playerresult);
    return 
result;
}

public 
NativeIterReset(pluginargc) {
    
PrivilegesIterate 0;
    return 
1;
}

public 
bool:NativeIterEnded(pluginargc) {
    return 
bool:(PrivilegesIterate >= TrieSnapshotLength(PrivilegesSnapshot) - 1);
}

public 
NativeIterNext(pluginargc) {
    
PrivilegesIterate++;
    new 
key[MAX_KEY_LENGTH];
    
TrieSnapshotGetKey(PrivilegesSnapshotPrivilegesIteratekeycharsmax(key));
    
TrieGetArray(PrivilegeskeyPrivilegesizeof Privilege);
    return 
1;
}

public 
NativeGetPlayerPrivilege(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc10)
    
enum arg_player };
    new 
player get_param(arg_player);
    
CHECK_NATIVE_PLAYER(player0)
    
    
Privilege UsersPrivilege[player];
    return 
1;
}

public 
NativeGetPlayerExpired(pluginargc) {
    
CHECK_NATIVE_ARGS_NUM(argc1, -1)
    
enum arg_player };
    new 
player get_param(arg_player);
    
CHECK_NATIVE_PLAYER(player, -1)
    
    return 
UsersPrivilege[player][PrivilegeExpired];
}

checkAPIVersion() {
    for(new 
iget_pluginsnum(), status[2], funcni++) {
        if(
== PluginId) {
            continue;
        }

        
get_plugin(i, .status status, .len5 charsmax(status));

        
//status debug || status running
        
if(status[0] != 'd' && status[0] != 'r') {
            continue;
        }
    
        
func get_func_id("__uac_version_check"i);

        if(
func == -1) {
            continue;
        }

        if(
callfunc_begin_i(funci) == 1) {
            
callfunc_push_int(UAC_MAJOR_VERSION);
            
callfunc_push_int(UAC_MINOR_VERSION);
            
callfunc_end();
        }
    }
}

#if defined LOG_ADMIN_ACTIVITY
public UAC_Checked(const id, const UAC_CheckResult:found) {
    if (
found != UAC_CHECK_SUCCESS) {
        return;
    }

    new 
name[MAX_NAME_LENGTH], steamid[MAX_AUTHID_LENGTH], ip[MAX_IP_LENGTH], access[32], prefix[UAC_MAX_PREFIX_LENGTH], expired[32];
    
    
get_user_name(idnamecharsmax(name));
    
get_user_authid(idsteamidcharsmax(steamid));
    
get_user_ip(idipcharsmax(ip), 1);
    
get_flags(UAC_GetAccess(), accesscharsmax(access));
    
UAC_GetPrefix(prefixcharsmax(prefix));
    if (
UAC_GetExpired() > 0) {
        
format_time(expiredcharsmax(expired), "%d.%m.%Y - %H:%M:%S"UAC_GetExpired());
    } else {
        
expired "never";
    }
    
fprintf(
        
LogFile
        
"Player '%s' (steamid '%s')(ip '%s') became an admin (access ^"%s^") (prefix ^"%s^") (id %d) (expires %s)^n",
        
namesteamidipaccessprefix,  UAC_GetId(), expired
    
);

    
server_print(
        
"Player '%s' (steamid '%s')(ip '%s') became an admin (access ^"%s^") (prefix ^"%s^") (id %d) (expires %s)",
        
namesteamidipaccessprefix,  UAC_GetId(), expired
    
);
}
#endif

#if defined LOAD_USERS_INI
public UAC_Loading() {
    
UAC_StartLoad();

    new 
fileName[128];
    
get_localinfo("amxx_configsdir"fileNamecharsmax(fileName));
    
add(fileNamecharsmax(fileName), "/users.ini");
    new 
file fopen(fileName"rt");
    if (!
file) {
        
UAC_FinishLoad();
        return;
    }

    new 
line[512], semicolonPos 0;
    new 
sysTime get_systime();
    new 
id 0;
    new 
auth[MAX_AUTHID_LENGTH], password[UAC_MAX_PASSWORD_LENGTH], access[32], flags[32], expired[32], staticBanTime[2], expiredTimeoptions;

    while (!
feof(file)) {
        
arrayset(line0sizeof line);
        
fgets(filelinecharsmax(line));
        
        if ((
semicolonPos contain(line";")) > 0) {
            
line[semicolonPos] = EOS;
        }

        
trim(line);
        
        
id++;
        if (
line[0] == EOS || line[0]==';') {
            continue;
        }

        
arrayset(auth0sizeof auth);
        
arrayset(password0sizeof password);
        
arrayset(access0sizeof access);
        
arrayset(flags0sizeof flags);
        
arrayset(expired0sizeof expired);
        
arrayset(staticBanTime0sizeof staticBanTime);

        if (
parse(lineauthcharsmax(auth), passwordcharsmax(password), accesscharsmax(access), flagscharsmax(flags), 
            
staticBanTimecharsmax(staticBanTime), expiredcharsmax(expired)) < 4) {
            continue;
        }

        
options 0;
        if (!
staticBanTime[0] || str_to_num(staticBanTime)) {
            
options |= UAC_OPTIONS_STATIC_BANTIME;
        }

        
expiredTime expired[0] != EOS && strcmp(expired"0") != parse_time(expired"%d.%m.%Y") : 0;

        new 
hashFile 1;
        if (
hashFile == || (hashFile == && isMD5(password))) {
            
options |= UAC_OPTIONS_MD5;
        }

        if (
expiredTime == || expiredTime sysTime) {
            
UAC_Push(idauthpasswordread_flags(access), read_flags(flags), ""expiredTimeoptions);
        }
    }
    
fclose(file);
    
UAC_FinishLoad();
}

stock bool:isMD5(const value[]) {
    new 
len strlen(value);
    if (
len != 32) {
        return 
false;
    }

    for (new 
0leni++) {
        if (!(
'0' <= value[i] <= '9') && !('a' <= value[i] <= 'f') && !('A' <= value[i] <= 'F')) {
            return 
false;
        }
    }

    return 
true;
}
#endif

public GMX_CfgLoaded() {
    if (
GMXLoaded) {
        return;
    }
    
GMXLoaded true;
    if (!
UACLoading) {
        return;
    }

    
GMX_MakeRequest("server/privileges"Invalid_GripJSONValue"OnResponse");
    
UACLoading false;
}

public 
UAC_Loading() {
    
UAC_StartLoad();
    
UACLoading true;

    new 
bool:needRequest trueGripJSONValue:data;
    if (!
Loaded && GMX_CacheLoad("privileges"data)) {
        
needRequest = !parseData(data);
        
grip_destroy_json_value(data);
        
Loaded true;
    }

    if (!
needRequest) {
        
UAC_FinishLoad();
    } else if (
GMXLoaded) {
        
GMX_MakeRequest("server/privileges"Invalid_GripJSONValue"OnResponse");
    } else {
        
UACLoading true;
    }
}

public 
OnResponse(const GmxResponseStatus:status, const GripJSONValue:data) {
    if (
status != GmxResponseStatusOk) {
        
UAC_FinishLoad();
        return;
    }

    
parseData(data);
    
GMX_CacheSave("privileges"data);
    
UAC_FinishLoad();
}

bool:parseData(const GripJSONValue:data) {
    if (
grip_json_get_type(data) != GripJSONObject) {
        return 
false;
    }

    new 
GripJSONValue:tmp;
    
tmp grip_json_object_get_value(data"groups");
    
parseGroups(tmp);
    
grip_destroy_json_value(tmp);

    
tmp grip_json_object_get_value(data"privileges");
    
parsePrivileges(tmp);
    
grip_destroy_json_value(tmp);
    return 
true;
}

parseGroups(const GripJSONValue:data) {
    if (
Groups == Invalid_Array) {
        
Groups ArrayCreate(GroupInfo1);
    } else {
        
ArrayClear(Groups);
    }
    for (new 
0grip_json_array_get_count(data), GripJSONValue:tmpni++) {
        
tmp grip_json_array_get_value(datai);
        if (
grip_json_get_type(tmp) == GripJSONObject) {
            
arrayset(Group0sizeof Group);
            
Group[GroupId] = grip_json_object_get_number(tmp"id");
            
grip_json_object_get_string(tmp"title"Group[GroupTitle], charsmax(Group[GroupTitle]));
            
Group[GroupFlags] = grip_json_object_get_number(tmp"flags");
            
Group[GroupPriority] = grip_json_object_get_number(tmp"priority");

            new 
GripJSONValue:prefix grip_json_object_get_value(tmp"prefix");
            if (
grip_json_get_type(prefix) != GripJSONNull) {
                
grip_json_get_string(prefixGroup[GroupPrefix], charsmax(Group[GroupPrefix]));
            }
            
grip_destroy_json_value(prefix);
            
ArrayPushArray(GroupsGroupsizeof Group);
        }
        
grip_destroy_json_value(tmp);
    }
    
GroupsNum ArraySize(Groups);
}

parsePrivileges(const GripJSONValue:data) {
    new 
now get_systime(0);
    new 
idauth[MAX_AUTHID_LENGTH], password[UAC_MAX_PASSWORD_LENGTH], accessflagsexpiredprefix[UAC_MAX_PREFIX_LENGTH], optionsauthTypeStr[32];
    for (new 
0grip_json_array_get_count(data), GripJSONValue:tmpGripJSONValue:passwordValueGripJSONValue:prefixValueni++) {
        
tmp grip_json_array_get_value(datai);
        if (
grip_json_get_type(tmp) != GripJSONObject) {
            
grip_destroy_json_value(tmp);
            continue;
        }

        
arrayset(auth0sizeof auth);
        
arrayset(password0sizeof password);
        
arrayset(prefix0sizeof prefix);
        
access 0;
        
flags 0;
        
expired 0;
        
options 0;

        
id grip_json_object_get_number(tmp"id");

        
passwordValue grip_json_object_get_value(tmp"password");
        if (
grip_json_get_type(passwordValue) != GripJSONNull) {
            
grip_json_get_string(passwordValuepasswordcharsmax(password));
        }    
        
grip_destroy_json_value(passwordValue);

        
prefixValue grip_json_object_get_value(tmp"prefix");
        if (
grip_json_get_type(prefixValue) != GripJSONNull) {
            
grip_json_get_string(prefixValueprefixcharsmax(prefix));
        }
        
grip_destroy_json_value(prefixValue);

        
grip_json_object_get_string(tmp"auth_type"authTypeStrcharsmax(authTypeStr));
        switch (
getAuthType(authTypeStr)) {
            case 
AUTH_TYPE_STEAM: {
                
flags |= FLAG_AUTHID FLAG_NOPASS;
                
grip_json_object_get_string(tmp"steamid"authcharsmax(auth));
            }

            case 
AUTH_TYPE_STEAM_AND_PASS: {
                
flags |= FLAG_AUTHID FLAG_KICK;
                
grip_json_object_get_string(tmp"steamid"authcharsmax(auth));
                
options |= UAC_OPTIONS_MD5;
            }

            case 
AUTH_TYPE_NICK_AND_PASS: {
                
flags |= FLAG_KICK;
                
grip_json_object_get_string(tmp"nick"authcharsmax(auth));
                
options |= UAC_OPTIONS_MD5;
            }
        }

        new 
GripJSONValue:privileges grip_json_object_get_value(tmp"privileges");
        for (new 
0grip_json_array_get_count(privileges), GripJSONValue:privilegeGripJSONValue:expiredValgroup_idpriority = -1kj++) {
            
privilege grip_json_array_get_value(privilegesj);
            
group_id grip_json_object_get_number(privilege"group_id");
            if (!
getGroup(group_id)) {
                
grip_destroy_json_value(privilege);
                continue;
            }

            
access |= Group[GroupFlags];
            if (
Group[GroupPriority] > priority) {
                
priority Group[GroupPriority];
                
expiredVal grip_json_object_get_value(privilege"expired_at");
                
expired grip_json_get_type(expiredVal) != GripJSONNull grip_json_get_number(expiredVal) : 0;
                
grip_destroy_json_value(expiredVal);

                if (
prefix[0] == EOS) {
                    
copy(prefixcharsmax(prefix), Group[GroupPrefix]);
                }
            }
            
grip_destroy_json_value(privilege);
        }
        
grip_destroy_json_value(privileges);

        if (
expired == || expired >= now) {
            
UAC_Push(idauthpasswordaccessflagsprefixexpiredoptions);
        }

        
grip_destroy_json_value(tmp);
    }
}

AUTH_TYPE:getAuthType(const authType[]) {
    if (
strcmp(authType"steamid_pass") == 0) {
        return 
AUTH_TYPE_STEAM_AND_PASS;
    } else if (
strcmp(authType"nick_pass") == 0) {
        return 
AUTH_TYPE_NICK_AND_PASS;
    } else if (
strcmp(authType"steamid_hash") == 0) {
        return 
AUTH_TYPE_STEAM_AND_HASH;
    } else if (
strcmp(authType"nick_hash") == 0) {
        return 
AUTH_TYPE_NICK_AND_HASH;
    } else {
        return 
AUTH_TYPE_STEAM;
    }
}

bool:getGroup(const id) {
    if (
id == 0) {
        return 
false;
    }

    for (new 
0GroupsNumi++) {
        if (
ArrayGetArray(GroupsiGroupsizeof Group) && Group[GroupId] == id) {
            return 
true;
        }
    }

    return 
false;


Last edited by DJBosma; 03-31-2020 at 17:42.
DJBosma is offline