#pragma semicolon 1
#include <sourcemod>

Database g_hDatabase;

public Plugin myinfo ={
    name = "List SourceMod Command",
    author = "jenzur",
    description = "Lists SourceMod commands accessible to the client in a menu. just stolen from darthninja",
    version = "1.0",
    url = "https://forums.alliedmods.net/showthread.php?p=1524781"
}; 

public void OnMapStart()
{
    if (!g_hDatabase)
    {
        Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
    }
    else
    {
        Command_listcmd();
    }
}

public void OnPluginStart()
{
    if (!g_hDatabase)
    {
        Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
    }
}

public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
{
    if(!db || strlen(error))
    {
        LogError("Database error: %s", error);
        return;
    }
    g_hDatabase = db;
    Command_listcmd();
}

public void Command_listcmd()
{
	decl String:Command[64];
	decl String:Description[255];
	new Handle:hIterator = GetCommandIterator();

	new iFlags;
	decl String:strFlags[64];

	/* Start printing the commands to the client */
	while (ReadCommandIterator(hIterator, Command, sizeof(Command), iFlags, Description, sizeof(Description)))
    {
        Format(strFlags, sizeof(strFlags), "");
        
        //This still may not be the best way to do this
        if (iFlags & ADMFLAG_RESERVATION)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_RESERVATION");
        if (iFlags & ADMFLAG_GENERIC)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_GENERIC");
        if (iFlags & ADMFLAG_KICK)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_KICK");
        if (iFlags & ADMFLAG_BAN)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_BAN");
        if (iFlags & ADMFLAG_UNBAN)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_UNBAN");
        if (iFlags & ADMFLAG_SLAY)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_SLAY");
        if (iFlags & ADMFLAG_CHANGEMAP)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CHANGEMAP");
        if (iFlags & ADMFLAG_CONVARS)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CONVARS");
        if (iFlags & ADMFLAG_CONFIG)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CONFIG");
        if (iFlags & ADMFLAG_CHAT)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CHAT");
        if (iFlags & ADMFLAG_VOTE)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_VOTE");
        if (iFlags & ADMFLAG_PASSWORD)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_PASSWORD");
        if (iFlags & ADMFLAG_RCON)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_RCON");
        if (iFlags & ADMFLAG_CHEATS)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CHEATS");
        if (iFlags & ADMFLAG_ROOT)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_ROOT");
        if (iFlags & ADMFLAG_CUSTOM1)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM1");
        if (iFlags & ADMFLAG_CUSTOM2)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM2");
        if (iFlags & ADMFLAG_CUSTOM3)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM3");
        if (iFlags & ADMFLAG_CUSTOM4)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM4");
        if (iFlags & ADMFLAG_CUSTOM5)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM5");
        if (iFlags & ADMFLAG_CUSTOM6)
            StrCat(strFlags, sizeof(strFlags), "ADMFLAG_CUSTOM6");
        if (iFlags == 0)
            Format(strFlags, sizeof(strFlags), "No flag registered");

        if (StrEqual(Description, "", false))
            Format(Description, sizeof(Description), "No description found");
        //PrintToChatAll("Command: %s Description: %s strFlags: %s", Command, Description, strFlags);
        char sQuery[2048];
        int size2 = 2 * strlen(Description) + 1;
        char[] sEscapedDescription = new char[size2 + 1];

        g_hDatabase.Escape(Description, sEscapedDescription, size2 + 1);
        Format(sQuery, sizeof(sQuery), "INSERT INTO `ze_commands_info` (`command`, `description`, `flag`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `description` = '%s', `flag` = '%s'", Command, sEscapedDescription, strFlags, sEscapedDescription, strFlags);

        DataPack hDataPack = new DataPack();
        hDataPack.WriteString(sQuery);
        g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, hDataPack, DBPrio_Low);
    }
	CloseHandle(hIterator);
}

public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, DataPack data)
{
    if (!db || strlen(error))
    {
        char sQuery[2048];
        ResetPack(data);
        data.ReadString(sQuery, sizeof(sQuery));
        LogError("Query error 3: %s", error); 
        LogError("actual query: %s", sQuery);
    }
    delete results;
    delete data;
}