[Tutorial] Filterscripts loader
#1

Hello. I'm gonna make a small tutorial -and final script- of a filterscript that (un/re)loads all your filterscripts (NOTE: These must be defined in an array in one filterscript).

Why would this be usefull?
Well, if you have loadfs of filterscripts, it could be usefull to put all of these filterscripts in a seperate directory in your filterscripts folder, and put one filterscript named 'fs' (or something like that) that have to be (un/re)loaded only in order to reload all your filterscripts.
Also, this describes some functions people might not understand. It explains the next functions/things:
while(), format(), SendRconCommand() = obvious, double/single arrays, 'i'=>'index'


Example
/SAMP/filterscripts:
* /fscripts
* fs.pwn
* fs.amx

/SAMP/filterscripts/fscripts:
* debug.pwn
* debug.amx
* ls_elevator.amx
* npc_record.amx
* NPCTest.amx
* NPCTest.pwn
* UIC.amx
* UIC.pwn
(etc.)

In order to load all the filterscripts in the 'filterscripts/fscripts' map, you have to load the 'fs.amx' only. You can (probably) use a plugin to even get all the files in /fscripts and automatically load all the .amx files, but I'll use a_samp (and eventually zcmd) only to make it easier.

How is it gonna work?
The idea is 'easy as hell'. It's just an array containing all the .amx filenames (without .amx). When 'fs.amx' is initialising (OnFilterScriptInit), it'll loop through all those filenames in the array and load all those filterscripts. When the filterscript is exitting (OnFilterScriptExit), it'll do the same, but then using the RCON command 'unloadfs' instead of 'loadfs' (small difference). You can eventually create an ingame command that does the same again, but then with 'reloadfs'.

How to create this array
You have to create a double array: new filterScripts[][] and NOT a single one (new filterScripts[]). You musn't use a single array, because the loop won't loop through those names then, but through all the names character by character (and then adding the previous characters too). Examples:
new filterScripts[] = {"fs","gm","debug"};
When you use this one, and you loop through the array, the system will try to load the filterscripts like this (or atleast similar to this):
loadfs s
loadfs fs
loadfs m
loadfs gm
loadfs g
loadfs ug
loadfs bug
loadfs ebug
loadfs debug

This will give alot "Failed to load filterscript" errors in the client, and it just is useless. When using a double array, this won't happen.
The example filterscripts in this script will be the next scripts: debug, ls_elevator, npc_record, NPCTest, UIC
This array will look like this:
pawn Код:
new filterScripts[][] = {
    "debug",
    "ls_elevator",
    "npc_record",
    "NPCTest",
    "UIC"
};
How to create this loop
I'll be using the function 'while()'. This function will run untill the statement within the brackets is 'false'. So we'll create an "index" (new index;). The standard value of this index is '0', since it hasn't got a value. We will combine this with the "sizeof" function; it checks the size of an array. The array I am using has got 5 strings, so sizeof(filterScripts); will return 5. This means we'll be checking if the value of index is beneath 5. While it's beneath 5, it'll be returned as true, so the loop will continue. When it's 5 (or higher), the index is not beneath 5 and it will return FALSE, which will stop the loop. After one loop, we'll be increasing the "index".
So, how to do this? I'll show you:
pawn Код:
new index; //The 'index', value = 0
while (index < sizeof(filterScripts)) //While 'index' < '5';
{
    index++; //Increase 'index' by 1. Once it reached 5, it won't be continued next time.
}
So this loop is done, and it works.

How to unload, reload of load the filterscript
The function "SendRconCommand" is required for this. This function can send RCON command just like in the RCON console or ingame (ingame = command "/rcon {rcon_command}" - in the console: "{rcon_command}").
An example to load the filterscript "fs.amx": SendRconCommand("loadfs fs");. If this 'fs.amx' is inside the 'fscripts' folder (inside the 'filterscripts'), it must look like this: SendRconCommand("loadfs fscripts/fs");.
If you're very new to scripting, you may not know that you can't just use the value of the array in the command directly. You must first "format" it. We'll need a string for this, and the format function. This is very basic so I'll just give the example. I'm using a string with a length of 50. In order to get the current string name from the array in the loop, you must use the index we created (so yes, it has two usefull functions this "index")
pawn Код:
new loadFsString[50];
format (loadFsString, 50, "loadfs fscript/%s", filterScripts[index]);
In order to use this string in the SendRconCommand function, you must replace the quotes and the text with the "loadFsString": SendRconCommand(loadFsString);
You mostly see loops using 'i'. If you didn't understand why it was 'i' before, you know it now: It stands for "index" (Well, atleast that's what I guessed. Please correct me if I'm wrong).
Know our entire script looks like this:
pawn Код:
#include <a_samp> //Didn't mention it before, but this is just something basic. The only required include for this script

new filterScripts[][] = {
    "debug",
    "ls_elevator",
    "npc_record",
    "NPCTest",
    "UIC"
};

//You can't just use this script nothing and everywhere. This should be in "public OnFilterScriptInit()", so all the 'filterScripts' will be loaded when the 'fs.amx' is loaded.
new index, loadFsString[50];
while (index < sizeof(filterScripts))
{
    format (loadFsString, 50, "loadfs fscript/%s", filterScripts[index]);
    SendRconCommand(loadFsString);
    index++; //Don't put this before the SendRconCommand and the format() function, otherwise 'debug' won't be loaded!
}
So, all the strings in "filterScripts" will be loaded, IF this 'fs.amx' is loaded, and if the next files exist:
/filterscripts/fscripts/debug.amx
/filterscripts/fscripts/ls_elevator.amx
/filterscripts/fscripts/npc_record.amx
/filterscripts/fscripts/NPCTest.amx
/filterscripts/fscripts/UIC.amx

What else?
Nothing really. In order to do the same with unloading and reloading, just change the "loadfs" in the format() function to "unloadfs" or "reloadfs". I recommend to put this "unloadfs" in OnFilterScriptExit(), and the 'reloadfs' eventually in a command.

A full example, as a working filterscript (unless if you don't have these filterscripts in the 'fscripts' directory ^^
pawn Код:
#define FILTERSCRIPT

#include <a_samp>
#include <zcmd>

new filterScripts[][] = {
    "debug",
    "ls_elevator",
    "npc_record",
    "NPCTest",
    "UIC"
};

public OnFilterScriptInit()
{
    new loadFsStr[50], index = -1;
    while (index <= sizeof(filterScripts))
    {
        index++;
        format(loadFsStr, 50, "loadfs fscript/%s", filterScripts[index]);
        SendRconCommand(loadFsStr);
    }
    return 1;
}

public OnFilterScriptExit()
{
    new loadFsStr[50], index = -1;
    while (index <= sizeof(filterScripts))
    {
        index++;
        format(loadFsStr, 50, "unloadfs fscript/%s", filterScripts[index]);
        SendRconCommand(loadFsStr);
    }
    return 1;
}

CMD:reloadfs(playerid, params[])
{
    new loadFsStr[50], index = -1;
    while (index < sizeof(filterScripts))
    {
        index++;
        format(loadFsStr, 50, "reloadfs fscript/%s", filterScripts[index]);
        SendRconCommand(loadFsStr);
    }
   
    SendClientMessage(playerid, -1, "{00FF00}Filterscripts reloaded");
    return 1;
}
NOTE: I am used to do the 'index++' before the format() and SendRconCommand() functions. This would mean that 'debug' wouldn't be loaded, but this is not true! Because instead of leaving the 'index' value on '0', I gave it '-1' so it'll be '0' on the first loop (Counting in scripting starts at 0 instead of 1)

I hope this will be usefull for atleast one person. I'd like to get feedbacks, with eventually tips, corrections and compliments ^^

Kind regards,
Kwarde

p.s.
To show that it really worked, I created temporarly a custom 'SendRconCommand' that puts the input into a file. Eg. if 'loadfs debug' was called, it was saved in a file. Here's the file's content:
Код:
loadfs fscript/debug
loadfs fscript/ls_elevator
loadfs fscript/npc_record
loadfs fscript/NPCTest
loadfs fscript/UIC
unloadfs fscript/debug
unloadfs fscript/ls_elevator
unloadfs fscript/npc_record
unloadfs fscript/NPCTest
unloadfs fscript/UIC
Reply
#2

God Work, but more easy:

pawn Код:
// Load:
SendRconCommand(#loadfs cars);
SendRconCommand(#loadfs armourshot);
SendRconCommand(#loadfs race);

// Unload
SendRconCommand(#unloadfs cars);
SendRconCommand(#unloadfs armourshot);
SendRconCommand(#unloadfs race);
Ps: for looping is very fast of that while.
Reply
#3

I actually didn't think that was easy. Because if you remove some filterscripts, or suddenly add 10 more or something (just a quite unrealistic example, but this happened to me) you must first add all those functions etc. And then you have to copy it (or re-write it -.-) and then add for all those 10 commands the 'un' in front of the 'loadfs'. I'm kinda lazy so I thought this was easier, so this is why I created it. Now you only have to add the filenames of the .amx files to an array and the script will do the rest
Reply
#4

Even more simple!
Open your server.cfg under filterscripts put in the filterscripts you want to load.
Done!
Reply
#5

@FireCat:
If you'd read the post a bit, you'd be able to read that this is also intended for reloading/unloading them all... And this also describes some functions, as how they work : ) [Trying to get atleast something positive out of this tutorial ]
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)