St1geR

Flood Control - GTA-SAMP.LT

Jan 3rd, 2013
751
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.27 KB | None | 0 0
  1. #define foreach(%1,%2) for (new %2 = 0; %2 < sizeof(%1); %2++ )
  2.  
  3. // Store last X ips, 37 seems to be a perfectly decent and efficiently well rounded number for this purpose.
  4. #define max_joins_log 37
  5.  
  6. // Current index @ ipjoinlog in sequence
  7. new autoinc_join_sequence = 0;
  8.  
  9. enum core_ipjoin { // struct
  10. ip_add,
  11. timestamp
  12. }
  13.  
  14. new ipjoinlog[max_joins_log][core_ipjoin]; // last X times and ips of people joining.
  15.  
  16. stock intabs(innumber) {
  17.  
  18. if (innumber < 0)
  19. return -innumber;
  20.  
  21. return innumber;
  22. }
  23.  
  24. stock Distance1Dint(fPos1, fPos2) {
  25.  
  26. if (fPos1 > fPos2)
  27. return intabs(fPos1 - fPos2);
  28. else
  29. return intabs(fPos2 - fPos1);
  30.  
  31. }
  32.  
  33. // This function manages to properly calculate time even if the timers wrap around and underflow.
  34. stock GetTimeDistance(a, b) {
  35.  
  36. // a pawn cell is signed 32-bit integer.
  37. // -2147483648 to 2147483647
  38.  
  39. if ((a < 0) && (b > 0)) {
  40.  
  41. new dist;
  42. dist = Distance1Dint(a, b);
  43. if (dist > 2147483647)
  44. return Distance1Dint(a - 2147483647, b - 2147483647);
  45. else
  46. return dist;
  47.  
  48. } else {
  49.  
  50. return Distance1Dint(a, b);
  51.  
  52. }
  53.  
  54. }
  55.  
  56. // 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.
  57. // (by specification the returned type of inet_aton should be UNSIGNED int 32)
  58. // example conversion failures:
  59. // 127.0.0.1 -> 2130706433
  60. // 128.68.103.132 -> -2143000700
  61.  
  62. stock inet_aton(ip[]) {
  63.  
  64. new ipv = strval(ip) << 24, pos = 0;
  65.  
  66. while (pos < 15 && ip[pos++] != '.') {}
  67. ipv += strval(ip[pos]) << 16;
  68. while (pos < 15 && ip[pos++] != '.') {}
  69. ipv += strval(ip[pos]) << 8;
  70. while (pos < 15 && ip[pos++] != '.') {}
  71. ipv += strval(ip[pos]);
  72.  
  73. return ipv;
  74. }
  75.  
  76. stock log_new_join(PlayerID) {
  77.  
  78. new ip[18];
  79. GetPlayerIp(PlayerID, ip, sizeof(ip));
  80. new ipv = inet_aton(ip);
  81.  
  82. ipjoinlog[autoinc_join_sequence][ip_add] = ipv;
  83. ipjoinlog[autoinc_join_sequence][timestamp] = TickCount();
  84.  
  85. autoinc_join_sequence++;
  86.  
  87. if (autoinc_join_sequence >= max_joins_log)
  88. autoinc_join_sequence = 0;
  89.  
  90. }
  91.  
  92. stock number_joins_time_range(PlayerID, max_time) {
  93.  
  94. new ip[18];
  95. GetPlayerIp(PlayerID, ip, sizeof(ip));
  96.  
  97. new ipv = inet_aton(ip);
  98. new counted = 0;
  99.  
  100. foreach(ipjoinlog, I) {
  101.  
  102. if (ipjoinlog[I][ip_add] != ipv) // different IP.
  103. continue;
  104.  
  105. if (GetTimeDistance(TickCount(), ipjoinlog[I][timestamp]) <= max_time)
  106. counted++;
  107.  
  108. }
  109.  
  110. return counted;
  111. }
  112.  
  113. public OnPlayerConnect(playerid) {
  114. log_new_join(playerid);
  115. new intjoins = number_joins_time_range(playerid, 5000);
  116.  
  117. printf("received player %d with nickname %s and number of joins from same ip in last 5 seconds is %d", playerid, pNickname[playerid], intjoins);
  118.  
  119. // Now you know how many times the IP has joined in past 5 seconds, now you can do as you please.
  120. // I suggest a RCON ban as it will block all the join spam and all further attempts to mess with your server further
  121.  
  122. }
Advertisement
Add Comment
Please, Sign In to add comment