Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define foreach(%1,%2) for (new %2 = 0; %2 < sizeof(%1); %2++ )
- // Store last X ips, 37 seems to be a perfectly decent and efficiently well rounded number for this purpose.
- #define max_joins_log 37
- // Current index @ ipjoinlog in sequence
- new autoinc_join_sequence = 0;
- enum core_ipjoin { // struct
- ip_add,
- timestamp
- }
- new ipjoinlog[max_joins_log][core_ipjoin]; // last X times and ips of people joining.
- stock intabs(innumber) {
- if (innumber < 0)
- return -innumber;
- return innumber;
- }
- stock Distance1Dint(fPos1, fPos2) {
- if (fPos1 > fPos2)
- return intabs(fPos1 - fPos2);
- else
- return intabs(fPos2 - fPos1);
- }
- // This function manages to properly calculate time even if the timers wrap around and underflow.
- stock GetTimeDistance(a, b) {
- // a pawn cell is signed 32-bit integer.
- // -2147483648 to 2147483647
- if ((a < 0) && (b > 0)) {
- new dist;
- dist = Distance1Dint(a, b);
- if (dist > 2147483647)
- return Distance1Dint(a - 2147483647, b - 2147483647);
- else
- return dist;
- } else {
- return Distance1Dint(a, b);
- }
- }
- // please note that this is NOT a perfect inet_aton function, but you will not be able to output the number as a unsigned integer as pawn uses signed int32 only.
- // (by specification the returned type of inet_aton should be UNSIGNED int 32)
- // example conversion failures:
- // 127.0.0.1 -> 2130706433
- // 128.68.103.132 -> -2143000700
- stock inet_aton(ip[]) {
- new ipv = strval(ip) << 24, pos = 0;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]) << 16;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]) << 8;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]);
- return ipv;
- }
- stock log_new_join(PlayerID) {
- new ip[18];
- GetPlayerIp(PlayerID, ip, sizeof(ip));
- new ipv = inet_aton(ip);
- ipjoinlog[autoinc_join_sequence][ip_add] = ipv;
- ipjoinlog[autoinc_join_sequence][timestamp] = TickCount();
- autoinc_join_sequence++;
- if (autoinc_join_sequence >= max_joins_log)
- autoinc_join_sequence = 0;
- }
- stock number_joins_time_range(PlayerID, max_time) {
- new ip[18];
- GetPlayerIp(PlayerID, ip, sizeof(ip));
- new ipv = inet_aton(ip);
- new counted = 0;
- foreach(ipjoinlog, I) {
- if (ipjoinlog[I][ip_add] != ipv) // different IP.
- continue;
- if (GetTimeDistance(TickCount(), ipjoinlog[I][timestamp]) <= max_time)
- counted++;
- }
- return counted;
- }
- public OnPlayerConnect(playerid) {
- log_new_join(playerid);
- new intjoins = number_joins_time_range(playerid, 5000);
- printf("received player %d with nickname %s and number of joins from same ip in last 5 seconds is %d", playerid, pNickname[playerid], intjoins);
- // Now you know how many times the IP has joined in past 5 seconds, now you can do as you please.
- // I suggest a RCON ban as it will block all the join spam and all further attempts to mess with your server further
- }
Advertisement
Add Comment
Please, Sign In to add comment