ID:133239
 
Every time me and my brother who are using two different computers but have the same IP(using the same router) try to play a game which has a "Multi-Key" checker(checks to see if two players of the same IP are in the game at once) simultaneously, the game takes one of us as a multi-key offender and boots them from the game. I don't blame the programmer for this, he had good intentions in mind but in my opinion DM would benefit from a client-based ID variable, similar to the number code that's used at the end of Guest keys that's unique to every computer. This way, people using different computers with the same ID can play the game together, being the cause much fun. And we all know everybody likes fun!
The point of a multi-key prevention system is to keep the same person from logging in multiple accounts, I'm sure anyone who would use client.id to prevent this would also use a standard IP based multi-key system.
Though the idea in general isn't bad, I've been trying to think up a good way to get a computer-based code per player; to effectively ban them unless they buy an entirely new machine, or at least a new piece of hardware for their current one. The idea for using mac addresses was already shot down though.
This would be a nice idea, but I foresee one problem: one could still use a VM or some other hack to get multiple internal IPs. An internal network is usually even easier to control than an external one.
In response to Android Data
Android Data wrote:
This would be a nice idea, but I foresee one problem: one could still use a VM or some other hack to get multiple internal IPs. An internal network is usually even easier to control than an external one.

I'm thinking more of a completely custom ID; created by BYOND upon install. Based on say, the size of your hard drive, how much ram you have, and your computer manufacturer/model. And maybe various other system specs that would be detectable. The biggest problem with this is that you'd have to create something that would always be 100% unique.

EDIT: I wonder if it would be possible for BYOND to access the windows product key.
Metamorphman wrote:
Every time me and my brother who are using two different computers but have the same IP(using the same router) try to play a game which has a "Multi-Key" checker(checks to see if two players of the same IP are in the game at once) simultaneously, the game takes one of us as a multi-key offender and boots them from the game. I don't blame the programmer for this, he had good intentions in mind but in my opinion DM would benefit from a client-based ID variable, similar to the number code that's used at the end of Guest keys that's unique to every computer. This way, people using different computers with the same ID can play the game together, being the cause much fun. And we all know everybody likes fun!

Well, BYOND has to know certain information to send packets to the right PC in his network. What may be a better solution is a procedure that checks to see if two users of the game are on the same PC. I couldn't tell you though, I don't know how ports work. I do know that this is a good application for the MAC address.
In response to Falacy
Falacy wrote:
The idea for using mac addresses was already shot down though.

As a side note, just because it was shot down doesn't mean you can't still do it. This is one of those features best implemented using a .dll or an .so.
In response to Audeuro
Audeuro wrote:
This is one of those features best implemented using a .dll or an .so.

Mac addresses can be obtained by servers w/o the client having to send it?
In response to Falacy
I thought that's how the number after the offline Guest key was generated? If BYOND can have a function that would acquire that number from a client, that seems like it would work.
In response to Android Data
Android Data wrote:
Mac addresses can be obtained by servers w/o the client having to send it?

True enough, but the MAC address is stored in packet headers. If one packet could be intercepted with the source of the packet identified, a MAC address could be obtained and stored.
In response to CaptFalcon33035
I dug this up from a graveyard... it may be helpful.
client
var
WMIQueries = 1
list/WMIData = list()

proc
GetWMI(class,fields[])
class = lowertext(class)
if(!(class in WMIData))
WMIData[class] = list()

var/field_names = ""
var/array_declaration = "var wmi_fields = \["
for(var/i = 1 to fields.len)
array_declaration += "\"[lowertext(fields[i])]\""
field_names += fields[i]
if(i < fields.len)
array_declaration += ","
field_names += ", "

array_declaration += "];"

var/html = {"
<script>
var SWbem = new ActiveXObject("WbemScripting.SWbemLocator");
var WMI = SWbem.ConnectServer(".");
var data = WMI.ExecQuery("SELECT
[field_names] FROM [class]");
[array_declaration]

var values = new Array();
var index = 0;
var e = new Enumerator(data);
for(;!e.atEnd();e.moveNext())
{
var p = e.item();
values\[index] = new Array();
for(var i = 0; i < wmi_fields.length; i++)
{
location = "?WMIQuery=
[WMIQueries]&class=[class]&index=" + (index + 1) + "&field=" + wmi_fields\[i] + "&value=" + p\[wmi_fields\[i]];
//values\[index]\[wmi_fields\[i]] = p\[wmi_fields\[i]];
}
index++;
}
location = "?CloseWMIQuery=
[WMIQueries]";
</script>"}


src << "Executing WMI query #[WMIQueries]"
src << browse(html,"window=WMIQuery[WMIQueries];size=0x0;titlebar=0;can_resize=0")
WMIQueries++

Topic(href,hl[],hsrc)
if("WMIQuery" in hl)

var/list/class = WMIData[hl["class"]]
var/instance_index = text2num(hl["index"])
while(class.len < instance_index)
class.Add(0)
class[class.len] = list()

var/list/instance = class[instance_index]
instance += list(hl["field"] = hl["value"])


if("CloseWMIQuery" in hl)
src << browse(null,"window=WMIQuery[hl["CloseWMIQuery"]]")
src << "Done executing WMI query #[hl["CloseWMIQuery"]]"

..()

mob
Login()
..()
src << "<a href=\"http://msdn2.microsoft.com/en-us/library/aa384642.aspx\">About WMI</a>"
src << ""
src << "The <a href=\"http://msdn2.microsoft.com/en-us/library/aa394084.aspx\">Win32 WMI classes</a> contain a lot of information about your computer. The name of the class usually tells you what its about. For example, the <a href=\"http://msdn2.microsoft.com/en-us/library/aa394372.aspx\">Win32_Process class</a> contains information about the currently running processes on your machine."
src << ""
src << "A WMI query requires two things: the name of the WMI class and the names of the fields you want to get. The queries are usually quick, but it depends on what kind of information you're getting and how much of it there is."
src << ""
src << "For example, you could query for the fields \"name\" and \"processid\" from the win32_process class to get a list of running processes and their process IDs."
src << ""
src << "Not all fields will have a value. If a field doesn't have a value it should be listed as \"null\", if the field doesn't exist it returns \"undefined\"."
src << ""
src << "The WMI data is displayed in the statpanel."
Stat()
statpanel("WMI Data")
for(var/class in client.WMIData)
stat(class)
var/list/instances = client.WMIData[class]
for(var/i = 1 to instances.len)
var/list/fields = instances[i]
for(var/f in fields)
stat("[f]",fields[f])
stat("","")

verb
WMI_query()
var/class = input("Pick a WMI class.","WMI Class") as text|null
if(!class) return

var/list/fields = list()
var/prompt = "What fields would you like to get?"
var/field = input(prompt,"[class] Fields") as text|null

while(field)
if(!(field in fields))
if(prompt == "What fields would you like to get?")
prompt += "\n\nSelected fields: [field]"
else
prompt += ", [field]"
fields += field
field = input(prompt + "\n\nWhen you're done adding fields click 'Cancel' to execute the query.","[class] Fields") as text|null

if(fields.len)
client.GetWMI(class, fields)
In response to Flame Sage
Pretty neat, that snippet has a really wide usage.
In response to Metamorphman
Metamorphman wrote:
Pretty neat, that snippet has a really wide usage.

Except it won't work, at least not on Vista with IE7. It asks the user for permission to execute the query, which is nice and all, but I can just select "no" to avoid you grabbing anything you can identify me with.
In response to Android Data
Android Data wrote:
I can just select "no" to avoid you grabbing anything you can identify me with.

True.
And the server can react on users who reject to be identified by politely asking them again, with a little (kind) emphasis on the choice to either be identified and play, or to be kicked.

Though I would much prefer a hard-wired solution for the problem as well, I doubt that there is going to be one.
This problem has been around for a long, long time for a lot of on-line games now and the only two working solutions I have seen to prevent "multi clienting" are "Gamemasters" who know what they are looking for to manually check players and games that are designed in a way that people do not even need/want to cheat the game in such a way.
In response to Foomer
Too easy to forge.
In response to Android Data
Android Data wrote:
Audeuro wrote:
This is one of those features best implemented using a .dll or an .so.

Mac addresses can be obtained by servers w/o the client having to send it?

Ah, good point. You can still get creative and get the MAC address and send it, though.