Forum

> > CS2D > Scripts > "Location Mod v1.0" Modification
Forums overviewCS2D overview Scripts overviewLog in to reply

English "Location Mod v1.0" Modification

No replies
To the start Previous 1 Next To the start

old "Location Mod v1.0" Modification

RichNagel
User Off Offline

Quote
I recently stumbled upon this neat little script here -> LocMod 1.0, created by ColdX.

The script displays a player's country whenever they join the server, and uses the "IP to Country" CSV format database ("IPToCountry.csv") that is freely available on the Internet for IP lookup.

One problem with the script is that a much older format of the CSV database file is included, and since the current updates for the file are in a different format, the script can't parse the current format of the currently available database files.

FYI, the current updates for the database "IPToCountry.csv" file can be downloaded from here -> http://software77.net/geo-ip ( http://software77.net/geo-ip/?DL=2&;x=Download ).

Unfortunately, it appears that ColdX hasn't visited the site since January 2011, and has disallowed commments and likes for LocMod 1.0.

That being said, I made a few edits to the script that *DO* allow the newer format CSV databases to be used with the script... as well as adding the player's USGN ID (or "None" if the player is not currently logged in) to the displayed in-game messages

I also added a simple line that will change the "Reserved" text to "a local LAN" (for the country name) for any players that may be connecting to their dedicated server via their local LAN/router (the CSV database lists any local LAN IPs as "Reserved").

For anyone interested (the following "LocationMod.lua" file goes into the "Sys\Lua\Autorun" directory on your hard drive, and the "IPToCountry.csv" that you can download from the above-mentioned link(s) goes into the "Sys" directory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
---------------------------------------------------------------------------
-- Location Mod v1.0 for Counter-Strike 2D                               --
--                                                                       --
-- Created by ColdX (USGN: 10055) - October 14, 2010                     --
-- http://www.unrealsoftware.de/profile.php?userid=10055                 --
--                                                                       --
-- This Lua script for Counter-Strike 2D displays a player's country and --
-- USGN ID whenever they join the server.                                --
---------------------------------------------------------------------------

-- WebNet "IPToCountry.csv" (http://software77.net/geo-ip/?DL=2&;x=Download) Parsing Routine

webnet = {}

function webnet:new(name,strict)
        local w = setmetatable({},{__index=webnet})
    if type(name) == 'string' then 
        local t,e = w:load(name,strict)
        if t == nil then w = nil; return nil,e end
    end
    return w
end

function webnet:load(name,strict)
    local last = -1
    local ib,ie,ia,_,co,cou,coun
    local ibn, ien
    local iptab,cotab = {},{}
    local f = io.open(name,"rt")
    
    -- Is the file actually there?
    if f == nil then return nil,"file not found" end
    
    -- Iterate through the file.
    for str in f:lines() do
        -- Try to split the line into fields.
        ib,ie,ia,_,co,cou,coun = 
                str:match('"(%d+)","(%d+)","(%a+)","(%d+)","(%u%u)","(%u%u%u?)","(.*)"')
        -- Check that it was a well-formed line.
        if ib == nil or ie == nil or co == nil then
            -- Unparseable lines are ignored unless they start with '"'.
            -- This prevents new-format lines getting ignored for ever.
            -- Note we must skip lines where co=nil lest we return it.
            if str:sub(1,1) == '"' then return nil,"bad line in file",str end
        else
            -- Parseable lines belong in the table.
            ibn, ien = tonumber(ib), tonumber(ie)
            if ibn <= last or ien < ibn then
                -- Don't accept this record if it's out-of-order.
                -- (See comments above about repeated ranges in real data.)
                if strict then return nil,"ip data out of order" end
            else
                -- If this record doesn't follow on from the last, fill the 'gap',
                if ibn ~= last+1 then
                    iptab[#iptab+1] = last+1
                    cotab[#cotab+1] = "-- UNALLOCATED"
                end
                -- and add this record to the (sorted) lists.
                -- Note: Lua internalises strings so the regular repetition
                -- of common country names doesn't waste memory.
                iptab[#iptab+1] = ibn
                cotab[#cotab+1] = co..' '..coun
                last = ien
            end
        end
    end    
    
    -- Add a catchall record (doesn't matter if out of 32-bit range).
    iptab[#iptab+1] = last+1
    cotab[#cotab+1] = "-- UNALLOCATED"
    
    self.iptab, self.cotab = iptab, cotab
    return self
end

function webnet:lookup(ip)
    -- Validate and convert the IP parameter.
    if type(ip) == 'number' then 
       if ip<0 or ip>=2^32 then return nil,"bad ip number" end
    elseif type(ip) == 'string' then
       local a,b,c,d = ip:match('(%d+).(%d+).(%d+).(%d+)')
       if a==nil or b==nil or c==nil or d==nil then return nil, "bad ip string" end
       a,b,c,d = a+0,b+0,c+0,d+0
       if a<0 or b<0 or c<0 or d<0 then return nil,"bad ip string" end
       if a>255 or b>255 or c>255 or d>255 then return nil,"bad ip string" end
       ip = a*2^24 + b*2^16 + c*2^8 + d
    else
       return nil, "bad ip parameter"
    end
    
    -- Check that IP number is inside our table's coverage.
    local bot,top = 1,#self.iptab
    if ip <  self.iptab[bot] then return "-- ","UNALLOCATED" end
    if ip >= self.iptab[top] then return "-- ","UNALLOCATED" end
    
    -- Now binary chop the table until we find the country.
    -- This should never take more than log-base-2(tablesize) chops.
    -- Lap and lim are there just in case, to ensure no infinite loops.
    local lap,lim = 0,(math.log(#self.iptab)/math.log(2))*1.5
    repeat
        lap = lap+1
        local mid = bot + math.floor((top-bot)/2)
        -- See if we've found the answer.
        if ip >= self.iptab[mid] and ip < self.iptab[mid+1] then
            return self.cotab[mid]:match('(%C%C) (.*)')
        end
        -- If not, chop off the half it can't be in.
        if ip < self.iptab[mid] then top = mid else bot = mid+1 end
    until bot >= top or lap > lim
    
    -- This isn't supposed to happen unless the table is corrupt.
    return nil,"lookup error"
end

-- Location Mod Routine

w = webnet.new()
e,e_msg,s = w:load('Sys/IPToCountry.csv')

addhook("join","location_mod")
function location_mod(id)
        iso,country_name = w:lookup(player(id,"ip"))
        if country_name=="Reserved" then
                -- country_name="Reserved"
                -- country_name="a local LAN"
                country_name="a local LAN"
        else
                country_name=country_name
        end
        if player(id,"usgn")==0 then
                -- msg("©000255255"..player(id,"name").." (USGN ID: NONE) has just joined the game from "..country_name.."!")
                msg("©000255255"..player(id,"name").." (USGN ID: NONE) has just joined the game from "..country_name.."!")
        else
                -- msg("©000255255"..player(id,"name").." (USGN ID: "..player(id,"usgn")..") has just joined the game from "..country_name.."!")
                msg("©000255255"..player(id,"name").." (USGN ID: "..player(id,"usgn")..") has just joined the game from "..country_name.."!")
        end
end

P.S. The thing that does the magic (allowing the newer format CSV databases to be used with the script) is the following (edited) line:

1
str:match('"(%d+)","(%d+)","(%a+)","(%d+)","(%u%u)","(%u%u%u?)","(.*)"')
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview