Tracking users in a virtual world
I have a virtual world (MMO environment) in which I require users to login with a username and password into the world. Currently, when a user connects and login I store their socket/connection info in a dictionary; the socket being the key and the account object being the value. However, I later find the need to when for example:
"A sends a message to B"
"Server reckgnonzies this; and B is identified as Bob in the packet"
"Server now needs to know what socket Bob's is"
How can I figure this out without using a very slow for loop?
Quote:login with a username and password
This means that there is some store, a database perchance, which has a list of all user/password pairs.
Assign each of these a unique number (ID). If using a database, primary or any auto increment key will do.
Quote:I store their socket/connection info in a dictionary
Instead, store their ID. Then have the following structures:
- Player, which holds socket, ID and anything else
- ID->Player dictionary
Quote:Original post by AntheusQuote:login with a username and password
This means that there is some store, a database perchance, which has a list of all user/password pairs.
Assign each of these a unique number (ID). If using a database, primary or any auto increment key will do.Quote:I store their socket/connection info in a dictionary
Instead, store their ID. Then have the following structures:
- Player, which holds socket, ID and anything else
- ID->Player dictionary
Wouldn't the username already function as a unique identifier?
You probably want a sort of connection/player object that stores both the socket and the username.
When a socket receives data it can easily grab the username in the same object.
Also if someone for example, send a tell to "username", you can have a dictionary with every connection/player object using the username as key.
Then lookup the username in the dictionary to fetch the right connection/player object which contains the socket.
If the problem is "how do I go from socket (int) to user information" then a std::hash_map is probably the right answer in C++, and a similar container (Dictionary<>, dict(), etc) in other languages. This works for TCP.
For UDP, you will have to map remote IP address/port (as seen in recvfrom()) instead, but it's the same idea.
Trusting a user ID sent by the user on the wire is not a good idea, because the user may lie (hack their client).
For UDP, you will have to map remote IP address/port (as seen in recvfrom()) instead, but it's the same idea.
Trusting a user ID sent by the user on the wire is not a good idea, because the user may lie (hack their client).
Quote:Original post by hplus0603
If the problem is "how do I go from socket (int) to user information" then a std::hash_map is probably the right answer in C++, and a similar container (Dictionary<>, dict(), etc) in other languages.
Trusting a user ID sent by the user on the wire is not a good idea, because the user may lie (hack their client).
You don't have to trust the user to get the ID from him, you just need to verify it. I'd use a simple std::vector and the user sent ID for indexing, then for validation I'd compare the stored IP address/port with the sender's.
Quote:You don't have to trust the user to get the ID from him, you just need to verify it.
Right, but what have you won? Using a vector instead of a hash_map? And, at that point, you have to write more complex code, because you have to also test that the ID is not out of range for the vector. Plus you have to manage the vector integer name space. Neither of which is hard, but all of which has more possibilities for bugs than just std::hash_map::insert()/erase(). (Or, if your stdlib is older, std::map)
The issue indeed is connection to user info. I'm pairing the end point (UDP) to the dictionary (C#) or hash table in many other languages. The issue here is, if my packet information refers to another user. How would I reference this user easily? Such as sending a 'private' message?
Quote:Original post by hplus0603Quote:You don't have to trust the user to get the ID from him, you just need to verify it.
Right, but what have you won? Using a vector instead of a hash_map?
I just like the lightweight, simple and fast solutoins. Why hash_map if you get away with a simple vector?
Quote:
And, at that point, you have to write more complex code, because you have to also test that the ID is not out of range for the vector. Plus you have to manage the vector integer name space.
you just deriver from std::vector and overload the operator[] where you index by size(), not that many bugs you could cause. sure, those are some more lines of code compared to using hash_map, but the complexity of the overall code is less.
it's like a hashmap without the need of hash and collision-resolving (just the bounds checking).
Quote: Neither of which is hard, but all of which has more possibilities for bugs than just std::hash_map::insert()/erase(). (Or, if your stdlib is older, std::map)
sure, you could use those, you could always use those, but I guess nobody does if he gets away with less complex solutions (although the complexity is hidden under the interface of the stl).
I guess I don't see the complexity of the map based approach?
Vector:
0) receive user packet with IP
1) read id from the user packet
2) check whether ID is in range for vector, if not -> bad id
3) read user information from vector
4) compare IP address in user information with IP from user packet, if different -> bad id
Hash map:
0) receive user packet with IP
1) retrieve user information from hash map using IP, if not there -> bad id
Of course, this is such a small bit of data that it doesn't really matter, and won't show up in a profiling tool ever. Use whatever you're most comfortable with :-)
Vector:
0) receive user packet with IP
1) read id from the user packet
2) check whether ID is in range for vector, if not -> bad id
3) read user information from vector
4) compare IP address in user information with IP from user packet, if different -> bad id
Hash map:
0) receive user packet with IP
1) retrieve user information from hash map using IP, if not there -> bad id
Of course, this is such a small bit of data that it doesn't really matter, and won't show up in a profiling tool ever. Use whatever you're most comfortable with :-)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement