Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Anti Server Flood v2 script by Amit_B
- #include "a_samp.inc"
- #undef MAX_PLAYERS
- #define MAX_PLAYERS 1000 // sa-mp player limit - do not change
- #define TIMER 20 // maximum slots for bots attack, increase only if 500 bots are connecting per less than ten second
- #define LOADING_UPDATE 10 // percent to log on blocked ips loading
- #define BLOCKFILE "antiflood.txt" // blocked ips file name
- #define SERVERIP "" // server ip. leave blank if you have 'bind' defined in your server.cfg
- #define DEBUG
- enum e_Connection { IP[MAX_PLAYERS], IPs, Next, Timer, bool:Used }
- new ConnectionPacks[TIMER][e_Connection], Player[MAX_PLAYERS][2], str[32],
- lastTickCount = 0, serverIP[16], MAX_PLAYERS_ = 0, BlockedIP[MAX_PLAYERS][2],
- BlockedIPs = 0;
- public OnFilterScriptInit()
- {
- print("Anti server flood script v2.0 - loading");
- MAX_PLAYERS_ = GetMaxPlayers();
- if(strlen(SERVERIP) > 0) format(serverIP,sizeof(serverIP),SERVERIP);
- else GetServerVarAsString("bind",serverIP,sizeof(serverIP));
- for(new i = 0; i < MAX_PLAYERS_; i++) Player[i] = {-1,-1};
- if(fexist(BLOCKFILE))
- {
- new File:fh = fopen(BLOCKFILE,io_read);
- if(fh)
- {
- new string[20], l, fl = flength(fh), c = 0, j = 0;
- const est = 16;
- printf("Blocking estimated count of %d IPs",fl / est);
- while(fread(fh,string))
- {
- if((l = strlen(string)) < 9 || string[0] == '#') continue;
- for(j = 1; j <= 2; j++) if(string[l-j] == '\n' || string[l-j] == '\r') string[l-j] = 0;
- BlockIpAddress(string,0);
- if(++c % ((fl / est) / LOADING_UPDATE) == 0) printf("Blocked %d of %d (estimated count)",c,fl / est);
- }
- fclose(fh);
- }
- }
- SetTimer("ClosingConnections",1000,1);
- print("Anti server flood script v2.0 - loaded");
- return 1;
- }
- public OnPlayerConnect(playerid)
- {
- Remove(playerid);
- return 1;
- }
- public OnPlayerDisconnect(playerid,reason)
- {
- Remove(playerid);
- return 1;
- }
- public OnPlayerCommandText(playerid,cmdtext[])
- {
- if(!strcmp(cmdtext,"/unblockip",true) && IsPlayerAdmin(playerid))
- {
- UnBlockIpAddress(cmdtext[11]);
- SendClientMessage(playerid,-1,"IP unblocked. Now you should remove it's line from \"" BLOCKFILE "\".");
- return 1;
- }
- return 0;
- }
- public OnIncomingConnection(playerid,ip_address[],port)
- {
- if(!strcmp(ip_address,serverIP)) return 1; // prevent NPCs from getting blocked
- if(GetTickCount()-lastTickCount <= 50)
- {
- new cur = -1;
- for(new i = 0; i < TIMER && cur == -1; i++) if(!ConnectionPacks[i][Used]) cur = i;
- #if defined DEBUG
- printf("debug: inserting %s into a pack (%d)",ip_address,cur);
- #endif
- if(cur > -1) if(ConnectionPacks[cur][Next] != -1)
- {
- new place = -1;
- if(ConnectionPacks[cur][Next] == ConnectionPacks[cur][IPs]) ConnectionPacks[cur][IPs]++, place = ConnectionPacks[cur][Next]++;
- else
- {
- place = ConnectionPacks[cur][Next];
- for(new i = place; i < MAX_PLAYERS_ && place == -1; i++) if(ConnectionPacks[cur][IP][i] == 0) place = i;
- }
- if(place == -1 || place == MAX_PLAYERS_)
- {
- ConnectionPacks[cur][Next] = -1;
- #if defined DEBUG
- printf("debug: was unable to place %s in pack %d at place %d",ip_address,cur,place);
- #endif
- }
- else
- {
- do ConnectionPacks[cur][IP][place] = 1 + random(99999);
- while existproperty(.value=prfrmt(ConnectionPacks[cur][IP][place]));
- setproperty(.value=prfrmt(ConnectionPacks[cur][IP][place]),.string=ip_address);
- Player[playerid][0] = cur, Player[playerid][1] = place;
- #if defined DEBUG
- printf("debug: placed %s in pack %d at place %d",ip_address,cur,place);
- #endif
- }
- if(ConnectionPacks[cur][IPs] > 5)
- {
- if(ConnectionPacks[cur][Timer] != 0) KillTimer(ConnectionPacks[cur][Timer]);
- ConnectionPacks[cur][Timer] = SetTimerEx("Timeout",1000,0,"ii",cur,false);
- }
- }
- }
- lastTickCount = GetTickCount();
- return 1;
- }
- forward Timeout(pack,bool:block);
- public Timeout(pack,bool:block)
- {
- if(block)
- {
- new File:fh = fopen(BLOCKFILE,fexist(BLOCKFILE) ? io_append : io_write);
- if(fh)
- {
- for(new i = 0, val[16]; i < ConnectionPacks[pack][IPs]; i++)
- {
- getproperty(.value=prfrmt(ConnectionPacks[pack][IP][i]),.string=val);
- strunpack(val,val,sizeof(val));
- BlockIpAddress(val,0);
- deleteproperty(.value=prfrmt(ConnectionPacks[pack][IP][i]));
- CloseConnection(val);
- format(str,sizeof(str),"%s\r\n",val);
- fwrite(fh,str);
- ConnectionPacks[pack][IP][i] = 0;
- }
- fclose(fh);
- printf("Blocked %d new IPs",ConnectionPacks[pack][IPs]);
- ConnectionPacks[pack][Used] = false, ConnectionPacks[pack][IPs] = 0, ConnectionPacks[pack][Next] = 0;
- }
- }
- else
- {
- ConnectionPacks[pack][Next] = -1, ConnectionPacks[pack][Used] = true, ConnectionPacks[pack][Timer] = 0;
- SetTimerEx("Timeout",TIMER*1000,0,"ii",pack,true);
- #if defined DEBUG
- printf("debug: timer has stopped for pack %d, blocking in " #TIMER "s",pack);
- #endif
- }
- }
- forward ClosingConnections();
- public ClosingConnections()
- {
- new bool:unb = false;
- for(new i = 0, val[32]; i < BlockedIPs; i++) if(BlockedIP[i][0] > 0 && BlockedIP[i][1] > 0)
- {
- if(!--BlockedIP[i][1])
- {
- if(existproperty(.value = prfrmt(BlockedIP[i][0],true)))
- {
- getproperty(.value=prfrmt(prfrmt(BlockedIP[i][0],true)),.string=val);
- strunpack(val,val,sizeof(val));
- SendRconCommand((format(val,sizeof(val),"unbanip %s",val), val));
- deleteproperty(.value=prfrmt(prfrmt(BlockedIP[i][0],true)));
- if(!unb) unb = true;
- }
- for(new j = i; j < BlockedIPs && j < MAX_PLAYERS; j++) BlockedIP[j][0] = BlockedIP[j+1][0], BlockedIP[j][1] = BlockedIP[j+1][1];
- BlockedIP[--BlockedIPs] = {0,0};
- }
- }
- if(unb) SendRconCommand("reloadbans");
- }
- stock Remove(playerid)
- {
- if(Player[playerid][0] != -1 && Player[playerid][1] != -1)
- {
- if(existproperty(.value = prfrmt(ConnectionPacks[Player[playerid][0]][IP][Player[playerid][1]]))) deleteproperty(.value=prfrmt(ConnectionPacks[Player[playerid][0]][IP][Player[playerid][1]]));
- ConnectionPacks[Player[playerid][0]][IP][Player[playerid][1]] = 0, ConnectionPacks[Player[playerid][0]][Next] = Player[playerid][1];
- #if defined DEBUG
- printf("debug: removed place %d from %d as it's recognized as a real player",Player[playerid][0],Player[playerid][1]);
- #endif
- Player[playerid][0] = -1, Player[playerid][1] = -1;
- }
- }
- stock CloseConnection(ip[])
- {
- SendRconCommand((format(str,sizeof(str),"banip %s",ip), str));
- do BlockedIP[BlockedIPs][0] = 1 + random(99999);
- while existproperty(.value=prfrmt(BlockedIP[BlockedIPs][0],true));
- setproperty(.value=prfrmt(BlockedIP[BlockedIPs][0],true),.string=ip);
- BlockedIP[BlockedIPs][1] = 20, BlockedIPs++;
- }
- stock prfrmt(num,bool = false) return hash((format(str,sizeof(str),"%cip%d",bool ? 'b' : 'f',num), str));
- stock hash(prop[])
- {
- new s[2] = {1,0};
- for(new i = 0, l = strlen(prop); i < l; i++) s[0] = (s[0] + prop[i]) % 65521, s[1] = (s[1] + s[0]) % 65521;
- return (s[1] << 16) + s[0];
- }
Advertisement
Add Comment
Please, Sign In to add comment