Author Topic: Locate IP  (Read 872 times)

0 Members and 1 Guest are viewing this topic.

Offline soldat-game

  • Camper
  • ***
  • Posts: 400
Locate IP
« on: January 05, 2022, 08:08:50 pm »
Script Name: Locate IP
Script Description: Adds commands !locate !locate <ID,name,partname> !locateall /locate /locate <ID,name,partname> /locateall and notifying the administrator from which country the player joined when he joined the server. It displays the latest location data after ip.
Original Author(s): Dominik
Core Version: 1.1
Test on server: 2.8.2
Download: Attachment

The script was originally intended to use an internal database. However, stability on weaker servers could be achieved by implementing only a database specifying which country the player is from. However, I wanted it to show more
continent, country, country code, province, city in addition, the database also enters data such as continent code, decimal_IP, IPS. The server downloads data from an external website that has been on the market for many years (https://ip-api.com/).
But to prevent spamming and server floding, the server builds a database in the ram so that players trying to abuse the database will take advantage of the database.
The database will be lost when the server is restarted, which will also empty the use of the ram. It works extremely quickly and efficiently.
Start the server with the parameter -safe 0.

Code: (Pascal) [Select]
unit Locate_IP_By_Dominik;

interface

const
GOOD = $66CC66;
BAD = $B22222;
Inform_all_players_what_country_player_joined = false;
Inform_admin_when_found_player_location = true;
Only_admins_can_see_advanced_location = false;

type Table_Of_IP = record
Decimal_IP: longword;
Last_Updated: double;
Continent, Continent_Code, Country, Country_Code, Province, City, IPS, VPN: string;
end;

var
IP_Data: array of Table_Of_IP;
Data: TStringList;

implementation

function IPToLong(const IP_String: string): longword;
var temp: TStringList;
begin
try
temp := File.CreateStringList;
SplitRegExpr('\.', IP_String, temp);
Result := StrToInt(temp[0]) shl 24 + StrToInt(temp[1]) shl 16 + StrToInt(temp[2]) shl 8 + StrToInt(temp[3]);
except
Result := 0;
finally
temp.Free;
end;
end;

function ContainsStrSC3(const AText, ASubText: string): Boolean;
begin
Result := Pos(ASubText,AText)>0;
end;

procedure Url_Info(Player: TActivePlayer);
var Res: TStringList; b: byte; Temp_Len: longword;
begin
try
Res := File.CreateStringList;
SplitRegExpr('\n', GetURL('http://ip-api.com/line/'+Player.IP+'?fields=3293723'), Res);
if Res[0] = 'success' then begin
Temp_Len := Length(IP_Data);
setLength(IP_Data, Temp_Len + 1);
IP_Data[Temp_Len].Decimal_IP := IPToLong(Player.IP);
IP_Data[Temp_Len].Last_Updated := now();
IP_Data[Temp_Len].Continent := Res[1];
IP_Data[Temp_Len].Continent_Code := Res[2];
IP_Data[Temp_Len].Country := Res[3];
IP_Data[Temp_Len].Country_Code := Res[4];
IP_Data[Temp_Len].Province := Res[5];
IP_Data[Temp_Len].City := Res[6];
IP_Data[Temp_Len].IPS := Res[7];
IP_Data[Temp_Len].VPN := Res[8];
Data.Values[Player.IP] := inttostr(Temp_Len);
if Inform_all_players_what_country_player_joined then Players.WriteConsole(Player.Name+' join from '+IP_Data[Temp_Len].Country+' (ISO: '+IP_Data[Temp_Len].Country_Code + ')', GOOD) else if Inform_admin_when_found_player_location then for b := 1 to 32 do if Players[b].IsAdmin then Players[b].WriteConsole(Player.Name+' join from '+IP_Data[Temp_Len].Country+' (ISO: '+IP_Data[Temp_Len].Country_Code + ')', GOOD);
end else if Inform_all_players_what_country_player_joined then Players.WriteConsole(Player.Name+' location has not been established', GOOD) else if Inform_admin_when_found_player_location then for b := 1 to 32 do if Players[b].IsAdmin then Players[b].WriteConsole(Player.Name+' location has not been established', GOOD);
except
Res.Free;
finally
Res.Free;
end;
end;

procedure JoinGame(Player: TActivePlayer; Team: TTeam);
var Temp_Index: longword; b: byte;
begin
if Data.Values[Player.IP] <> nil then begin
Temp_Index := strtoint(Data.Values[Player.IP]);
if Inform_all_players_what_country_player_joined then Players.WriteConsole(Player.Name+' join from '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code + ')', GOOD) else if Inform_admin_when_found_player_location then for b := 1 to 32 do if Players[b].IsAdmin then Players[b].WriteConsole(Player.Name+' join from '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code + ')', GOOD);
end else Url_Info(Player);
end;

function Find_Online_Player_ID(s: string): byte;
var i: byte;
begin
Result := 0;
if ExecRegExpr('^([1-9]|[12][0-9]|3[0-2])$',s) then begin
i := StrToInt(s);
if Players[i].Active then begin
Result := i;
exit;
end;
end;
for i := 1 to 32 do if Players[i].Active then begin
if ContainsStrSC3(LowerCase(Players[i].Name), s) then begin
Result := i;
exit;
end;
end;
end;

procedure Show_Locate(Player: TActivePlayer; Text: String; All: boolean);
var Found_ID, i: byte; Temp_Index: longword;
begin
if All then begin
if (Only_admins_can_see_advanced_location = false) or (Player.IsAdmin) then begin
for i := 1 to 32 do if Players[i].Active then begin
if Data.Values[Players[i].IP] <> nil then begin
Temp_Index := strtoint(Data.Values[Players[i].IP]);
if IP_Data[Temp_Index].VPN = 'false' then Player.WriteConsole('Player '+Players[i].Name+' is from '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City, GOOD) else Player.WriteConsole('Player '+Players[i].Name+' is from '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City+' (Possible VPN)', GOOD);
end else Player.WriteConsole('Player '+Players[i].Name+' is now localized or missing data.', BAD);
end;
end else
begin
for i := 1 to 32 do if Players[i].Active then begin
if Data.Values[Players[i].IP] <> nil then begin
Temp_Index := strtoint(Data.Values[Players[i].IP]);
Player.WriteConsole('Player '+Players[i].Name+' is from '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+')', GOOD);
end else Player.WriteConsole('Player '+Players[i].Name+' is now localized or missing data.', BAD);
end;
end;
end else
begin
delete(text,1,8); text := trim(text);
if text <> nil then Found_ID := Find_Online_Player_ID(text) else Found_ID := Player.ID;
if Found_ID > 0 then begin
if Data.Values[Players[Found_ID].IP] <> nil then begin
if (Only_admins_can_see_advanced_location = false) or (Player.IsAdmin) then begin
Temp_Index := strtoint(Data.Values[Players[Found_ID].IP]);
if Found_ID = Player.ID then begin
if IP_Data[Temp_Index].VPN = 'false' then Player.WriteConsole('You`re from: '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City, GOOD) else Player.WriteConsole('You`re from: '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City+' (Possible VPN)', GOOD);
end else if IP_Data[Temp_Index].VPN = 'false' then Player.WriteConsole('Player '+Players[Found_ID].Name+' is from: '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City, GOOD) else Player.WriteConsole('Player '+Players[Found_ID].Name+' is from: '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+'), Province: '+IP_Data[Temp_Index].Province+', City: ~'+IP_Data[Temp_Index].City+' (Possible VPN)', GOOD);
end else Player.WriteConsole('Player '+Players[i].Name+' is from '+IP_Data[Temp_Index].Continent+', Country: '+IP_Data[Temp_Index].Country+' (ISO: '+IP_Data[Temp_Index].Country_Code+')', GOOD);
end else if Found_ID = Player.ID then Player.WriteConsole('You are localized or missing data.', BAD) else Player.WriteConsole('Player '+Players[Found_ID].Name+' is now localized or missing data.', BAD);
end else Player.WriteConsole('No player found for the search "'+text+'".', BAD);
exit;
end;
end;

procedure Speak(Player: TActivePlayer; Text: string);
var Lower_Case_Text: string;
begin
Lower_Case_Text := lowercase(text);

if ExecRegExpr('^(\!locate|\!locate\s(.{0,23})\S)$', Lower_Case_Text) then begin
Show_Locate(Player, Text, false);
exit;
end;
if Lower_Case_Text = '!locateall' then Show_Locate(Player, '', true);
end;

function Commands(Player: TActivePlayer; Text: string): Boolean;
var Lower_Case_Text: string;
begin
Result := false;
Lower_Case_Text := lowercase(text);

if ExecRegExpr('^(\/locate|\/locate\s(.{0,23})\S)$', Lower_Case_Text) then begin
Show_Locate(Player, Text, false);
exit;
end;
if Lower_Case_Text = '/locateall' then Show_Locate(Player, '', true);
end;

procedure ScriptDecl();
var i: byte;
begin
for i := 1 to 32 do begin
Players[i].OnCommand := @Commands;
Players[i].OnSpeak := @Speak;

//if Players[i].Active then Url_Info(Players[i]);

end;
Game.OnJoin := @JoinGame;
Data := File.CreateStringList;
end;

initialization
begin
ScriptDecl();
end;

end.

Update 1.1:
 - Fix: Typo
 - Add: When the player uses a VPN, the message "Probably VPN" will appear
 - Fix: A crash when the script was loaded with the "recompile" command, while the players are on the server.
 - Added a new setting:
     - Inform_all_players_what_country_player_joined
     - Only_admins_can_see_advanced_location
« Last Edit: January 29, 2022, 06:40:06 pm by soldat-game »

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Locate IP
« Reply #1 on: January 10, 2022, 08:48:11 am »
Thanks for the contribution!

Offline soldat-game

  • Camper
  • ***
  • Posts: 400
Re: Locate IP
« Reply #2 on: January 29, 2022, 06:33:52 pm »
Update 1.1:
 - Fix: Typo
 - Add: When the player uses a VPN, the message "Probably VPN" will appear
 - Fix: A crash when the script was loaded with the "recompile" command, while the players are on the server.
 - Added a new setting:
     - Inform_all_players_what_country_player_joined
     - Only_admins_can_see_advanced_location
« Last Edit: January 29, 2022, 06:39:58 pm by soldat-game »