Well. There are several problems here. Some technical, some not. First, the technical, because that's the easy part:
- @WTFE's method above is a great solution if you have shell access, which probably covers the set of people who should be doing this anyway (see social problems, below).
- If you want it in game, consider if history matters;
- Most mush types record the last connected address (or even a handful of them) on some of the wizard only attrs; if that's enough, it becomes a process of sweeping through character objects to find matches of some sort.
- If that isn't enough, you'll need to record the history yourself in some format. Consider how you want to do this and whether or not it is worth the trouble; SQL is one reasonable solution, but there are likely others.
If you have what you need in attributes, see @grep
and similar tools. If you need it in SQL, you'll need your alt-detector to run a select of some sort to find things.
...I just looked at what I had on TheReach and ... uh, no, that's ugly. In summary though, I had a table with IPv4 address, hostname, char dbref number, and some time data. When people connected, it updated it as needed, and alts checks of various levels used select
s with a horridly tangled mess of subqueries to do CIDR bitmasking in sql, which was kinda cool but horrible slow, done inside a synchronous sql()
that stalled the whole game and pretty much theno was the only one who ever knew how to use it safely. Do not recommend.
Gotchas I noted that you should keep in mind: Many games are starting to support IPv6. Most older games are IPv4 only, and the traditional "dotted quad" form we know and love is IPv4-only. Brief review on terminology:
- IP stands for Internet Protocol; TCP/UDP are implemented on top of IP packets. PING and similar tools send special IP packets.
- IPv4 has 32bit host addresses, conventionally represented with a dotted set of four 8bit numbers written in decimal (i.e. 0-255). Hilariously, 4 billion addresses aren't enough and we're running out. (Well, ran out a while back, but limping alone either way)
- IPv6 has 128bit addresses, conventionally represented as colon-separated sets of 16bit numbers written in hexadecimal. (i.e. 0-ffff).
- IPv6 has a lot of zeros in it, so the :: means "shove a ton of zeros in that spot 'til it makes a full address." (e.g. ::1, or all zeros followed by 1 -- is the IPv6 localhost)
- Hostnames may point to any number of IPv4 or IPv6 addresses, or both. (In A and AAAA recordsets via DNS, which is another lecture)
- IPs can point to hostnames (really just one unless someone screwed things up) but are often misconfigured.
For both of these, we talk about "netmasks" as a way to describe ranges of addresses. Instead of 1.2.3.*, meaning 1.2.3.0 through 1.2.3.255, a better way to describe it is 1.2.3.0/24 -- the 24 meaning the first 24 bits are meaningful but the last 8 are not. Likewise 1.2.2.0/23 covers 1.2.2.0 though 1.2.3.255. There are calculators online that can help with this if you get confused, or you can use the really ugly old form with netmasks like 255.255.255.0, (meaning /24)
IPv6 does the same thing, but obviously has more bits. /48's and /64's are very common. /128's are almost useless, because of how many addressable bits can be freely rechosen by the client under normal configs in the interest of privacy. (Yes: Modern internet is designed to make this difficult for you to do.) Players can and DO actively set their ipv6 address to hilarious stuff, like :feed:face:dead:beef: and whatnot.
Hostname resolution from an IP is not reliable. IP's might come into your game in either form. You can represent ipv4 as an ipv6 addr of the form ::ffff:1234:5678 where the last two terms represent the 32bits of the ipv4 addr. e.g. 10.0.0.1 -> ::ffff:a00:1.
Players connecting via dynamic IP might:
- Keep the same IP for years
- Switch addresses several times a night in their same ipv4 /24.
- Alternate between several seemingly unrelated ISPs (which can be home/work/school/coffeeshop, but not always)
- Switch addresses periodically over astonishingly large sets like /16 or worse.
The wider you match, the more matches you can find, but the less meaningful they will be. Believe it or not, some people do live in neighborhoods with OTHER PEOPLE that actually use internet! This can muddy waters quite a bit.
You need to handle and use this sort of matching for it to really be an effective tool. If storing in sql, use the async @query
system if your game has it (mux, etc). sql()
is synchronous and will make you cry.
This brings us to the social problems part. People don't seem to understand the concept of false positives. For that reason, +alts checking of this sort usually needs to be limited to a very small set of people or you'll spend all your staff time trying to put out drama fires. No, documentation does not help. Meetings do not help. BBposts, forumposts, wiki pages, etc. all do not help. People are dumb, suspicious, and paranoid. If they see the slightest hint that person A is connecting from THE SAME PLANET as person B then CLEARLY THEY ARE THE SAME PERSON and OUT TO GET THEM. This gets old very, very fast.
Further, there are a very large number of cases where multiple people from the same household play, so they all show up on an IP. HOWEVER, you cannot use ip-match to prove people live together. Consider:
- Most of my mush connections would appear to originate from 66.220.1.33.
- My lovely partner has her own farm of servers and while we would often be playing from the same room, we potentially appear continents apart.
- Both of us offer shells in various forms for various purposes, leading to a multitude of other people that seem to live with us, but do not.
- 66.220.1.33 was the ipv4 address for KUU, one of the big Mechanipus servers hosting the Reach and a bunch of others. That quickly made it look like all game wiz's on all games there were coming from the same place, which I'm sure made all sorts of hilariously salacious rumormongering possible.
- It gets even worse if you connect via localhost.
So: Can this sort of ip-address based system tell you:
- If two people are the same, for certain? No.
- If two people are different, for certain? No.
If that is confusing, disheartening, or seems otherwise wrong, then that methodology cannot help you. (Not sure anything can, really...)
So: What's the best path forward?
On Haunted Memories, we had a player-accessible system for declaring your alts for staff. This worked very well, nice, and safely. It did 90% of what staff ever needs these things for, didn't show other players who was who, and didn't have any false positives(*). It did depend on player honesty and player trust in staffers.
Really though, if you can't trust staff with the knowledge of your alts, why the hell would you play there?
(*) Actually it had some hilarious bugs related to recycled DBrefs getting reused without correctly updating these tables, so for months it showed one of my alts as somebody's armor vouchers or something, but that's a different sort of trouble.