-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuserManager.js
More file actions
144 lines (125 loc) · 4.71 KB
/
userManager.js
File metadata and controls
144 lines (125 loc) · 4.71 KB
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
138
139
140
141
142
143
144
/**
* An object that manages the users and their name and socket.
* Sockets received by this object should be socket.io sockets, or minimally
* objects which can have named properties set and gotten in the same way.
*/
/**
* Creates and returns a new user manager with the provided default username.
*/
function createUserManager(defaultUsername){
return new userManager(defaultUsername);
}
function userManager(defaultUsername){
//removeUser's call to usernameExists via a callback causes this to change scope,
//and the method to fail. This ensures self always refers to the current scope of this.
var self = this;
self.socketsByUsername = {};
self.defaultUsername = defaultUsername;
/**
* Removes all existing users from the manager.
*/
function _clearUsers(){
self.socketsByUsername = {};
}
self.clearUsers = _clearUsers;
/**
* Indicates whether the provided username exists in the user manager.
* @return
*/
function _usernameExists(username){
return self.socketsByUsername.hasOwnProperty(username);
}
self.usernameExists = _usernameExists;
/**
* Creates a user for the provided socket, adding it to the internal map
* and giving it a username.
* @param socket Socket for which to create a user.
* @param callback Callback that is called after creating the user. It receives the username as a parameter.
*/
function _createUser(socket, callback){
var username = self.generateUsername();
socket.set('username', username, function(){
self.socketsByUsername[username] = socket;
callback(username);
});
}
self.createUser = _createUser;
/**
* Removes the user that corresponds to the provided socket.
* If no user corresponds to that socket, does nothing.
* @param socket Socket whose user to remove
* @param callback Called after a successful removal. Receives one parameter, the removed username.
* @param errback Optional, called with an error message if removal fails.
*/
function _removeUser(socket, callback, errback){
socket.get('username', function(err, username){
if(err){
if(errback){
errback(err);
}
return;
}
if(self.usernameExists(username)){
delete self.socketsByUsername[username];
callback(username);
} else {
if(errback){
errback("No user associated to socket");
}
}
});
}
self.removeUser = _removeUser;
/**
* Attempts to rename a user.
* If new name is free and socket has a user, user is renamed.
* @param socket Socket whose user to rename
* @param newUsername New username to give to the user
* @param callback Called in case of success. Receives one parameter, the old username.
* @param existsCallback Called if the operation fails specifically because newUsername is already in use.
* @param errback Optional, called with an error message in case of unhandled failure.
*/
function _renameUser(socket, newUsername, callback, existsCallback, errback){
//Call proper callback if the new name is already in use
if(self.usernameExists(newUsername)){
existsCallback();
return;
}
//If name is free, then remove socket's user and add it back with its new name.
self.removeUser(socket, function(oldUsername){
socket.set('username', newUsername, function(){
self.socketsByUsername[newUsername] = socket;
callback(oldUsername);
});
}, errback);
}
self.renameUser = _renameUser;
/**
* Generates an unused username, containing the default username and probably a number.
* @return The generated username
*/
function _generateUsername(){
var newUsername;
if(!self.usernameExists(self.defaultUsername)){
newUsername = self.defaultUsername;
} else {
var i = 2;
while(self.usernameExists(self.defaultUsername + i)){
i++;
}
newUsername = self.defaultUsername + i;
}
return newUsername;
}
self.generateUsername = _generateUsername;
/**
* Returns the socket associated with the provided username.
* @param username Name by which to get a socket.
* @return the user's socket, or undefined if there isn't one.
*/
function _getUserSocket(username){
return self.socketsByUsername[username];
}
self.getUserSocket = _getUserSocket;
}
exports.create = createUserManager;