
   /* AMX Mod script.
   *
   * (c) Copyright 2003, Dra
   * This file is provided as is (no warranties).
   *
   */
   #include <amxmod>
   #include <amxmisc>
   /*
   * cmd :
   *  amx_loopcmd <loopid> <freq. in. sec.> "<cmd>"
   *  amx_loopstart <loopid>
   *  amx_loopstop <loopid>
   *  amx_looplist
   *
   * loopid is 1 to 9999
   *  amx_loopstart 0 mean start all
   *  amx_loopstop 0 mean stop all
   *
   * loop examples:
   *  amx_loopcmd 32 300 "amx_tsay yellow welcome amx server"
   *  amx_loopcmd 32 5 "amx_tsay cyan visit amxmod.net"
   *  amx_loopcmd 32 5 "amx_tsay magenta dont swear or kick"
   *  amx_loopstart 32
   *
   * run once examples:
   *  amx_loopcmd 99 60 "say re 3 go"
   *  amx_loopcmd 99 3 "sv_restart 1"
   *  amx_loopcmd 99 2 "sv_restart 1"
   *  amx_loopcmd 99 2 "sv_restart 5"
   *  amx_loopcmd 99 6 "say live ! live ! live !"
   *  amx_loopcmd 99 1 "amx_loopstop 99"
   *  amx_loopstart 99
   */
   #define MAX_CMD_NUM 32
   #define MAX_CMD_LENGTH 192
   new msg_stopall[] = " * All loopcmds stoped"
   new msg_stop[] = " * Loopcmd %d stoped"        // %d is loopid
   new msg_startall[] = " * All loopcmds starting"
   new msg_start[] = " * Loopcmd %d starting"        // %d is loopid
   new msg_add[] = " * New loopcmd added"
   new loopstats[3]={'X',' ','O'}
   new logfilename[256]
   new nextcmdid
   new nextloopid
   new cmddata[MAX_CMD_NUM][MAX_CMD_LENGTH]    // [cmdid] <cmd>
   new Float:cmdfreq[MAX_CMD_NUM]                // [cmdid] <freq>
   new   cmdid[MAX_CMD_NUM][MAX_CMD_NUM]        //   [loopid]   [loopcid]
   <cmdid>
   new cmdnum[MAX_CMD_NUM]                // [loopid] <loopcmdnum>
   new loopid[MAX_CMD_NUM]
   new looping[MAX_CMD_NUM]={-1, ...}
   public admin_loopcmd(id,level,cid) {
       if (!cmd_access(id,level,cid,4))
           return PLUGIN_HANDLED
       new argv[8]
       read_argv(1,argv,7)
       new a=strtonum(argv)
       if (a<1 || a>9999) {
           console_print(id," * invalid loopid")
           return PLUGIN_HANDLED
       }
       read_argv(2,argv,7)
       new loopfreq=strtonum(argv)
       if (!loopfreq) {
           console_print(id," * invalid loopfreq")
           return PLUGIN_HANDLED
       }
       if (nextcmdid>=MAX_CMD_NUM) {
           console_print(id," * loopcmd full")
           return PLUGIN_HANDLED
       }
       new lid=get_loopid(a)
       if (lid==-1) {
           lid = nextloopid++
           loopid[lid] = a
       }
       cmdid[lid][cmdnum[lid]]=nextcmdid
       cmdfreq[nextcmdid]=float(loopfreq)
       read_argv(3,cmddata[nextcmdid],MAX_CMD_LENGTH-1)
       nextcmdid++
       cmdnum[lid]++
       console_print(id,msg_add)
       say_cmd(id)
       return PLUGIN_CONTINUE
   }
   public admin_loopstop(id,level,cid) {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new argv[8]
       read_argv(1,argv,7)
       if (equal(argv,"0")) {
           stop_all()
           console_print(id,msg_stopall)
           say_cmd(id)
           return PLUGIN_CONTINUE
       }
       new a=strtonum(argv)
       if (a) {
           new lid=get_loopid(a)
           if (lid!=-1) {
               stop_loop(lid)
               console_print(id,msg_stop,a)
               say_cmd(id)
               return PLUGIN_CONTINUE
           }
       }
       console_print(id," * invalid loopid")
       return PLUGIN_HANDLED
   }
   public admin_loopstart(id,level,cid) {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new argv[8]
       read_argv(1,argv,7)
       if (equal(argv,"0")) {
           start_all()
           console_print(id,msg_startall)
           say_cmd(id)
           return PLUGIN_CONTINUE
       }
       new a=strtonum(argv)
       if (a) {
           new lid=get_loopid(a)
           if (lid!=-1) {
               start_loop(lid)
               console_print(id,msg_start,a)
               say_cmd(id)
               return PLUGIN_CONTINUE
           }
       }
       console_print(id," * invalid loopid")
       return PLUGIN_HANDLED
   }
   public admin_looplist(id,level,cid) {
       if (!cmd_access(id,level,cid,1))
           return PLUGIN_HANDLED
       new loops[MAX_CMD_NUM]
       new i, j, k, a
       for (i=1;i<nextloopid;++i) {
           a=0
           for (j=0;j<i;++j) {
               if (loopid[i]>loopid[loops[j]]) {
                   for (k=i;k>j;--k)
                       loops[k]=loops[k-1]
                   loops[j]=i
                   a = 1
                   break
               }
           }
           if (!a)
               loops[i]=i
       }
       console_print(id,"-------------------------------------")
       console_print(id,"loopid stats command")
       new lid
       for (i=nextloopid-1;i>=0;--i) {
           lid=loops[i]
           for (j=0;j<cmdnum[lid];++j) {
               k= (looping[lid]==j ? 2 : (looping[lid]==-1 ? 0 : 1))
               console_print(id,"%6d %c
   %-64s",loopid[lid],loopstats[k],cmddata[cmdid[lid][j]])
           }
       }
       console_print(id,"-------------------------------------")
       return PLUGIN_CONTINUE
   }
   public run_cmd(parm[2]) {
       new lid=parm[0]
       new lcid=cmdid[lid][parm[1]]
       looping[lid]=(parm[1]+1)%cmdnum[lid]
       new pa[2]
       pa[0]=lid
       pa[1]=looping[lid]
       new nextlcid=cmdid[lid][looping[lid]]
       new Float:nextfreq=cmdfreq[nextlcid]
       set_task(nextfreq,"run_cmd",54088+lid,pa,2)
       server_cmd(cmddata[lcid])
   }
   public stop_all() {
       for (new i=0;i<MAX_CMD_NUM;++i) {
           stop_loop(i)
       }
   }
   public start_all() {
       for (new i=0;i<MAX_CMD_NUM;++i) {
           start_loop(i)
       }
   }
   public stop_loop(a) {
       if (looping[a]!=-1) {
           looping[a]=-1
           remove_task(54088+a)
       }
   }
   public start_loop(a) {
       if (looping[a]==-1 && cmdnum[a]) {
           looping[a]=0
           new parm[2]
           parm[0]=a
           set_task(cmdfreq[cmdid[a][0]],"run_cmd",54088+a,parm,2)
           return 1
       }
       return 0
   }
   public say_cmd(id) {
       if (!id)
           return 0
       new name[32], authid[16], cmd[32], data[MAX_CMD_LENGTH+32]
       read_argv(0,cmd,31)
       read_args(data,MAX_CMD_LENGTH+31)
       get_user_name(id,name,31)
       get_user_authid(id,authid,15)
       switch(get_cvar_num("amx_show_activity")) {
       case 2:    client_print(0,print_chat,"%s : %s %s",
               name,cmd,data)
       case 1:    client_print(0,print_chat,"%s : %s %s",
               (get_user_flags(id)    &    ADMIN_USER)   ?   "PLAYER"   :
   "ADMIN",cmd,data)
       }
       log_to_file(logfilename,"Cmd: ^"%s<%d><%s><>^" %s ^"%s^"",
           name,get_user_userid(id),authid,cmd,data)
       return 1
   }
   public get_loopid(lid) {
       for (new i=0;i<nextloopid;++i) {
           if (lid == loopid[i])
               return i
       }
       return -1
   }
   public plugin_init() {
       register_plugin("Amx Loop Cmd","0.9.1","dra")
       register_concmd("amx_loopcmd","admin_loopcmd",ADMIN_RCON,"<loop
   id> <freq. in sec.> <cmd>")
       register_concmd("amx_loopstop","admin_loopstop",ADMIN_CFG,"<loop
   id>")
       register_concmd("amx_loopstart","admin_loopstart",ADMIN_CFG,"<loop
   id>")
       register_concmd("amx_looplist","admin_looplist",ADMIN_CFG,"-  list
   all loop cmds")
       get_time("addons/amx/logs/admin%m%d.log",logfilename,255)
       return PLUGIN_CONTINUE
   }
