void GScr_BanClient()
{
    client_t *cl;

    if(Scr_GetNumParam() != 1)
        Scr_Error("Usage: ban(<clientid>)\n");

    int clnum = Scr_GetInt(0);

    if(clnum < 0 || clnum >= g_maxclients->integer)
        Scr_Error("ban(): Out of range client id\n");

    cl = &svs.clients[clnum];

    if(!SV_UseUids()){

        SV_AddBan(0, 0, &cl->pbguid[24], cl->name, (time_t)-1, "Banned by scriptadmin");
        SV_DropClient(cl, "Banned by scriptadmin\n");
    }else{

        if(cl->uid > 0)
        {
            SV_AddBan(cl->uid, 0, cl->pbguid, cl->name, (time_t)-1, "Banned by scriptadmin");
            SV_DropClient(cl, "Banned by scriptadmin\n");

        }else{
            SV_DropClient(cl, "Player kicked by scriptadmin\n");
        }
    }
}
/*
============
Cmd_RemoteUnsetAdmin_f
============
*/
void SV_RemoteCmdUnsetAdmin(int uid, char* guid)
{

    adminPower_t *admin, **this;

    if(SV_UseUids()){

        if(uid < 1){
            Com_Printf("No such player\n");
            return;
        }

        NV_ProcessBegin();

        for(this = &adminpower, admin = *this; admin ; admin = *this)
        {

            if(admin->uid == uid){
                *this = admin->next;
                Z_Free(admin);
                NV_ProcessEnd();
                Com_Printf( "User removed: uid: %i\n", uid);
                SV_PrintAdministrativeLog( "removed admin with uid: %i", uid);
                return;
            }
            this = &admin->next;
        }

    }else{

        if(guid && strlen(guid) == 32)
        {
            guid += 24;
        }
        if(!guid || strlen(guid) != 8)
        {
                Com_Printf("Error: No such player\n");
                return;
        }

        NV_ProcessBegin();
        for(this = &adminpower, admin = *this; admin ; admin = *this)
        {

            if(!Q_stricmp(admin->guid, guid)){
                *this = admin->next;
                Z_Free(admin);
                NV_ProcessEnd();
                Com_Printf( "User removed: guid: %s\n", guid);
                SV_PrintAdministrativeLog( "removed admin with guid: %s", guid);
                return;
            }
            this = &admin->next;
        }

    }

    Com_Printf( "Error: No such user in database\n");
    NV_ProcessEnd();
}
void QDECL SV_PrintAdministrativeLog( const char *fmt, ... ) {

	va_list		argptr;
	char		msg[MAXPRINTMSG];
	char		inputmsg[MAXPRINTMSG];
	struct tm 	*newtime;
	char*		ltime;
	time_t		realtime;

	va_start (argptr,fmt);
	Q_vsnprintf (inputmsg, sizeof(inputmsg), fmt, argptr);
	va_end (argptr);

	Com_UpdateRealtime();
	realtime = Com_GetRealtime();
	newtime = localtime( &realtime );
	ltime = asctime( newtime );
	ltime[strlen(ltime)-1] = 0;

	if(SV_UseUids())
		Com_sprintf(msg, sizeof(msg), "%s - Admin %i with %i power %s\n", ltime, cmdInvoker.currentCmdInvoker, cmdInvoker.currentCmdPower, inputmsg);
	else
		Com_sprintf(msg, sizeof(msg), "%s - Admin %s with %i power %s\n", ltime, cmdInvoker.currentCmdInvokerGuid, cmdInvoker.currentCmdPower, inputmsg);

	Com_PrintAdministrativeLog( msg );

}
int SV_RemoteCmdGetClPower(client_t* cl){

    adminPower_t *admin;
    int uid;
    char* guid;

    guid = &cl->pbguid[24];
    uid = cl->uid;

    if(SV_UseUids()){
        if(uid < 1) return 1;

        for(admin = adminpower; admin ; admin = admin->next){

            if(admin->uid == uid){

                return admin->power;
            }
        }

    }else{
        if(cl->authentication != 1) return 1;

        for(admin = adminpower; admin ; admin = admin->next){

            if(!Q_stricmp(admin->guid, guid)){
                return admin->power;
            }
        }

    }

    return 1;
}
void SV_RemoteCmdSetAdmin(int uid, char* guid, int power)
{

    adminPower_t *admin;
    adminPower_t *this;

    if(SV_UseUids()){

        if(uid < 1){
            Com_Printf("No such player\n");
            return;
        }

        NV_ProcessBegin();

        for(admin = adminpower ; admin ; admin = admin->next){
            if(admin->uid == uid){
                if(admin->power != power){
                    admin->power = power;

                    Com_Printf( "Admin power changed for: uid: %i to level: %i\n", uid, power);
                    SV_PrintAdministrativeLog( "changed power of admin with uid: %i to new power: %i", uid, power);
                }
                NV_ProcessEnd();
                return;
            }
        }

        this = Z_Malloc(sizeof(adminPower_t));
        if(this){
            this->uid = uid;
            this->power = power;
            this->next = adminpower;
            adminpower = this;
            Com_Printf( "Admin added: uid: %i level: %i\n", uid, power);
            SV_PrintAdministrativeLog( "added a new admin with uid: %i and power: %i", uid, power);
        }

    }else{

        if(guid && strlen(guid) == 32)
        {
            guid += 24;
        }
        if(!guid || strlen(guid) != 8)
        {
                Com_Printf("Error: No such player\n");
                return;
        }

        NV_ProcessBegin();

        for(admin = adminpower ; admin ; admin = admin->next)
        {
            if(!Q_stricmp(admin->guid, guid)){
                if(admin->power != power){
                    admin->power = power;

                    Com_Printf( "Admin power changed for: guid: %s to level: %i\n", guid, power);
                    SV_PrintAdministrativeLog( "changed power of admin with guid: %s to new power: %i", guid, power);
                }
                NV_ProcessEnd();
                return;
            }
        }

        this = Z_Malloc(sizeof(adminPower_t));
        if(this)
        {
            Q_strncpyz(this->guid, guid, sizeof(this->guid));
            this->power = power;
            this->next = adminpower;
            adminpower = this;
            Com_Printf( "Admin added: guid: %s level: %i\n", guid, power);
            SV_PrintAdministrativeLog( "added a new admin with guid: %s and power: %i", guid, power);
        }
    }

    NV_ProcessEnd();
}
void SV_ExecuteRemoteCmd(int clientnum, const char *msg){
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char cmd[30];
	char buffer[256];
	char oldinvokerguid[9];
	int i = 0;
	int j = 0;
	int powercmd;
	int power;
	client_t *cl;

        if(!cmdSystemInitialized){
	    SV_SendServerCommand(redirectClient, "e \"Error: Remote control system is not initialized\n\"");
	    Com_Printf("Error: Remote control system is not initialized\n");
            return;
        }


	if(clientnum < 0 || clientnum > 63) return;
	cl = &svs.clients[clientnum];
	redirectClient = cl;

	while ( msg[i] != ' ' && msg[i] != '\0' && msg[i] != '\n' && i < 32 ){
		i++;
	}
	
	if(i > 29 || i < 3) return;
	Q_strncpyz(cmd,msg,i+1);


	//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
	Q_strncpyz(buffer,msg,256);
	Q_strchrrepl(buffer,';','\0');
	Q_strchrrepl(buffer,'\n','\0');
	Q_strchrrepl(buffer,'\r','\0');
	// start redirecting all print outputs to the packet

        power = SV_RemoteCmdGetClPower(cl);
        powercmd = Cmd_GetPower(cmd);

	if(powercmd == -1){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Invalid command invoked - Type ^2$cmdlist ^3to get a list of all available commands\"", buffer);
            return;
	}
	if(powercmd > power){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Insufficient power to execute this command.\n^3You need at least ^6%i ^3powerpoints to invoke this command.\n^3Type ^2$cmdlist ^3to get a list of all available commands\"",
            buffer, powercmd);
	    return;
	}
        if(SV_UseUids())
		Com_Printf( "Command execution: %s   Invoked by: %s   InvokerUID: %i Power: %i\n", buffer, cl->name, cl->uid, power);
	else
		Com_Printf( "Command execution: %s   Invoked by: %s   InvokerGUID: %s Power: %i\n", buffer, cl->name, cl->pbguid, power);

	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ReliableSendRedirect);

	i = cmdInvoker.currentCmdPower;
	cmdInvoker.currentCmdPower = power;
	cmdInvoker.authserver = qfalse;

	if(SV_UseUids()){
		j = cmdInvoker.currentCmdInvoker;
		cmdInvoker.currentCmdInvoker = cl->uid;
	}else{
		Q_strncpyz(oldinvokerguid, cmdInvoker.currentCmdInvokerGuid, sizeof(oldinvokerguid));
		Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, &cl->pbguid[24], sizeof(cmdInvoker.currentCmdInvokerGuid));
	}

	cmdInvoker.clientnum = clientnum;

	Cmd_ExecuteSingleCommand( 0, 0, buffer );

	if(!Q_stricmpn(buffer, "pb_sv_", 6)) PbServerForceProcess();

	SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\"", buffer);

	cmdInvoker.currentCmdPower = i;
	if(SV_UseUids()){
		cmdInvoker.currentCmdInvoker = j;
	}else{
		//Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, oldinvokerguid, sizeof(cmdInvoker.currentCmdInvokerGuid));
		Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, "N/A", sizeof(cmdInvoker.currentCmdInvokerGuid));
	}
	cmdInvoker.clientnum = -1;

	Com_EndRedirect();
}